90th Cygnus<->FSF quick merge

From-SVN: r13141
This commit is contained in:
Mike Stump 1996-11-12 19:49:48 +00:00
parent 3aad04640f
commit 9a3b49acbc
17 changed files with 398 additions and 266 deletions

View File

@ -1,3 +1,112 @@
Tue Nov 12 08:39:17 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (cp_finish_decl): In MINIMAL_PARSE_MODE, only try to use
the DECL_VINDEX of DECL if it's set.
* tree.c (mapcar): Handle RTL_EXPR.
Mon Nov 11 13:57:31 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (current_template_args): New fn.
(push_template_decl): Use it.
* decl.c (grokdeclarator): Use it.
* decl2.c (build_expr_from_tree): Dereference ref vars.
* decl.c (grokdeclarator): Generalize handling of TYPENAME_TYPEs in
the decl-specifier-seq.
* decl.c (grok_op_properties): Don't force the type of a conversion
op to be complete. Don't warn about converting to the same type
for template instantiations.
* decl2.c (finish_file): Don't call instantiate_decl on synthesized
methods.
Mon Nov 11 13:20:34 1996 Bob Manson <manson@charmed.cygnus.com>
* typeck.c (get_delta_difference): Remove previous bogusness.
Don't give errors if force is set.
Fri Nov 8 17:38:44 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (finish_file): Don't emit debug info.
* decl.c (start_function): Call note_debug_info_needed for context.
(start_decl): Likewise.
(cp_finish_decl): Not here.
(finish_function): Or here.
(pushdecl): Lose obsolete code.
(grokdeclarator): Still do the long long thing after complaining.
(finish_enum): Don't call rest_of_type_compilation
for DWARF.
* class.c (finish_struct_1): Don't call rest_of_type_compilation
for DWARF.
* search.c (dfs_debug_mark): For DWARF, just call
rest_of_type_compilation.
(note_debug_info_needed): Don't do anything if we're in a template.
* parse.y (named_complex_class_head_sans_basetype): Likewise.
* method.c (synthesize_method): For non-local classes,
push_to_top_level first.
Fri Nov 8 11:52:28 1996 Bob Manson <manson@charmed.cygnus.com>
* typeck.c (get_delta_difference): Add no_error parameter.
(build_ptrmemfunc): Call get_delta_difference with no_error set;
we don't want error messages when converting unrelated
pointer-to-member functions.
Thu Nov 7 11:16:24 1996 Mike Stump <mrs@cygnus.com>
* error.c (dump_expr): Improve the wording on error messages that
involve pointer to member functions.
Tue Nov 5 17:12:05 1996 Mike Stump <mrs@cygnus.com>
* cvt.c (cp_convert_to_pointer): Move code for conversions from
(::*)() to void* or (*)() up a bit, so that we can convert from
METHOD_TYPEs as well.
Tue Nov 5 14:54:17 1996 Jason Merrill <jason@yorick.cygnus.com>
* rtti.c (get_tinfo_fn): Make sure 'type' is permanent.
There are no 'member' types.
(get_tinfo_fn_dynamic): Diagnose typeid of overloaded fn.
(build_x_typeid): Handle errors.
Mon Nov 4 17:43:12 1996 Mike Stump <mrs@cygnus.com>
* typeck.c (convert_for_assignment): Handle anachronistic implicit
conversions from (::*)() to void* or (*)().
* cvt.c (cp_convert_to_pointer): Likewise.
(cp_convert_to_pointer_force): Remove cp_convert_to_pointer
conversions from here.
* decl2.c (lang_decode_option): Add -W{no-,}pmf-conversions.
* lang-options.h: Likewise.
* decl2.c (warn_pmf2ptr): Define.
* cp-tree.h: Declare it.
* typeck2.c (digest_init): Allow pmfs down into
convert_for_initialization.
Sun Nov 3 09:43:00 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (c_expand_return): Fix for returning overloaded fn.
Fri Nov 1 08:53:17 1996 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h (DIRECT_BIND): Change from INDIRECT_BIND.
* decl.c (grok_reference_init): Pass DIRECT_BIND.
* cvt.c (build_up_reference): Don't mark 'this' addressable. Use
DIRECT_BIND.
* call.c (convert_like): Don't pass INDIRECT_BIND.
* typeck.c (convert_arguments): Likewise.
* typeck.c (mark_addressable): Allow &this if flag_this_is_variable.
Thu Oct 31 17:08:49 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (mark_addressable): Support TARGET_EXPR, unify with
similar code in build_up_ref.
* cvt.c (build_up_reference): Drastically simplify.
Mon Oct 28 12:45:05 1996 Jeffrey A Law (law@cygnus.com)
* typeck.c (signed_or_unsigned_type): If the given type already

