Commit 5f3682ff by Nathan Sidwell Committed by Nathan Sidwell

[PATCH] New lang hook

https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01340.html
	PR c++/82836
	PR c++/82737
	* tree.h (COPY_DECL_RTL): Rename parms for clarity.
	(SET_DECL_ASSEMBLER_NAME): Forward to
	overwrite_decl_assembler_name.
	(COPY_DECL_ASSEMBLER_NAME): Rename parms for clarity.
	(overwrite_decl_assembler_name): Declare.
	* tree.c (overwrite_decl_assembler_name): New.
	* langhooks-def.h (lhd_overwrite_decl_assembler_name): Declare.
	(LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME): Provide default.
	(LANG_HOOKS_INITIALIZER): Add it.
	* langhooks.h (struct lang_hooks): Add overwrite_decl_assembler_name.
	* langhooks.c (lhd_set_decl_assembler_name): Use
	SET_DECL_ASSEMBLER_NAME.
	(lhd_overwrite_decl_assembler_name): Default implementation.

	PR c++/82836
	PR c++/82737
	* cp-objcp-common.h (LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME):
	Override.
	* cp-tree.h (overwrite_mangling): Declare.
	* decl2.c (struct mangled_decl_hash): Entries are deletable.
	(overwrite_mangling): New.

	PR c++/82836
	PR c++/82737
	* g++.dg/pr82836.C: New.

