Commit 5daf7c0a by Jason Merrill Committed by Jason Merrill

tree.h (DECL_UNINLINABLE): Move from C++ frontend.

        * tree.h (DECL_UNINLINABLE): Move from C++ frontend.
        (struct tree_decl): Add uninlinable bitfield.
        * c-decl.c (duplicate_decls): Set it.
        * integrate.c (function_cannot_inline_p): Check it.
        * cp-tree.h (struct lang_decl_flags): Remove uninlinable flag.
        (DECL_UNINLINABLE): Move to middle-end.

        * dwarf2out.c (add_name_and_src_coords_attributes): Don't add
        DW_AT_MIPS_linkage_name to abstract methods.
        (dwarf2out_abstract_function): Emit class context before calling
        set_decl_abstract_flags.  Don't clear DECL_ABSTRACT.
        (gen_subprogram_die): Remove obsolete code.
        (gen_member_die): Don't include clones in the member list.
        (gen_decl_die): Emit abstract info for clone origin.
        * dwarfout.c (output_type): Don't include clones in the member list.
        * dbxout.c (dbxout_type_methods): Ignore abstract methods.
        * toplev.c (note_deferral_of_defined_inline_function): Don't clear
        DECL_ABSTRACT on a function that already has it set.
        * class.c (clone_function_decl): Set DECL_ABSTRACT on original fn.
        * decl.c (duplicate_decls): Preserve DECL_ABSTRACT.
        * class.c (build_clone): Set DECL_ABSTRACT_ORIGIN for the clone.
        * optimize.c (maybe_clone_body): Set DECL_ABSTRACT_ORIGIN for the
        parms and outer BLOCK.  note_deferral_of_defined_inline_function.

        * dwarf2out.c (gen_formal_types_die): Also accept a FUNCTION_DECL.
        (get_subprogram_die): Pass it in.
        * method.c (implicitly_declare_fn): Don't set DECL_ARTIFICIAL on
        second parm of op=.