View File

@ -4900,7 +4900,7 @@ convert_like (convs, expr)
case REF_BIND:
return convert_to_reference
(TREE_TYPE (convs), expr,
CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION|INDIRECT_BIND,
CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
error_mark_node);
case LVALUE_CONV:
return decay_conversion (expr);

View File

@ -873,7 +873,7 @@ modify_vtable_entry (old_entry_in_list, new_entry, fndecl)
}
}
/* Access the virtual function table entry i. VIRTUALS is the virtual
/* Access the virtual function table entry N. VIRTUALS is the virtual
function table's initializer. */
static tree
@ -4188,7 +4188,10 @@ finish_struct_1 (t, warn_anon)
For example, if a member function is seen and we decide to
write out that member function, then we can change the value
of the DECL_IGNORED_P slot, and the type will be output when
that member function's debug info is written out. */
that member function's debug info is written out.
We can't do this with DWARF, which does not support name
references between translation units. */
if (CLASSTYPE_METHOD_VEC (t))
{
extern tree pending_vtables;
@ -4209,10 +4212,10 @@ finish_struct_1 (t, warn_anon)
}
else if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
}
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel_bindings_p ());
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel_bindings_p ());
}
return t;
}

View File

@ -243,6 +243,11 @@ extern int warn_format;
extern int warn_nonvdtor;
/* Non-zero means warn when we convert a pointer to member function
into a pointer to (void or function). */
extern int warn_pmf2ptr;
/* Non-zero means warn when a function is declared extern and later inline. */
extern int warn_extern_inline;
@ -1845,9 +1850,9 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
LOOKUP_HAS_IN_CHARGE means that the "in charge" variable is already
in the parameter list.
LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
INDIRECT_BIND means that if a temporary is created, it should be created so
that it lives only as long as WITH_CLEANUP_EXPRs live, else if a temporary
is created then it should live as long as the current variable bindings.
DIRECT_BIND means that if a temporary is created, it should be created so
that it lives as long as the current variable bindings; otherwise it
only lives until the end of the complete-expression.
LOOKUP_SPECULATIVELY means return NULL_TREE if we cannot find what we are
after. Note, LOOKUP_COMPLAIN is checked and error messages printed
before LOOKUP_SPECULATIVELY is checked.
@ -1865,7 +1870,7 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_HAS_IN_CHARGE (32)
#define LOOKUP_SPECULATIVELY (64)
#define LOOKUP_ONLYCONVERTING (128)
#define INDIRECT_BIND (256)
#define DIRECT_BIND (256)
#define LOOKUP_NO_CONVERSION (512)
#define LOOKUP_DESTRUCTOR (512)
#define LOOKUP_NO_TEMP_BIND (1024)
@ -2290,6 +2295,7 @@ extern void begin_template_parm_list PROTO((void));
extern tree process_template_parm PROTO((tree, tree));
extern tree end_template_parm_list PROTO((tree));
extern void end_template_decl PROTO((void));
extern tree current_template_args PROTO((void));
extern void push_template_decl PROTO((tree));
extern tree lookup_template_class PROTO((tree, tree, tree));
extern int uses_template_parms PROTO((tree));

View File

