Commit b97e8a14 by Jason Merrill Committed by Jason Merrill

cp-tree.h (struct lang_decl): Overhaul.

	* cp-tree.h (struct lang_decl): Overhaul.
	(struct lang_decl_flags): Remove.
	(struct lang_decl_base): New.
	(struct lang_decl_min): New.
	(struct lang_decl_fn): New.
	(struct lang_decl_ns): New.
	(CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN.
	(LANG_DECL_MIN_CHECK): New.
	(LANG_DECL_FN_CHECK): New.
	(LANG_DECL_NS_CHECK): New.
	(STRIP_TEMPLATE): New.
	(NON_THUNK_FUNCTION_CHECK): Remove.
	(DECL_DECLARES_FUNCTION_P): New.
	(lots): Adjust.
	* lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust.
	* decl.c (push_local_name, duplicate_decls): Adjust.
	* decl2.c (start_objects): Don't set u2sel.
	* semantics.c (finish_omp_threadprivate): Adjust.
	* class.c (build_clone): Don't do much on TEMPLATE_DECLs.
	(decl_cloned_function_p): Out-of-line implementation of macros.
	(clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P.
	* mangle.c (write_unqualified_name): Don't check function flags
	on non-functions.
	* method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION.
	* pt.c (build_template_decl): Don't set function flags.
	(check_default_tmpl_args): Check that it's a function.
	(instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the
	cloned template.

	* pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst
	DECL_CLONED_FUNCTION.

	* cp-tree.h (struct lang_type_class): Move sorted_fields here.
	* class.c (finish_struct_1): Adjust.
	* ptree.c (cxx_print_decl, cxx_print_type): Adjust.
	* search.c (lookup_field_1): Adjust.

	* cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove.
	* decl.c (finish_method): Don't add to it.
	* class.c (fixup_pending_inline): Remove.
	(fixup_inline_methods): Remove.
	(finish_struct_1): Don't call it.

	* error.c (dump_function_name): Handle null name.

From-SVN: r149217
parent 07302a1b
2009-07-03 Jason Merrill <jason@redhat.com>
* cp-tree.h (struct lang_decl): Overhaul.
(struct lang_decl_flags): Remove.
(struct lang_decl_base): New.
(struct lang_decl_min): New.
(struct lang_decl_fn): New.
(struct lang_decl_ns): New.
(CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN.
(LANG_DECL_MIN_CHECK): New.
(LANG_DECL_FN_CHECK): New.
(LANG_DECL_NS_CHECK): New.
(STRIP_TEMPLATE): New.
(NON_THUNK_FUNCTION_CHECK): Remove.
(DECL_DECLARES_FUNCTION_P): New.
(lots): Adjust.
* lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust.
* decl.c (push_local_name, duplicate_decls): Adjust.
* decl2.c (start_objects): Don't set u2sel.
* semantics.c (finish_omp_threadprivate): Adjust.
* class.c (build_clone): Don't do much on TEMPLATE_DECLs.
(decl_cloned_function_p): Out-of-line implementation of macros.
(clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P.
* mangle.c (write_unqualified_name): Don't check function flags
on non-functions.
* method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION.
* pt.c (build_template_decl): Don't set function flags.
(check_default_tmpl_args): Check that it's a function.
(instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the
cloned template.
* pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst
DECL_CLONED_FUNCTION.
* cp-tree.h (struct lang_type_class): Move sorted_fields here.
* class.c (finish_struct_1): Adjust.
* ptree.c (cxx_print_decl, cxx_print_type): Adjust.
* search.c (lookup_field_1): Adjust.
* cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove.
* decl.c (finish_method): Don't add to it.
* class.c (fixup_pending_inline): Remove.
(fixup_inline_methods): Remove.
(finish_struct_1): Don't call it.
* error.c (dump_function_name): Handle null name.
2009-07-02 Mark Mitchell <mark@codesourcery.com> 2009-07-02 Mark Mitchell <mark@codesourcery.com>
* typeck.c (cp_build_binary_op): Move warnings about use of NULL * typeck.c (cp_build_binary_op): Move warnings about use of NULL
......
...@@ -151,8 +151,6 @@ static void check_bases_and_members (tree); ...@@ -151,8 +151,6 @@ static void check_bases_and_members (tree);
static tree create_vtable_ptr (tree, tree *); static tree create_vtable_ptr (tree, tree *);
static void include_empty_classes (record_layout_info); static void include_empty_classes (record_layout_info);
static void layout_class_type (tree, tree *); static void layout_class_type (tree, tree *);
static void fixup_pending_inline (tree);
static void fixup_inline_methods (tree);
static void propagate_binfo_offsets (tree, tree); static void propagate_binfo_offsets (tree, tree);
static void layout_virtual_bases (record_layout_info, splay_tree); static void layout_virtual_bases (record_layout_info, splay_tree);
static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *); static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
...@@ -3799,12 +3797,27 @@ build_clone (tree fn, tree name) ...@@ -3799,12 +3797,27 @@ build_clone (tree fn, tree name)
/* Copy the function. */ /* Copy the function. */
clone = copy_decl (fn); clone = copy_decl (fn);
/* Remember where this function came from. */
DECL_CLONED_FUNCTION (clone) = fn;
DECL_ABSTRACT_ORIGIN (clone) = fn;
/* Reset the function name. */ /* Reset the function name. */
DECL_NAME (clone) = name; DECL_NAME (clone) = name;
SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE); SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
/* Remember where this function came from. */
DECL_ABSTRACT_ORIGIN (clone) = fn;
/* Make it easy to find the CLONE given the FN. */
TREE_CHAIN (clone) = TREE_CHAIN (fn);
TREE_CHAIN (fn) = clone;
/* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */
if (TREE_CODE (clone) == TEMPLATE_DECL)
{
tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name);
DECL_TEMPLATE_RESULT (clone) = result;
DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
DECL_TI_TEMPLATE (result) = clone;
TREE_TYPE (clone) = TREE_TYPE (result);
return clone;
}
DECL_CLONED_FUNCTION (clone) = fn;
/* There's no pending inline data for this function. */ /* There's no pending inline data for this function. */
DECL_PENDING_INLINE_INFO (clone) = NULL; DECL_PENDING_INLINE_INFO (clone) = NULL;
DECL_PENDING_INLINE_P (clone) = 0; DECL_PENDING_INLINE_P (clone) = 0;
...@@ -3852,61 +3865,79 @@ build_clone (tree fn, tree name) ...@@ -3852,61 +3865,79 @@ build_clone (tree fn, tree name)
TYPE_ATTRIBUTES (TREE_TYPE (fn))); TYPE_ATTRIBUTES (TREE_TYPE (fn)));
} }
/* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL /* Copy the function parameters. */
aren't function parameters; those are the template parameters. */ DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
if (TREE_CODE (clone) != TEMPLATE_DECL) /* Remove the in-charge parameter. */
if (DECL_HAS_IN_CHARGE_PARM_P (clone))
{
TREE_CHAIN (DECL_ARGUMENTS (clone))
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
}
/* And the VTT parm, in a complete [cd]tor. */
if (DECL_HAS_VTT_PARM_P (fn))
{ {
DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone)); if (DECL_NEEDS_VTT_PARM_P (clone))
/* Remove the in-charge parameter. */ DECL_HAS_VTT_PARM_P (clone) = 1;
if (DECL_HAS_IN_CHARGE_PARM_P (clone)) else
{ {
TREE_CHAIN (DECL_ARGUMENTS (clone)) TREE_CHAIN (DECL_ARGUMENTS (clone))
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
DECL_HAS_IN_CHARGE_PARM_P (clone) = 0; DECL_HAS_VTT_PARM_P (clone) = 0;
}
/* And the VTT parm, in a complete [cd]tor. */
if (DECL_HAS_VTT_PARM_P (fn))
{
if (DECL_NEEDS_VTT_PARM_P (clone))
DECL_HAS_VTT_PARM_P (clone) = 1;
else
{
TREE_CHAIN (DECL_ARGUMENTS (clone))
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
DECL_HAS_VTT_PARM_P (clone) = 0;
}
} }
}
for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
{ {
DECL_CONTEXT (parms) = clone; DECL_CONTEXT (parms) = clone;
cxx_dup_lang_specific_decl (parms); cxx_dup_lang_specific_decl (parms);
}
} }
/* Create the RTL for this function. */ /* Create the RTL for this function. */
SET_DECL_RTL (clone, NULL_RTX); SET_DECL_RTL (clone, NULL_RTX);
rest_of_decl_compilation (clone, /*top_level=*/1, at_eof); rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
/* Make it easy to find the CLONE given the FN. */ if (pch_file)
TREE_CHAIN (clone) = TREE_CHAIN (fn); note_decl_for_pch (clone);
TREE_CHAIN (fn) = clone;
/* If this is a template, handle the DECL_TEMPLATE_RESULT as well. */ return clone;
if (TREE_CODE (clone) == TEMPLATE_DECL) }
{
tree result;
DECL_TEMPLATE_RESULT (clone) /* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
= build_clone (DECL_TEMPLATE_RESULT (clone), name); not invoke this function directly.
result = DECL_TEMPLATE_RESULT (clone);
DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result)); For a non-thunk function, returns the address of the slot for storing
DECL_TI_TEMPLATE (result) = clone; the function it is a clone of. Otherwise returns NULL_TREE.
If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
cloned_function is unset. This is to support the separate
DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
on a template makes sense, but not the former. */
tree *
decl_cloned_function_p (const_tree decl, bool just_testing)
{
tree *ptr;
if (just_testing)
decl = STRIP_TEMPLATE (decl);
if (TREE_CODE (decl) != FUNCTION_DECL
|| !DECL_LANG_SPECIFIC (decl)
|| DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
{
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
if (!just_testing)
lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
else
#endif
return NULL;
} }
else if (pch_file)
note_decl_for_pch (clone);
return clone; ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
if (just_testing && *ptr == NULL_TREE)
return NULL;
else
return ptr;
} }
/* Produce declarations for all appropriate clones of FN. If /* Produce declarations for all appropriate clones of FN. If
...@@ -3920,7 +3951,7 @@ clone_function_decl (tree fn, int update_method_vec_p) ...@@ -3920,7 +3951,7 @@ clone_function_decl (tree fn, int update_method_vec_p)
/* Avoid inappropriate cloning. */ /* Avoid inappropriate cloning. */
if (TREE_CHAIN (fn) if (TREE_CHAIN (fn)
&& DECL_CLONED_FUNCTION (TREE_CHAIN (fn))) && DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn)))
return; return;
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)) if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
...@@ -3977,7 +4008,7 @@ adjust_clone_args (tree decl) ...@@ -3977,7 +4008,7 @@ adjust_clone_args (tree decl)
{ {
tree clone; tree clone;
for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone); for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
clone = TREE_CHAIN (clone)) clone = TREE_CHAIN (clone))
{ {
tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone)); tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
...@@ -4447,54 +4478,6 @@ create_vtable_ptr (tree t, tree* virtuals_p) ...@@ -4447,54 +4478,6 @@ create_vtable_ptr (tree t, tree* virtuals_p)
return NULL_TREE; return NULL_TREE;
} }
/* Fixup the inline function given by INFO now that the class is
complete. */
static void
fixup_pending_inline (tree fn)
{
if (DECL_PENDING_INLINE_INFO (fn))
{
tree args = DECL_ARGUMENTS (fn);
while (args)
{
DECL_CONTEXT (args) = fn;
args = TREE_CHAIN (args);
}
}
}
/* Fixup the inline methods and friends in TYPE now that TYPE is
complete. */
static void
fixup_inline_methods (tree type)
{
tree method = TYPE_METHODS (type);
VEC(tree,gc) *friends;
unsigned ix;
if (method && TREE_CODE (method) == TREE_VEC)
{
if (TREE_VEC_ELT (method, 1))
method = TREE_VEC_ELT (method, 1);
else if (TREE_VEC_ELT (method, 0))
method = TREE_VEC_ELT (method, 0);
else
method = TREE_VEC_ELT (method, 2);
}
/* Do inline member functions. */
for (; method; method = TREE_CHAIN (method))
fixup_pending_inline (method);
/* Do friends. */
for (friends = CLASSTYPE_INLINE_FRIENDS (type), ix = 0;
VEC_iterate (tree, friends, ix, method); ix++)
fixup_pending_inline (method);
CLASSTYPE_INLINE_FRIENDS (type) = NULL;
}
/* Add OFFSET to all base types of BINFO which is a base in the /* Add OFFSET to all base types of BINFO which is a base in the
hierarchy dominated by T. hierarchy dominated by T.
...@@ -5219,8 +5202,6 @@ finish_struct_1 (tree t) ...@@ -5219,8 +5202,6 @@ finish_struct_1 (tree t)
TYPE_SIZE (t) = NULL_TREE; TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
fixup_inline_methods (t);
/* Make assumptions about the class; we'll reset the flags if /* Make assumptions about the class; we'll reset the flags if
necessary. */ necessary. */
CLASSTYPE_EMPTY_P (t) = 1; CLASSTYPE_EMPTY_P (t) = 1;
...@@ -5332,9 +5313,7 @@ finish_struct_1 (tree t) ...@@ -5332,9 +5313,7 @@ finish_struct_1 (tree t)
add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
qsort (field_vec->elts, n_fields, sizeof (tree), qsort (field_vec->elts, n_fields, sizeof (tree),
field_decl_cmp); field_decl_cmp);
if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t))) CLASSTYPE_SORTED_FIELDS (t) = field_vec;
retrofit_lang_decl (TYPE_MAIN_DECL (t));
DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
} }
/* Complain if one of the field types requires lower visibility. */ /* Complain if one of the field types requires lower visibility. */
......
...@@ -873,7 +873,7 @@ push_local_name (tree decl) ...@@ -873,7 +873,7 @@ push_local_name (tree decl)
{ {
if (!DECL_LANG_SPECIFIC (decl)) if (!DECL_LANG_SPECIFIC (decl))
retrofit_lang_decl (decl); retrofit_lang_decl (decl);
DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1; DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
if (DECL_LANG_SPECIFIC (t)) if (DECL_LANG_SPECIFIC (t))
DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1; DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
else else
...@@ -1786,9 +1786,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1786,9 +1786,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{ {
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl); DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
if (CAN_HAVE_FULL_LANG_DECL_P (newdecl) if (TREE_CODE (newdecl) == FUNCTION_DECL)
&& DECL_LANG_SPECIFIC (newdecl)
&& DECL_LANG_SPECIFIC (olddecl))
{ {
DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl); DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
...@@ -1894,24 +1892,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1894,24 +1892,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* Don't really know how much of the language-specific /* Don't really know how much of the language-specific
values we should copy from old to new. */ values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 =
DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl); DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
if (DECL_TEMPLATE_INFO (newdecl))
new_template_info = DECL_TEMPLATE_INFO (newdecl);
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
DECL_INITIALIZED_IN_CLASS_P (newdecl) DECL_INITIALIZED_IN_CLASS_P (newdecl)
|= DECL_INITIALIZED_IN_CLASS_P (olddecl); |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
olddecl_friend = DECL_FRIEND_P (olddecl);
hidden_friend = (DECL_ANTICIPATED (olddecl)
&& DECL_HIDDEN_FRIEND_P (olddecl)
&& newdecl_is_friend);
/* Only functions have DECL_BEFRIENDING_CLASSES. */ if (LANG_DECL_HAS_MIN (newdecl))
{
DECL_LANG_SPECIFIC (newdecl)->u.min.u2 =
DECL_LANG_SPECIFIC (olddecl)->u.min.u2;
if (DECL_TEMPLATE_INFO (newdecl))
new_template_info = DECL_TEMPLATE_INFO (newdecl);
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
}
/* Only functions have these fields. */
if (TREE_CODE (newdecl) == FUNCTION_DECL if (TREE_CODE (newdecl) == FUNCTION_DECL
|| DECL_FUNCTION_TEMPLATE_P (newdecl)) || DECL_FUNCTION_TEMPLATE_P (newdecl))
{ {
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
olddecl_friend = DECL_FRIEND_P (olddecl);
hidden_friend = (DECL_ANTICIPATED (olddecl)
&& DECL_HIDDEN_FRIEND_P (olddecl)
&& newdecl_is_friend);
DECL_BEFRIENDING_CLASSES (newdecl) DECL_BEFRIENDING_CLASSES (newdecl)
= chainon (DECL_BEFRIENDING_CLASSES (newdecl), = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
DECL_BEFRIENDING_CLASSES (olddecl)); DECL_BEFRIENDING_CLASSES (olddecl));
...@@ -12582,16 +12583,6 @@ finish_method (tree decl) ...@@ -12582,16 +12583,6 @@ finish_method (tree decl)
DECL_INITIAL (fndecl) = old_initial; DECL_INITIAL (fndecl) = old_initial;
/* We used to check if the context of FNDECL was different from
current_class_type as another way to get inside here. This didn't work
for String.cc in libg++. */
if (DECL_FRIEND_P (fndecl))
{
VEC_safe_push (tree, gc, CLASSTYPE_INLINE_FRIENDS (current_class_type),
fndecl);
decl = void_type_node;
}
return decl; return decl;
} }
......
...@@ -2634,7 +2634,6 @@ start_objects (int method_type, int initp) ...@@ -2634,7 +2634,6 @@ start_objects (int method_type, int initp)
DECL_GLOBAL_CTOR_P (current_function_decl) = 1; DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
else else
DECL_GLOBAL_DTOR_P (current_function_decl) = 1; DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1;
body = begin_compound_stmt (BCS_FN_BODY); body = begin_compound_stmt (BCS_FN_BODY);
......
...@@ -1406,7 +1406,7 @@ dump_function_name (tree t, int flags) ...@@ -1406,7 +1406,7 @@ dump_function_name (tree t, int flags)
pp_cxx_ws_string (cxx_pp, "operator"); pp_cxx_ws_string (cxx_pp, "operator");
dump_type (TREE_TYPE (TREE_TYPE (t)), flags); dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
} }
else if (IDENTIFIER_OPNAME_P (name)) else if (name && IDENTIFIER_OPNAME_P (name))
pp_cxx_tree_identifier (cxx_pp, name); pp_cxx_tree_identifier (cxx_pp, name);
else else
dump_decl (name, flags); dump_decl (name, flags);
......
...@@ -532,19 +532,20 @@ retrofit_lang_decl (tree t) ...@@ -532,19 +532,20 @@ retrofit_lang_decl (tree t)
{ {
struct lang_decl *ld; struct lang_decl *ld;
size_t size; size_t size;
int sel;
if (CAN_HAVE_FULL_LANG_DECL_P (t))
size = sizeof (struct lang_decl); if (TREE_CODE (t) == FUNCTION_DECL)
sel = 1, size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (t) == NAMESPACE_DECL)
sel = 2, size = sizeof (struct lang_decl_ns);
else if (LANG_DECL_HAS_MIN (t))
sel = 0, size = sizeof (struct lang_decl_min);
else else
size = sizeof (struct lang_decl_flags); gcc_unreachable ();
ld = GGC_CNEWVAR (struct lang_decl, size); ld = GGC_CNEWVAR (struct lang_decl, size);
ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0; ld->u.base.selector = sel;
ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
ld->decl_flags.u2sel = 0;
if (ld->decl_flags.can_be_full)
ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
DECL_LANG_SPECIFIC (t) = ld; DECL_LANG_SPECIFIC (t) = ld;
if (current_lang_name == lang_name_cplusplus if (current_lang_name == lang_name_cplusplus
...@@ -572,10 +573,15 @@ cxx_dup_lang_specific_decl (tree node) ...@@ -572,10 +573,15 @@ cxx_dup_lang_specific_decl (tree node)
if (! DECL_LANG_SPECIFIC (node)) if (! DECL_LANG_SPECIFIC (node))
return; return;
if (!CAN_HAVE_FULL_LANG_DECL_P (node)) if (TREE_CODE (node) == FUNCTION_DECL)
size = sizeof (struct lang_decl_flags); size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (node) == NAMESPACE_DECL)
size = sizeof (struct lang_decl_ns);
else if (LANG_DECL_HAS_MIN (node))
size = sizeof (struct lang_decl_min);
else else
size = sizeof (struct lang_decl); gcc_unreachable ();
ld = GGC_NEWVAR (struct lang_decl, size); ld = GGC_NEWVAR (struct lang_decl, size);
memcpy (ld, DECL_LANG_SPECIFIC (node), size); memcpy (ld, DECL_LANG_SPECIFIC (node), size);
DECL_LANG_SPECIFIC (node) = ld; DECL_LANG_SPECIFIC (node) = ld;
......
...@@ -1088,43 +1088,54 @@ write_unqualified_name (const tree decl) ...@@ -1088,43 +1088,54 @@ write_unqualified_name (const tree decl)
{ {
MANGLE_TRACE_TREE ("unqualified-name", decl); MANGLE_TRACE_TREE ("unqualified-name", decl);
if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_CONSTRUCTOR_P (decl)) if (DECL_NAME (decl) == NULL_TREE)
write_special_name_constructor (decl);
else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
write_special_name_destructor (decl);
else if (DECL_NAME (decl) == NULL_TREE)
{ {
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
write_source_name (DECL_ASSEMBLER_NAME (decl)); write_source_name (DECL_ASSEMBLER_NAME (decl));
return;
} }
else if (DECL_CONV_FN_P (decl)) else if (DECL_DECLARES_FUNCTION_P (decl))
{ {
/* Conversion operator. Handle it right here. bool found = true;
<operator> ::= cv <type> */ if (DECL_CONSTRUCTOR_P (decl))
tree type; write_special_name_constructor (decl);
if (decl_is_template_id (decl, NULL)) else if (DECL_DESTRUCTOR_P (decl))
write_special_name_destructor (decl);
else if (DECL_CONV_FN_P (decl))
{ {
tree fn_type; /* Conversion operator. Handle it right here.
fn_type = get_mostly_instantiated_function_type (decl); <operator> ::= cv <type> */
type = TREE_TYPE (fn_type); tree type;
if (decl_is_template_id (decl, NULL))
{
tree fn_type;
fn_type = get_mostly_instantiated_function_type (decl);
type = TREE_TYPE (fn_type);
}
else
type = DECL_CONV_FN_TYPE (decl);
write_conversion_operator_name (type);
}
else if (DECL_OVERLOADED_OPERATOR_P (decl))
{
operator_name_info_t *oni;
if (DECL_ASSIGNMENT_OPERATOR_P (decl))
oni = assignment_operator_name_info;
else
oni = operator_name_info;
write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
} }
else else
type = DECL_CONV_FN_TYPE (decl); found = false;
write_conversion_operator_name (type);
}
else if (DECL_OVERLOADED_OPERATOR_P (decl))
{
operator_name_info_t *oni;
if (DECL_ASSIGNMENT_OPERATOR_P (decl))
oni = assignment_operator_name_info;
else
oni = operator_name_info;
write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name); if (found)
return;
} }
else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
&& DECL_NAMESPACE_SCOPE_P (decl) if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
&& decl_linkage (decl) == lk_internal) && DECL_NAMESPACE_SCOPE_P (decl)
&& decl_linkage (decl) == lk_internal)
{ {
MANGLE_TRACE_TREE ("local-source-name", decl); MANGLE_TRACE_TREE ("local-source-name", decl);
write_char ('L'); write_char ('L');
......
...@@ -277,7 +277,6 @@ make_alias_for (tree function, tree newid) ...@@ -277,7 +277,6 @@ make_alias_for (tree function, tree newid)
DECL_SAVED_FUNCTION_DATA (alias) = NULL; DECL_SAVED_FUNCTION_DATA (alias) = NULL;
DECL_DESTRUCTOR_P (alias) = 0; DECL_DESTRUCTOR_P (alias) = 0;
DECL_CONSTRUCTOR_P (alias) = 0; DECL_CONSTRUCTOR_P (alias) = 0;
DECL_CLONED_FUNCTION (alias) = NULL_TREE;
DECL_EXTERNAL (alias) = 0; DECL_EXTERNAL (alias) = 0;
DECL_ARTIFICIAL (alias) = 1; DECL_ARTIFICIAL (alias) = 1;
DECL_NO_STATIC_CHAIN (alias) = 1; DECL_NO_STATIC_CHAIN (alias) = 1;
......
...@@ -3458,17 +3458,6 @@ build_template_decl (tree decl, tree parms, bool member_template_p) ...@@ -3458,17 +3458,6 @@ build_template_decl (tree decl, tree parms, bool member_template_p)
DECL_TEMPLATE_PARMS (tmpl) = parms; DECL_TEMPLATE_PARMS (tmpl) = parms;
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p; DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
if (DECL_LANG_SPECIFIC (decl))
{
DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);
DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl);
DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);
DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);
if (DECL_OVERLOADED_OPERATOR_P (decl))
SET_OVERLOADED_OPERATOR_CODE (tmpl,
DECL_OVERLOADED_OPERATOR_P (decl));
}
return tmpl; return tmpl;
} }
...@@ -3792,6 +3781,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, ...@@ -3792,6 +3781,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
if (current_class_type if (current_class_type
&& !TYPE_BEING_DEFINED (current_class_type) && !TYPE_BEING_DEFINED (current_class_type)
&& DECL_LANG_SPECIFIC (decl) && DECL_LANG_SPECIFIC (decl)
&& DECL_DECLARES_FUNCTION_P (decl)
/* If this is either a friend defined in the scope of the class /* If this is either a friend defined in the scope of the class
or a member function. */ or a member function. */
&& (DECL_FUNCTION_MEMBER_P (decl) && (DECL_FUNCTION_MEMBER_P (decl)
...@@ -8594,13 +8584,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -8594,13 +8584,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
DECL_SAVED_TREE (r) = NULL_TREE; DECL_SAVED_TREE (r) = NULL_TREE;
DECL_STRUCT_FUNCTION (r) = NULL; DECL_STRUCT_FUNCTION (r) = NULL;
TREE_USED (r) = 0; TREE_USED (r) = 0;
if (DECL_CLONED_FUNCTION (r)) /* We'll re-clone as appropriate in instantiate_template. */
{ DECL_CLONED_FUNCTION (r) = NULL_TREE;
DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t),
args, complain, t);
TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r));
TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
}
/* Set up the DECL_TEMPLATE_INFO for R. There's no need to do /* Set up the DECL_TEMPLATE_INFO for R. There's no need to do
this in the special friend case mentioned above where this in the special friend case mentioned above where
...@@ -12330,8 +12315,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) ...@@ -12330,8 +12315,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
tree spec; tree spec;
tree clone; tree clone;
spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr, /* Use DECL_ABSTRACT_ORIGIN because only FUNCTION_DECLs have
complain); DECL_CLONED_FUNCTION. */
spec = instantiate_template (DECL_ABSTRACT_ORIGIN (tmpl),
targ_ptr, complain);
if (spec == error_mark_node) if (spec == error_mark_node)
return error_mark_node; return error_mark_node;
......
...@@ -65,10 +65,6 @@ cxx_print_decl (FILE *file, tree node, int indent) ...@@ -65,10 +65,6 @@ cxx_print_decl (FILE *file, tree node, int indent)
&& DECL_PENDING_INLINE_INFO (node)) && DECL_PENDING_INLINE_INFO (node))
fprintf (file, " pending-inline-info %p", fprintf (file, " pending-inline-info %p",
(void *) DECL_PENDING_INLINE_INFO (node)); (void *) DECL_PENDING_INLINE_INFO (node));
if (TREE_CODE (node) == TYPE_DECL
&& DECL_SORTED_FIELDS (node))
fprintf (file, " sorted-fields %p",
(void *) DECL_SORTED_FIELDS (node));
if ((TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL) if ((TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL)
&& DECL_TEMPLATE_INFO (node)) && DECL_TEMPLATE_INFO (node))
fprintf (file, " template-info %p", fprintf (file, " template-info %p",
...@@ -95,13 +91,6 @@ cxx_print_type (FILE *file, tree node, int indent) ...@@ -95,13 +91,6 @@ cxx_print_type (FILE *file, tree node, int indent)
print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4); print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
return; return;
case RECORD_TYPE:
case UNION_TYPE:
indent_to (file, indent + 4);
fprintf (file, "full-name \"%s\"",
type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
break;
default: default:
return; return;
} }
...@@ -113,6 +102,10 @@ cxx_print_type (FILE *file, tree node, int indent) ...@@ -113,6 +102,10 @@ cxx_print_type (FILE *file, tree node, int indent)
if (! CLASS_TYPE_P (node)) if (! CLASS_TYPE_P (node))
return; return;
indent_to (file, indent + 4);
fprintf (file, "full-name \"%s\"",
type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
indent_to (file, indent + 3); indent_to (file, indent + 3);
if (TYPE_NEEDS_CONSTRUCTING (node)) if (TYPE_NEEDS_CONSTRUCTING (node))
...@@ -140,6 +133,9 @@ cxx_print_type (FILE *file, tree node, int indent) ...@@ -140,6 +133,9 @@ cxx_print_type (FILE *file, tree node, int indent)
fputs (" delete[]", file); fputs (" delete[]", file);
if (TYPE_HAS_ASSIGN_REF (node)) if (TYPE_HAS_ASSIGN_REF (node))
fputs (" this=(X&)", file); fputs (" this=(X&)", file);
if (CLASSTYPE_SORTED_FIELDS (node))
fprintf (file, " sorted-fields %p",
(void *) CLASSTYPE_SORTED_FIELDS (node));
if (TREE_CODE (node) == RECORD_TYPE) if (TREE_CODE (node) == RECORD_TYPE)
{ {
......
...@@ -395,12 +395,10 @@ lookup_field_1 (tree type, tree name, bool want_type) ...@@ -395,12 +395,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */ The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */
return NULL_TREE; return NULL_TREE;
if (TYPE_NAME (type) if (CLASSTYPE_SORTED_FIELDS (type))
&& DECL_LANG_SPECIFIC (TYPE_NAME (type))
&& DECL_SORTED_FIELDS (TYPE_NAME (type)))
{ {
tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0]; tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0];
int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len; int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len;
int i; int i;
while (lo < hi) while (lo < hi)
......
...@@ -3861,7 +3861,7 @@ finish_omp_threadprivate (tree vars) ...@@ -3861,7 +3861,7 @@ finish_omp_threadprivate (tree vars)
/* Make sure that DECL_DISCRIMINATOR_P continues to be true /* Make sure that DECL_DISCRIMINATOR_P continues to be true
after the allocation of the lang_decl structure. */ after the allocation of the lang_decl structure. */
if (DECL_DISCRIMINATOR_P (v)) if (DECL_DISCRIMINATOR_P (v))
DECL_LANG_SPECIFIC (v)->decl_flags.u2sel = 1; DECL_LANG_SPECIFIC (v)->u.base.u2sel = 1;
} }
if (! DECL_THREAD_LOCAL_P (v)) if (! DECL_THREAD_LOCAL_P (v))
......
2009-07-03 Jason Merrill <jason@redhat.com>
* g++.dg/template/pure1.C: Expect another error.
2009-07-03 Richard Guenther <rguenther@suse.de> 2009-07-03 Richard Guenther <rguenther@suse.de>
PR tree-optimization/40640 PR tree-optimization/40640
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
struct A struct A
{ {
template<int> void foo() = 1; // { dg-error "pure" } template<int> void foo() = 1; // { dg-error "pure|non-virtual" }
}; };
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