aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.c
diff options
context:
space:
mode:
authorPhil Muldoon <pmuldoon@gcc.gnu.org>2014-10-27 17:21:42 +0000
committerPhil Muldoon <pmuldoon@gcc.gnu.org>2014-10-27 17:21:42 +0000
commitddc8de034a1f79861fed57b231813a5c5c48a130 (patch)
tree93d1166de8622ded3678c7599baa864b75cb5e25 /gcc/c/c-decl.c
parent50a504654d2c54b270615541ab66af7c4f3d664f (diff)
downloadgcc-ddc8de034a1f79861fed57b231813a5c5c48a130.zip
gcc-ddc8de034a1f79861fed57b231813a5c5c48a130.tar.gz
gcc-ddc8de034a1f79861fed57b231813a5c5c48a130.tar.bz2
Let GDB reuse GCC's parser.
2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Tom Tromey <tromey@redhat.com> * aclocal.m4: New file. * callbacks.cc: New file. * callbacks.hh: New file. * cc1plugin-config.h.in: New file. * configure: New file. * configure.ac: New file. * connection.cc: New file. * connection.hh: New file. * findcomp.cc: New file. * findcomp.hh: New file. * libcc1.cc: New file. * libcc1plugin.sym: New file. * libcc1.sym: New file. * Makefile.am: New file. * Makefile.in: New file. * marshall.cc: New file. * marshall.hh: New file. * names.cc: New file. * names.hh: New file. * plugin.cc: New file. * rpc.hh: New file. * status.hh: New file. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Tom Tromey <tromey@redhat.com> * gcc-c-fe.def: New file. * gcc-c-interface.h: New file. * gcc-interface.h: New file. 2014-10-27 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. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Tom Tromey <tromey@redhat.com> * aclocal.m4, configure: Rebuild. * Makefile.in (aclocal_deps): Add gcc-plugin.m4. * configure.ac: Use GCC_ENABLE_PLUGINS. * stor-layout.c (finish_bitfield_layout): Now public. Change argument type to 'tree'. (finish_record_layout): Update. * stor-layout.h (finish_bitfield_layout): Declare. 2014-10-27 Tom Tromey <tromey@redhat.com> * gcc-plugin.m4: New file. 2014-10-27 Phil Muldoon <pmuldoon@redhat.com> Tom Tromey <tromey@redhat.com> * Makefile.def: Add libcc1 to host_modules. * configure.ac (host_tools): Add libcc1. * Makefile.in, configure: Rebuild. From-SVN: r216748
Diffstat (limited to 'gcc/c/c-decl.c')
-rw-r--r--gcc/c/c-decl.c164
1 files changed, 149 insertions, 15 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 7d1840e..d0105ff 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -220,21 +220,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. */
@@ -250,6 +235,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"),
@@ -618,6 +693,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);
@@ -628,6 +712,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,
@@ -1494,6 +1580,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);
+}
/* Subroutine of compare_decls. Allow harmless mismatches in return
and argument types provided that the type modes match. This function