@ -154,6 +154,50 @@ cp_convert_to_pointer (type, expr)
if (TYPE_PTRMEMFUNC_P (intype))
intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
/* Handle anachronistic conversions from (::*)() to void* or (*)(). */
if (TREE_CODE (type) == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
|| TREE_TYPE (type) == void_type_node))
{
/* Allow an implicit this pointer for pointer to member
functions. */
if (TREE_CODE (intype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE)
{
tree decl, basebinfo;
tree fntype = TREE_TYPE (intype);
tree t = TYPE_METHOD_BASETYPE (fntype);
if (current_class_type == 0
|| get_base_distance (t, current_class_type, 0, &basebinfo)
== -1)
{
decl = build1 (NOP_EXPR, t, error_mark_node);
}
else if (current_class_ptr == 0)
decl = build1 (NOP_EXPR, t, error_mark_node);
else
decl = current_class_ref;
expr = build (OFFSET_REF, fntype, decl, expr);
}
if (TREE_CODE (expr) == OFFSET_REF
&& TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
expr = resolve_offset_ref (expr);
if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
expr = build_addr_func (expr);
if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
if (pedantic || warn_pmf2ptr)
cp_pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr),
type);
return build1 (NOP_EXPR, type, expr);
}
intype = TREE_TYPE (expr);
}
form = TREE_CODE (intype);
if (form == POINTER_TYPE || form == REFERENCE_TYPE)
@ -282,44 +326,6 @@ convert_to_pointer_force (type, expr)
form = TREE_CODE (intype);
}
if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
{
/* Allow an implicit this pointer for pointer to member
functions. */
if (TYPE_PTRMEMFUNC_P (intype))
{
tree decl, basebinfo;
tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype));
tree t = TYPE_METHOD_BASETYPE (fntype);
if (current_class_type == 0
|| get_base_distance (t, current_class_type, 0, &basebinfo) == -1)
{
decl = build1 (NOP_EXPR, t, error_mark_node);
}
else if (current_class_ptr == 0)
decl = build1 (NOP_EXPR, t, error_mark_node);
else
decl = current_class_ref;
expr = build (OFFSET_REF, fntype, decl, expr);
intype = TREE_TYPE (expr);
}
if (TREE_CODE (expr) == OFFSET_REF && TREE_CODE (intype) == METHOD_TYPE)
expr = resolve_offset_ref (expr);
if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
expr = build_addr_func (expr);
if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
{
if (pedantic
&& TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
cp_pedwarn ("cannot convert `%T' to `%T'", intype, type);
return build1 (NOP_EXPR, type, expr);
}
}
if (form == POINTER_TYPE)
{
intype = TYPE_MAIN_VARIANT (intype);
@ -355,7 +361,6 @@ convert_to_pointer_force (type, expr)
}
return build_vbase_path (code, type, expr, path, 0);
}
return build1 (NOP_EXPR, type, expr);
}
return cp_convert_to_pointer (type, expr);
@ -366,7 +371,7 @@ convert_to_pointer_force (type, expr)
value we have to begin with is in ARG.
FLAGS controls how we manage access checking.
INDIRECT_BIND in FLAGS controls how any temporarys are generated.
DIRECT_BIND in FLAGS controls how any temporarys are generated.
CHECKCONST controls if we report error messages on const subversion. */
static tree
@ -512,72 +517,20 @@ build_up_reference (type, arg, flags, checkconst)
but complain if we need a reference to something declared
as `register'. */
case RESULT_DECL:
if (staticp (targ))
literal_flag = 1;
TREE_ADDRESSABLE (targ) = 1;
put_var_into_stack (targ);
break;
case PARM_DECL:
#if 0
if (targ == current_class_ptr)
{
error ("address of `this' not available");
/* #if 0 */
/* This code makes the following core dump the compiler on a sun4,
if the code below is used.
/* 'this' is not an lvalue. */
if (targ == current_class_ptr && ! flag_this_is_variable)
break;
class e_decl;
class a_decl;
typedef a_decl* a_ref;
class a_s {
public:
a_s();
void* append(a_ref& item);
};
class a_decl {
public:
a_decl (e_decl *parent);
a_s generic_s;
a_s decls;
e_decl* parent;
};
class e_decl {
public:
e_decl();
a_s implementations;
};
void foobar(void *);
a_decl::a_decl(e_decl *parent) {
parent->implementations.append(this);
}
*/
TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */
put_var_into_stack (targ);
break;
/* #else */
return error_mark_node;
/* #endif */
}
#endif
/* Fall through. */
case RESULT_DECL:
case VAR_DECL:
case CONST_DECL:
if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ)
&& !DECL_ARTIFICIAL (targ))
cp_warning ("address needed to build reference for `%D', which is declared `register'",
targ);
else if (staticp (targ))
if (staticp (targ))
literal_flag = 1;
TREE_ADDRESSABLE (targ) = 1;
put_var_into_stack (targ);
/* Fall through. */
case TARGET_EXPR:
mark_addressable (targ);
break;
case COMPOUND_EXPR:
@ -632,75 +585,30 @@ build_up_reference (type, arg, flags, checkconst)
TREE_REFERENCE_EXPR (rval) = 1;
return rval;
case TARGET_EXPR:
TREE_ADDRESSABLE (targ) = 1;
put_var_into_stack (TREE_OPERAND (targ, 0));
break;
default:
break;
}
if (TREE_ADDRESSABLE (targ) == 0)
if ((flags&DIRECT_BIND)
&& ! real_lvalue_p (targ))
{
if (! (flags&INDIRECT_BIND)
&& toplevel_bindings_p ())
if (toplevel_bindings_p ())
{
tree temp = get_temp_name (argtype, 0);
/* Give this new temp some rtl and initialize it. */
DECL_INITIAL (temp) = targ;
TREE_STATIC (temp) = 1;
cp_finish_decl (temp, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
/* Do this after declaring it static. */
rval = build_unary_op (ADDR_EXPR, temp, 0);
TREE_TYPE (rval) = type;
literal_flag = TREE_CONSTANT (rval);
goto done;
}
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
{
arg = build_cplus_new (argtype, targ);
}
else if (flags&INDIRECT_BIND)
{
/* This should be the default, not the below code. */
/* All callers except grok_reference_init should probably
use INDIRECT_BIND. */
tree slot = build (VAR_DECL, argtype);
layout_decl (slot, 0);
arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
arg = get_temp_name (argtype, 1);
literal_flag = 1;
}
else
{
tree temp = get_temp_name (argtype, 0);
rval = build_unary_op (ADDR_EXPR, temp, 0);
if (binfo && !BINFO_OFFSET_ZEROP (binfo))
rval = convert_pointer_to (target_type, rval);
else
TREE_TYPE (rval) = type;
temp = build (MODIFY_EXPR, argtype, temp, arg);
TREE_SIDE_EFFECTS (temp) = 1;
return build (COMPOUND_EXPR, type, temp, rval);
arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype));
DECL_ARTIFICIAL (arg) = 1;
}
DECL_INITIAL (arg) = targ;
cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
}
if (! (flags&INDIRECT_BIND))
else if (TREE_ADDRESSABLE (targ) == 0 && !(flags&DIRECT_BIND))
{
if (TREE_CODE (arg) == TARGET_EXPR)
{
tree decl = TREE_OPERAND (arg, 0);
tree cleanup;
if (! toplevel_bindings_p () && ! DECL_RTL (decl))
{
expand_decl (decl);
cleanup = maybe_build_cleanup (decl);
if (cleanup)
expand_decl_cleanup (decl, cleanup);
}
}
tree slot = build_decl (VAR_DECL, NULL_TREE, argtype);
arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
}
rval = build1 (ADDR_EXPR, type, arg);

