From: David Malcolm <dmalcolm@redhat.com>
To: Iain Buclaw <ibuclaw@gdcproject.org>,
gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH 02/14] Add D frontend (GDC) implementation.
Date: Mon, 15 Oct 2018 14:25:00 -0000 [thread overview]
Message-ID: <1539613141.14521.172.camel@redhat.com> (raw)
In-Reply-To: <CABOHX+c1-je7h4sABuyfYzEvnKj=Ev0ExEWYYm9WbbpjjoZY7Q@mail.gmail.com>
On Tue, 2018-09-18 at 02:33 +0200, Iain Buclaw wrote:
> This patch adds the D front-end implementation, the only part of the
> compiler that interacts with GCC directly, and being the parts that I
> maintain, is something that I can talk about more directly.
>
> For the actual code generation pass, that converts the front-end AST
> to GCC trees, most parts use a separate Visitor interfaces to do a
> certain kind of lowering, for instance, types.cc builds *_TYPE trees
> from AST Type's. The Visitor class is part of the DMD front-end, and
> is defined in dfrontend/visitor.h.
>
> There are also a few interfaces which have their headers in the DMD
> frontend, but are implemented here because they do something that
> requires knowledge of the GCC backend (d-target.cc), does something
> that may not be portable, or differ between D compilers
> (d-frontend.cc) or are a thin wrapper around something that is
> managed
> by GCC (d-diagnostic.cc).
>
> Many high level operations result in generation of calls to D runtime
> library functions (runtime.def), all with require some kind of
> runtime
> type information (typeinfo.cc). The compiler also generates
> functions
> for registering/deregistering compiled modules with the D runtime
> library (modules.cc).
>
> As well as the D language having it's own built-in functions
> (intrinsics.cc), we also expose GCC builtins to D code via a
> `gcc.builtins' module (d-builtins.cc), and give special treatment to
> a
> number of UDAs that could be applied to functions (d-attribs.cc).
>
>
> That is roughly the high level jist of how things are currently
> organized.
>
> ftp://ftp.gdcproject.org/patches/v4/02-v4-d-frontend-gdc.patch
Hi Iain. I took at look at this patch, focusing on the diagnostics
side of things.
These are more suggestions than hard review blockers.
diff --git a/gcc/d/d-attribs.c b/gcc/d/d-attribs.c
new file mode 100644
index 00000000000..6c65b8cad9e
--- /dev/null
+++ b/gcc/d/d-attribs.c
I believe all new C++ source files are meant to be .cc, rather than .c,
so this should be d-attribs.cc, rather that d-attribs.c.
[...snip...]
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
new file mode 100644
index 00000000000..c698890ba07
--- /dev/null
+++ b/gcc/d/d-codegen.cc
[...snip...]
+/* Return the GCC location for the D frontend location LOC. */
+
+location_t
+get_linemap (const Loc& loc)
+{
I don't like the name "get_linemap", as it suggests to me that it's
getting the "struct line_map *" for LOC, rather than a location_t.
How about "get_location_t" instead, or "make_location_t"? The latter
feels more appropriate, as it's doing non-trivial work.
+ location_t gcc_location = input_location;
+
+ if (loc.filename)
+ {
+ linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
+ linemap_line_start (line_table, loc.linnum, 0);
+ gcc_location = linemap_position_for_column (line_table, loc.charnum);
+ linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
+ }
+
+ return gcc_location;
+}
[...snip...]
diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc
new file mode 100644
index 00000000000..8b8a21e31b6
--- /dev/null
+++ b/gcc/d/d-diagnostic.cc
@@ -0,0 +1,347 @@
+/* d-diagnostics.cc -- D frontend interface to gcc diagnostics.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "dmd/globals.h"
+#include "dmd/errors.h"
+
+#include "tree.h"
+#include "options.h"
+#include "diagnostic.h"
+
+#include "d-tree.h"
+
+
+/* Rewrite the format string FORMAT to deal with any format extensions not
+ supported by pp_format(). The result should be freed by the caller. */
+static char *
+expand_format (const char *format)
Am I right in thinking this is to handle FORMAT strings coming from the
upstream D frontend, and this has its own formatting conventions?
Please can the leading comment have example(s) of the format, and what
it becomes (e.g. the backticks thing).
Maybe adopt a naming convention in the file, to distinguish d format
strings from pp format strings? Maybe "d_format" vs "gcc_format"
?(though given the verbatim vs !verbatim below, am not sure how
feasible that is).
Maybe rename this function to expand_d_format??
(Might be nice to add some unittesting of this function via "selftest",
but that's definitely not a requirement; it's awkward to add right now)
+{
+ OutBuffer buf;
+ bool inbacktick = false;
+
+ for (const char *p = format; *p; )
+ {
+ while (*p != '\0' && *p != '%' && *p != '`')
+ {
+ buf.writeByte (*p);
+ p++;
+ }
+
+ if (*p == '\0')
+ break;
+
+ if (*p == '`')
+ {
+ /* Text enclosed by `...` are translated as a quoted string. */
+ if (inbacktick)
+ {
+ buf.writestring ("%>");
+ inbacktick = false;
+ }
+ else
+ {
+ buf.writestring ("%<");
+ inbacktick = true;
+ }
+ p++;
+ continue;
+ }
+
+ /* Check the conversion specification for unhandled flags. */
+ buf.writeByte (*p);
+ p++;
+
+ Lagain:
+ switch (*p)
+ {
+ case '\0':
+ /* Malformed format string. */
+ gcc_unreachable ();
+
+ case '-':
+ /* Remove whitespace formatting. */
+ p++;
+ while (ISDIGIT (*p))
+ p++;
+ goto Lagain;
+
+ case '0':
+ /* Remove zero padding from format string. */
+ while (ISDIGIT (*p))
+ p++;
+ goto Lagain;
+
+ case 'X':
+ /* Hex format only supports lower-case. */
+ buf.writeByte ('x');
+ p++;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ gcc_assert (!inbacktick);
+ return buf.extractString ();
+}
+
+/* Helper routine for all error routines. Reports a diagnostic specified by
+ KIND at the explicit location LOC, where the message FORMAT has not yet
+ been translated by the gcc diagnostic routines. */
+
+static void ATTRIBUTE_GCC_DIAG(3,0)
+d_diagnostic_report_diagnostic (const Loc& loc, int opt, const char *format,
+ va_list ap, diagnostic_t kind, bool verbatim)
Given the call to expand_format for the !verbatim case, it seems that
ATTRIBUTE_GCC_DIAG isn't necessarily quite right here, as FORMAT would
then be a D format string. But it's probably close enough for now.
+{
+ va_list argp;
+ va_copy (argp, ap);
+
+ if (loc.filename || !verbatim)
+ {
+ rich_location rich_loc (line_table, get_linemap (loc));
+ diagnostic_info diagnostic;
+ char *xformat = expand_format (format);
+
+ diagnostic_set_info (&diagnostic, xformat, &argp, &rich_loc, kind);
+ if (opt != 0)
+ diagnostic.option_index = opt;
+
+ diagnostic_report_diagnostic (global_dc, &diagnostic);
+ free (xformat);
+ }
+ else
+ {
+ /* Write verbatim messages with no location direct to stream. */
+ text_info text;
+ text.err_no = errno;
+ text.args_ptr = &argp;
+ text.format_spec = expand_format (format);
+ text.x_data = NULL;
+
+ pp_format_verbatim (global_dc->printer, &text);
+ pp_newline_and_flush (global_dc->printer);
+ }
+
+ va_end (argp);
+}
+
+/* Print a hard error message with explicit location LOC, increasing the
+ global or gagged error count. */
+
+void ATTRIBUTE_GCC_DIAG(2,3)
+error (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ verror (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+verror (const Loc& loc, const char *format, va_list ap,
+ const char *p1, const char *p2, const char *)
This one needs a leading comment: what's the deal with P1 and P2?
+{
+ if (!global.gag || global.params.showGaggedErrors)
+ {
+ char *xformat;
+
+ /* Build string and emit. */
+ if (p2 != NULL)
+ xformat = xasprintf ("%s %s %s", p1, p2, format);
+ else if (p1 != NULL)
+ xformat = xasprintf ("%s %s", p1, format);
+ else
+ xformat = xasprintf ("%s", format);
+
+ d_diagnostic_report_diagnostic (loc, 0, xformat, ap,
+ global.gag ? DK_ANACHRONISM : DK_ERROR,
+ false);
+ free (xformat);
+ }
+
+ if (global.gag)
+ global.gaggedErrors++;
+
+ global.errors++;
+}
+
+/* Print supplementary message about the last error with explicit location LOC.
+ This doesn't increase the global error count. */
+
+void ATTRIBUTE_GCC_DIAG(2,3)
+errorSupplemental (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ verrorSupplemental (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+verrorSupplemental (const Loc& loc, const char *format, va_list ap)
+{
+ if (global.gag && !global.params.showGaggedErrors)
+ return;
+
+ d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, false);
+}
+
+/* Print a warning message with explicit location LOC, increasing the
+ global warning count. */
+
+void ATTRIBUTE_GCC_DIAG(2,3)
+warning (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ vwarning (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+vwarning (const Loc& loc, const char *format, va_list ap)
+{
+ if (global.params.warnings && !global.gag)
+ {
+ /* Warnings don't count if gagged. */
+ if (global.params.warnings == 1)
What's the magic "1" value above? Can it be an enum? (or is this
something from the upstream parsing code?)
+ global.warnings++;
+
+ d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_WARNING, false);
+ }
+}
+
+/* Print supplementary message about the last warning with explicit location
+ LOC. This doesn't increase the global warning count. */
+
+void ATTRIBUTE_GCC_DIAG(2,3)
+warningSupplemental (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ vwarningSupplemental (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+vwarningSupplemental (const Loc& loc, const char *format, va_list ap)
+{
+ if (!global.params.warnings || global.gag)
+ return;
+
+ d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, false);
+}
+
+/* Print a deprecation message with explicit location LOC, increasing the
+ global warning or error count depending on how deprecations are treated. */
+
+void ATTRIBUTE_GCC_DIAG(2,3)
+deprecation (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ vdeprecation (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+vdeprecation (const Loc& loc, const char *format, va_list ap,
+ const char *p1, const char *p2)
+{
Again: please can this have a leading comment explaining P1 and P2.
+ if (global.params.useDeprecated == 0)
+ verror (loc, format, ap, p1, p2);
+ else if (global.params.useDeprecated == 2 && !global.gag)
Can these "0" and "2" values be enums?
+ {
+ char *xformat;
+
+ /* Build string and emit. */
+ if (p2 != NULL)
+ xformat = xasprintf ("%s %s %s", p1, p2, format);
+ else if (p1 != NULL)
+ xformat = xasprintf ("%s %s", p1, format);
+ else
+ xformat = xasprintf ("%s", format);
+
+ d_diagnostic_report_diagnostic (loc, OPT_Wdeprecated, xformat, ap,
+ DK_WARNING, false);
+ free (xformat);
+ }
+}
+
+/* Print supplementary message about the last deprecation with explicit
+ location LOC. This does not increase the global error count. */
+
+void ATTRIBUTE_GCC_DIAG(2,3)
+deprecationSupplemental (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ vdeprecationSupplemental (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+vdeprecationSupplemental (const Loc& loc, const char *format, va_list ap)
+{
+ if (global.params.useDeprecated == 0)
+ verrorSupplemental (loc, format, ap);
+ else if (global.params.useDeprecated == 2 && !global.gag)
+ d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, false);
As before for the "0" and "2".
+}
+
+/* Print a verbose message with explicit location LOC. */
+
+void ATTRIBUTE_GCC_DIAG(2, 3)
+message (const Loc& loc, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ vmessage (loc, format, ap);
+ va_end (ap);
+}
+
+void ATTRIBUTE_GCC_DIAG(2,0)
+vmessage(const Loc& loc, const char *format, va_list ap)
+{
+ d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, true);
+}
+
+/* Same as above, but doesn't take a location argument. */
+
+void ATTRIBUTE_GCC_DIAG(1, 2)
+message (const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ vmessage (Loc (), format, ap);
+ va_end (ap);
+}
+
+/* Call this after printing out fatal error messages to clean up and
+ exit the compiler. */
+
+void
+fatal (void)
+{
+ exit (FATAL_EXIT_CODE);
+}
[...snip...]
diff --git a/gcc/d/d-spec.c b/gcc/d/d-spec.c
new file mode 100644
index 00000000000..6a68ebbcf24
--- /dev/null
+++ b/gcc/d/d-spec.c
As above, this new C++ file should be .cc, rather than .c.
[...snip...]
Hope this is constructive
Dave
next prev parent reply other threads:[~2018-10-15 14:19 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-18 0:34 Iain Buclaw
2018-09-19 20:06 ` Iain Buclaw
2018-10-14 19:28 ` Richard Sandiford
2018-10-15 7:36 ` Iain Buclaw
2018-10-20 10:51 ` Richard Sandiford
2018-10-20 15:53 ` Iain Buclaw
2018-10-20 22:57 ` Iain Buclaw
2018-10-22 1:13 ` Iain Buclaw
2018-10-23 14:47 ` Richard Sandiford
2018-10-23 19:49 ` Iain Buclaw
2018-10-25 14:12 ` Is the D frontend good to go? (was Re: [PATCH 02/14] Add D frontend (GDC) implementation.) David Malcolm
2018-10-25 15:01 ` Iain Buclaw
2018-10-26 10:07 ` Richard Biener
2018-10-28 23:55 ` Iain Buclaw
2018-10-16 11:14 ` [PATCH 02/14] Add D frontend (GDC) implementation Richard Sandiford
2018-10-16 11:39 ` Richard Sandiford
2018-10-21 0:02 ` Iain Buclaw
2018-10-15 14:25 ` David Malcolm [this message]
2018-10-15 16:46 ` Iain Buclaw
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1539613141.14521.172.camel@redhat.com \
--to=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=ibuclaw@gdcproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).