From-SVN: r39945
parent 3c88f366
2001-02-21 Jason Merrill <jason@redhat.com>
* tree.h (DECL_UNINLINABLE): Move from C++ frontend.
(struct tree_decl): Add uninlinable bitfield.
* c-decl.c (duplicate_decls): Set it.
* integrate.c (function_cannot_inline_p): Check it.
* dwarf2out.c (add_name_and_src_coords_attributes): Don't add
DW_AT_MIPS_linkage_name to abstract methods.
(dwarf2out_abstract_function): Emit class context before calling
set_decl_abstract_flags. Don't clear DECL_ABSTRACT.
(gen_subprogram_die): Remove obsolete code.
(gen_member_die): Don't include clones in the member list.
(gen_decl_die): Emit abstract info for clone origin.
* dwarfout.c (output_type): Don't include clones in the member list.
* dbxout.c (dbxout_type_methods): Ignore abstract methods.
* toplev.c (note_deferral_of_defined_inline_function): Don't clear
DECL_ABSTRACT on a function that already has it set.
* dwarf2out.c (gen_formal_types_die): Also accept a FUNCTION_DECL.
(get_subprogram_die): Pass it in.
2001-02-21 Richard Earnshaw <rearnsha@arm.com> 2001-02-21 Richard Earnshaw <rearnsha@arm.com>
* flow.c (mark_set_1): Make not_dead unsigned long. For * flow.c (mark_set_1): Make not_dead unsigned long. For
......
...@@ -1928,19 +1928,6 @@ duplicate_decls (newdecl, olddecl, different_binding_level) ...@@ -1928,19 +1928,6 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
/* For functions, static overrides non-static. */ /* For functions, static overrides non-static. */
if (TREE_CODE (newdecl) == FUNCTION_DECL) if (TREE_CODE (newdecl) == FUNCTION_DECL)
{ {
/* If we're redefining a function previously defined as extern
inline, make sure we emit debug info for the inline before we
throw it away, in case it was inlined into a function that hasn't
been written out yet. */
if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl))
{
note_outlining_of_inline_function (olddecl);
/* The new defn must not be inline.
FIXME what about -finline-functions? */
DECL_INLINE (newdecl) = 0;
}
TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
/* This is since we don't automatically /* This is since we don't automatically
copy the attributes of NEWDECL into OLDDECL. */ copy the attributes of NEWDECL into OLDDECL. */
...@@ -1974,12 +1961,27 @@ duplicate_decls (newdecl, olddecl, different_binding_level) ...@@ -1974,12 +1961,27 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
if (TREE_CODE (newdecl) == FUNCTION_DECL) if (TREE_CODE (newdecl) == FUNCTION_DECL)
{ {
/* If either decl says `inline', this fn is inline, /* If we're redefining a function previously defined as extern
unless its definition was passed already. */ inline, make sure we emit debug info for the inline before we
if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) throw it away, in case it was inlined into a function that hasn't
DECL_INLINE (olddecl) = 1; been written out yet. */
if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl))
{
note_outlining_of_inline_function (olddecl);
DECL_INLINE (newdecl) = DECL_INLINE (olddecl); /* The new defn must not be inline. */
DECL_INLINE (newdecl) = 0;
DECL_UNINLINABLE (newdecl) = 1;
}
else
{
/* If either decl says `inline', this fn is inline,
unless its definition was passed already. */
if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
DECL_INLINE (olddecl) = 1;
DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
}
if (DECL_BUILT_IN (olddecl)) if (DECL_BUILT_IN (olddecl))
{ {
......
2001-02-21 Jason Merrill <jason@redhat.com>
* cp-tree.h (struct lang_decl_flags): Remove uninlinable flag.
(DECL_UNINLINABLE): Move to middle-end.
* class.c (clone_function_decl): Set DECL_ABSTRACT on original fn.
* decl.c (duplicate_decls): Preserve DECL_ABSTRACT.
* class.c (build_clone): Set DECL_ABSTRACT_ORIGIN for the clone.
* optimize.c (maybe_clone_body): Set DECL_ABSTRACT_ORIGIN for the
parms and outer BLOCK. note_deferral_of_defined_inline_function.
* method.c (implicitly_declare_fn): Don't set DECL_ARTIFICIAL on
second parm of op=.
2001-02-19 Mark Mitchell <mark@codesourcery.com> 2001-02-19 Mark Mitchell <mark@codesourcery.com>
* decl2.c (set_decl_namespace): Allow explicit instantiations in * decl2.c (set_decl_namespace): Allow explicit instantiations in
......
...@@ -4179,6 +4179,7 @@ build_clone (fn, name) ...@@ -4179,6 +4179,7 @@ build_clone (fn, name)
clone = copy_decl (fn); clone = copy_decl (fn);
/* Remember where this function came from. */ /* Remember where this function came from. */
DECL_CLONED_FUNCTION (clone) = fn; 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;
DECL_ASSEMBLER_NAME (clone) = DECL_NAME (clone); DECL_ASSEMBLER_NAME (clone) = DECL_NAME (clone);
...@@ -4339,6 +4340,9 @@ clone_function_decl (fn, update_method_vec_p) ...@@ -4339,6 +4340,9 @@ clone_function_decl (fn, update_method_vec_p)
if (update_method_vec_p) if (update_method_vec_p)
add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0);
} }
/* Note that this is an abstract function that is never emitted. */
DECL_ABSTRACT (fn) = 1;
} }
/* For each of the constructors and destructors in T, create an /* For each of the constructors and destructors in T, create an
......
...@@ -1811,7 +1811,7 @@ struct lang_decl_flags ...@@ -1811,7 +1811,7 @@ struct lang_decl_flags
unsigned static_function : 1; unsigned static_function : 1;
unsigned pure_virtual : 1; unsigned pure_virtual : 1;
unsigned has_in_charge_parm_p : 1; unsigned has_in_charge_parm_p : 1;
unsigned uninlinable : 1; unsigned has_vtt_parm_p : 1;
unsigned deferred : 1; unsigned deferred : 1;
unsigned use_template : 2; unsigned use_template : 2;
...@@ -1828,7 +1828,7 @@ struct lang_decl_flags ...@@ -1828,7 +1828,7 @@ struct lang_decl_flags
unsigned assignment_operator_p : 1; unsigned assignment_operator_p : 1;
unsigned anticipated_p : 1; unsigned anticipated_p : 1;
unsigned generate_with_vtable_p : 1; unsigned generate_with_vtable_p : 1;
unsigned has_vtt_parm_p : 1; /* One unused bit. */
union { union {
/* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
...@@ -2469,10 +2469,6 @@ extern int flag_new_for_scope; ...@@ -2469,10 +2469,6 @@ extern int flag_new_for_scope;
/* Record whether a typedef for type `int' was actually `signed int'. */ /* Record whether a typedef for type `int' was actually `signed int'. */
#define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) #define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp))
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.uninlinable)
/* Returns non-zero if DECL has external linkage, as specified by the /* Returns non-zero if DECL has external linkage, as specified by the
language standard. (This predicate may hold even when the language standard. (This predicate may hold even when the
corresponding entity is not actually given external linkage in the corresponding entity is not actually given external linkage in the
......
...@@ -3626,6 +3626,9 @@ duplicate_decls (newdecl, olddecl) ...@@ -3626,6 +3626,9 @@ duplicate_decls (newdecl, olddecl)
DECL_INLINE (olddecl) = 1; DECL_INLINE (olddecl) = 1;
DECL_INLINE (newdecl) = DECL_INLINE (olddecl); DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
/* Preserve abstractness on cloned [cd]tors. */
DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
if (! types_match) if (! types_match)
{ {
DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl); DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
......
...@@ -1026,8 +1026,6 @@ implicitly_declare_fn (kind, type, const_p) ...@@ -1026,8 +1026,6 @@ implicitly_declare_fn (kind, type, const_p)
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 20000408); my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 20000408);
if (kind != sfk_constructor && kind != sfk_destructor)
DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn))) = 1;
DECL_ARTIFICIAL (fn) = 1; DECL_ARTIFICIAL (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_THIS_INLINE (fn) = 1; DECL_THIS_INLINE (fn) = 1;
......
...@@ -932,6 +932,9 @@ maybe_clone_body (fn) ...@@ -932,6 +932,9 @@ maybe_clone_body (fn)
&& !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
return 0; return 0;
/* Emit the DWARF1 abstract instance. */
note_deferral_of_defined_inline_function (fn);
/* We know that any clones immediately follow FN in the TYPE_METHODS /* We know that any clones immediately follow FN in the TYPE_METHODS
list. */ list. */
for (clone = TREE_CHAIN (fn); for (clone = TREE_CHAIN (fn);
...@@ -996,6 +999,7 @@ maybe_clone_body (fn) ...@@ -996,6 +999,7 @@ maybe_clone_body (fn)
from the CLONE to this parameter. */ from the CLONE to this parameter. */
if (DECL_HAS_VTT_PARM_P (clone)) if (DECL_HAS_VTT_PARM_P (clone))
{ {
DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
splay_tree_insert (id.decl_map, splay_tree_insert (id.decl_map,
(splay_tree_key) parm, (splay_tree_key) parm,
(splay_tree_value) clone_parm); (splay_tree_value) clone_parm);
...@@ -1013,6 +1017,7 @@ maybe_clone_body (fn) ...@@ -1013,6 +1017,7 @@ maybe_clone_body (fn)
function. */ function. */
else else
{ {
DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
splay_tree_insert (id.decl_map, splay_tree_insert (id.decl_map,
(splay_tree_key) parm, (splay_tree_key) parm,
(splay_tree_value) clone_parm); (splay_tree_value) clone_parm);
...@@ -1029,7 +1034,9 @@ maybe_clone_body (fn) ...@@ -1029,7 +1034,9 @@ maybe_clone_body (fn)
/* Now, expand this function into RTL, if appropriate. */ /* Now, expand this function into RTL, if appropriate. */
function_name_declared_p = 1; function_name_declared_p = 1;
expand_body (finish_function (0)); finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
expand_body (clone);
pop_from_top_level (); pop_from_top_level ();
} }
......
...@@ -841,7 +841,9 @@ dbxout_type_methods (type) ...@@ -841,7 +841,9 @@ dbxout_type_methods (type)
last = fndecl; last = fndecl;
if (DECL_IGNORED_P (fndecl)) /* Also ignore abstract methods; those are only interesting to
the DWARF backends. */
if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT (fndecl))
continue; continue;
if (flag_minimal_debug) if (flag_minimal_debug)
......
...@@ -9390,7 +9390,8 @@ add_name_and_src_coords_attributes (die, decl) ...@@ -9390,7 +9390,8 @@ add_name_and_src_coords_attributes (die, decl)
if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
&& TREE_PUBLIC (decl) && TREE_PUBLIC (decl)
&& DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)
&& !DECL_ABSTRACT (decl))
add_AT_string (die, DW_AT_MIPS_linkage_name, add_AT_string (die, DW_AT_MIPS_linkage_name,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
} }
...@@ -9936,24 +9937,22 @@ gen_formal_types_die (function_or_method_type, context_die) ...@@ -9936,24 +9937,22 @@ gen_formal_types_die (function_or_method_type, context_die)
{ {
register tree link; register tree link;
register tree formal_type = NULL; register tree formal_type = NULL;
register tree first_parm_type = TYPE_ARG_TYPES (function_or_method_type); register tree first_parm_type;
tree arg;
#if 0 if (TREE_CODE (function_or_method_type) == FUNCTION_DECL)
/* In the case where we are generating a formal types list for a C++ {
non-static member function type, skip over the first thing on the arg = DECL_ARGUMENTS (function_or_method_type);
TYPE_ARG_TYPES list because it only represents the type of the hidden function_or_method_type = TREE_TYPE (function_or_method_type);
`this pointer'. The debugger should be able to figure out (without }
being explicitly told) that this non-static member function type takes a else
`this pointer' and should be able to figure what the type of that hidden arg = NULL_TREE;
parameter is from the DW_AT_member attribute of the parent
DW_TAG_subroutine_type DIE. */ first_parm_type = TYPE_ARG_TYPES (function_or_method_type);
if (TREE_CODE (function_or_method_type) == METHOD_TYPE)
first_parm_type = TREE_CHAIN (first_parm_type);
#endif
/* Make our first pass over the list of formal parameter types and output a /* Make our first pass over the list of formal parameter types and output a
DW_TAG_formal_parameter DIE for each one. */ DW_TAG_formal_parameter DIE for each one. */
for (link = first_parm_type; link; link = TREE_CHAIN (link)) for (link = first_parm_type; link; )
{ {
register dw_die_ref parm_die; register dw_die_ref parm_die;
...@@ -9963,9 +9962,14 @@ gen_formal_types_die (function_or_method_type, context_die) ...@@ -9963,9 +9962,14 @@ gen_formal_types_die (function_or_method_type, context_die)
/* Output a (nameless) DIE to represent the formal parameter itself. */ /* Output a (nameless) DIE to represent the formal parameter itself. */
parm_die = gen_formal_parameter_die (formal_type, context_die); parm_die = gen_formal_parameter_die (formal_type, context_die);
if (TREE_CODE (function_or_method_type) == METHOD_TYPE if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
&& link == first_parm_type) && link == first_parm_type)
|| (arg && DECL_ARTIFICIAL (arg)))
add_AT_flag (parm_die, DW_AT_artificial, 1); add_AT_flag (parm_die, DW_AT_artificial, 1);
link = TREE_CHAIN (link);
if (arg)
arg = TREE_CHAIN (arg);
} }
/* If this function type has an ellipsis, add a /* If this function type has an ellipsis, add a
...@@ -10025,19 +10029,34 @@ void ...@@ -10025,19 +10029,34 @@ void
dwarf2out_abstract_function (decl) dwarf2out_abstract_function (decl)
tree decl; tree decl;
{ {
register dw_die_ref old_die = lookup_decl_die (decl); register dw_die_ref old_die;
tree save_fn; tree save_fn;
tree context;
int was_abstract = DECL_ABSTRACT (decl);
/* Make sure we have the actual abstract inline, not a clone. */
decl = DECL_ORIGIN (decl);
old_die = lookup_decl_die (decl);
if (old_die && get_AT_unsigned (old_die, DW_AT_inline)) if (old_die && get_AT_unsigned (old_die, DW_AT_inline))
/* We've already generated the abstract instance. */ /* We've already generated the abstract instance. */
return; return;
/* Be sure we've emitted the in-class declaration DIE (if any) first, so
we don't get confused by DECL_ABSTRACT. */
context = decl_class_context (decl);
if (context)
gen_type_die_for_member
(context, decl, decl_function_context (decl) ? NULL : comp_unit_die);
/* Pretend we've just finished compiling this function. */
save_fn = current_function_decl; save_fn = current_function_decl;
current_function_decl = decl; current_function_decl = decl;
set_decl_abstract_flags (decl, 1); set_decl_abstract_flags (decl, 1);
dwarf2out_decl (decl); dwarf2out_decl (decl);
set_decl_abstract_flags (decl, 0); if (! was_abstract)
set_decl_abstract_flags (decl, 0);
current_function_decl = save_fn; current_function_decl = save_fn;
} }
...@@ -10088,17 +10107,6 @@ gen_subprogram_die (decl, context_die) ...@@ -10088,17 +10107,6 @@ gen_subprogram_die (decl, context_die)
subr_die = new_die (DW_TAG_subprogram, context_die); subr_die = new_die (DW_TAG_subprogram, context_die);
add_abstract_origin_attribute (subr_die, origin); add_abstract_origin_attribute (subr_die, origin);
} }
else if (old_die && DECL_ABSTRACT (decl)
&& get_AT_unsigned (old_die, DW_AT_inline))
{
/* This must be a redefinition of an extern inline function.
We can just reuse the old die here. */
subr_die = old_die;
/* Clear out the inlined attribute and parm types. */
remove_AT (subr_die, DW_AT_inline);
remove_children (subr_die);
}
else if (old_die) else if (old_die)
{ {
register unsigned file_index register unsigned file_index
...@@ -10261,7 +10269,7 @@ gen_subprogram_die (decl, context_die) ...@@ -10261,7 +10269,7 @@ gen_subprogram_die (decl, context_die)
if (debug_info_level <= DINFO_LEVEL_TERSE) if (debug_info_level <= DINFO_LEVEL_TERSE)
; ;
else if (declaration) else if (declaration)
gen_formal_types_die (TREE_TYPE (decl), subr_die); gen_formal_types_die (decl, subr_die);
else else
{ {
/* Generate DIEs to represent all known formal parameters */ /* Generate DIEs to represent all known formal parameters */
...@@ -10738,6 +10746,10 @@ gen_member_die (type, context_die) ...@@ -10738,6 +10746,10 @@ gen_member_die (type, context_die)
/* Now output info about the function members (if any). */ /* Now output info about the function members (if any). */
for (member = TYPE_METHODS (type); member; member = TREE_CHAIN (member)) for (member = TYPE_METHODS (type); member; member = TREE_CHAIN (member))
{ {
/* Don't include clones in the member list. */
if (DECL_ABSTRACT_ORIGIN (member))
continue;
child = lookup_decl_die (member); child = lookup_decl_die (member);
if (child) if (child)
splice_child_die (context_die, child); splice_child_die (context_die, child);
...@@ -11266,20 +11278,23 @@ gen_decl_die (decl, context_die) ...@@ -11266,20 +11278,23 @@ gen_decl_die (decl, context_die)
&& (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl))) && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
break; break;
/* If we're emitting a clone, emit info for the abstract instance. */
if (DECL_ORIGIN (decl) != decl)
dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl));
/* If we're emitting an out-of-line copy of an inline function, /* If we're emitting an out-of-line copy of an inline function,
emit info for the abstract instance and set up to refer to it. */ emit info for the abstract instance and set up to refer to it. */
if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl) else if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
&& ! class_scope_p (context_die) && ! class_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just a /* dwarf2out_abstract_function won't emit a die if this is just
declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */ that case, because that works only if we have a die. */
&& DECL_INITIAL (decl) != NULL_TREE) && DECL_INITIAL (decl) != NULL_TREE)
{ {
dwarf2out_abstract_function (decl); dwarf2out_abstract_function (decl);
set_decl_origin_self (decl); set_decl_origin_self (decl);
} }
/* Otherwise we're emitting the primary DIE for this decl. */
if (debug_info_level > DINFO_LEVEL_TERSE) else if (debug_info_level > DINFO_LEVEL_TERSE)
{ {
/* Before we describe the FUNCTION_DECL itself, make sure that we /* Before we describe the FUNCTION_DECL itself, make sure that we
have described its return type. */ have described its return type. */
......
...@@ -4444,7 +4444,13 @@ output_type (type, containing_scope) ...@@ -4444,7 +4444,13 @@ output_type (type, containing_scope)
for (func_member = TYPE_METHODS (type); for (func_member = TYPE_METHODS (type);
func_member; func_member;
func_member = TREE_CHAIN (func_member)) func_member = TREE_CHAIN (func_member))
output_decl (func_member, type); {
/* Don't include clones in the member list. */
if (DECL_ABSTRACT_ORIGIN (func_member))
continue;
output_decl (func_member, type);
}
} }
--in_class; --in_class;
......
...@@ -139,6 +139,9 @@ function_cannot_inline_p (fndecl) ...@@ -139,6 +139,9 @@ function_cannot_inline_p (fndecl)
register tree parms; register tree parms;
rtx result; rtx result;
if (DECL_UNINLINABLE (fndecl))
return N_("function cannot be inline");
/* No inlines with varargs. */ /* No inlines with varargs. */
if ((last && TREE_VALUE (last) != void_type_node) if ((last && TREE_VALUE (last) != void_type_node)
|| current_function_varargs) || current_function_varargs)
......
...@@ -2661,19 +2661,23 @@ note_deferral_of_defined_inline_function (decl) ...@@ -2661,19 +2661,23 @@ note_deferral_of_defined_inline_function (decl)
/* Generate the DWARF info for the "abstract" instance of a function /* Generate the DWARF info for the "abstract" instance of a function
which we may later generate inlined and/or out-of-line instances which we may later generate inlined and/or out-of-line instances
of. */ of. */
if (write_symbols == DWARF_DEBUG && DECL_INLINE (decl)) if (write_symbols == DWARF_DEBUG
&& (DECL_INLINE (decl) || DECL_ABSTRACT (decl))
&& ! DECL_ABSTRACT_ORIGIN (decl))
{ {
/* The front-end may not have set CURRENT_FUNCTION_DECL, but the /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
DWARF code expects it to be set in this case. Intuitively, DWARF code expects it to be set in this case. Intuitively,
DECL is the function we just finished defining, so setting DECL is the function we just finished defining, so setting
CURRENT_FUNCTION_DECL is sensible. */ CURRENT_FUNCTION_DECL is sensible. */
tree saved_cfd = current_function_decl; tree saved_cfd = current_function_decl;
int was_abstract = DECL_ABSTRACT (decl);
current_function_decl = decl; current_function_decl = decl;
/* Let the DWARF code do its work. */ /* Let the DWARF code do its work. */
set_decl_abstract_flags (decl, 1); set_decl_abstract_flags (decl, 1);
dwarfout_file_scope_decl (decl, 0); dwarfout_file_scope_decl (decl, 0);
set_decl_abstract_flags (decl, 0); if (! was_abstract)
set_decl_abstract_flags (decl, 0);
/* Reset CURRENT_FUNCTION_DECL. */ /* Reset CURRENT_FUNCTION_DECL. */
current_function_decl = saved_cfd; current_function_decl = saved_cfd;
......
...@@ -239,8 +239,6 @@ struct tree_common ...@@ -239,8 +239,6 @@ struct tree_common
INTEGER_TYPE, ENUMERAL_TYPE, FIELD_DECL INTEGER_TYPE, ENUMERAL_TYPE, FIELD_DECL
DECL_BUILT_IN_NONANSI in DECL_BUILT_IN_NONANSI in
FUNCTION_DECL FUNCTION_DECL
TREE_PARMLIST in
TREE_PARMLIST (C++)
SAVE_EXPR_NOPLACEHOLDER in SAVE_EXPR_NOPLACEHOLDER in
SAVE_EXPR SAVE_EXPR
...@@ -1461,6 +1459,9 @@ struct tree_type ...@@ -1461,6 +1459,9 @@ struct tree_type
where it is called. */ where it is called. */
#define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag) #define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag)
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
/* Nonzero in a FUNCTION_DECL means this is a built-in function /* Nonzero in a FUNCTION_DECL means this is a built-in function
that is not specified by ansi C and that users are supposed to be allowed that is not specified by ansi C and that users are supposed to be allowed
to redefine for any purpose whatever. */ to redefine for any purpose whatever. */
...@@ -1632,7 +1633,8 @@ struct tree_decl ...@@ -1632,7 +1633,8 @@ struct tree_decl
unsigned pointer_depth : 2; unsigned pointer_depth : 2;
unsigned non_addressable : 1; unsigned non_addressable : 1;
unsigned user_align : 1; unsigned user_align : 1;
/* Three unused bits. */ unsigned uninlinable : 1;
/* Two unused bits. */
unsigned lang_flag_0 : 1; unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1; unsigned lang_flag_1 : 1;
......
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