View File

@ -3085,20 +3085,6 @@ pushdecl (x)
if (global_bindings_p ())
TYPE_NAME (type) = x;
}
else
{
tree tname = DECL_NAME (name);
/* This is a disgusting kludge for dealing with UPTs. */
if (global_bindings_p () && ANON_AGGRNAME_P (tname))
{
/* do gratuitous C++ typedefing, and make sure that
we access this type either through TREE_TYPE field
or via the tags list. */
TYPE_NAME (TREE_TYPE (x)) = x;
pushtag (tname, TREE_TYPE (x), 0);
}
}
my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140);
if (type != error_mark_node
@ -5823,6 +5809,12 @@ start_decl (declarator, declspecs, initialized)
}
}
/* Do this before the decl is actually defined so that the DWARF debug
info for the class reflects the declaration, rather than the
definition, of this decl. */
if (TREE_CODE (decl) == VAR_DECL && context)
note_debug_info_needed (context);
if (initialized)
{
if (! toplevel_bindings_p ()
@ -6085,7 +6077,8 @@ grok_reference_init (decl, type, init, cleanupp)
}
tmp = convert_to_reference
(type, init, CONV_IMPLICIT, LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl);
(type, init, CONV_IMPLICIT,
LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND, decl);
if (tmp == error_mark_node)
goto fail;
@ -6218,7 +6211,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
{
if (init && DECL_INITIAL (decl))
DECL_INITIAL (decl) = init;
if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl))
if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl)
&& DECL_VINDEX (decl))
{
tree stmt = DECL_VINDEX (decl);
DECL_VINDEX (decl) = NULL_TREE;
@ -6466,10 +6460,6 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
/* Let debugger know it should output info for this type. */
note_debug_info_needed (ttype);
if (TREE_STATIC (decl) && DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
note_debug_info_needed (DECL_CONTEXT (decl));
if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
&& DECL_SIZE (decl) != NULL_TREE
&& ! TREE_CONSTANT (DECL_SIZE (decl)))
@ -7813,7 +7803,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
if (pedantic && ! in_system_header)
pedwarn ("ANSI C++ does not support `long long'");
else if (longlong)
if (longlong)
error ("`long long long' is too long for GCC");
else
longlong = 1;
@ -7834,18 +7824,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else
{
type = TREE_TYPE (id);
if (TREE_CODE (type) == TYPENAME_TYPE
&& TYPE_CONTEXT (type) == current_class_type)
{
/* Members of the current class get resolved immediately;
we couldn't catch this one earlier because we hadn't
pushed into the class yet. */
if (TREE_TYPE (type))
type = TREE_TYPE (type);
else
type = make_typename_type (TYPE_CONTEXT (type),
TYPE_IDENTIFIER (type));
}
TREE_VALUE (spec) = type;
}
goto found;
@ -8810,6 +8788,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
;
else if (TREE_COMPLEXITY (declarator) == current_class_depth)
{
/* Resolve any TYPENAME_TYPEs from the decl-specifier-seq
that refer to ctype. They couldn't be resolved earlier
because we hadn't pushed into the class yet.
Example: resolve 'B<T>::type' in
'B<typename B<T>::type> B<T>::f () { }'. */
if (current_template_parms
&& uses_template_parms (type)
&& uses_template_parms (current_class_type))
{
tree args = current_template_args ();
type = tsubst (type, &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE);
}
/* This pop_nested_class corresponds to the
push_nested_class used to push into class scope for
parsing the argument list of a function decl, in
@ -8831,19 +8823,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
ctype = TREE_OPERAND (declarator, 0);
if (TREE_CODE (ctype) == TYPENAME_TYPE
&& TYPE_CONTEXT (ctype) == current_class_type)
{
/* Members of the current class get resolved immediately;
we couldn't catch this one earlier because we hadn't
pushed into the class yet. */
if (TREE_TYPE (ctype))
ctype = TREE_TYPE (ctype);
else
ctype = make_typename_type (TYPE_CONTEXT (ctype),
TYPE_IDENTIFIER (ctype));
}
if (sname == NULL_TREE)
goto done_scoping;
@ -10139,7 +10118,7 @@ grok_op_properties (decl, virtualp, friendp)
|| name == ansi_opname[(int) METHOD_CALL_EXPR])
return; /* no restrictions on args */
if (IDENTIFIER_TYPENAME_P (name))
if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
{
tree t = TREE_TYPE (name);
if (TREE_CODE (t) == VOID_TYPE)
@ -10153,7 +10132,9 @@ grok_op_properties (decl, virtualp, friendp)
if (t == current_class_type)
what = "the same type";
/* Don't force t to be complete here. */
else if (IS_AGGR_TYPE (t)
&& TYPE_SIZE (t)
&& DERIVED_FROM_P (t, current_class_type))
what = "a base class";
@ -10735,7 +10716,8 @@ finish_enum (enumtype, values)
}
/* Finish debugging output for this type. */
rest_of_type_compilation (enumtype, global_bindings_p ());
if (write_symbols != DWARF_DEBUG)
rest_of_type_compilation (enumtype, global_bindings_p ());
return enumtype;
}
@ -11014,6 +10996,12 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
}
}
/* Do this before the decl is actually defined so that the DWARF debug
info for the class reflects the declaration, rather than the
definition, of this decl. */
if (DECL_FUNCTION_MEMBER_P (decl1))
note_debug_info_needed (DECL_CLASS_CONTEXT (decl1));
/* Warn if function was previously implicitly declared
(but not if we warned then). */
if (! warn_implicit
@ -12000,9 +11988,6 @@ finish_function (lineno, call_poplevel, nested)
mark_inline_for_output (fndecl);
}
if (ctype && TREE_ASM_WRITTEN (fndecl))
note_debug_info_needed (ctype);
current_function_returns_null |= can_reach_end;
/* Since we don't normally go through c_expand_return for constructors,

View File

@ -42,7 +42,6 @@ extern tree cleanups_this_call;
static void grok_function_init PROTO((tree, tree));
void import_export_decl ();
extern int current_class_depth;
extern int symout_time;
/* A list of virtual function tables we must make sure to write out. */
tree pending_vtables;
@ -242,6 +241,10 @@ int warn_reorder;
/* Non-zero means warn when synthesis behavior differs from Cfront's. */
int warn_synth;
/* Non-zero means warn when we convert a pointer to member function
into a pointer to (void or function). */
int warn_pmf2ptr = 1;
/* Nonzero means `$' can be in an identifier.
See cccp.c for reasons why this breaks some obscure ANSI C programs. */
@ -555,6 +558,8 @@ lang_decode_option (p)
warn_reorder = setting;
else if (!strcmp (p, "synth"))
warn_synth = setting;
else if (!strcmp (p, "pmf-conversions"))
warn_pmf2ptr = setting;
else if (!strcmp (p, "comment"))
; /* cpp handles this one. */
else if (!strcmp (p, "comments"))
@ -2642,9 +2647,6 @@ extern int parse_time, varconst_time;
extern tree pending_templates;
extern tree maybe_templates;
#define TIMEVAR(VAR, BODY) \
do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
extern struct obstack permanent_obstack;
extern tree get_id_2 ();
@ -2711,7 +2713,8 @@ finish_file ()
instantiate_class_template (decl);
if (CLASSTYPE_TEMPLATE_INSTANTIATION (decl))
for (vars = TYPE_METHODS (decl); vars; vars = TREE_CHAIN (vars))
instantiate_decl (vars);
if (! DECL_ARTIFICIAL (vars))
instantiate_decl (vars);
}
else
instantiate_decl (decl);
@ -2768,13 +2771,6 @@ finish_file ()
{
tree decl = TREE_VALUE (vars);
#ifdef DWARF_DEBUGGING_INFO
/* Output DWARF information for file-scope tentative data object
declarations. */
if (write_symbols == DWARF_DEBUG)
TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
#endif
if (DECL_TEMPLATE_INSTANTIATION (decl)
&& ! DECL_IN_AGGR_P (decl))
{
@ -3430,6 +3426,9 @@ build_expr_from_tree (t)
case TYPEID_EXPR:
return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
case VAR_DECL:
return convert_from_reference (t);
default:
return t;
}

View File

@ -1262,6 +1262,44 @@ dump_expr (t, nop)
break;
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
{
tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
if (integer_all_onesp (idx))
{
tree pfn = PFN_FROM_PTRMEMFUNC (t);
dump_expr (pfn);
break;
}
if (TREE_CODE (idx) == INTEGER_CST
&& TREE_INT_CST_HIGH (idx) == 0)
{
tree virtuals;
unsigned HOST_WIDE_INT n;
t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
t = TYPE_METHOD_BASETYPE (t);
virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
n = TREE_INT_CST_LOW (idx);
/* Map vtable index back one, to allow for the null pointer to
member. */
--n;
while (n > 0 && virtuals)
{
--n;
virtuals = TREE_CHAIN (virtuals);
}
if (virtuals)
{
dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)));
break;
}
}
}
OB_PUTC ('{');
dump_expr_list (CONSTRUCTOR_ELTS (t));
OB_PUTC ('}');