From-SVN: r254823
parent a930324d
2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836
PR c++/82737
* tree.h (COPY_DECL_RTL): Rename parms for clarity.
(SET_DECL_ASSEMBLER_NAME): Forward to
overwrite_decl_assembler_name.
(COPY_DECL_ASSEMBLER_NAME): Rename parms for clarity.
(overwrite_decl_assembler_name): Declare.
* tree.c (overwrite_decl_assembler_name): New.
* langhooks-def.h (lhd_overwrite_decl_assembler_name): Declare.
(LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME): Provide default.
(LANG_HOOKS_INITIALIZER): Add it.
* langhooks.h (struct lang_hooks): Add overwrite_decl_assembler_name.
* langhooks.c (lhd_set_decl_assembler_name): Use
SET_DECL_ASSEMBLER_NAME.
(lhd_overwrite_decl_assembler_name): Default implementation.
2017-11-16 Wilco Dijkstra <wdijkstr@arm.com>
Jackson Woodruff <jackson.woodruff@arm.com>
2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836
PR c++/82737
* cp-objcp-common.h (LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME):
Override.
* cp-tree.h (overwrite_mangling): Declare.
* decl2.c (struct mangled_decl_hash): Entries are deletable.
(overwrite_mangling): New.
PR c++/81060
* decl.c (xref_tag_1): Push lambda into current scope.
* name-lookup.c (do_pushtag): Don't deal with ts_lambda here.
......
......@@ -73,6 +73,8 @@ extern void cp_register_dumps (gcc::dump_manager *);
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl
#undef LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME
#define LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME overwrite_mangling
#undef LANG_HOOKS_PRINT_STATISTICS
#define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics
#undef LANG_HOOKS_PRINT_XNODE
......
......@@ -6187,6 +6187,7 @@ extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t);
/* in decl2.c */
extern void record_mangling (tree, bool);
extern void overwrite_mangling (tree, tree);
extern void note_mangling_alias (tree, tree);
extern void generate_mangling_aliases (void);
extern tree build_memfn_type (tree, tree, cp_cv_quals, cp_ref_qualifier);
......
......@@ -123,9 +123,14 @@ struct mangled_decl_hash : ggc_remove <tree>
static inline void mark_empty (value_type &p) {p = NULL_TREE;}
static inline bool is_empty (value_type p) {return !p;}
/* Nothing is deletable. Everything is insertable. */
static bool is_deleted (value_type) { return false; }
static void mark_deleted (value_type) { gcc_unreachable (); }
static bool is_deleted (value_type e)
{
return e == reinterpret_cast <value_type> (1);
}
static void mark_deleted (value_type &e)
{
e = reinterpret_cast <value_type> (1);
}
};
/* A hash table of decls keyed by mangled name. Used to figure out if
......@@ -4439,6 +4444,33 @@ record_mangling (tree decl, bool need_warning)
}
}
/* The mangled name of DECL is being forcibly changed to NAME. Remove
any existing knowledge of DECL's mangled name meaning DECL. */
void
overwrite_mangling (tree decl, tree name)
{
if (tree id = DECL_ASSEMBLER_NAME_RAW (decl))
if ((TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FUNCTION_DECL)
&& mangled_decls)
if (tree *slot
= mangled_decls->find_slot_with_hash (id, IDENTIFIER_HASH_VALUE (id),
NO_INSERT))
if (*slot == decl)
{
mangled_decls->clear_slot (slot);
/* If this is an alias, remove it from the symbol table. */
if (DECL_ARTIFICIAL (decl) && DECL_IGNORED_P (decl))
if (symtab_node *n = symtab_node::get (decl))
if (n->cpp_implicit_alias)
n->remove ();
}
DECL_ASSEMBLER_NAME_RAW (decl) = name;
}
/* The entire file is now complete. If requested, dump everything
to a file. */
......
......@@ -51,7 +51,8 @@ extern const char *lhd_dwarf_name (tree, int);
extern int lhd_types_compatible_p (tree, tree);
extern void lhd_print_error_function (diagnostic_context *,
const char *, struct diagnostic_info *);
extern void lhd_set_decl_assembler_name (tree);
extern void lhd_set_decl_assembler_name (tree decl);
extern void lhd_overwrite_decl_assembler_name (tree decl, tree name);
extern bool lhd_warn_unused_global_decl (const_tree);
extern tree lhd_type_for_size (unsigned precision, int unsignedp);
extern void lhd_incomplete_type_error (location_t, const_tree, const_tree);
......@@ -107,6 +108,7 @@ extern int lhd_type_dwarf_attribute (const_tree, int);
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
#define LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME lhd_overwrite_decl_assembler_name
#define LANG_HOOKS_PRINT_STATISTICS lhd_do_nothing
#define LANG_HOOKS_PRINT_XNODE lhd_print_tree_nothing
#define LANG_HOOKS_PRINT_DECL lhd_print_tree_nothing
......@@ -310,6 +312,7 @@ extern void lhd_end_section (void);
LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
LANG_HOOKS_OVERWRITE_DECL_ASSEMBLER_NAME, \
LANG_HOOKS_PRINT_STATISTICS, \
LANG_HOOKS_PRINT_XNODE, \
LANG_HOOKS_PRINT_DECL, \
......
......@@ -171,8 +171,15 @@ lhd_set_decl_assembler_name (tree decl)
ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
id = get_identifier (label);
}
SET_DECL_ASSEMBLER_NAME (decl, id);
}
/* Forcibly overwrite the DECL_ASSEMBLER_NAME for DECL to NAME. */
void
lhd_overwrite_decl_assembler_name (tree decl, tree name)
{
DECL_ASSEMBLER_NAME_RAW (decl) = name;
}
/* Type promotion for variable arguments. */
......
......@@ -395,6 +395,10 @@ struct lang_hooks
assembler does not talk about it. */
void (*set_decl_assembler_name) (tree);
/* Overwrite the DECL_ASSEMBLER_NAME for a node. The name is being
changed (including to or from NULL_TREE). */
void (*overwrite_decl_assembler_name) (tree, tree);
/* The front end can add its own statistics to -fmem-report with
this hook. It should output to stderr. */
void (*print_statistics) (void);
......
2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836
PR c++/82737
* g++.dg/pr82836.C: New.
PR c++81060
* g++.dg/cpp0x/lambda/lambda-template13.C: Avoid undefined
template using local type error.
......
......@@ -674,6 +674,17 @@ decl_assembler_name (tree decl)
return DECL_ASSEMBLER_NAME_RAW (decl);
}
/* The DECL_ASSEMBLER_NAME_RAW of DECL is being explicitly set to NAME
(either of which may be NULL). Inform the FE, if this changes the
name. */
void
overwrite_decl_assembler_name (tree decl, tree name)
{
if (DECL_ASSEMBLER_NAME_RAW (decl) != name)
lang_hooks.overwrite_decl_assembler_name (decl, name);
}
/* When the target supports COMDAT groups, this indicates which group the
DECL is associated with. This can be either an IDENTIFIER_NODE or a
decl, in which case its DECL_ASSEMBLER_NAME identifies the group. */
......
......@@ -2528,11 +2528,11 @@ extern void decl_value_expr_insert (tree, tree);
#define DECL_RTL_SET_P(NODE) \
(HAS_RTL_P (NODE) && DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl != NULL)
/* Copy the RTL from NODE1 to NODE2. If the RTL was not set for
NODE1, it will not be set for NODE2; this is a lazy copy. */
#define COPY_DECL_RTL(NODE1, NODE2) \
(DECL_WRTL_CHECK (NODE2)->decl_with_rtl.rtl \
= DECL_WRTL_CHECK (NODE1)->decl_with_rtl.rtl)
/* Copy the RTL from SRC_DECL to DST_DECL. If the RTL was not set for
SRC_DECL, it will not be set for DST_DECL; this is a lazy copy. */
#define COPY_DECL_RTL(SRC_DECL, DST_DECL) \
(DECL_WRTL_CHECK (DST_DECL)->decl_with_rtl.rtl \
= DECL_WRTL_CHECK (SRC_DECL)->decl_with_rtl.rtl)
/* The DECL_RTL for NODE, if it is set, or NULL, if it is not set. */
#define DECL_RTL_IF_SET(NODE) (DECL_RTL_SET_P (NODE) ? DECL_RTL (NODE) : NULL)
......@@ -2723,19 +2723,21 @@ extern void decl_value_expr_insert (tree, tree);
/* Set the DECL_ASSEMBLER_NAME for NODE to NAME. */
#define SET_DECL_ASSEMBLER_NAME(NODE, NAME) \
(DECL_ASSEMBLER_NAME_RAW (NODE) = (NAME))
overwrite_decl_assembler_name (NODE, NAME)
/* Copy the DECL_ASSEMBLER_NAME from DECL1 to DECL2. Note that if DECL1's
DECL_ASSEMBLER_NAME has not yet been set, using this macro will not cause
the DECL_ASSEMBLER_NAME of either DECL to be set. In other words, the
semantics of using this macro, are different than saying:
/* Copy the DECL_ASSEMBLER_NAME from SRC_DECL to DST_DECL. Note that
if SRC_DECL's DECL_ASSEMBLER_NAME has not yet been set, using this
macro will not cause the DECL_ASSEMBLER_NAME to be set, but will
clear DECL_ASSEMBLER_NAME of DST_DECL, if it was already set. In
other words, the semantics of using this macro, are different than
saying:
SET_DECL_ASSEMBLER_NAME(DECL2, DECL_ASSEMBLER_NAME (DECL1))
SET_DECL_ASSEMBLER_NAME(DST_DECL, DECL_ASSEMBLER_NAME (SRC_DECL))
which will try to set the DECL_ASSEMBLER_NAME for DECL1. */
which will try to set the DECL_ASSEMBLER_NAME for SRC_DECL. */
#define COPY_DECL_ASSEMBLER_NAME(DECL1, DECL2) \
SET_DECL_ASSEMBLER_NAME (DECL2, DECL_ASSEMBLER_NAME_RAW (DECL1))
#define COPY_DECL_ASSEMBLER_NAME(SRC_DECL, DST_DECL) \
SET_DECL_ASSEMBLER_NAME (DST_DECL, DECL_ASSEMBLER_NAME_RAW (SRC_DECL))
/* Records the section name in a section attribute. Used to pass
the name from decl_attributes to make_function_rtl and make_decl_rtl. */
......@@ -3872,6 +3874,7 @@ id_equal (const char *str, const_tree id)
|| ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
extern tree decl_assembler_name (tree);
extern void overwrite_decl_assembler_name (tree decl, tree name);
extern tree decl_comdat_group (const_tree);
extern tree decl_comdat_group_id (const_tree);
extern const char *decl_section_name (const_tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment