mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libcc1: share basic context code
Both plugins in libcc1 share a fair amount of boilerplate. They both share error-emission code, context management code, and tree GC code. This patch unifies these two bodies of code, avoiding needless duplication. libcc1 * libcc1plugin.cc: Move code to context.cc. * libcp1plugin.cc: Move code to context.cc. * context.hh: New file. * context.cc: New file. * Makefile.in: Rebuild. * Makefile.am (AM_CPPFLAGS): Add more gcc flags. (CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update. (libcc1plugin_la_SOURCES): Add context.hh, context.cc. (libcp1plugin_la_SOURCES): Likewise.
This commit is contained in:
@@ -19,11 +19,10 @@
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
gcc_build_dir = ../gcc
|
||||
AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
|
||||
-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC)
|
||||
CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \
|
||||
-I $(srcdir)/../libcpp/include
|
||||
CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c
|
||||
CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp
|
||||
-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \
|
||||
-I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include
|
||||
CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c
|
||||
CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp
|
||||
AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS)
|
||||
if DARWIN_DYNAMIC_LOOKUP
|
||||
AM_CXXFLAGS += -Wl,-undefined,dynamic_lookup
|
||||
@@ -55,7 +54,8 @@ marshall_c_source = marshall-c.hh
|
||||
marshall_cxx_source = marshall-cp.hh
|
||||
|
||||
libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
|
||||
libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source)
|
||||
libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \
|
||||
$(shared_source) $(marshall_c_source)
|
||||
libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C)
|
||||
libcc1plugin_la_LIBADD = $(libiberty)
|
||||
libcc1plugin_la_DEPENDENCIES = $(libiberty_dep)
|
||||
@@ -64,7 +64,8 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@
|
||||
|
||||
libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym
|
||||
libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) $(marshall_cxx_source)
|
||||
libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \
|
||||
$(shared_source) $(marshall_cxx_source)
|
||||
libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX)
|
||||
libcp1plugin_la_LIBADD = $(libiberty)
|
||||
libcp1plugin_la_DEPENDENCIES = $(libiberty_dep)
|
||||
|
||||
@@ -148,12 +148,12 @@ am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo compiler.lo \
|
||||
names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2)
|
||||
libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS)
|
||||
@ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir)
|
||||
am_libcc1plugin_la_OBJECTS = libcc1plugin.lo $(am__objects_1) \
|
||||
$(am__objects_2)
|
||||
am_libcc1plugin_la_OBJECTS = libcc1plugin.lo context.lo \
|
||||
$(am__objects_1) $(am__objects_2)
|
||||
libcc1plugin_la_OBJECTS = $(am_libcc1plugin_la_OBJECTS)
|
||||
@ENABLE_PLUGIN_TRUE@am_libcc1plugin_la_rpath = -rpath $(plugindir)
|
||||
am_libcp1plugin_la_OBJECTS = libcp1plugin.lo $(am__objects_1) \
|
||||
$(am__objects_2)
|
||||
am_libcp1plugin_la_OBJECTS = libcp1plugin.lo context.lo \
|
||||
$(am__objects_1) $(am__objects_2)
|
||||
libcp1plugin_la_OBJECTS = $(am_libcp1plugin_la_OBJECTS)
|
||||
@ENABLE_PLUGIN_TRUE@am_libcp1plugin_la_rpath = -rpath $(plugindir)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
@@ -379,13 +379,11 @@ visibility = @visibility@
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
gcc_build_dir = ../gcc
|
||||
AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
|
||||
-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC)
|
||||
-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \
|
||||
-I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include
|
||||
|
||||
CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \
|
||||
-I $(srcdir)/../libcpp/include
|
||||
|
||||
CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c
|
||||
CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp
|
||||
CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c
|
||||
CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp
|
||||
AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS) \
|
||||
$(am__append_1)
|
||||
# Can be simplified when libiberty becomes a normal convenience library.
|
||||
@@ -408,7 +406,9 @@ shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \
|
||||
marshall_c_source = marshall-c.hh
|
||||
marshall_cxx_source = marshall-cp.hh
|
||||
libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
|
||||
libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source)
|
||||
libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \
|
||||
$(shared_source) $(marshall_c_source)
|
||||
|
||||
libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C)
|
||||
libcc1plugin_la_LIBADD = $(libiberty)
|
||||
libcc1plugin_la_DEPENDENCIES = $(libiberty_dep)
|
||||
@@ -417,7 +417,9 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@
|
||||
|
||||
libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym
|
||||
libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) $(marshall_cxx_source)
|
||||
libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \
|
||||
$(shared_source) $(marshall_cxx_source)
|
||||
|
||||
libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX)
|
||||
libcp1plugin_la_LIBADD = $(libiberty)
|
||||
libcp1plugin_la_DEPENDENCIES = $(libiberty_dep)
|
||||
@@ -579,6 +581,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compiler.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findcomp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1plugin.Plo@am__quote@
|
||||
|
||||
171
libcc1/context.cc
Normal file
171
libcc1/context.cc
Normal file
@@ -0,0 +1,171 @@
|
||||
/* Generic plugin context
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 <cc1plugin-config.h>
|
||||
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_STRING
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
#include "../gcc/config.h"
|
||||
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_STRING
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
#include "gcc-plugin.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "stringpool.h"
|
||||
#include "hash-set.h"
|
||||
#include "diagnostic.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
|
||||
#include "gcc-interface.h"
|
||||
|
||||
#include "context.hh"
|
||||
#include "marshall.hh"
|
||||
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
int plugin_is_GPL_compatible;
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
cc1_plugin::plugin_context *cc1_plugin::current_context;
|
||||
|
||||
|
||||
|
||||
// This is put into the lang hooks when the plugin starts.
|
||||
|
||||
static void
|
||||
plugin_print_error_function (diagnostic_context *context, const char *file,
|
||||
diagnostic_info *diagnostic)
|
||||
{
|
||||
if (current_function_decl != NULL_TREE
|
||||
&& DECL_NAME (current_function_decl) != NULL_TREE
|
||||
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
|
||||
GCC_FE_WRAPPER_FUNCTION) == 0)
|
||||
return;
|
||||
lhd_print_error_function (context, file, diagnostic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
location_t
|
||||
cc1_plugin::plugin_context::get_location_t (const char *filename,
|
||||
unsigned int line_number)
|
||||
{
|
||||
if (filename == NULL)
|
||||
return UNKNOWN_LOCATION;
|
||||
|
||||
filename = intern_filename (filename);
|
||||
linemap_add (line_table, LC_ENTER, false, filename, line_number);
|
||||
location_t loc = linemap_line_start (line_table, line_number, 0);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
return loc;
|
||||
}
|
||||
|
||||
// Add a file name to FILE_NAMES and return the canonical copy.
|
||||
const char *
|
||||
cc1_plugin::plugin_context::intern_filename (const char *filename)
|
||||
{
|
||||
const char **slot = file_names.find_slot (filename, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
/* The file name must live as long as the line map, which
|
||||
effectively means as long as this compilation. So, we copy
|
||||
the string here but never free it. */
|
||||
*slot = xstrdup (filename);
|
||||
}
|
||||
return *slot;
|
||||
}
|
||||
|
||||
void
|
||||
cc1_plugin::plugin_context::mark ()
|
||||
{
|
||||
for (const auto &item : address_map)
|
||||
{
|
||||
ggc_mark (item->decl);
|
||||
ggc_mark (item->address);
|
||||
}
|
||||
|
||||
for (const auto &item : preserved)
|
||||
ggc_mark (&item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Perform GC marking.
|
||||
|
||||
static void
|
||||
gc_mark (void *, void *)
|
||||
{
|
||||
if (cc1_plugin::current_context != NULL)
|
||||
cc1_plugin::current_context->mark ();
|
||||
}
|
||||
|
||||
void
|
||||
cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info,
|
||||
unsigned int version)
|
||||
{
|
||||
long fd = -1;
|
||||
for (int i = 0; i < plugin_info->argc; ++i)
|
||||
{
|
||||
if (strcmp (plugin_info->argv[i].key, "fd") == 0)
|
||||
{
|
||||
char *tail;
|
||||
errno = 0;
|
||||
fd = strtol (plugin_info->argv[i].value, &tail, 0);
|
||||
if (*tail != '\0' || errno != 0)
|
||||
fatal_error (input_location,
|
||||
"%s: invalid file descriptor argument to plugin",
|
||||
plugin_info->base_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd == -1)
|
||||
fatal_error (input_location,
|
||||
"%s: required plugin argument %<fd%> is missing",
|
||||
plugin_info->base_name);
|
||||
|
||||
current_context = new plugin_context (fd);
|
||||
|
||||
// Handshake.
|
||||
cc1_plugin::protocol_int h_version;
|
||||
if (!current_context->require ('H')
|
||||
|| ! ::cc1_plugin::unmarshall (current_context, &h_version))
|
||||
fatal_error (input_location,
|
||||
"%s: handshake failed", plugin_info->base_name);
|
||||
if (h_version != version)
|
||||
fatal_error (input_location,
|
||||
"%s: unknown version in handshake", plugin_info->base_name);
|
||||
|
||||
register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
|
||||
gc_mark, NULL);
|
||||
|
||||
lang_hooks.print_error_function = plugin_print_error_function;
|
||||
}
|
||||
121
libcc1/context.hh
Normal file
121
libcc1/context.hh
Normal file
@@ -0,0 +1,121 @@
|
||||
/* Generic plugin context
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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/>. */
|
||||
|
||||
#ifndef CC1_PLUGIN_CONTEXT_HH
|
||||
#define CC1_PLUGIN_CONTEXT_HH
|
||||
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tree.h"
|
||||
|
||||
#include "connection.hh"
|
||||
|
||||
namespace cc1_plugin
|
||||
{
|
||||
static inline unsigned long long
|
||||
convert_out (tree t)
|
||||
{
|
||||
return (unsigned long long) (uintptr_t) t;
|
||||
}
|
||||
|
||||
static inline tree
|
||||
convert_in (unsigned long long v)
|
||||
{
|
||||
return (tree) (uintptr_t) v;
|
||||
}
|
||||
|
||||
struct decl_addr_value
|
||||
{
|
||||
tree decl;
|
||||
tree address;
|
||||
};
|
||||
|
||||
struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
|
||||
{
|
||||
static hashval_t hash (const decl_addr_value *e)
|
||||
{
|
||||
return DECL_UID (e->decl);
|
||||
}
|
||||
|
||||
static bool equal (const decl_addr_value *p1,
|
||||
const decl_addr_value *p2)
|
||||
{
|
||||
return p1->decl == p2->decl;
|
||||
}
|
||||
};
|
||||
|
||||
struct string_hasher : nofree_ptr_hash<const char>
|
||||
{
|
||||
static inline hashval_t hash (const char *s)
|
||||
{
|
||||
return htab_hash_string (s);
|
||||
}
|
||||
|
||||
static inline bool equal (const char *p1, const char *p2)
|
||||
{
|
||||
return strcmp (p1, p2) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct plugin_context : public cc1_plugin::connection
|
||||
{
|
||||
plugin_context (int fd)
|
||||
: cc1_plugin::connection (fd),
|
||||
address_map (30),
|
||||
preserved (30),
|
||||
file_names (30)
|
||||
{
|
||||
}
|
||||
|
||||
// Map decls to addresses.
|
||||
hash_table<decl_addr_hasher> address_map;
|
||||
|
||||
// A collection of trees that are preserved for the GC.
|
||||
hash_table< nofree_ptr_hash<tree_node> > preserved;
|
||||
|
||||
// File name cache.
|
||||
hash_table<string_hasher> file_names;
|
||||
|
||||
// Perform GC marking.
|
||||
void mark ();
|
||||
|
||||
// Preserve a tree during the plugin's operation.
|
||||
tree preserve (tree t)
|
||||
{
|
||||
tree_node **slot = preserved.find_slot (t, INSERT);
|
||||
*slot = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
location_t get_location_t (const char *filename,
|
||||
unsigned int line_number);
|
||||
|
||||
private:
|
||||
|
||||
// Add a file name to FILE_NAMES and return the canonical copy.
|
||||
const char *intern_filename (const char *filename);
|
||||
};
|
||||
|
||||
extern plugin_context *current_context;
|
||||
|
||||
void generic_plugin_init (struct plugin_name_args *plugin_info,
|
||||
unsigned int version);
|
||||
}
|
||||
|
||||
#endif // CC1_PLUGIN_CONTEXT_HH
|
||||
@@ -66,87 +66,11 @@
|
||||
#include "marshall.hh"
|
||||
#include "rpc.hh"
|
||||
#include "gcc-c-interface.h"
|
||||
#include "context.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
int plugin_is_GPL_compatible;
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// This is put into the lang hooks when the plugin starts.
|
||||
|
||||
static void
|
||||
plugin_print_error_function (diagnostic_context *context, const char *file,
|
||||
diagnostic_info *diagnostic)
|
||||
{
|
||||
if (current_function_decl != NULL_TREE
|
||||
&& DECL_NAME (current_function_decl) != NULL_TREE
|
||||
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
|
||||
GCC_FE_WRAPPER_FUNCTION) == 0)
|
||||
return;
|
||||
lhd_print_error_function (context, file, diagnostic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned long long
|
||||
convert_out (tree t)
|
||||
{
|
||||
return (unsigned long long) (uintptr_t) t;
|
||||
}
|
||||
|
||||
static tree
|
||||
convert_in (unsigned long long v)
|
||||
{
|
||||
return (tree) (uintptr_t) v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct decl_addr_value
|
||||
{
|
||||
tree decl;
|
||||
tree address;
|
||||
};
|
||||
|
||||
struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
|
||||
{
|
||||
static inline hashval_t hash (const decl_addr_value *);
|
||||
static inline bool equal (const decl_addr_value *, const decl_addr_value *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
decl_addr_hasher::hash (const decl_addr_value *e)
|
||||
{
|
||||
return IDENTIFIER_HASH_VALUE (DECL_NAME (e->decl));
|
||||
}
|
||||
|
||||
inline bool
|
||||
decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2)
|
||||
{
|
||||
return p1->decl == p2->decl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct string_hasher : nofree_ptr_hash<const char>
|
||||
{
|
||||
static inline hashval_t hash (const char *s)
|
||||
{
|
||||
return htab_hash_string (s);
|
||||
}
|
||||
|
||||
static inline bool equal (const char *p1, const char *p2)
|
||||
{
|
||||
return strcmp (p1, p2) == 0;
|
||||
}
|
||||
};
|
||||
using namespace cc1_plugin;
|
||||
|
||||
|
||||
|
||||
@@ -166,85 +90,6 @@ pushdecl_safe (tree decl)
|
||||
|
||||
|
||||
|
||||
struct plugin_context : public cc1_plugin::connection
|
||||
{
|
||||
plugin_context (int fd);
|
||||
|
||||
// Map decls to addresses.
|
||||
hash_table<decl_addr_hasher> address_map;
|
||||
|
||||
// A collection of trees that are preserved for the GC.
|
||||
hash_table< nofree_ptr_hash<tree_node> > preserved;
|
||||
|
||||
// File name cache.
|
||||
hash_table<string_hasher> file_names;
|
||||
|
||||
// Perform GC marking.
|
||||
void mark ();
|
||||
|
||||
// Preserve a tree during the plugin's operation.
|
||||
tree preserve (tree t)
|
||||
{
|
||||
tree_node **slot = preserved.find_slot (t, INSERT);
|
||||
*slot = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
location_t get_location_t (const char *filename,
|
||||
unsigned int line_number)
|
||||
{
|
||||
if (filename == NULL)
|
||||
return UNKNOWN_LOCATION;
|
||||
|
||||
filename = intern_filename (filename);
|
||||
linemap_add (line_table, LC_ENTER, false, filename, line_number);
|
||||
location_t loc = linemap_line_start (line_table, line_number, 0);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
return loc;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Add a file name to FILE_NAMES and return the canonical copy.
|
||||
const char *intern_filename (const char *filename)
|
||||
{
|
||||
const char **slot = file_names.find_slot (filename, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
/* The file name must live as long as the line map, which
|
||||
effectively means as long as this compilation. So, we copy
|
||||
the string here but never free it. */
|
||||
*slot = xstrdup (filename);
|
||||
}
|
||||
return *slot;
|
||||
}
|
||||
};
|
||||
|
||||
static plugin_context *current_context;
|
||||
|
||||
|
||||
|
||||
plugin_context::plugin_context (int fd)
|
||||
: cc1_plugin::connection (fd),
|
||||
address_map (30),
|
||||
preserved (30),
|
||||
file_names (30)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
plugin_context::mark ()
|
||||
{
|
||||
for (const auto &item : address_map)
|
||||
{
|
||||
ggc_mark (item->decl);
|
||||
ggc_mark (item->address);
|
||||
}
|
||||
|
||||
for (const auto &item : preserved)
|
||||
ggc_mark (&item);
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_binding_oracle (enum c_oracle_request kind, tree identifier)
|
||||
{
|
||||
@@ -899,15 +744,6 @@ plugin_error (cc1_plugin::connection *,
|
||||
|
||||
|
||||
|
||||
// Perform GC marking.
|
||||
|
||||
static void
|
||||
gc_mark (void *, void *)
|
||||
{
|
||||
if (current_context != NULL)
|
||||
current_context->mark ();
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
@@ -916,46 +752,12 @@ int
|
||||
plugin_init (struct plugin_name_args *plugin_info,
|
||||
struct plugin_gcc_version *)
|
||||
{
|
||||
long fd = -1;
|
||||
for (int i = 0; i < plugin_info->argc; ++i)
|
||||
{
|
||||
if (strcmp (plugin_info->argv[i].key, "fd") == 0)
|
||||
{
|
||||
char *tail;
|
||||
errno = 0;
|
||||
fd = strtol (plugin_info->argv[i].value, &tail, 0);
|
||||
if (*tail != '\0' || errno != 0)
|
||||
fatal_error (input_location,
|
||||
"%s: invalid file descriptor argument to plugin",
|
||||
plugin_info->base_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd == -1)
|
||||
fatal_error (input_location,
|
||||
"%s: required plugin argument %<fd%> is missing",
|
||||
plugin_info->base_name);
|
||||
|
||||
current_context = new plugin_context (fd);
|
||||
|
||||
// Handshake.
|
||||
cc1_plugin::protocol_int version;
|
||||
if (!current_context->require ('H')
|
||||
|| ! ::cc1_plugin::unmarshall (current_context, &version))
|
||||
fatal_error (input_location,
|
||||
"%s: handshake failed", plugin_info->base_name);
|
||||
if (version != GCC_C_FE_VERSION_1)
|
||||
fatal_error (input_location,
|
||||
"%s: unknown version in handshake", plugin_info->base_name);
|
||||
generic_plugin_init (plugin_info, GCC_C_FE_VERSION_1);
|
||||
|
||||
register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
|
||||
plugin_init_extra_pragmas, NULL);
|
||||
register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
|
||||
rewrite_decls_to_addresses, NULL);
|
||||
register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
|
||||
gc_mark, NULL);
|
||||
|
||||
lang_hooks.print_error_function = plugin_print_error_function;
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
{ \
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "stringpool.h"
|
||||
|
||||
#include "gcc-interface.h"
|
||||
#include "hash-set.h"
|
||||
#include "machmode.h"
|
||||
#include "vec.h"
|
||||
#include "double-int.h"
|
||||
@@ -69,172 +68,19 @@
|
||||
#include "connection.hh"
|
||||
#include "marshall-cp.hh"
|
||||
#include "rpc.hh"
|
||||
#include "context.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
int plugin_is_GPL_compatible;
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
using namespace cc1_plugin;
|
||||
|
||||
|
||||
|
||||
static_assert (GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END,
|
||||
"GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END");
|
||||
|
||||
// This is put into the lang hooks when the plugin starts.
|
||||
|
||||
static void
|
||||
plugin_print_error_function (diagnostic_context *context, const char *file,
|
||||
diagnostic_info *diagnostic)
|
||||
{
|
||||
if (current_function_decl != NULL_TREE
|
||||
&& DECL_NAME (current_function_decl) != NULL_TREE
|
||||
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
|
||||
GCC_FE_WRAPPER_FUNCTION) == 0)
|
||||
return;
|
||||
lhd_print_error_function (context, file, diagnostic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned long long
|
||||
convert_out (tree t)
|
||||
{
|
||||
return (unsigned long long) (uintptr_t) t;
|
||||
}
|
||||
|
||||
static tree
|
||||
convert_in (unsigned long long v)
|
||||
{
|
||||
return (tree) (uintptr_t) v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct decl_addr_value
|
||||
{
|
||||
tree decl;
|
||||
tree address;
|
||||
};
|
||||
|
||||
struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
|
||||
{
|
||||
static inline hashval_t hash (const decl_addr_value *);
|
||||
static inline bool equal (const decl_addr_value *, const decl_addr_value *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
decl_addr_hasher::hash (const decl_addr_value *e)
|
||||
{
|
||||
return DECL_UID (e->decl);
|
||||
}
|
||||
|
||||
inline bool
|
||||
decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2)
|
||||
{
|
||||
return p1->decl == p2->decl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct string_hasher : nofree_ptr_hash<const char>
|
||||
{
|
||||
static inline hashval_t hash (const char *s)
|
||||
{
|
||||
return htab_hash_string (s);
|
||||
}
|
||||
|
||||
static inline bool equal (const char *p1, const char *p2)
|
||||
{
|
||||
return strcmp (p1, p2) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct plugin_context : public cc1_plugin::connection
|
||||
{
|
||||
plugin_context (int fd);
|
||||
|
||||
// Map decls to addresses.
|
||||
hash_table<decl_addr_hasher> address_map;
|
||||
|
||||
// A collection of trees that are preserved for the GC.
|
||||
hash_table< nofree_ptr_hash<tree_node> > preserved;
|
||||
|
||||
// File name cache.
|
||||
hash_table<string_hasher> file_names;
|
||||
|
||||
// Perform GC marking.
|
||||
void mark ();
|
||||
|
||||
// Preserve a tree during the plugin's operation.
|
||||
tree preserve (tree t)
|
||||
{
|
||||
tree_node **slot = preserved.find_slot (t, INSERT);
|
||||
*slot = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
location_t get_location_t (const char *filename,
|
||||
unsigned int line_number)
|
||||
{
|
||||
if (filename == NULL)
|
||||
return UNKNOWN_LOCATION;
|
||||
|
||||
filename = intern_filename (filename);
|
||||
linemap_add (line_table, LC_ENTER, false, filename, line_number);
|
||||
location_t loc = linemap_line_start (line_table, line_number, 0);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
return loc;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Add a file name to FILE_NAMES and return the canonical copy.
|
||||
const char *intern_filename (const char *filename)
|
||||
{
|
||||
const char **slot = file_names.find_slot (filename, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
/* The file name must live as long as the line map, which
|
||||
effectively means as long as this compilation. So, we copy
|
||||
the string here but never free it. */
|
||||
*slot = xstrdup (filename);
|
||||
}
|
||||
return *slot;
|
||||
}
|
||||
};
|
||||
|
||||
static plugin_context *current_context;
|
||||
|
||||
|
||||
|
||||
plugin_context::plugin_context (int fd)
|
||||
: cc1_plugin::connection (fd),
|
||||
address_map (30),
|
||||
preserved (30),
|
||||
file_names (30)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
plugin_context::mark ()
|
||||
{
|
||||
for (const auto &item : address_map)
|
||||
{
|
||||
ggc_mark (item->decl);
|
||||
ggc_mark (item->address);
|
||||
}
|
||||
|
||||
for (const auto &item : preserved)
|
||||
ggc_mark (&item);
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_binding_oracle (enum cp_oracle_request kind, tree identifier)
|
||||
{
|
||||
@@ -3645,15 +3491,6 @@ plugin_add_static_assert (cc1_plugin::connection *self,
|
||||
|
||||
|
||||
|
||||
// Perform GC marking.
|
||||
|
||||
static void
|
||||
gc_mark (void *, void *)
|
||||
{
|
||||
if (current_context != NULL)
|
||||
current_context->mark ();
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
@@ -3662,46 +3499,12 @@ int
|
||||
plugin_init (struct plugin_name_args *plugin_info,
|
||||
struct plugin_gcc_version *)
|
||||
{
|
||||
long fd = -1;
|
||||
for (int i = 0; i < plugin_info->argc; ++i)
|
||||
{
|
||||
if (strcmp (plugin_info->argv[i].key, "fd") == 0)
|
||||
{
|
||||
char *tail;
|
||||
errno = 0;
|
||||
fd = strtol (plugin_info->argv[i].value, &tail, 0);
|
||||
if (*tail != '\0' || errno != 0)
|
||||
fatal_error (input_location,
|
||||
"%s: invalid file descriptor argument to plugin",
|
||||
plugin_info->base_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd == -1)
|
||||
fatal_error (input_location,
|
||||
"%s: required plugin argument %<fd%> is missing",
|
||||
plugin_info->base_name);
|
||||
|
||||
current_context = new plugin_context (fd);
|
||||
|
||||
// Handshake.
|
||||
cc1_plugin::protocol_int version;
|
||||
if (!current_context->require ('H')
|
||||
|| ! ::cc1_plugin::unmarshall (current_context, &version))
|
||||
fatal_error (input_location,
|
||||
"%s: handshake failed", plugin_info->base_name);
|
||||
if (version != GCC_CP_FE_VERSION_0)
|
||||
fatal_error (input_location,
|
||||
"%s: unknown version in handshake", plugin_info->base_name);
|
||||
generic_plugin_init (plugin_info, GCC_CP_FE_VERSION_0);
|
||||
|
||||
register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
|
||||
plugin_init_extra_pragmas, NULL);
|
||||
register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
|
||||
rewrite_decls_to_addresses, NULL);
|
||||
register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
|
||||
gc_mark, NULL);
|
||||
|
||||
lang_hooks.print_error_function = plugin_print_error_function;
|
||||
|
||||
#define GCC_METHOD0(R, N) \
|
||||
{ \
|
||||
|
||||
Reference in New Issue
Block a user