View File

@ -101,3 +101,5 @@ Boston, MA 02111-1307, USA. */
"-Wno-reorder",
"-Wsynth",
"-Wno-synth",
"-Wpmf-conversions",
"-Wno-pmf-conversions",

View File

@ -2116,7 +2116,9 @@ synthesize_method (fndecl)
tree context = hack_decl_function_context (fndecl);
tree base = DECL_CLASS_CONTEXT (fndecl);
if (nested)
if (! context)
push_to_top_level ();
else if (nested)
push_cp_function_context (context);
interface_unknown = 1;
@ -2156,6 +2158,8 @@ synthesize_method (fndecl)
}
extract_interface_info ();
if (nested)
if (! context)
pop_from_top_level ();
else if (nested)
pop_cp_function_context (context);
}

View File

@ -2233,7 +2233,10 @@ named_complex_class_head_sans_basetype:
{
current_aggr = $1;
if (TREE_CODE ($3) == TYPE_DECL)
$$ = $3;
{
$$ = $3;
note_debug_info_needed (DECL_CONTEXT ($$));
}
else
{
cp_error ("`%T' does not have a nested type named `%D'",

View File

@ -198,26 +198,13 @@ end_template_decl ()
(void) get_pending_sizes (); /* Why? */
}
void
push_template_decl (decl)
tree decl;
/* Generate a valid set of template args from current_template_parms. */
tree
current_template_args ()
{
tree header = current_template_parms;
tree tmpl;
tree args = NULL_TREE;
tree info;
tree ctx = DECL_CONTEXT (decl) ? DECL_CONTEXT (decl) : current_class_type;
int primary = 0;
/* Kludge! */
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)
&& DECL_CLASS_CONTEXT (decl))
;
/* Note that this template is a "primary template" */
else if (! ctx || ! CLASSTYPE_TEMPLATE_INFO (ctx)
/* || (processing_template_decl > CLASSTYPE_TEMPLATE_LEVEL (ctx)) */)
primary = 1;
while (header)
{
tree a = copy_node (TREE_VALUE (header));
@ -236,8 +223,32 @@ push_template_decl (decl)
header = TREE_CHAIN (header);
}
args = nreverse (args);
/* FIXME Remove this when we support member templates. */
args = TREE_VALUE (args);
return args;
}
void
push_template_decl (decl)
tree decl;
{
tree tmpl;
tree args = NULL_TREE;
tree info;
tree ctx = DECL_CONTEXT (decl) ? DECL_CONTEXT (decl) : current_class_type;
int primary = 0;
/* Kludge! */
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)
&& DECL_CLASS_CONTEXT (decl))
;
/* Note that this template is a "primary template" */
else if (! ctx || ! CLASSTYPE_TEMPLATE_INFO (ctx)
/* || (processing_template_decl > CLASSTYPE_TEMPLATE_LEVEL (ctx)) */)
primary = 1;
/* Partial specialization. */
if (TREE_CODE (decl) == TYPE_DECL
&& CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
@ -262,6 +273,8 @@ push_template_decl (decl)
return;
}
args = current_template_args ();
if (! ctx || TYPE_BEING_DEFINED (ctx))
{
tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);

