/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
#include "tree-mudflap.h"
#include "cgraph.h"
#include "tree-inline.h"
+#include "c-pragma.h"
extern cpp_reader *parse_in;
} *priority_info;
static void mark_vtable_entries (tree);
-static void grok_function_init (tree, tree);
static bool maybe_emit_vtables (tree);
-static tree build_anon_union_vars (tree);
static bool acceptable_java_type (tree);
static tree start_objects (int, int);
static void finish_objects (int, int, tree);
/* A list of static class variables. This is needed, because a
static class variable can be declared inside the class without
an initializer, and then initialized, statically, outside the class. */
-static GTY(()) varray_type pending_statics;
-#define pending_statics_used \
- (pending_statics ? pending_statics->elements_used : 0)
+static GTY(()) VEC(tree,gc) *pending_statics;
/* A list of functions which were declared inline, but which we
may need to emit outline anyway. */
-static GTY(()) varray_type deferred_fns;
-#define deferred_fns_used \
- (deferred_fns ? deferred_fns->elements_used : 0)
-
-/* Flag used when debugging spew.c */
-
-extern int spew_debug;
+static GTY(()) VEC(tree,gc) *deferred_fns;
/* Nonzero if we're done parsing and into end-of-file activities. */
/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
indicated NAME. */
-tree
+static tree
build_artificial_parm (tree name, tree type)
{
tree parm = cp_build_parm_decl (name, type);
this_quals |= TYPE_QUAL_CONST;
qual_type = cp_build_qualified_type (type, this_quals);
parm = build_artificial_parm (this_identifier, qual_type);
- c_apply_type_quals_to_decl (this_quals, parm);
+ cp_apply_type_quals_to_decl (this_quals, parm);
TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
DECL_ARGUMENTS (function) = parm;
}
return t;
}
- exp = convert_from_reference (exp);
-
/* An array can't have been allocated by new, so complain. */
if (TREE_CODE (exp) == VAR_DECL
&& TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
- warning ("deleting array %q#D", exp);
+ warning (0, "deleting array %q#D", exp);
t = build_expr_type_conversion (WANT_POINTER, exp, true);
/* Deleting ptr to void is undefined behavior [expr.delete/3]. */
if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
{
- warning ("deleting %qT is undefined", type);
+ warning (0, "deleting %qT is undefined", type);
doing_vec = 0;
}
ix = class_method_index_for_fn (complete_type (ctype), function);
if (ix >= 0)
{
- VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
+ VEC(tree,gc) *methods = CLASSTYPE_METHOD_VEC (ctype);
tree fndecls, fndecl = 0;
bool is_conv_op;
- bool pop_p;
+ tree pushed_scope;
const char *format = NULL;
- pop_p = push_scope (ctype);
+ pushed_scope = push_scope (ctype);
for (fndecls = VEC_index (tree, methods, ix);
fndecls; fndecls = OVL_NEXT (fndecls))
{
== DECL_TI_TEMPLATE (fndecl))))
break;
}
- if (pop_p)
- pop_scope (ctype);
+ if (pushed_scope)
+ pop_scope (pushed_scope);
if (fndecls)
return OVL_CURRENT (fndecls);
- error ("prototype for `%#D' does not match any in class `%T'",
+ error ("prototype for %q#D does not match any in class %qT",
function, ctype);
is_conv_op = DECL_CONV_FN_P (fndecl);
{
DECL_DEFERRED_FN (decl) = 1;
DECL_DEFER_OUTPUT (decl) = 1;
- if (!deferred_fns)
- VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
- VARRAY_PUSH_TREE (deferred_fns, decl);
+ VEC_safe_push (tree, gc, deferred_fns, decl);
}
}
static void
note_vague_linkage_var (tree var)
{
- if (!pending_statics)
- VARRAY_TREE_INIT (pending_statics, 32, "pending_statics");
- VARRAY_PUSH_TREE (pending_statics, var);
+ VEC_safe_push (tree, gc, pending_statics, var);
}
/* We have just processed the DECL, which is a static data member.
if (!declspecs->any_specifiers_p
&& declarator->kind == cdk_id
- && TREE_CODE (declarator->u.id.name) == SCOPE_REF
- && (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1))
- == IDENTIFIER_NODE))
+ && declarator->u.id.qualifying_scope
+ && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
/* Access declaration */
- return do_class_using_decl (declarator->u.id.name);
+ return do_class_using_decl (declarator->u.id.qualifying_scope,
+ declarator->u.id.unqualified_name);
if (init
&& TREE_CODE (init) == TREE_LIST
value = push_template_decl (value);
if (attrlist)
- cplus_decl_attributes (&value, attrlist, 0);
+ {
+ /* Avoid storing attributes in template parameters:
+ tsubst is not ready to handle them. */
+ tree type = TREE_TYPE (value);
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ sorry ("applying attributes to template parameters is not implemented");
+ else
+ cplus_decl_attributes (&value, attrlist, 0);
+ }
return value;
}
{
if (TREE_CODE (value) == FUNCTION_DECL)
{
- grok_function_init (value, init);
- init = NULL_TREE;
+ /* Initializers for functions are rejected early in the parser.
+ If we get here, it must be a pure specifier for a method. */
+ gcc_assert (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE);
+ gcc_assert (error_operand_p (init) || integer_zerop (init));
+ DECL_PURE_VIRTUAL_P (value) = 1;
}
else if (pedantic && TREE_CODE (value) != VAR_DECL)
/* Already complained in grokdeclarator. */
if (!processing_template_decl)
{
- if (TREE_CODE (init) == CONST_DECL)
- init = DECL_INITIAL (init);
- else if (TREE_READONLY_DECL_P (init))
- init = decl_constant_value (init);
- else if (TREE_CODE (init) == CONSTRUCTOR)
+ if (TREE_CODE (init) == CONSTRUCTOR)
init = digest_init (TREE_TYPE (value), init, (tree *)0);
+ else
+ init = integral_constant_value (init);
+
if (init != error_mark_node && ! TREE_CONSTANT (init))
{
/* We can allow references to things that are effectively
case FIELD_DECL:
if (asmspec)
- error ("`asm' specifiers are not permitted on non-static data members");
+ error ("%<asm%> specifiers are not permitted on non-static data members");
if (DECL_INITIAL (value) == error_mark_node)
init = error_mark_node;
cp_finish_decl (value, init, NULL_TREE, flags);
return value;
}
-/* When a function is declared with an initializer,
- do the right thing. Currently, there are two possibilities:
-
- class B
- {
- public:
- // initialization possibility #1.
- virtual void f () = 0;
- int g ();
- };
-
- class D1 : B
- {
- public:
- int d1;
- // error, no f ();
- };
-
- class D2 : B
- {
- public:
- int d2;
- void f ();
- };
-
- class D3 : B
- {
- public:
- int d3;
- // initialization possibility #2
- void f () = B::f;
- };
-
-*/
-
-static void
-grok_function_init (tree decl, tree init)
-{
- /* An initializer for a function tells how this function should
- be inherited. */
- tree type = TREE_TYPE (decl);
-
- if (TREE_CODE (type) == FUNCTION_TYPE)
- error ("initializer specified for non-member function %qD", decl);
- else if (integer_zerop (init))
- DECL_PURE_VIRTUAL_P (decl) = 1;
- else
- error ("invalid initializer for virtual method %qD", decl);
-}
\f
void
cplus_decl_attributes (tree *decl, tree attributes, int flags)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
}
\f
-/* Walks through the namespace- or function-scope anonymous union OBJECT,
- building appropriate ALIAS_DECLs. Returns one of the fields for use in
- the mangled name. */
+/* Walks through the namespace- or function-scope anonymous union
+ OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs.
+ Returns one of the fields for use in the mangled name. */
static tree
-build_anon_union_vars (tree object)
+build_anon_union_vars (tree type, tree object)
{
- tree type = TREE_TYPE (object);
tree main_decl = NULL_TREE;
tree field;
decl = pushdecl (decl);
}
else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- decl = build_anon_union_vars (ref);
+ decl = build_anon_union_vars (TREE_TYPE (field), ref);
else
decl = 0;
return;
}
- main_decl = build_anon_union_vars (anon_union_decl);
+ main_decl = build_anon_union_vars (type, anon_union_decl);
if (main_decl == NULL_TREE)
{
- warning ("anonymous union with no members");
+ warning (0, "anonymous union with no members");
return;
}
&& DECL_DECLARED_INLINE_P (decl)
&& visibility_options.inlines_hidden)
{
- DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
- DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ /* Don't change it if it has been set explicitly by user. */
+ if (!DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
}
else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
{
DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
DECL_VISIBILITY_SPECIFIED (decl) = 1;
}
- /* If no explicit visibility information has been provided for
- this class, some targets require that class data be
- exported. */
- else if (TREE_CODE (decl) == VAR_DECL
- && targetm.cxx.export_class_data ()
- && (DECL_TINFO_P (decl)
- || (DECL_VTABLE_OR_VTT_P (decl)
- /* Construction virtual tables are not emitted
- because they cannot be referred to from other
- object files; their name is not standardized by
- the ABI. */
- && !DECL_CONSTRUCTION_VTABLE_P (decl))))
- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
- else
+ else if (!DECL_VISIBILITY_SPECIFIED (decl))
{
DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
DECL_VISIBILITY_SPECIFIED (decl) = 0;
int emit_p;
bool comdat_p;
bool import_p;
+ tree class_type = NULL_TREE;
if (DECL_INTERFACE_KNOWN (decl))
return;
vague linkage, maybe_commonize_var is used.
Therefore, the only declarations that should be provided to this
- function are those with external linkage that:
+ function are those with external linkage that are:
* implicit instantiations of function templates
;
else if (TREE_CODE (decl) == VAR_DECL && DECL_VTABLE_OR_VTT_P (decl))
{
- tree type = DECL_CONTEXT (decl);
- import_export_class (type);
- if (TYPE_FOR_JAVA (type))
+ class_type = DECL_CONTEXT (decl);
+ import_export_class (class_type);
+ if (TYPE_FOR_JAVA (class_type))
import_p = true;
- else if (CLASSTYPE_INTERFACE_KNOWN (type)
- && CLASSTYPE_INTERFACE_ONLY (type))
+ else if (CLASSTYPE_INTERFACE_KNOWN (class_type)
+ && CLASSTYPE_INTERFACE_ONLY (class_type))
import_p = true;
- else if (TARGET_WEAK_NOT_IN_ARCHIVE_TOC
- && !CLASSTYPE_USE_TEMPLATE (type)
- && CLASSTYPE_KEY_METHOD (type)
- && !DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (type)))
+ else if ((!flag_weak || TARGET_WEAK_NOT_IN_ARCHIVE_TOC)
+ && !CLASSTYPE_USE_TEMPLATE (class_type)
+ && CLASSTYPE_KEY_METHOD (class_type)
+ && !DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (class_type)))
/* The ABI requires that all virtual tables be emitted with
COMDAT linkage. However, on systems where COMDAT symbols
don't show up in the table of contents for a static
- archive, the linker will report errors about undefined
- symbols because it will not see the virtual table
- definition. Therefore, in the case that we know that the
- virtual table will be emitted in only one translation
- unit, we make the virtual table an ordinary definition
- with external linkage. */
+ archive, or on systems without weak symbols (where we
+ approximate COMDAT linkage by using internal linkage), the
+ linker will report errors about undefined symbols because
+ it will not see the virtual table definition. Therefore,
+ in the case that we know that the virtual table will be
+ emitted in only one translation unit, we make the virtual
+ table an ordinary definition with external linkage. */
DECL_EXTERNAL (decl) = 0;
- else if (CLASSTYPE_INTERFACE_KNOWN (type))
+ else if (CLASSTYPE_INTERFACE_KNOWN (class_type))
{
- /* TYPE is being exported from this translation unit, so DECL
- should be defined here. The ABI requires COMDAT
- linkage. Normally, we only emit COMDAT things when they
- are needed; make sure that we realize that this entity is
- indeed needed. */
- comdat_p = true;
- mark_needed (decl);
+ /* CLASS_TYPE is being exported from this translation unit,
+ so DECL should be defined here. */
+ if (!flag_weak && CLASSTYPE_EXPLICIT_INSTANTIATION (class_type))
+ /* If a class is declared in a header with the "extern
+ template" extension, then it will not be instantiated,
+ even in translation units that would normally require
+ it. Often such classes are explicitly instantiated in
+ one translation unit. Therefore, the explicit
+ instantiation must be made visible to other translation
+ units. */
+ DECL_EXTERNAL (decl) = 0;
+ else
+ {
+ /* The generic C++ ABI says that class data is always
+ COMDAT, even if there is a key function. Some
+ variants (e.g., the ARM EABI) says that class data
+ only has COMDAT linkage if the the class data might
+ be emitted in more than one translation unit. */
+ if (!CLASSTYPE_KEY_METHOD (class_type)
+ || targetm.cxx.class_data_always_comdat ())
+ {
+ /* The ABI requires COMDAT linkage. Normally, we
+ only emit COMDAT things when they are needed;
+ make sure that we realize that this entity is
+ indeed needed. */
+ comdat_p = true;
+ mark_needed (decl);
+ }
+ }
}
else if (!flag_implicit_templates
- && CLASSTYPE_IMPLICIT_INSTANTIATION (type))
+ && CLASSTYPE_IMPLICIT_INSTANTIATION (class_type))
import_p = true;
else
comdat_p = true;
tree type = TREE_TYPE (DECL_NAME (decl));
if (CLASS_TYPE_P (type))
{
+ class_type = type;
import_export_class (type);
if (CLASSTYPE_INTERFACE_KNOWN (type)
&& TYPE_POLYMORPHIC_P (type)
import_p = true;
else
{
- comdat_p = true;
if (CLASSTYPE_INTERFACE_KNOWN (type)
&& !CLASSTYPE_INTERFACE_ONLY (type))
- mark_needed (decl);
+ {
+ comdat_p = targetm.cxx.class_data_always_comdat ();
+ mark_needed (decl);
+ if (!flag_weak)
+ {
+ comdat_p = false;
+ DECL_EXTERNAL (decl) = 0;
+ }
+ }
+ else
+ comdat_p = true;
}
}
else
comdat_linkage (decl);
}
+ /* Give the target a chance to override the visibility associated
+ with DECL. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && (DECL_TINFO_P (decl)
+ || (DECL_VTABLE_OR_VTT_P (decl)
+ /* Construction virtual tables are not exported because
+ they cannot be referred to from other object files;
+ their name is not standardized by the ABI. */
+ && !DECL_CONSTRUCTION_VTABLE_P (decl)))
+ && TREE_PUBLIC (decl)
+ && !DECL_REALLY_EXTERN (decl)
+ && DECL_VISIBILITY_SPECIFIED (decl)
+ && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)))
+ targetm.cxx.determine_class_data_visibility (decl);
+
DECL_INTERFACE_KNOWN (decl) = 1;
}
DECL_WEAK (guard) = DECL_WEAK (decl);
DECL_ARTIFICIAL (guard) = 1;
+ DECL_IGNORED_P (guard) = 1;
TREE_USED (guard) = 1;
pushdecl_top_level_and_finish (guard, NULL_TREE);
}
if (targetm.have_ctors_dtors)
{
rtx fnsym = XEXP (DECL_RTL (fn), 0);
+ cgraph_mark_needed_node (cgraph_node (fn));
if (method_type == 'I')
(* targetm.asm_out.constructor) (fnsym, initp);
else
/* All the static storage duration functions created in this
translation unit. */
-static GTY(()) varray_type ssdf_decls;
+static GTY(()) VEC(tree,gc) *ssdf_decls;
/* A map from priority levels to information about that priority
level. There may be many such levels, so efficient lookup is
static constructors and destructors. */
if (!ssdf_decls)
{
- VARRAY_TREE_INIT (ssdf_decls, 32, "ssdf_decls");
+ ssdf_decls = VEC_alloc (tree, gc, 32);
/* Take this opportunity to initialize the map from priority
numbers to information about that priority level. */
get_priority_info (DEFAULT_INIT_PRIORITY);
}
- VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl);
+ VEC_safe_push (tree, gc, ssdf_decls, ssdf_decl);
/* Create the argument list. */
initialize_p_decl = cp_build_parm_decl
if (init)
finish_expr_stmt (init);
- /* If we're using __cxa_atexit, register a a function that calls the
+ /* If we're using __cxa_atexit, register a function that calls the
destructor for the object. */
if (flag_use_cxa_atexit)
finish_expr_stmt (register_dtor_fn (decl));
global constructors and destructors. */
body = NULL_TREE;
+ /* For Objective-C++, we may need to initialize metadata found in this module.
+ This must be done _before_ any other static initializations. */
+ if (c_dialect_objc () && (priority == DEFAULT_INIT_PRIORITY)
+ && constructor_p && objc_static_init_needed_p ())
+ {
+ body = start_objects (function_key, priority);
+ static_ctors = objc_generate_static_init_call (static_ctors);
+ }
+
/* Call the static storage duration function with appropriate
arguments. */
- if (ssdf_decls)
- for (i = 0; i < ssdf_decls->elements_used; ++i)
- {
- fndecl = VARRAY_TREE (ssdf_decls, i);
-
- /* Calls to pure or const functions will expand to nothing. */
- if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
- {
- if (! body)
- body = start_objects (function_key, priority);
-
- arguments = tree_cons (NULL_TREE,
- build_int_cst (NULL_TREE, priority),
- NULL_TREE);
- arguments = tree_cons (NULL_TREE,
- build_int_cst (NULL_TREE, constructor_p),
- arguments);
- finish_expr_stmt (build_function_call (fndecl, arguments));
- }
- }
+ for (i = 0; VEC_iterate (tree, ssdf_decls, i, fndecl); ++i)
+ {
+ /* Calls to pure or const functions will expand to nothing. */
+ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
+ {
+ if (! body)
+ body = start_objects (function_key, priority);
+
+ arguments = tree_cons (NULL_TREE,
+ build_int_cst (NULL_TREE, priority),
+ NULL_TREE);
+ arguments = tree_cons (NULL_TREE,
+ build_int_cst (NULL_TREE, constructor_p),
+ arguments);
+ finish_expr_stmt (build_function_call (fndecl, arguments));
+ }
+ }
/* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in
calls to any functions marked with attributes indicating that
location_t locus;
unsigned ssdf_count = 0;
int retries = 0;
+ tree decl;
locus = input_location;
at_eof = 1;
do
{
tree t;
+ tree decl;
reconsider = false;
/* Go through the set of inline functions whose bodies have not
been emitted yet. If out-of-line copies of these functions
are required, emit them. */
- for (i = 0; i < deferred_fns_used; ++i)
+ for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i)
{
- tree decl = VARRAY_TREE (deferred_fns, i);
-
/* Does it need synthesizing? */
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
&& (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl)))
reconsider = true;
/* Static data members are just like namespace-scope globals. */
- for (i = 0; i < pending_statics_used; ++i)
+ for (i = 0; VEC_iterate (tree, pending_statics, i, decl); ++i)
{
- tree decl = VARRAY_TREE (pending_statics, i);
if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl))
continue;
import_export_decl (decl);
if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
DECL_EXTERNAL (decl) = 0;
}
- if (pending_statics
- && wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0),
- pending_statics_used))
- reconsider = true;
-
- /* Ask the back end to emit functions and variables that are
- enqueued. These emissions may result in marking more entities
- as needed. */
- if (cgraph_assemble_pending_functions ())
- reconsider = true;
- if (cgraph_varpool_assemble_pending_decls ())
+ if (VEC_length (tree, pending_statics) != 0
+ && wrapup_global_declarations (VEC_address (tree, pending_statics),
+ VEC_length (tree, pending_statics)))
reconsider = true;
retries++;
while (reconsider);
/* All used inline functions must have a definition at this point. */
- for (i = 0; i < deferred_fns_used; ++i)
+ for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i)
{
- tree decl = VARRAY_TREE (deferred_fns, i);
-
if (/* Check online inline functions that were actually used. */
TREE_USED (decl) && DECL_DECLARED_INLINE_P (decl)
/* But not defined. */
already verified there was a definition. */
&& !DECL_EXPLICIT_INSTANTIATION (decl))
{
- cp_warning_at ("inline function `%D' used but never defined", decl);
+ cp_warning_at ("inline function %qD used but never defined", decl);
/* This symbol is effectively an "extern" declaration now.
This is not strictly necessary, but removes a duplicate
warning. */
if (priority_info_map)
splay_tree_delete (priority_info_map);
+ /* Generate any missing aliases. */
+ maybe_apply_pending_pragma_weaks ();
+
/* We're done with static constructors, so we can go back to "C++"
linkage now. */
pop_lang_context ();
/* Now, issue warnings about static, but not defined, functions,
etc., and emit debugging information. */
walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
- if (pending_statics)
- check_global_declarations (&VARRAY_TREE (pending_statics, 0),
- pending_statics_used);
+ if (VEC_length (tree, pending_statics) != 0)
+ check_global_declarations (VEC_address (tree, pending_statics),
+ VEC_length (tree, pending_statics));
finish_repo ();
&& DECL_ARTIFICIAL (decl)
&& !DECL_THUNK_P (decl)
&& ! DECL_INITIAL (decl)
- /* Kludge: don't synthesize for default args. */
+ /* Kludge: don't synthesize for default args. Unfortunately this
+ rules out initializers of namespace-scoped objects too, but
+ it's sort-of ok if the implicit ctor or dtor decl keeps
+ pointing to the class location. */
&& current_function_decl)
{
+ /* Put the function definition at the position where it is needed,
+ rather than within the body of the class. That way, an error
+ during the generation of the implicit body points at the place
+ where the attempt to generate the function occurs, giving the
+ user a hint as to why we are attempting to generate the
+ function. */
+ DECL_SOURCE_LOCATION (decl) = input_location;
+
synthesize_method (decl);
/* If we've already synthesized the method we don't need to
instantiate it, so we can return right away. */