public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@redhat.com>
To: Jeff Law <law@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH 3/5] introduce the binding oracle
Date: Thu, 19 Jun 2014 20:43:00 -0000	[thread overview]
Message-ID: <87vbrwbpfl.fsf@fleche.redhat.com> (raw)
In-Reply-To: <5376632D.3000409@redhat.com> (Jeff Law's message of "Fri, 16 May	2014 13:12:45 -0600")

Jeff> Just a nit.  C-style comment would be appreciated.  It might also help
Jeff> to clarify what "much more sane" really means here.

Jeff> Otherwise, it looks OK to me.

Here's the updated patch.

Tom

2014-06-19  Phil Muldoon  <pmuldoon@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* c-tree.h (enum c_oracle_request): New.
	(c_binding_oracle_function): New typedef.
	(c_binding_oracle, c_pushtag, c_bind): Declare.
	* c-decl.c (c_binding_oracle): New global.
	(I_SYMBOL_CHECKED): New macro.
	(i_symbol_binding): New function.
	(I_SYMBOL_BINDING, I_SYMBOL_DECL): Redefine.
	(I_TAG_CHECKED): New macro.
	(i_tag_binding): New function.
	(I_TAG_BINDING, I_TAG_DECL): Redefine.
	(I_LABEL_CHECKED): New macro.
	(i_label_binding): New function.
	(I_LABEL_BINDING, I_LABEL_DECL): Redefine.
	(c_print_identifier): Save and restore c_binding_oracle.
	(c_pushtag, c_bind): New functions.

---
 gcc/c/ChangeLog |  19 +++++++
 gcc/c/c-decl.c  | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 gcc/c/c-tree.h  |  24 +++++++++
 3 files changed, 192 insertions(+), 15 deletions(-)

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 3456030..b0f47af 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -216,21 +216,6 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
 #define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
 #define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
 
-#define I_SYMBOL_BINDING(node) \
-  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->symbol_binding)
-#define I_SYMBOL_DECL(node) \
- (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
-
-#define I_TAG_BINDING(node) \
-  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->tag_binding)
-#define I_TAG_DECL(node) \
- (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
-
-#define I_LABEL_BINDING(node) \
-  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->label_binding)
-#define I_LABEL_DECL(node) \
- (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
-
 /* Each C symbol points to three linked lists of c_binding structures.
    These describe the values of the identifier in the three different
    namespaces defined by the language.  */
@@ -246,6 +231,96 @@ struct GTY(()) lang_identifier {
 extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
 [(sizeof(struct lang_identifier) == C_SIZEOF_STRUCT_LANG_IDENTIFIER) ? 1 : -1];
 
+/* The binding oracle; see c-tree.h.  */
+void (*c_binding_oracle) (enum c_oracle_request, tree identifier);
+
+/* This flag is set on an identifier if we have previously asked the
+   binding oracle for this identifier's symbol binding.  */
+#define I_SYMBOL_CHECKED(node) \
+  (TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding* *
+i_symbol_binding (tree node)
+{
+  struct lang_identifier *lid
+    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+  if (lid->symbol_binding == NULL
+      && c_binding_oracle != NULL
+      && !I_SYMBOL_CHECKED (node))
+    {
+      /* Set the "checked" flag first, to avoid infinite recursion
+	 when the binding oracle calls back into gcc.  */
+      I_SYMBOL_CHECKED (node) = 1;
+      c_binding_oracle (C_ORACLE_SYMBOL, node);
+    }
+
+  return &lid->symbol_binding;
+}
+
+#define I_SYMBOL_BINDING(node) (*i_symbol_binding (node))
+
+#define I_SYMBOL_DECL(node) \
+ (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
+
+/* This flag is set on an identifier if we have previously asked the
+   binding oracle for this identifier's tag binding.  */
+#define I_TAG_CHECKED(node) \
+  (TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding **
+i_tag_binding (tree node)
+{
+  struct lang_identifier *lid
+    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+  if (lid->tag_binding == NULL
+      && c_binding_oracle != NULL
+      && !I_TAG_CHECKED (node))
+    {
+      /* Set the "checked" flag first, to avoid infinite recursion
+	 when the binding oracle calls back into gcc.  */
+      I_TAG_CHECKED (node) = 1;
+      c_binding_oracle (C_ORACLE_TAG, node);
+    }
+
+  return &lid->tag_binding;
+}
+
+#define I_TAG_BINDING(node) (*i_tag_binding (node))
+
+#define I_TAG_DECL(node) \
+ (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
+
+/* This flag is set on an identifier if we have previously asked the
+   binding oracle for this identifier's label binding.  */
+#define I_LABEL_CHECKED(node) \
+  (TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding **
+i_label_binding (tree node)
+{
+  struct lang_identifier *lid
+    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+  if (lid->label_binding == NULL
+      && c_binding_oracle != NULL
+      && !I_LABEL_CHECKED (node))
+    {
+      /* Set the "checked" flag first, to avoid infinite recursion
+	 when the binding oracle calls back into gcc.  */
+      I_LABEL_CHECKED (node) = 1;
+      c_binding_oracle (C_ORACLE_LABEL, node);
+    }
+
+  return &lid->label_binding;
+}
+
+#define I_LABEL_BINDING(node) (*i_label_binding (node))
+
+#define I_LABEL_DECL(node) \
+ (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
+
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
@@ -612,6 +687,15 @@ decl_jump_unsafe (tree decl)
 void
 c_print_identifier (FILE *file, tree node, int indent)
 {
+  void (*save) (enum c_oracle_request, tree identifier);
+
+  /* Temporarily hide any binding oracle.  Without this, calls to
+     debug_tree from the debugger will end up calling into the oracle,
+     making for a confusing debug session.  As the oracle isn't needed
+     here for normal operation, it's simplest to suppress it.  */
+  save = c_binding_oracle;
+  c_binding_oracle = NULL;
+
   print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
   print_node (file, "tag", I_TAG_DECL (node), indent + 4);
   print_node (file, "label", I_LABEL_DECL (node), indent + 4);
@@ -622,6 +706,8 @@ c_print_identifier (FILE *file, tree node, int indent)
       fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
 	       (void *) rid, IDENTIFIER_POINTER (rid));
     }
+
+  c_binding_oracle = save;
 }
 
 /* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
@@ -1486,6 +1572,54 @@ pushtag (location_t loc, tree name, tree type)
 	}
     }
 }
+
+/* An exported interface to pushtag.  This is used by the gdb plugin's
+   binding oracle to introduce a new tag binding.  */
+
+void
+c_pushtag (location_t loc, tree name, tree type)
+{
+  pushtag (loc, name, type);
+}
+
+/* An exported interface to bind a declaration.  LOC is the location
+   to use.  DECL is the declaration to bind.  The decl's name is used
+   to determine how it is bound.  If DECL is a VAR_DECL, then
+   IS_GLOBAL determines whether the decl is put into the global (file
+   and external) scope or the current function's scope; if DECL is not
+   a VAR_DECL then it is always put into the file scope.  */
+
+void
+c_bind (location_t loc, tree decl, bool is_global)
+{
+  struct c_scope *scope;
+  bool nested = false;
+
+  if (TREE_CODE (decl) != VAR_DECL || current_function_scope == NULL)
+    {
+      /* Types and functions are always considered to be global.  */
+      scope = file_scope;
+      DECL_EXTERNAL (decl) = 1;
+      TREE_PUBLIC (decl) = 1;
+    }
+  else if (is_global)
+    {
+      /* Also bind it into the external scope.  */
+      bind (DECL_NAME (decl), decl, external_scope, true, false, loc);
+      nested = true;
+      scope = file_scope;
+      DECL_EXTERNAL (decl) = 1;
+      TREE_PUBLIC (decl) = 1;
+    }
+  else
+    {
+      DECL_CONTEXT (decl) = current_function_decl;
+      TREE_PUBLIC (decl) = 0;
+      scope = current_function_scope;
+    }
+
+  bind (DECL_NAME (decl), decl, scope, false, nested, loc);
+}
 \f
 /* Subroutine of compare_decls.  Allow harmless mismatches in return
    and argument types provided that the type modes match.  This function
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 133930f..a6c3527 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -665,12 +665,36 @@ extern int current_function_returns_abnormally;
 extern enum machine_mode c_default_pointer_mode;
 
 /* In c-decl.c */
+
+/* Tell the binding oracle what kind of binding we are looking for.  */
+
+enum c_oracle_request
+{
+  C_ORACLE_SYMBOL,
+  C_ORACLE_TAG,
+  C_ORACLE_LABEL
+};
+
+/* If this is non-NULL, then it is a "binding oracle" which can lazily
+   create bindings when needed by the C compiler.  The oracle is told
+   the name and type of the binding to create.  It can call pushdecl
+   or the like to ensure the binding is visible; or do nothing,
+   leaving the binding untouched.  c-decl.c takes note of when the
+   oracle has been called and will not call it again if it fails to
+   create a given binding.  */
+
+typedef void c_binding_oracle_function (enum c_oracle_request, tree identifier);
+
+extern c_binding_oracle_function *c_binding_oracle;
+
 extern void c_finish_incomplete_decl (tree);
 extern void c_write_global_declarations (void);
 extern tree c_omp_reduction_id (enum tree_code, tree);
 extern tree c_omp_reduction_decl (tree);
 extern tree c_omp_reduction_lookup (tree, tree);
 extern tree c_check_omp_declare_reduction_r (tree *, int *, void *);
+extern void c_pushtag (location_t, tree, tree);
+extern void c_bind (location_t, tree, bool);
 
 /* In c-errors.c */
 extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
-- 
1.9.3

  parent reply	other threads:[~2014-06-19 20:43 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-16 15:26 [PATCH 0/5] let gdb reuse gcc'c C compiler Tom Tromey
2014-05-16 15:26 ` [PATCH 1/5] export finish_bitfield_layout from stor-layout Tom Tromey
2014-05-16 18:27   ` Jeff Law
2014-05-16 15:27 ` [PATCH 4/5] add gcc/gdb interface files Tom Tromey
2014-05-22 12:52   ` Jeff Law
2014-05-22 13:16     ` Jakub Jelinek
2014-05-22 15:13       ` Jeff Law
2014-06-04 20:39       ` Tom Tromey
2014-06-05 19:23         ` Jeff Law
2014-06-05 19:30           ` Jakub Jelinek
2014-06-06  1:54             ` Tom Tromey
2014-06-06  5:35               ` Jakub Jelinek
2014-06-09 17:09               ` Jeff Law
2014-06-19 20:45                 ` Tom Tromey
2014-05-16 15:27 ` [PATCH 2/5] c_diagnostic_ignored_function hack Tom Tromey
2014-05-16 16:05   ` Joseph S. Myers
2014-06-19 20:46     ` Tom Tromey
2014-05-16 18:33   ` Jeff Law
2014-05-16 18:42     ` Tom Tromey
2014-05-16 15:27 ` [PATCH 3/5] introduce the binding oracle Tom Tromey
2014-05-16 19:12   ` Jeff Law
2014-06-05 15:31     ` Tom Tromey
2014-06-19 20:43     ` Tom Tromey [this message]
2014-05-16 16:29 ` [PATCH 0/5] let gdb reuse gcc'c C compiler Mike Stump
2014-05-16 18:48 ` [PATCH 5/5] add libcc1 Tom Tromey
2014-05-16 20:29   ` Joseph S. Myers
2014-05-16 21:03     ` Tom Tromey
2014-06-18 21:07     ` Tom Tromey
2014-06-19 20:47     ` Tom Tromey
2014-05-16 21:36   ` Mike Stump
2014-05-16 22:17   ` Mike Stump
2014-06-05 19:34     ` Tom Tromey
2014-06-05 21:35       ` Mike Stump
2014-06-19 20:52   ` Tom Tromey
2014-06-19 21:45     ` Jakub Jelinek
2014-06-19 22:22       ` Tom Tromey
2014-06-20  3:11     ` Trevor Saunders
2014-06-20 15:34       ` Tom Tromey
2014-06-23 19:09         ` Jeff Law
2014-06-24  3:13           ` Trevor Saunders
2014-06-24 17:12             ` Tom Tromey
2014-06-24 18:10               ` Trevor Saunders
2014-07-18 19:00     ` Tom Tromey
2014-07-31  4:49     ` Jeff Law
2014-07-31  8:15       ` Richard Biener
2014-07-31 10:53         ` Trevor Saunders
2014-07-31 11:28           ` Richard Biener
2014-07-31 15:08             ` Joseph S. Myers
2014-07-31 19:20         ` Tom Tromey
2014-07-31 19:21           ` Jakub Jelinek
2014-07-31 19:51           ` Trevor Saunders
2014-07-31 20:07             ` Tom Tromey
2014-08-01  2:18               ` Trevor Saunders
2014-07-31 21:14       ` Mike Stump
2014-08-04 14:23         ` Tom Tromey
2014-08-05 19:34       ` Tom Tromey
2014-08-08 12:15         ` [PATCH 5/5] add libcc1 [gcc-5/changes.html] Jan Kratochvil
2014-08-31 15:12           ` Gerald Pfeifer
2014-09-14 15:07             ` Manuel López-Ibáñez
2014-09-17 14:14               ` Jan Kratochvil
2014-10-09  9:07       ` [PATCH 5/5] add libcc1 Phil Muldoon
2014-10-09  9:12         ` Jakub Jelinek
2014-10-09  9:18         ` Phil Muldoon
2014-10-10 22:31         ` Jeff Law
2014-10-24  7:43           ` Phil Muldoon
2014-10-24  7:53             ` Jakub Jelinek
2014-10-24 16:47             ` Jeff Law
2014-10-27 20:03               ` Phil Muldoon
2014-10-28 13:29                 ` Joseph S. Myers
2014-10-28 18:00                   ` Phil Muldoon
2014-10-29  3:32                     ` Joseph S. Myers
2014-10-29 10:29                     ` Jakub Jelinek
2014-10-29 10:45                       ` Paolo Bonzini
2014-10-29 10:58                         ` Jakub Jelinek
2014-10-29 10:59                           ` Paolo Bonzini
2014-10-29 11:03                             ` Jakub Jelinek
2014-10-29 15:00                               ` Paolo Bonzini
2014-10-29 11:10                             ` Phil Muldoon
2014-10-29 11:42                             ` Phil Muldoon
2014-10-30  5:37                       ` Jeff Law
2014-06-19 20:42 ` [PATCH 0/5] let gdb reuse gcc'c C compiler Tom Tromey
2014-07-30 16:28   ` Tom Tromey

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=87vbrwbpfl.fsf@fleche.redhat.com \
    --to=tromey@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=law@redhat.com \
    /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).