View File

@ -175,6 +175,12 @@ get_tinfo_fn_dynamic (exp)
if (exp == error_mark_node)
return error_mark_node;
if (type_unknown_p (exp))
{
error ("typeid of overloaded function");
return error_mark_node;
}
type = TREE_TYPE (exp);
/* peel back references, so they match. */
@ -244,6 +250,10 @@ build_x_typeid (exp)
}
exp = get_tinfo_fn_dynamic (exp);
if (exp == error_mark_node)
return error_mark_node;
exp = build_call (exp, type, NULL_TREE);
if (cond)
@ -316,9 +326,17 @@ tree
get_tinfo_fn (type)
tree type;
{
tree name = build_overload_with_type (tinfo_fn_id, type);
tree name;
tree d;
if (TREE_CODE (type) == OFFSET_TYPE)
type = TREE_TYPE (type);
if (TREE_CODE (type) == METHOD_TYPE)
type = build_function_type (TREE_TYPE (type),
TREE_CHAIN (TYPE_ARG_TYPES (type)));
name = build_overload_with_type (tinfo_fn_id, type);
if (IDENTIFIER_GLOBAL_VALUE (name))
return IDENTIFIER_GLOBAL_VALUE (name);
@ -330,7 +348,7 @@ get_tinfo_fn (type)
DECL_ARTIFICIAL (d) = 1;
DECL_NOT_REALLY_EXTERN (d) = 1;
DECL_MUTABLE_P (d) = 1;
TREE_TYPE (name) = type;
TREE_TYPE (name) = copy_to_permanent (type);
pushdecl_top_level (d);
make_function_rtl (d);
assemble_external (d);

View File

@ -2539,9 +2539,20 @@ dfs_debug_mark (binfo)
CLASSTYPE_DEBUG_REQUESTED (t) = 1;
/* If interface info is known, the value of (?@@?) is correct. */
if (methods == 0
|| CLASSTYPE_INTERFACE_KNOWN (t)
if (methods == 0)
return;
/* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which
does not support name references between translation units. */
if (write_symbols == DWARF_DEBUG)
{
rest_of_type_compilation (t, global_bindings_p ());
return;
}
/* If interface info is known, either we've already emitted the debug
info or we don't need to. */
if (CLASSTYPE_INTERFACE_KNOWN (t)
|| (write_virtuals == 2 && TYPE_VIRTUAL_P (t)))
return;
@ -3120,6 +3131,10 @@ note_debug_info_needed (type)
tree type;
{
tree field;
if (current_template_parms)
return;
dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{

View File

@ -1592,6 +1592,16 @@ mapcar (t, func)
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
return t;
break;
case RTL_EXPR:
t = copy_node (t);
if (RTL_EXPR_SEQUENCE (t))
RTL_EXPR_SEQUENCE (t) = copy_rtx (RTL_EXPR_SEQUENCE (t));
if (RTL_EXPR_RTL (t))
RTL_EXPR_RTL (t) = copy_rtx (RTL_EXPR_RTL (t));
return t;
break;
case CONVERT_EXPR:
case ADDR_EXPR:

View File

@ -2822,9 +2822,9 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
}
else
{
parmval = convert_for_initialization (return_loc, type, val,
flags|INDIRECT_BIND,
"argument passing", fndecl, i);
parmval = convert_for_initialization
(return_loc, type, val, flags,
"argument passing", fndecl, i);
#ifdef PROMOTE_PROTOTYPES
if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE)
@ -4616,7 +4616,8 @@ mark_addressable (exp)
case PARM_DECL:
if (x == current_class_ptr)
{
error ("address of `this' not available");
if (! flag_this_is_variable)
error ("address of `this' not available");
TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
put_var_into_stack (x);
return 1;
@ -4649,8 +4650,10 @@ mark_addressable (exp)
case CONST_DECL:
case RESULT_DECL:
/* For C++, we don't warn about taking the address of a register
variable for CONST_DECLs; ARM p97 explicitly says it's okay. */
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
&& !DECL_ARTIFICIAL (x) && extra_warnings)
cp_warning ("address requested for `%D', which is declared `register'",
x);
put_var_into_stack (x);
TREE_ADDRESSABLE (x) = 1;
return 1;
@ -4678,6 +4681,11 @@ mark_addressable (exp)
TREE_ADDRESSABLE (x) = 1;
return 1;
case TARGET_EXPR:
TREE_ADDRESSABLE (x) = 1;
mark_addressable (TREE_OPERAND (x, 0));
return 1;
default:
return 1;
}
@ -6082,7 +6090,7 @@ get_delta_difference (from, to, force)
binfo = get_binfo (from, to, 1);
if (binfo == error_mark_node)
{
error (" in pointer to member function conversion");
error (" in pointer to member function conversiona");
return delta;
}
if (binfo == 0)
@ -6096,12 +6104,14 @@ get_delta_difference (from, to, force)
binfo = get_binfo (to, from, 1);
if (binfo == error_mark_node)
{
error (" in pointer to member conversion");
if (!force)
error (" in pointer to member conversion");
return delta;
}
if (binfo == 0)
{
cp_error ("cannot convert pointer to member of type %T to unrelated pointer to member of type %T", from, to);
if (!force)
cp_error ("cannot convert pointer to member of type %T to unrelated pointer to member of type %T", from, to);
return delta;
}
if (TREE_VIA_VIRTUAL (binfo))
@ -6751,6 +6761,13 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
else if (TYPE_HAS_CONSTRUCTOR (type) || IS_AGGR_TYPE (TREE_TYPE (rhs)))
return convert (type, rhs);
/* Handle anachronistic conversions from (::*)() to void* or (*)(). */
else if (TREE_CODE (type) == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
|| TREE_TYPE (type) == void_type_node)
&& TREE_TYPE (rhs)
&& TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
return convert (type, rhs);
cp_error ("%s to `%T' from `%T'", errtype, type, rhstype);
return error_mark_node;
@ -7180,7 +7197,7 @@ c_expand_return (retval)
if (retval == result
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
else if (TYPE_MODE (TREE_TYPE (retval)) == VOIDmode)
else if (TREE_TYPE (retval) == void_type_node)
{
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);

View File

@ -829,7 +829,9 @@ digest_init (type, init, tail)
}
init = element;
}
while (TREE_CODE (init) == CONSTRUCTOR)
while (TREE_CODE (init) == CONSTRUCTOR
&& ! (TREE_TYPE (init)
&& TYPE_PTRMEMFUNC_P (TREE_TYPE (init))))
{
cp_pedwarn ("braces around scalar initializer for `%T'", type);
init = CONSTRUCTOR_ELTS (init);