83rd Cygnus<->FSF merge

From-SVN: r11362
This commit is contained in:
Mike Stump 1996-02-28 22:01:56 +00:00
parent 8bd04c5653
commit 5566b478bd
27 changed files with 5061 additions and 3391 deletions

View File

@ -1,3 +1,433 @@
Wed Feb 28 09:28:44 1996 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (do_identifier): Check for DECL_INITIAL before using it.
Tue Feb 27 16:35:32 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck2.c (build_x_arrow): Call complete_type.
* pt.c (add_pending_template): Broken out.
(lookup_template_class): If -fexternal-templates, call it for all
the methods of implemented types.
(instantiate_class_template): Instead of instantiating them here.
(instantiate_decl): Handle -fexternal-templates earlier.
Tue Feb 27 15:51:32 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* search.c, lex.c, decl.c, class.c, cp-tree.h: Don't wrap the
memoized lookup stuff inside GATHER_STATISTICS.
Tue Feb 27 10:38:08 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (start_decl): Complain about array of incomplete type
here.
(grokdeclarator): Not here.
* parse.y (template_parm): Expand full_parm inline so we can set
the rule's precedence.
* pt.c (tsubst_expr): If we're in a template, just do tsubst_copy.
(tsubst): tsubst_expr the DECL_INITIAL of FIELD_DECLs.
* decl2.c (grokbitfield): Don't check for integer constant here.
* class.c (finish_struct_1): Check here.
* decl.c (define_label): Make the min decl go on permanent_obstack.
* pt.c (unify): Don't handle CONST_DECLs.
(uses_template_parms): Don't check DECL_INITIAL on a CONST_DECL.
(tsubst_copy): Ditto.
* lex.c (do_identifier): Do pull the DECL_INITIAL out of a
CONST_DECL for a template parm.
Mon Feb 26 12:48:18 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Complain about array of incomplete type
here.
(start_decl_1): Not here.
* pt.c (tsubst): Handle pointer-to-function declarators.
* method.c (hack_identifier): If pedantic, diagnose local class
methods that require a static chain.
* decl.c (grok_op_properties): No longer static.
* cp-tree.h: Declare it.
* pt.c (tsubst): Call it for operators.
Use tsubst_copy for TREE_VECs.
* parse.y (template_arg): The expr has precedence like '>'.
Fri Feb 23 14:51:52 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (coerce_template_parms): Don't coerce an expression using
template parms.
(uses_template_parms): Also check DECL_INITIAL in CONST_DECLs.
(tsubst): Don't use build_index_2_type if the max_value uses template
parms.
* method.c (build_overload_int): Emit something arbitrary for an
expression using template parms.
* parse.y (template_close_bracket): New non-terminal to catch use
of '>>' instead of '> >' in template class names.
(template_type): Use it.
* Makefile.in (CONFLICTS): Causes one more r/r conflict.
* tree.def: Add CAST_EXPR.
* typeck2.c (build_functional_cast): Use CAST_EXPR instead of
CONVERT_EXPR for minimal_parse_mode.
* typeck.c (build_c_cast): Ditto.
* pt.c (tsubst_copy): Ditto.
* decl2.c (build_expr_from_tree): Ditto.
* error.c (dump_expr): Ditto.
Fri Feb 23 10:36:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* except.c (SetTerminate, SetUnexpected): Put back global vars.
(init_exception_processing): Put back decl/init of
set_unexpected_fndecl and set_terminate_fndecl, needed to get the
fns from libstdc++.
* decl.c (struct binding_level): Delete ACCEPT_ANY bitfield.
(declare_uninstantiated_type_level, uninstantiated_type_level_p):
Delete unused fns.
* cp-tree.h (declare_uninstantiated_type_level,
uninstantiated_type_level_p): Delete prototypes.
Thu Feb 22 19:36:15 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (tsubst_expr): Add default return.
Thu Feb 22 16:47:24 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* error.c (fndecl_as_string): Delete unused arg CNAME.
* sig.c (build_signature_table_constructor,
build_signature_method_call): Fix calls.
* class.c (the_null_vtable_entry): Delete var definition.
(init_class_processing): Delete tree the_null_vtable_entry init.
* decl.c (no_print_{functions, builtins}): Declare as static.
(__tp_desc_type_node): #if 0 var definition.
(init_type_desc): #if 0 init of __tp_desc_type_node.
(vb_off_identifier): Move var decl into init_decl_processing.
(current_function_assigns_this): Declare as static.
(int_ftype_ptr_ptr_int, void_ftype_ptr_int_int): Delete var decls.
(init_decl_processing): Delete init of void_ftype_ptr_ptr_int.
Move decls of string_ftype_ptr_ptr and int_ftype_string_string here.
* decl2.c (delete_sanity): Delete definition/mod of local var ELT_SIZE.
* init.c (BI_header_type, BI_header_size): Declare as static.
* pt.c (template_classes): Delete unused var.
(add_pending_template): Delete decl for non-existent fn.
(lookup_template_class): Delete vars CODE and TAG_CODE.
(instantiate_template): Delete unused var TARGS.
* cp-tree.h (vb_off_identifier, current_function_assigns_this):
Delete decls.
(__tp_desc_type_node): #if 0 var decl.
(fndecl_as_string): Fix prototype.
Thu Feb 22 15:56:19 1996 Jason Merrill <jason@yorick.cygnus.com>
* tree.def: Add GOTO_STMT.
* pt.c (tsubst_expr): Support goto and labels.
* decl.c (define_label): Support minimal parsing.
* parse.y (simple_stmt): Ditto.
Thu Feb 22 15:30:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* xref.c (GNU_xref_member): Only define/set var I if
XREF_SHORT_MEMBER_NAMES is defined, to match when it's actually
used.
(GNU_xref_end_scope): Delete unused fifth arg TRNS.
(GNU_xref_end): Fix call.
* decl.c (poplevel, poplevel_class, finish_method): Fix calls.
* cp-tree.h (GNU_xref_end_scope): Fix prototype.
* tree.c (build_exception_variant): Delete unused vars I, A, T,
T2, and CNAME.
(layout_vbasetypes): Delete unused var NONVIRTUAL_VAR_SIZE.
(mapcar): Delete unused var CODE.
(build_cplus_new): Delete unused arg WITH_CLEANUP_P.
(break_out_cleanups): Fix call.
(bot_manip): Likewise.
* call.c (build_method_call): Likewise.
* cvt.c (build_up_reference, convert_to_reference, cp_convert):
Likewise.
* typeck.c (unary_complex_lvalue, build_modify_expr,
convert_for_initialization): Likewise.
* typeck2.c (build_functional_cast): Likewise.
* cp-tree.h (build_cplus_new): Fix prototype.
* repo.c (open_repo_file): Delete unused var Q.
(repo_compile_flags, repo_template_declared,
repo_template_defined, repo_class_defined, repo_inline_used,
repo_vtable_used, repo_tinfo_used): #if 0 unused fns.
(repo_get_id, repo_vtable_used): Declare as static.
* cp-tree.h (mark_{decl,class}_instantiated, finish_repo): Add
prototypes.
Thu Feb 22 14:53:35 1996 Jason Merrill <jason@yorick.cygnus.com>
* parse.y (pending_inlines): Add function_try_block case.
* pt.c (unify): Fix for template const parms.
Thu Feb 22 13:24:15 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* lex.c (extract_interface_info): Delete forward decl.
(default_copy_constructor_body, default_assign_ref_body): Delete
decls for non-existent functions.
(synth_firstobj, inline_text_firstobjs): Delete unused vars.
(init_lex): Delete setting them.
(cons_up_default_function): Delete unused vars FUNC_BUF,
FUNC_LEN, and COMPLEX. Delete code setting COMPLEX. Delete old
#if 0'd synth code.
(toplevel, expression_obstack): Delete unused extern decls.
(tree_node_kind): Delete unused enum.
(tree_node_counts, tree_node_sizes): Wrap with #ifdef
GATHER_STATISTICS.
(tree_node_kind_names): Delete unused extern decl.
(synth_obstack): Delete unused var.
(init_lex): Don't set it.
(init_parse): Add decl before use.
(reduce_count): Only define #ifdef GATHER_STATISTICS && REDUCE_LENGTH.
(current_unit_{name, language}): Delete unused vars.
(check_newline): Don't bother setting them, just accept the #pragma.
* cp-tree.h (init_repo, peek_yylex): Add prototypes.
(current_unit_{name, language}): Delete decls.
* search.c: Wrap all of the memoized functions, macros, and
variables inside #ifdef GATHER_STATISTICS.
(lookup_field, lookup_fnfields): Likewise.
(init_search_processing): Likewise.
(reinit_search_statistics): Wrap whole function.
* lex.c (reinit_lang_specific): Wrap call to reinit_search_statistics.
* decl.c (finish_function): Only call pop_memoized_context if
GATHER_STATISTICS is defined.
(start_function): Likewise for push_memoized_context.
* class.c (pushclass, popclass): Likewise.
* cp-tree.h (CLASSTYPE_MTABLE_ENTRY): Move definition from here...
* search.c (CLASSTYPE_MTABLE_ENTRY): ... to here.
* cvt.c (cp_convert): Delete unused local var FORM.
* cp-tree.h (can_convert, can_convert_arg, real_lvalue_p): Add
prototypes.
Thu Feb 22 13:19:44 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (do_poplevel): Oops; really return what we get from
poplevel this time.
Thu Feb 22 11:41:44 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* cp-tree.h (is_aggr_type): Add prototype.
* cp-tree.h ({push,pop}_cp_function_context): Add decls.
* method.c ({push,pop}_cp_function_context): Delete decls.
* except.c (start_eh_unwinder, end_eh_unwinder): Declare as void.
(SetUnexpected, SetTerminate): Delete unused vars.
(init_exception_processing): Don't set SetUnexpected or
SetTerminate. Don't set SET_UNEXPECTED_FNDECL or SET_TERMINATE_FNDECL.
(output_exception_table_entry): Delete unused array LABEL.
(expand_internal_throw): Delete unused var PARAMS.
(expand_start_catch_block): Delete unused var CLEANUP.
(emit_exception_table): Delete unused var EH_NODE_DECL.
(expand_builtin_throw): Delete unused vars UNWIND_AND_THROW and
GOTO_UNWIND_AND_THROW. Don't set them.
(end_eh_unwinder): Add top decl.
(pop_rtl_from_perm): Delete unused decl of PERMANENT_OBSTACK.
(exception_section, push_rtl_perm, do_function_call,
lang_interim_eh, push_eh_cleanup, eh_outer_context,
expand_end_eh_spec, end_eh_unwinder): Declare as static.
(saved_pc, saved_throw_type, saved_throw_value, saved_cleanup,
throw_used): Likewise.
* cp-tree.h (expand_end_eh_spec): Delete prototype.
* search.c (dfs_mark, dfs_mark_vtable_path,
dfs_unmark_vtable_path, dfs_mark_new_vtable,
dfs_unmark_new_vtable, dfs_clear_search_slot,
dfs_search_slot_nonempty_p, bfs_markedp, bfs_unmarkedp,
bfs_marked_vtable_pathp, bfs_unmarked_vtable_pathp,
bfs_marked_new_vtablep, bfs_unmarked_new_vtablep): #if 0 unused
functions.
(n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1,
n_calls_lookup_fnfields, n_calls_lookup_fnfields_1,
n_calls_get_base_type, n_outer_fields_searched, n_contexts_saved):
Only define #ifdef GATHER_STATISTICS.
(reinit_search_statistics): Only init some vars if GATHER_STATISTICS
is defined.
(vbase_decl): Delete var definition.
(init_search): Delete old decl.
(init_vbase_pointers): Delete building of VBASE_DECL, since it's
never actually used.
(expand_indirect_vtbls_init): Delete init of VBASE_DECL.
(get_base_distance_recursive): Delete unused fourth arg
BASETYPE_PATH. Fix call .
(get_base_distance): Fix call.
(push_class_decls): Delete unused var ID.
(make_memoized_table_entry): Declare as static.
(breadth_first_search): Declare as static.
(tree_has_any_destructor_p): Declare as static.
(pop_class_decls): Delete unused arg pop_class_decls.
* class.c (popclass): Fix call to pop_class_decls.
* cp-tree.h (make_memoized_table_entry, breadth_first_search,
tree_has_any_destructor_p): Delete prototypes.
* rtti.c (build_ptmf_desc): Delete unused arg TYPE.
(build_t_desc): Fix call. Delete unused vars ELEMS and TT.
(build_dynamic_cast): Delete unused local vars TMP1 and RETVAL.
(build_user_desc): Delete unused var T.
(build_class_desc): Delete unused vars T and OFF.
(build_t_desc): Delete unused var NAME_STRING.
(build_headof): Make static.
(get_bad_cast_node): Likewise.
(get_def_to_follow): Likewise.
* cp-tree.h (init_type_desc): Add prototype.
(build_headof): Remove prototype.
Thu Feb 22 00:54:22 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (tsubst): Only look for matching decls at file scope for
non-member functions.
* call.c (build_scoped_method_call): Handle scoped destructor
calls in templates.
* decl.c (*_top_level): Also save previous_class_values.
* pt.c (tsubst_expr): Support do {} while loops.
* parse.y (simple_stmt): Ditto.
* tree.def: Ditto.
* method.c (build_overload_identifier): For a class nested in a
template class, don't mangle in the template parms from our
context.
* lex.c, cp-tree.h: Remove support for template instantiations in
the pending_inlines code.
* pt.c: Remove dead functions and unused arguments.
(uses_template_parms): TYPENAME_TYPEs always use template parms.
* parse.y: Stop passing anything to end_template_decl.
* tree.c (print_lang_statistics): Only print tinst info #ifdef
GATHER_STATISTICS.
Wed Feb 21 16:57:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* init.c (expand_recursive_init{,_1}): Delete decls.
(sort_member_init): Delete unused var INIT.
(emit_base_init): Delete unused var X.
(build_offset_ref): Delete unused var CNAME.
(sort_member_init): Delete unused var FIELDS_TO_UNMARK.
(emit_base_init): Delete unused local var BASE. Delete extern
decl of IN_CHARGE_IDENTIFIER.
(build_delete): Delete unused local var VIRTUAL_SIZE.
* init.c (build_vec_delete): Delete unused third arg ELT_SIZE.
(build_delete): Fix call.
* decl2.c (delete_sanity): Likewise.
* cp-tree.h (build_vec_delete): Update prototype.
* typeck.c (common_base_type): Delete unused var TMP.
(build_binary_op): Delete local var ARGS_SAVE.
(build_array_ref): Delete unused var ITYPE.
(c_expand_return): Delete unused var USE_TEMP.
* typeck.c (compexcepttypes): Delete unused arg STRICT.
(comptypes): Fix calls.
* decl.c (duplicate_decls): Likewise.
* cp-tree.h (compexcepttypes): Delete extra arg.
* decl2.c (check_classfn): Delete unused second arg CNAME.
* decl.c (start_decl, grokfndecl): Fix calls.
* init.c (do_friend): Likewise.
* cp-tree.h (check_classfn): Update prototype.
* cp-tree.h (signature_error, import_export_vtable,
append_signature_fields, id_in_current_class, mark_used,
copy_assignment_arg_p): Add decls.
* decl2.c (mark_used): Delete decl.
* class.c (n_*): Wrap with #ifdef GATHER_STATISTICS.
* class.c (get_vtable_entry): Diable unused function.
(doing_hard_virtuals): Delete unused static global var.
(finish_struct_1): Don't init DOING_HARD_VIRTUALS.
(prepare_fresh_vtable): Delete unused vars PATH and RESULT.
(overrides): Delete unused vars RETTYPE and BASE_RETTYPE.
(modify_one_vtable): Delete unused var OLD_RTTI.
(finish_struct_anon): Delete unused vars OFFSET and X.
(finish_struct_bits): Delete unused var METHOD_VEC.
(get_basefndecls): Delete unused var PURPOSE. Delete unused
for-scope local variable METHODS.
* call.c (user_harshness): Delete unused/unneeded arg PARM.
(ideal_candidate): Delete unused args BASETYPE and PARMS.
(build_method_call): Delete unused args passed into ideal_candidate.
(build_overload_call_real): Likewise. Delete unused var OVERLOAD_NAME.
* cp-tree.h (synthesize_method): Add decl.
* decl.c (note_level_for_for): Give void return type.
(pushdecl_nonclass_level): Likewise.
(finish_function): Delete unused vars VFIELDS and ALLOCATED_THIS.
(poplevel): Delete unused var IMPLICIT_TRY_BLOCK.
(suspend_binding_level): Delete unused var LEVEL.
(duplicate_decls): Delete unused var CTYPE.
(duplicate_decls): Delete unused var PREVIOUS_C_DECL.
(init_decl_processing): Delete unused vars FLOAT_ENDLINK and
PTR_ENDLINK.
(grokdeclarator): Delete unused var C.
(grokdeclarator): Delete unused var SIZE_VARIES.
(grokparms): Delete unused var SAW_VOID.
(start_function): Delete unused var OLDDECL.
(cplus_expand_expr_stmt): Delete unused var
REMOVE_IMPLICIT_IMMEDIATELY.
* cp-tree.h (pushdecl_nonclass_level): Fix prototype.
* Makefile.in (CONFLICTS): Update to 12 shift/reduce.
Wed Feb 21 00:06:17 1996 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (build_min): Set TREE_COMPLEXITY to lineno.
(build_min_nt): Ditto.
* pt.c (do_pushlevel): Emit line note.
(do_poplevel): Return what we get from poplevel.
(tsubst_expr): Set lineno from TREE_COMPLEXITY in stmt nodes.
* parse.y: Use do_pushlevel and do_poplevel.
* cp-tree.h: Declare do_poplevel.
* cp-tree.h: Declare at_eof.
* decl.c (cp_finish_decl): Pass it to rest_of_decl_compilation.
* decl2.c (import_export_decl): Renamed from import_export_inline.
(finish_file): Call it to do interface handling for statics.
* pt.c (tsubst_copy): Call mark_used on variables and functions
used here.
* decl2.c (finish_file): Don't emit statics we can't generate.
* pt.c (instantiate_decl): Don't set interface on instantiations
we can't generate.
* cp-tree.h (struct tinst_level): Change 'classname' to 'decl'.
* tree.c (print_lang_statistics): Print max template depth.
* pt.c (push_tinst_level): Dump entire instantiation context.
(instantiate_class_template): Use it and pop_tinst_level.
(instantiate_decl): Ditto.
* call.c class.c cp-tree.h decl.c decl2.c error.c lex.c method.c
pt.c ptree.c tree.def: Remove all traces of UNINSTANTIATED_P_TYPE.
Tue Feb 20 18:21:51 1996 Jason Merrill <jason@yorick.cygnus.com>
* call.c class.c cp-tree.h cvt.c decl.c decl2.c error.c expr.c
init.c lex.c method.c parse.y pt.c repo.c search.c spew.c tree.c
tree.def typeck.c typeck2.c xref.c: Massive, systemic changes for
the new template implementation.
Tue Feb 20 17:14:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl2.c (check_cp_case_value): Use STRIP_TYPE_NOPS.
Thu Feb 15 18:44:42 1996 Mike Stump <mrs@cygnus.com>
* decl.c (cp_finish_decl): Delay emitting the debug information for

View File

@ -168,7 +168,6 @@ OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o
compiler: ../cc1plus
../cc1plus: $(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS)
rm -f ../cc1plus$(exeext)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
$(CXX_OBJS) $(OBJS) $(LIBS)
@ -196,7 +195,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
`echo $(PARSE_C) | sed 's,^\./,,'`
CONFLICTS = expect 7 shift/reduce conflicts and 38 reduce/reduce conflicts.
CONFLICTS = expect 12 shift/reduce conflicts and 39 reduce/reduce conflicts.
$(PARSE_H) : $(PARSE_C)
$(PARSE_C) : $(srcdir)/parse.y
@echo $(CONFLICTS)

View File

@ -175,8 +175,8 @@ convert_harshness (type, parmtype, parm)
if (! lvalue && ! (parm && TYPE_READONLY (ttl)))
return EVIL_RETURN (h);
if (TYPE_READONLY (ttl) < constp
|| TYPE_VOLATILE (ttl) < volatilep)
if ((TYPE_READONLY (ttl) < constp)
|| (TYPE_VOLATILE (ttl) < volatilep))
return EVIL_RETURN (h);
/* When passing a non-const argument into a const reference, dig it a
@ -646,9 +646,8 @@ convert_harshness (type, parmtype, parm)
overload resolution. */
int
user_harshness (type, parmtype, parm)
user_harshness (type, parmtype)
register tree type, parmtype;
tree parm;
{
tree conv;
tree winner = NULL_TREE;
@ -668,7 +667,7 @@ user_harshness (type, parmtype, parm)
continue;
if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
tmp.code < USER_CODE && tmp.distance >= 0)
(tmp.code < USER_CODE) && (tmp.distance >= 0))
{
if (winner)
return EVIL_CODE;
@ -692,7 +691,7 @@ can_convert (to, from)
{
struct harshness_code h;
h = convert_harshness (to, from, NULL_TREE);
return h.code < USER_CODE && h.distance >= 0;
return (h.code < USER_CODE) && (h.distance >= 0);
}
int
@ -701,7 +700,7 @@ can_convert_arg (to, from, arg)
{
struct harshness_code h;
h = convert_harshness (to, from, arg);
return h.code < USER_CODE && h.distance >= 0;
return (h.code < USER_CODE) && (h.distance >= 0);
}
#ifdef DEBUG_MATCHING
@ -1091,11 +1090,9 @@ strictly_better (x, y)
LEN is the length of the parameter list. */
static struct candidate *
ideal_candidate (basetype, candidates, n_candidates, parms, len)
tree basetype;
ideal_candidate (candidates, n_candidates, len)
struct candidate *candidates;
int n_candidates;
tree parms;
int len;
{
struct candidate *cp = candidates+n_candidates;
@ -1347,15 +1344,6 @@ find_scoped_type (type, inner_name, inner_types)
tags = TREE_CHAIN (tags);
}
#if 0
/* XXX This needs to be fixed better. */
if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
{
sorry ("nested class lookup in template type");
return NULL_TREE;
}
#endif
/* Look for a TYPE_DECL. */
for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags))
if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name)
@ -1477,6 +1465,17 @@ build_scoped_method_call (exp, basetype, name, parms)
|| basetype == error_mark_node)
return error_mark_node;
if (current_template_parms)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 1);
name = build_min_nt (BIT_NOT_EXPR, type);
}
name = build_min_nt (SCOPE_REF, basetype, name);
return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, 0);
}
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
@ -1489,7 +1488,7 @@ build_scoped_method_call (exp, basetype, name, parms)
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
exp, basetype, type);
name = TREE_OPERAND (name, 0);
if (basetype != get_type_value (name))
if (basetype != name && basetype != get_type_value (name))
cp_error ("qualified type `%T' does not match destructor name `~%T'",
basetype, name);
return convert (void_type_node, exp);
@ -1520,7 +1519,8 @@ build_scoped_method_call (exp, basetype, name, parms)
{
/* Explicit call to destructor. */
name = TREE_OPERAND (name, 0);
if (! (name == constructor_name (TREE_TYPE (decl))
if (! (name == TYPE_MAIN_VARIANT (TREE_TYPE (decl))
|| name == constructor_name (TREE_TYPE (decl))
|| TREE_TYPE (decl) == get_type_value (name)))
{
cp_error
@ -1607,7 +1607,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
register tree function, fntype, value_type;
register tree basetype, save_basetype;
register tree baselink, result, method_name, parmtypes, parm;
register tree baselink, result, parmtypes, parm;
#if 0
register tree method_name;
#endif
tree last;
int pass;
tree access = access_public_node;
@ -1636,6 +1639,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
|| (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
return error_mark_node;
if (current_template_parms)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 1);
name = build_min_nt (BIT_NOT_EXPR, type);
}
return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, 0);
}
/* This is the logic that magically deletes the second argument to
operator delete, if it is not needed. */
if (name == ansi_opname[(int) DELETE_EXPR] && list_length (parms)==2)
@ -1668,8 +1682,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
if (! ((IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype))
if (! (name == basetype
|| (IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype))
|| basetype == get_type_value (name)))
{
cp_error ("destructor name `~%D' does not match type `%T' of expression",
@ -1734,7 +1749,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
else if (IDENTIFIER_HAS_TYPE_VALUE (name))
{
basetype = IDENTIFIER_TYPE_VALUE (name);
name = constructor_name_full (basetype);
name = constructor_name (basetype);
}
else
{
@ -1884,7 +1899,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (TREE_CODE (instance) != CALL_EXPR)
my_friendly_abort (125);
if (TYPE_NEEDS_CONSTRUCTING (basetype))
instance = build_cplus_new (basetype, instance, 0);
instance = build_cplus_new (basetype, instance);
else
{
instance = get_temp_name (basetype, 0);
@ -1942,7 +1957,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
}
if (TYPE_SIZE (basetype) == 0)
if (TYPE_SIZE (complete_type (basetype)) == 0)
{
/* This is worth complaining about, I think. */
cp_error ("cannot lookup method in incomplete type `%T'", basetype);
@ -2033,8 +2048,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if ((IDENTIFIER_HAS_TYPE_VALUE (name)
&& ! IDENTIFIER_OPNAME_P (name)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))
&& TREE_CODE (IDENTIFIER_TYPE_VALUE (name)) != UNINSTANTIATED_P_TYPE)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name)))
|| name == constructor_name (basetype))
{
tree tmp = NULL_TREE;
@ -2301,8 +2315,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
int n_candidates = cp - candidates;
extern int warn_synth;
TREE_VALUE (parms) = instance_ptr;
cp = ideal_candidate (save_basetype, candidates,
n_candidates, parms, len);
cp = ideal_candidate (candidates, n_candidates, len);
if (cp == (struct candidate *)0)
{
if (flags & LOOKUP_COMPLAIN)
@ -2529,7 +2542,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
if (TYPE_SIZE (value_type) == 0)
if (TYPE_SIZE (complete_type (value_type)) == 0)
{
if (flags & LOOKUP_COMPLAIN)
incomplete_type_error (0, value_type);
@ -2710,7 +2723,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
int buildxxx;
{
/* must check for overloading here */
tree overload_name, functions, function, parm;
tree functions, function, parm;
tree parmtypes = NULL_TREE, last = NULL_TREE;
register tree outer;
int length;
@ -2831,7 +2844,6 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
function = outer;
if (TREE_CODE (function) != FUNCTION_DECL
&& ! (TREE_CODE (function) == TEMPLATE_DECL
&& ! DECL_TEMPLATE_IS_CLASS (function)
&& TREE_CODE (DECL_TEMPLATE_RESULT (function)) == FUNCTION_DECL))
{
enum tree_code code = TREE_CODE (function);
@ -2869,7 +2881,11 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
TYPE_ARG_TYPES (TREE_TYPE (function)),
parms, &template_cost, 0);
if (i == 0)
function = instantiate_template (function, targs);
{
function = instantiate_template (function, targs);
if (function == error_mark_node)
return function;
}
}
if (TREE_CODE (function) == TEMPLATE_DECL)
@ -2924,8 +2940,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
if (cp - candidates > 1)
{
struct candidate *best_cp
= ideal_candidate (NULL_TREE, candidates,
cp - candidates, parms, parmlength);
= ideal_candidate (candidates, cp - candidates, parmlength);
if (best_cp == (struct candidate *)0)
{
if (flags & LOOKUP_COMPLAIN)

View File

@ -81,7 +81,6 @@ tree previous_class_type; /* _TYPE: the previous type that was a class */
tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list
when leaving an outermost class scope. */
static tree get_vfield_name PROTO((tree));
tree the_null_vtable_entry;
/* Way of stacking language names. */
tree *current_lang_base, *current_lang_stack;
@ -109,6 +108,7 @@ tree access_private_virtual_node; /* 6 */
/* Variables shared between class.c and call.c. */
#ifdef GATHER_STATISTICS
int n_vtables = 0;
int n_vtable_entries = 0;
int n_vtable_searches = 0;
@ -117,6 +117,7 @@ int n_convert_harshness = 0;
int n_compute_conversion_costs = 0;
int n_build_method_call = 0;
int n_inner_fields_searched = 0;
#endif
/* Virtual baseclass things. */
tree
@ -362,7 +363,6 @@ build_vbase_path (code, type, expr, path, alias_this)
classes. We do all overrides after we layout virtual base classes.
*/
static tree pending_hard_virtuals;
static int doing_hard_virtuals;
/* Build an entry in the virtual function table.
DELTA is the offset for the `this' pointer.
@ -698,8 +698,7 @@ prepare_fresh_vtable (binfo, for_type)
for_type, and we really want different names. (mrs) */
tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
tree path, offset;
int result;
tree offset;
/* Remember which class this vtable is really for. */
DECL_CONTEXT (new_decl) = for_type;
@ -741,6 +740,7 @@ prepare_fresh_vtable (binfo, for_type)
SET_BINFO_NEW_VTABLE_MARKED (binfo);
}
#if 0
/* Access the virtual function table entry that logically
contains BASE_FNDECL. VIRTUALS is the virtual function table's
initializer. We can run off the end, when dealing with virtual
@ -765,6 +765,7 @@ get_vtable_entry (virtuals, base_fndecl)
}
return virtuals;
}
#endif
/* Put new entry ENTRY into virtual function table initializer
VIRTUALS.
@ -913,7 +914,7 @@ add_method (type, fields, method)
decl = copy_node (method);
if (DECL_RTL (decl) == 0
&& (!processing_template_decl
|| !uses_template_parms (decl)))
|| !uses_template_parms (decl)))
{
make_function_rtl (decl);
DECL_RTL (method) = DECL_RTL (decl);
@ -1087,8 +1088,16 @@ delete_duplicate_fields_1 (field, fields)
cp_error_at ("duplicate nested type `%D'", x);
else if (TREE_CODE (field) == TYPE_DECL
|| TREE_CODE (x) == TYPE_DECL)
cp_error_at ("duplicate field `%D' (as type and non-type)",
x);
{
/* Hide tag decls. */
if ((TREE_CODE (field) == TYPE_DECL
&& DECL_ARTIFICIAL (field))
|| (TREE_CODE (x) == TYPE_DECL
&& DECL_ARTIFICIAL (x)))
continue;
cp_error_at ("duplicate field `%D' (as type and non-type)",
x);
}
else
cp_error_at ("duplicate member `%D'", x);
if (prev == 0)
@ -1658,7 +1667,6 @@ finish_struct_bits (t, max_has_virtual)
int max_has_virtual;
{
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
tree method_vec = CLASSTYPE_METHOD_VEC (t);
/* Fix up variants (if any). */
tree variants = TYPE_NEXT_VARIANT (t);
@ -1677,6 +1685,7 @@ finish_struct_bits (t, max_has_virtual)
/* Copy whatever these are holding today. */
TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);
TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);
TYPE_FIELDS (variants) = TYPE_FIELDS (t);
variants = TYPE_NEXT_VARIANT (variants);
}
@ -2167,7 +2176,7 @@ overrides (fndecl, base_fndecl)
return 0;
if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
{
tree rettype, base_rettype, types, base_types;
tree types, base_types;
#if 0
retypes = TREE_TYPE (TREE_TYPE (fndecl));
base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl));
@ -2291,7 +2300,6 @@ modify_one_vtable (binfo, t, fndecl, pfn)
tree binfo, t, fndecl, pfn;
{
tree virtuals = BINFO_VIRTUALS (binfo);
tree old_rtti;
unsigned HOST_WIDE_INT n;
/* update rtti entry */
@ -2711,8 +2719,6 @@ get_basefndecls (fndecl, t)
while (methods)
{
tree purpose = NULL_TREE;
if (TREE_CODE (methods) == FUNCTION_DECL
&& DECL_VINDEX (methods) != NULL_TREE
&& DECL_NAME (fndecl) == DECL_NAME (methods))
@ -2728,7 +2734,6 @@ get_basefndecls (fndecl, t)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
tree basetype = BINFO_TYPE (base_binfo);
tree methods = TYPE_METHODS (basetype);
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
base_fndecls);
@ -2913,8 +2918,6 @@ finish_struct_anon (t)
tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
for (; *uelt; uelt = &TREE_CHAIN (*uelt))
{
tree offset, x;
if (TREE_CODE (*uelt) != FIELD_DECL)
continue;
@ -3190,8 +3193,11 @@ finish_struct_1 (t, attributes, warn_anon)
&has_virtual, x, t);
if (DECL_ABSTRACT_VIRTUAL_P (x))
abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals);
#if 0
/* XXX Why did I comment this out? (jason) */
else
TREE_USED (x) = 1;
#endif
}
}
@ -3377,9 +3383,26 @@ finish_struct_1 (t, attributes, warn_anon)
/* Detect and ignore out of range field width. */
if (DECL_INITIAL (x))
{
register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
tree w = DECL_INITIAL (x);
register int width;
if (width < 0)
/* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
STRIP_NOPS (w);
/* detect invalid field size. */
if (TREE_CODE (w) == CONST_DECL)
w = DECL_INITIAL (w);
else if (TREE_READONLY_DECL_P (w))
w = decl_constant_value (w);
if (TREE_CODE (w) != INTEGER_CST)
{
cp_error_at ("bit-field `%D' width not an integer constant",
x);
DECL_INITIAL (x) = NULL_TREE;
}
else if (width = TREE_INT_CST_LOW (w),
width < 0)
{
DECL_INITIAL (x) = NULL;
cp_error_at ("negative width in bit-field `%D'", x);
@ -3789,6 +3812,8 @@ finish_struct_1 (t, attributes, warn_anon)
{
tree name = DECL_NAME (x);
int i = /*TREE_VEC_ELT (method_vec, 0) ? 0 : */ 1;
if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
continue;
for (; i < n_methods; ++i)
if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
{
@ -3842,7 +3867,6 @@ finish_struct_1 (t, attributes, warn_anon)
/* Now fix up any virtual base class types that we left lying
around. We must get these done before we try to lay out the
virtual function table. */
doing_hard_virtuals = 1;
pending_hard_virtuals = nreverse (pending_hard_virtuals);
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
@ -3949,8 +3973,6 @@ finish_struct_1 (t, attributes, warn_anon)
}
}
doing_hard_virtuals = 0;
/* Under our model of GC, every C++ class gets its own virtual
function table, at least virtually. */
if (pending_virtuals || (flag_rtti && TYPE_VIRTUAL_P (t)))
@ -4090,42 +4112,6 @@ finish_struct_1 (t, attributes, warn_anon)
}
}
/* Now add the tags, if any, to the list of TYPE_DECLs
defined for this type. */
if (CLASSTYPE_TAGS (t))
{
x = CLASSTYPE_TAGS (t);
last_x = tree_last (TYPE_FIELDS (t));
while (x)
{
tree tag = TYPE_NAME (TREE_VALUE (x));
/* Check to see if it is already there. This will be the case if
was do enum { red; } color; */
if (chain_member (tag, TYPE_FIELDS (t)))
{
x = TREE_CHAIN (x);
continue;
}
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
/* Notify dwarfout.c that this TYPE_DECL node represent a
gratuitous typedef. */
DECL_IGNORED_P (tag) = 1;
}
#endif /* DWARF_DEBUGGING_INFO */
TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
x = TREE_CHAIN (x);
last_x = chainon (last_x, tag);
}
if (TYPE_FIELDS (t) == NULL_TREE)
TYPE_FIELDS (t) = last_x;
CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
}
if (TYPE_HAS_CONSTRUCTOR (t))
{
tree vfields = CLASSTYPE_VFIELDS (t);
@ -4185,17 +4171,12 @@ finish_struct_1 (t, attributes, warn_anon)
/* Make the rtl for any new vtables we have created, and unmark
the base types we marked. */
finish_vtbls (TYPE_BINFO (t), 1, t);
TYPE_BEING_DEFINED (t) = 0;
hack_incomplete_structures (t);
#if 0
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
#endif
if (current_class_type)
popclass (0);
else
error ("trying to finish struct, but kicked out due to previous parse errors.");
resume_momentary (old);
@ -4235,9 +4216,12 @@ finish_struct_1 (t, attributes, warn_anon)
= (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0);
else if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
#if 0
/* XXX do something about this. */
else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
/* Only a first approximation! */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
#endif
}
else if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
@ -4336,6 +4320,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
if (TREE_CODE (x) == FUNCTION_DECL)
{
DECL_CLASS_CONTEXT (x) = t;
if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x);
/* Link x onto end of TYPE_METHODS. */
@ -4354,6 +4339,8 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
DECL_RESULT (x) = n;
}
#endif
if (TREE_CODE (x) != TYPE_DECL)
DECL_FIELD_CONTEXT (x) = t;
if (! fields)
fields = x;
@ -4372,17 +4359,79 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
}
}
/* Now add the tags, if any, to the list of TYPE_DECLs
defined for this type. */
if (CLASSTYPE_TAGS (t))
{
x = CLASSTYPE_TAGS (t);
while (x)
{
tree tag = TYPE_NAME (TREE_VALUE (x));
/* Check to see if it is already there. This will be the case if
was do enum { red; } color; */
if (chain_member (tag, fields))
{
x = TREE_CHAIN (x);
continue;
}
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
/* Notify dwarfout.c that this TYPE_DECL node represent a
gratuitous typedef. */
DECL_IGNORED_P (tag) = 1;
}
#endif /* DWARF_DEBUGGING_INFO */
TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
x = TREE_CHAIN (x);
last_x = chainon (last_x, tag);
}
if (fields == NULL_TREE)
fields = last_x;
CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
}
*tail = NULL_TREE;
TYPE_FIELDS (t) = fields;
if (0 && processing_template_defn)
if (processing_template_decl)
{
tree d = getdecls ();
for (; d; d = TREE_CHAIN (d))
{
/* If this is the decl for the class or one of the template
parms, we've seen all the injected decls. */
if ((TREE_CODE (d) == TYPE_DECL
&& (TREE_TYPE (d) == t
|| TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM))
|| TREE_CODE (d) == CONST_DECL)
break;
/* Don't inject TYPE_NESTED_NAMEs. */
else if (TREE_MANGLED (DECL_NAME (d))
|| IDENTIFIER_TEMPLATE (DECL_NAME (d)))
continue;
DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))
= tree_cons (NULL_TREE, d,
DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
}
CLASSTYPE_METHOD_VEC (t)
= finish_struct_methods (t, TYPE_METHODS (t), 1);
return t;
}
TYPE_SIZE (t) = integer_zero_node;
}
else
return finish_struct_1 (t, attributes, warn_anon);
t = finish_struct_1 (t, attributes, warn_anon);
TYPE_BEING_DEFINED (t) = 0;
if (current_class_type)
popclass (0);
else
error ("trying to finish struct, but kicked out due to previous parse errors.");
return t;
}
/* Return non-zero if the effective type of INSTANCE is static.
@ -4516,7 +4565,6 @@ init_class_processing ()
access_private_virtual_node = build_int_2 (6, 0);
/* Keep these values lying around. */
the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node);
base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE);
@ -4592,6 +4640,9 @@ pushclass (type, modify)
pushlevel_class ();
if (CLASSTYPE_TEMPLATE_INFO (type))
overload_template_name (type);
if (modify)
{
tree tags;
@ -4604,9 +4655,7 @@ pushclass (type, modify)
else
current_function_decl = NULL_TREE;
if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
declare_uninstantiated_type_level ();
else if (type != previous_class_type || current_class_depth > 1)
if (type != previous_class_type || current_class_depth > 1)
{
build_mi_matrix (type);
push_class_decls (type);
@ -4633,9 +4682,6 @@ pushclass (type, modify)
unuse_fields (type);
}
if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (type)))
overload_template_name (current_class_name, 0);
for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
{
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
@ -4686,8 +4732,6 @@ popclass (modify)
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
tags = TREE_CHAIN (tags);
}
if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)))
undo_template_name_overload (current_class_name, 0);
}
/* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
@ -4698,7 +4742,7 @@ popclass (modify)
this really only frees the obstack used for these decls.
That's why it had to be moved down here. */
if (modify)
pop_class_decls (current_class_type);
pop_class_decls ();
current_class_depth--;
current_class_type = *--current_class_stack;
@ -4724,7 +4768,8 @@ push_nested_class (type, modify)
{
tree context;
if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type))
if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return;
context = DECL_CONTEXT (TYPE_NAME (type));
@ -4992,7 +5037,10 @@ instantiate_type (lhstype, rhs, complain)
}
}
if (save_elem)
return save_elem;
{
mark_used (save_elem);
return save_elem;
}
}
/* No match found, look for a compatible function. */

View File

@ -90,18 +90,13 @@ DEFTREECODE (TEMPLATE_DECL, "template_decl", "d", 0)
Use TYPE_FIELDS to find parmlist and index. */
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", "t", 0)
/* A type designated by 'typename T::t'. */
DEFTREECODE (TYPENAME_TYPE, "typename_type", "t", 0)
/* Index into a template parameter list. This parameter must not be a
type. */
DEFTREECODE (TEMPLATE_CONST_PARM, "template_const_parm", "c", 2)
/* For uninstantiated parameterized types.
TYPE_VALUES tree list:
TREE_PURPOSE template decl
TREE_VALUE parm vector
TREE_CHAIN null
Other useful fields to be defined later. */
DEFTREECODE (UNINSTANTIATED_P_TYPE, "uninstantiated_p_type", "t", 0)
/* A thunk is a stub function.
Thunks are used to implement multiple inheritance:
@ -118,3 +113,27 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
/* A using declaration. DECL_INITIAL contains the specified scope.
This is not an alias, but is later expanded into multiple aliases. */
DEFTREECODE (USING_DECL, "using_decl", "d", 0)
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
DEFTREECODE (CAST_EXPR, "cast_expr", "e", 1)
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "e", 1)
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "e", 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
DEFTREECODE (EXPR_STMT, "expr_stmt", "e", 1)
DEFTREECODE (COMPOUND_STMT, "compound_stmt", "e", 1)
DEFTREECODE (DECL_STMT, "decl_stmt", "e", 4)
DEFTREECODE (IF_STMT, "if_stmt", "e", 3)
DEFTREECODE (FOR_STMT, "for_stmt", "e", 4)
DEFTREECODE (WHILE_STMT, "while_stmt", "e", 2)
DEFTREECODE (DO_STMT, "do_stmt", "e", 2)
DEFTREECODE (RETURN_STMT, "return_stmt", "e", 1)
DEFTREECODE (BREAK_STMT, "break_stmt", "e", 0)
DEFTREECODE (CONTINUE_STMT, "continue_stmt", "e", 0)
DEFTREECODE (SWITCH_STMT, "switch_stmt", "e", 2)
DEFTREECODE (GOTO_STMT, "goto_stmt", "e", 1)
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2)
DEFTREECODE (CASE_LABEL, "case_label", "e", 2)

View File

@ -330,7 +330,7 @@ enum languages { lang_c, lang_cplusplus };
#define TYPE_MAIN_DECL(NODE) (TYPE_NAME (NODE))
#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE)
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
&& IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
@ -507,6 +507,8 @@ struct lang_type
union tree_node *signature_pointer_to;
union tree_node *signature_reference_to;
union tree_node *template_info;
int linenum;
};
@ -834,9 +836,6 @@ struct lang_type
/* Nonzero if a _DECL node requires us to output debug info for this class. */
#define CLASSTYPE_DEBUG_REQUESTED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.debug_requested)
#define TYPE_INCOMPLETE(NODE) \
(TYPE_SIZE (NODE) == NULL_TREE && TREE_CODE (NODE) != TEMPLATE_TYPE_PARM)
/* Additional macros for inheritance information. */
@ -956,6 +955,7 @@ struct lang_decl_flags
tree access;
tree context;
tree memfunc_pointer_to;
tree template_info;
struct binding_level *level;
};
@ -963,7 +963,6 @@ struct lang_decl
{
struct lang_decl_flags decl_flags;
struct template_info *template_info;
tree main_decl_variant;
struct pending_inline *pending_inline_info;
tree chain;
@ -1064,8 +1063,8 @@ struct lang_decl
? DECL_CLASS_CONTEXT (NODE) : DECL_CONTEXT (NODE))
/* For a FUNCTION_DECL: the chain through which the next method
in the method chain is found. We now use TREE_CHAIN to
link into the FIELD_DECL chain. */
with the same name is found. We now use TREE_CHAIN to
walk through the methods in order of declaration. */
#if 1
#define DECL_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->chain)
#else
@ -1097,8 +1096,23 @@ struct lang_decl
which this signature member function pointer was created. */
#define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to)
/* For a TEMPLATE_DECL: template-specific information. */
#define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->template_info)
/* For a VAR_DECL or FUNCTION_DECL: template-specific information. */
#define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info)
#define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info)
#define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE))
#define TI_ARGS(NODE) (TREE_VALUE (NODE))
#define TI_USES_TEMPLATE_PARMS(NODE) TREE_LANG_FLAG_0 (NODE)
#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))
#define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE)
#define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE)
#define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
#define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
/* Nonzero in INT_CST means that this int is negative by dint of
using a twos-complement negated operand. */
@ -1321,13 +1335,23 @@ extern int flag_new_for_scope;
#define SET_DECL_REFERENCE_SLOT(NODE,VAL) ((NODE)->decl.arguments=VAL)
/* Accessor macros for C++ template decl nodes. */
#define DECL_TEMPLATE_IS_CLASS(NODE) (DECL_RESULT(NODE) == NULL_TREE)
#define DECL_TEMPLATE_PARMS(NODE) DECL_ARGUMENTS(NODE)
/* For class templates. */
#define DECL_TEMPLATE_MEMBERS(NODE) DECL_SIZE(NODE)
/* For function, method, class-data templates. */
#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE)
#define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE)
#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE)
#define DECL_FUNCTION_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
#define PRIMARY_TEMPLATE_P(NODE) \
(TREE_TYPE (DECL_TEMPLATE_PARMS (NODE)) == (NODE))
#define CLASSTYPE_TEMPLATE_LEVEL(NODE) \
(TREE_INT_CST_HIGH (TREE_PURPOSE (CLASSTYPE_TI_TEMPLATE (NODE))))
/* Indicates whether or not (and how) a template was expanded for this
FUNCTION_DECL or VAR_DECL.
@ -1456,7 +1480,9 @@ extern tree default_function_type;
extern tree vtable_entry_type;
extern tree sigtable_entry_type;
extern tree __t_desc_type_node;
#if 0
extern tree __tp_desc_type_node;
#endif
extern tree __access_mode_type_node;
extern tree __bltn_desc_type_node, __user_desc_type_node;
extern tree __class_desc_type_node, __attr_desc_type_node;
@ -1471,7 +1497,6 @@ extern tree delta_identifier;
extern tree delta2_identifier;
extern tree pfn_or_delta2_identifier;
extern tree tag_identifier;
extern tree vb_off_identifier;
extern tree vt_off_identifier;
/* A node that is a list (length 1) of error_mark_nodes. */
@ -1497,37 +1522,22 @@ extern tree integer_two_node, integer_three_node;
extern tree boolean_type_node, boolean_true_node, boolean_false_node;
/* in pt.c */
/* PARM_VEC is a vector of template parameters, either IDENTIFIER_NODEs or
PARM_DECLs. BINDINGS, if non-null, is a vector of bindings for those
parameters. */
struct template_info {
/* Vector of template parameters, either PARM_DECLs or IDENTIFIER_NODEs. */
tree parm_vec;
/* If non-null, a vector of bindings for the template parms. */
tree bindings;
/* Text of template, and length. */
char *text;
int length;
/* Where it came from. */
char *filename;
int lineno;
/* What kind of aggregate -- struct, class, or null. */
tree aggr;
};
extern int processing_template_decl, processing_template_defn;
extern tree current_template_parms;
extern HOST_WIDE_INT processing_template_decl;
/* The template currently being instantiated, and where the instantiation
was triggered. */
struct tinst_level
{
tree classname;
tree decl;
int line;
char *file;
struct tinst_level *next;
};
extern int minimal_parse_mode;
/* in class.c */
extern tree current_class_name;
extern tree current_class_type;
@ -1545,7 +1555,6 @@ extern tree current_class_name, current_class_type, current_class_decl, C_C_D;
extern tree global_base_init_list;
extern tree current_base_init_list, current_member_init_list;
extern int current_function_assigns_this;
extern int current_function_just_assigned_this;
extern int current_function_parms_stored;
@ -1735,9 +1744,6 @@ extern tree access_default_virtual_node; /* 4 */
extern tree access_public_virtual_node; /* 5 */
extern tree access_private_virtual_node; /* 6 */
/* in lex.c */
extern tree current_unit_name, current_unit_language;
/* Things for handling inline functions. */
struct pending_inline
@ -1751,7 +1757,6 @@ struct pending_inline
char *buf; /* pointer to character stream */
int len; /* length of stream */
tree parm_vec, bindings; /* in case this is derived from a template */
unsigned int can_free : 1; /* free this after we're done with it? */
unsigned int deja_vu : 1; /* set iff we don't want to see it again. */
unsigned int interface : 2; /* 0=interface 1=unknown 2=implementation */
@ -1805,6 +1810,10 @@ extern int flag_implicit_templates;
extern int flag_weak;
/* Nonzero if we're done parsing and into end-of-file activities. */
extern int at_eof;
enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
extern tree current_class_decl, C_C_D; /* PARM_DECL: the class instance variable */
@ -1897,15 +1906,14 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))
/* These macros are for accessing the fields of TEMPLATE...PARM nodes. */
#define TEMPLATE_TYPE_TPARMLIST(NODE) TREE_PURPOSE (TYPE_FIELDS (NODE))
#define TEMPLATE_TYPE_IDX(NODE) TREE_INT_CST_LOW (TREE_VALUE (TYPE_FIELDS (NODE)))
#define TEMPLATE_TYPE_SET_INFO(NODE,P,I) \
(TYPE_FIELDS (NODE) = build_tree_list (P, build_int_2 (I, 0)))
#define TEMPLATE_CONST_TPARMLIST(NODE) (*(tree*)&TREE_INT_CST_LOW(NODE))
#define TEMPLATE_CONST_IDX(NODE) (TREE_INT_CST_HIGH(NODE))
#define TEMPLATE_CONST_SET_INFO(NODE,P,I) \
(TEMPLATE_CONST_TPARMLIST (NODE) = saved_parmlist, \
TEMPLATE_CONST_IDX (NODE) = I)
#define TEMPLATE_TYPE_IDX(NODE) TREE_INT_CST_LOW (TYPE_FIELDS (NODE))
#define TEMPLATE_TYPE_LEVEL(NODE) TREE_INT_CST_HIGH (TYPE_FIELDS (NODE))
#define TEMPLATE_TYPE_SET_INFO(NODE,I,L) \
(TYPE_FIELDS (NODE) = build_int_2 (I, L))
#define TEMPLATE_CONST_IDX(NODE) (TREE_INT_CST_LOW(NODE))
#define TEMPLATE_CONST_LEVEL(NODE) (TREE_INT_CST_HIGH(NODE))
#define TEMPLATE_CONST_SET_INFO(NODE,I,L) \
(TEMPLATE_CONST_IDX (NODE) = I, TEMPLATE_CONST_LEVEL (NODE) = L)
/* in lex.c */
/* Indexed by TREE_CODE, these tables give C-looking names to
@ -1922,6 +1930,8 @@ extern void unsigned_conversion_warning PROTO((tree, tree));
extern struct candidate *ansi_c_bullshit;
extern int rank_for_overload PROTO((struct candidate *, struct candidate *));
extern int can_convert PROTO((tree, tree));
extern int can_convert_arg PROTO((tree, tree, tree));
extern void compute_conversion_costs PROTO((tree, tree, struct candidate *, int));
extern int get_arglist_len_in_bytes PROTO((tree));
extern tree build_vfield_ref PROTO((tree, tree));
@ -1943,6 +1953,8 @@ extern void add_method PROTO((tree, tree *, tree));
extern tree get_vfield_offset PROTO((tree));
extern void duplicate_tag_error PROTO((tree));
extern tree finish_struct PROTO((tree, tree, tree, int));
extern tree finish_struct_1 PROTO((tree, tree, int));
extern tree finish_struct_methods PROTO((tree, tree, int));
extern int resolves_to_fixed_type_p PROTO((tree, int *));
extern void init_class_processing PROTO((void));
extern void pushclass PROTO((tree, int));
@ -1980,8 +1992,6 @@ extern int kept_level_p PROTO((void));
extern void declare_parm_level PROTO((void));
extern void declare_implicit_exception PROTO((void));
extern int have_exceptions_p PROTO((void));
extern void declare_uninstantiated_type_level PROTO((void));
extern int uninstantiated_type_level_p PROTO((void));
extern void declare_pseudo_global_level PROTO((void));
extern int pseudo_global_level_p PROTO((void));
extern void pushlevel PROTO((int));
@ -2008,7 +2018,7 @@ extern tree pushdecl_top_level PROTO((tree));
extern void push_class_level_binding PROTO((tree, tree));
extern void push_overloaded_decl_top_level PROTO((tree, int));
extern tree pushdecl_class_level PROTO((tree));
extern tree pushdecl_nonclass_level PROTO((tree));
extern void pushdecl_nonclass_level PROTO((tree));
extern int overloaded_globals_p PROTO((tree));
extern tree push_overloaded_decl PROTO((tree, int));
extern tree implicitly_declare PROTO((tree));
@ -2024,6 +2034,7 @@ extern tree lookup_name PROTO((tree, int));
extern tree lookup_namespace_name PROTO((tree, tree));
extern tree lookup_name_current_level PROTO((tree));
extern void init_decl_processing PROTO((void));
extern int init_type_desc PROTO((void));
/* skipped define_function */
extern void shadow_tag PROTO((tree));
extern int grok_ctor_properties PROTO((tree, tree));
@ -2056,6 +2067,10 @@ extern void finish_stmt PROTO((void));
extern void pop_implicit_try_blocks PROTO((tree));
extern void push_exception_cleanup PROTO((tree));
extern void revert_static_member_fn PROTO((tree *, tree *, tree *));
extern int id_in_current_class PROTO((tree));
extern void push_cp_function_context PROTO((tree));
extern void pop_cp_function_context PROTO((tree));
extern void grok_op_properties PROTO((tree, int, int));
/* in decl2.c */
extern int lang_decode_option PROTO((char *));
@ -2064,11 +2079,12 @@ extern void grokclassfn PROTO((tree, tree, tree, enum overload_flags, tree));
extern tree grok_alignof PROTO((tree));
extern tree grok_array_decl PROTO((tree, tree));
extern tree delete_sanity PROTO((tree, tree, int, int));
extern tree check_classfn PROTO((tree, tree, tree));
extern tree check_classfn PROTO((tree, tree));
extern tree grokfield PROTO((tree, tree, tree, tree, tree, tree));
extern tree grokbitfield PROTO((tree, tree, tree));
extern tree groktypefield PROTO((tree, tree));
extern tree grokoptypename PROTO((tree, tree));
extern int copy_assignment_arg_p PROTO((tree, int));
extern void cplus_decl_attributes PROTO((tree, tree, tree));
extern tree constructor_name_full PROTO((tree));
extern tree constructor_name PROTO((tree));
@ -2082,6 +2098,7 @@ extern tree finish_table PROTO((tree, tree, tree, int));
extern void finish_builtin_type PROTO((tree, char *, tree *, int, tree));
extern tree coerce_new_type PROTO((tree));
extern tree coerce_delete_type PROTO((tree));
extern void import_export_vtable PROTO((tree, tree, int));
extern void walk_vtables PROTO((void (*)(), void (*)()));
extern void walk_sigtables PROTO((void (*)(), void (*)()));
extern void finish_file PROTO((void));
@ -2089,6 +2106,7 @@ extern void warn_if_unknown_interface PROTO((tree));
extern tree grok_x_components PROTO((tree, tree));
extern tree reparse_absdcl_as_expr PROTO((tree, tree));
extern tree reparse_absdcl_as_casts PROTO((tree, tree));
extern tree build_expr_from_tree PROTO((tree));
extern tree reparse_decl_as_expr PROTO((tree, tree));
extern tree finish_decl_parsing PROTO((tree));
extern tree lookup_name_nonclass PROTO((tree));
@ -2098,6 +2116,7 @@ extern tree do_class_using_decl PROTO((tree));
extern tree current_namespace_id PROTO((tree));
extern tree get_namespace_id PROTO((void));
extern void check_default_args PROTO((tree));
extern void mark_used PROTO((tree));
/* in except.c */
extern tree protect_list;
@ -2118,7 +2137,6 @@ extern tree build_throw PROTO((tree));
extern void init_exception_processing PROTO((void));
extern void expand_builtin_throw PROTO((void));
extern void expand_start_eh_spec PROTO((void));
extern void expand_end_eh_spec PROTO((tree));
extern tree build_cleanup PROTO((tree));
extern tree start_anon_func PROTO((void));
@ -2128,8 +2146,11 @@ extern void init_cplus_expand PROTO((void));
extern void fixup_result_decl PROTO((tree, struct rtx_def *));
extern tree unsave_expr_now PROTO((tree));
/* in repo.c */
extern void init_repo PROTO((char*));
extern void finish_repo PROTO((void));
/* in rtti.c */
extern tree build_headof PROTO((tree));
extern tree build_classof PROTO((tree));
extern tree build_t_desc PROTO((tree, int));
extern tree build_i_desc PROTO((tree));
@ -2146,6 +2167,7 @@ extern void do_member_init PROTO((tree, tree, tree));
extern void expand_member_init PROTO((tree, tree, tree));
extern void expand_aggr_init PROTO((tree, tree, int, int));
extern int is_aggr_typedef PROTO((tree, int));
extern int is_aggr_type PROTO((tree, int));
extern tree get_aggr_from_typedef PROTO((tree, int));
extern tree get_type_value PROTO((tree));
extern tree build_member_call PROTO((tree, tree, tree));
@ -2156,7 +2178,7 @@ extern tree decl_constant_value PROTO((tree));
extern int is_friend_type PROTO((tree, tree));
extern int is_friend PROTO((tree, tree));
extern void make_friend_class PROTO((tree, tree));
extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree));
extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
extern void embrace_waiting_friends PROTO((tree));
extern tree build_builtin_call PROTO((tree, tree, tree));
extern tree build_new PROTO((tree, tree, tree, int));
@ -2164,7 +2186,7 @@ extern tree expand_vec_init PROTO((tree, tree, tree, tree, int));
extern tree build_x_delete PROTO((tree, tree, int, tree));
extern tree build_delete PROTO((tree, tree, tree, int, int));
extern tree build_vbase_delete PROTO((tree, tree));
extern tree build_vec_delete PROTO((tree, tree, tree, tree, tree, int));
extern tree build_vec_delete PROTO((tree, tree, tree, tree, int));
/* in input.c */
@ -2198,7 +2220,8 @@ extern int check_newline PROTO((void));
extern void dont_see_typename PROTO((void));
extern int identifier_type PROTO((tree));
extern void see_typename PROTO((void));
extern tree do_identifier PROTO((tree));
extern tree do_identifier PROTO((tree, int));
extern tree do_scoped_id PROTO((tree, int));
extern tree identifier_typedecl_value PROTO((tree));
extern int real_yylex PROTO((void));
extern tree build_lang_decl PROTO((enum tree_code, tree, tree));
@ -2223,7 +2246,7 @@ extern void cp_sprintf ();
/* in error.c */
extern void init_error PROTO((void));
extern char *fndecl_as_string PROTO((tree, tree, int));
extern char *fndecl_as_string PROTO((tree, int));
extern char *type_as_string PROTO((tree, int));
extern char *args_as_string PROTO((tree, int));
extern char *decl_as_string PROTO((tree, int));
@ -2251,36 +2274,37 @@ extern void declare_overloaded PROTO((tree));
extern int is_overloaded PROTO((tree));
#endif
extern tree build_opfncall PROTO((enum tree_code, int, tree, tree, tree));
extern tree hack_identifier PROTO((tree, tree, int));
extern tree hack_identifier PROTO((tree, tree));
extern tree build_component_type_expr PROTO((tree, tree, tree, int));
extern void synthesize_method PROTO((tree));
/* in pt.c */
extern tree tsubst PROTO ((tree, tree*, int, tree));
extern tree tsubst_expr PROTO ((tree, tree*, int, tree));
extern tree tsubst_copy PROTO ((tree, tree*, int, tree));
extern tree tsubst_chain PROTO((tree, tree));
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((tree, tree, tree, int));
extern void end_template_decl PROTO((void));
extern tree lookup_template_class PROTO((tree, tree, tree));
extern void push_template_decls PROTO((tree, tree, int));
extern void pop_template_decls PROTO((tree, tree, int));
extern int uses_template_parms PROTO((tree));
extern void instantiate_member_templates PROTO((tree));
extern tree instantiate_class_template PROTO((tree, int));
extern tree instantiate_class_template PROTO((tree));
extern tree instantiate_template PROTO((tree, tree *));
extern void undo_template_name_overload PROTO((tree, int));
extern void overload_template_name PROTO((tree, int));
extern void end_template_instantiation PROTO((tree));
extern void reinit_parse_for_template PROTO((int, tree, tree));
extern void overload_template_name PROTO((tree));
extern int type_unification PROTO((tree, tree *, tree, tree, int *, int));
extern int do_pending_expansions PROTO((void));
extern void do_pending_templates PROTO((void));
struct tinst_level *tinst_for_decl PROTO((void));
extern void mark_decl_instantiated PROTO((tree, int));
extern void mark_class_instantiated PROTO((tree, int));
extern void do_function_instantiation PROTO((tree, tree, tree));
extern void do_type_instantiation PROTO((tree, tree));
extern tree create_nested_upt PROTO((tree, tree));
extern tree make_typename_type PROTO((tree, tree));
extern tree instantiate_decl PROTO((tree));
extern tree classtype_mangled_name PROTO((tree));
extern tree lookup_nested_type_by_name PROTO((tree, tree));
extern tree do_poplevel PROTO((void));
/* in search.c */
extern tree make_memoized_table_entry PROTO((tree, tree, int));
extern void push_memoized_context PROTO((tree, int));
extern void pop_memoized_context PROTO((int));
extern tree get_binfo PROTO((tree, tree, int));
@ -2290,8 +2314,6 @@ extern tree lookup_field PROTO((tree, tree, int, int));
extern tree lookup_nested_field PROTO((tree, int));
extern tree lookup_fnfields PROTO((tree, tree, int));
extern tree lookup_nested_tag PROTO((tree, tree));
extern HOST_WIDE_INT breadth_first_search PROTO((tree, int (*)(), int (*)()));
extern int tree_has_any_destructor_p PROTO((tree, int));
extern tree get_matching_virtual PROTO((tree, tree, int));
extern tree get_abstract_virtuals PROTO((tree));
extern tree get_baselinks PROTO((tree, tree, tree));
@ -2307,7 +2329,7 @@ extern void add_mi_virtuals PROTO((int, tree));
extern void report_ambiguous_mi_virtuals PROTO((int, tree));
extern void note_debug_info_needed PROTO((tree));
extern void push_class_decls PROTO((tree));
extern void pop_class_decls PROTO((tree));
extern void pop_class_decls PROTO(());
extern void unuse_fields PROTO((tree));
extern void unmark_finished_struct PROTO((tree));
extern void print_search_statistics PROTO((void));
@ -2323,16 +2345,22 @@ extern tree build_signature_pointer_constructor PROTO((tree, tree));
extern tree build_signature_method_call PROTO((tree, tree, tree, tree));
extern tree build_optr_ref PROTO((tree));
extern tree build_sptr_ref PROTO((tree));
extern void append_signature_fields PROTO((tree));
/* in spew.c */
extern void init_spew PROTO((void));
extern int peek_yylex PROTO((void));
extern int yylex PROTO((void));
extern tree arbitrate_lookup PROTO((tree, tree, tree));
/* in tree.c */
extern int real_lvalue_p PROTO((tree));
extern tree build_min PVPROTO((enum tree_code, tree, ...));
extern tree build_min_nt PVPROTO((enum tree_code, ...));
extern tree min_tree_cons PROTO((tree, tree, tree));
extern int lvalue_p PROTO((tree));
extern int lvalue_or_else PROTO((tree, char *));
extern tree build_cplus_new PROTO((tree, tree, int));
extern tree build_cplus_new PROTO((tree, tree));
extern tree break_out_cleanups PROTO((tree));
extern tree break_out_calls PROTO((tree));
extern tree build_cplus_method_type PROTO((tree, tree, tree));
@ -2373,17 +2401,19 @@ extern tree break_out_target_exprs PROTO((tree));
extern tree build_unsave_expr PROTO((tree));
extern tree unsave_expr PROTO((tree));
extern int cp_expand_decl_cleanup PROTO((tree, tree));
extern tree get_type_decl PROTO((tree));
/* in typeck.c */
extern tree condition_conversion PROTO((tree));
extern tree target_type PROTO((tree));
extern tree require_complete_type PROTO((tree));
extern tree complete_type PROTO((tree));
extern int type_unknown_p PROTO((tree));
extern int fntype_p PROTO((tree));
extern tree require_instantiated_type PROTO((tree, tree, tree));
extern tree commonparms PROTO((tree, tree));
extern tree common_type PROTO((tree, tree));
extern int compexcepttypes PROTO((tree, tree, int));
extern int compexcepttypes PROTO((tree, tree));
extern int comptypes PROTO((tree, tree, int));
extern int comp_target_types PROTO((tree, tree, int));
extern tree common_base_types PROTO((tree, tree));
@ -2393,6 +2423,7 @@ extern int self_promoting_args_p PROTO((tree));
extern tree unsigned_type PROTO((tree));
extern tree signed_type PROTO((tree));
extern tree signed_or_unsigned_type PROTO((int, tree));
extern tree expr_sizeof PROTO((tree));
extern tree c_sizeof PROTO((tree));
extern tree c_sizeof_nowarn PROTO((tree));
extern tree c_alignof PROTO((tree));
@ -2426,6 +2457,7 @@ extern tree build_static_cast PROTO((tree, tree));
extern tree build_reinterpret_cast PROTO((tree, tree));
extern tree build_const_cast PROTO((tree, tree));
extern tree build_c_cast PROTO((tree, tree, int));
extern tree build_x_modify_expr PROTO((tree, enum tree_code, tree));
extern tree build_modify_expr PROTO((tree, enum tree_code, tree));
extern int language_lvalue_valid PROTO((tree));
extern void warn_for_assignment PROTO((char *, char *, char *, tree, int, int));
@ -2442,6 +2474,7 @@ extern tree binfo_or_else PROTO((tree, tree));
extern void error_with_aggr_type (); /* PROTO((tree, char *, HOST_WIDE_INT)); */
extern void readonly_error PROTO((tree, char *, int));
extern void abstract_virtuals_error PROTO((tree, tree));
extern void signature_error PROTO((tree, tree));
extern void incomplete_type_error PROTO((tree, tree));
extern void my_friendly_abort PROTO((int));
extern void my_friendly_assert PROTO((int, int));
@ -2459,7 +2492,7 @@ extern void GNU_xref_begin PROTO((char *));
extern void GNU_xref_end PROTO((int));
extern void GNU_xref_file PROTO((char *));
extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT));
extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int, int));
extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int));
extern void GNU_xref_ref PROTO((tree, char *));
extern void GNU_xref_decl PROTO((tree, tree));
extern void GNU_xref_call PROTO((tree, char *));

View File

@ -356,7 +356,7 @@ build_up_reference (type, arg, flags, checkconst)
initializing until now: it needs to initialize a temporary. */
if (TREE_HAS_CONSTRUCTOR (targ))
{
tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0), 1);
tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0));
TREE_HAS_CONSTRUCTOR (targ) = 0;
return build_up_reference (type, temp, flags, 1);
}
@ -586,7 +586,7 @@ build_up_reference (type, arg, flags, checkconst)
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
{
temp = build_cplus_new (argtype, targ, 1);
temp = build_cplus_new (argtype, targ);
rval = build1 (ADDR_EXPR, type, temp);
goto done;
}
@ -809,7 +809,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (init == error_mark_node)
return error_mark_node;
rval = build_cplus_new (type, init, 1);
rval = build_cplus_new (type, init);
rval = build_up_reference (reftype, rval, flags, 1);
}
rval_as_ctor = rval;
@ -888,7 +888,11 @@ convert_to_aggr (type, expr, msgp, protect)
tree basetype = type;
tree name = TYPE_IDENTIFIER (basetype);
tree function, fndecl, fntype, parmtypes, parmlist, result;
tree method_name, access;
#if 0
/* See code below that used this. */
tree method_name;
#endif
tree access;
int can_be_private, can_be_protected;
if (! TYPE_HAS_CONSTRUCTOR (basetype))
@ -1229,7 +1233,6 @@ cp_convert (type, expr, convtype, flags)
if (INTEGRAL_CODE_P (code))
{
tree intype = TREE_TYPE (e);
enum tree_code form = TREE_CODE (intype);
/* enum = enum, enum = int, enum = float are all errors. */
if (flag_int_enum_equivalence == 0
&& TREE_CODE (type) == ENUMERAL_TYPE
@ -1328,7 +1331,7 @@ cp_convert (type, expr, convtype, flags)
return conversion;
}
if (TYPE_HAS_CONSTRUCTOR (type))
if (TYPE_HAS_CONSTRUCTOR (complete_type (type)))
ctor = build_method_call (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type),
@ -1357,7 +1360,7 @@ cp_convert (type, expr, convtype, flags)
return conversion;
else if (ctor)
{
ctor = build_cplus_new (type, ctor, 0);
ctor = build_cplus_new (type, ctor);
return ctor;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
extern tree get_file_function_name ();
extern tree cleanups_this_call;
static void grok_function_init ();
void import_export_decl ();
extern int current_class_depth;
/* A list of virtual function tables we must make sure to write out. */
@ -67,6 +68,10 @@ static int global_temp_name_counter;
extern int spew_debug;
/* Nonzero if we're done parsing and into end-of-file activities. */
int at_eof;
/* Functions called along with real static constructors and destructors. */
tree static_ctors, static_dtors;
@ -1043,6 +1048,10 @@ grok_array_decl (array_expr, index_exp)
if (type == error_mark_node || index_exp == error_mark_node)
return error_mark_node;
if (current_template_parms)
return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
array_expr, index_exp);
if (type == NULL_TREE)
{
/* Something has gone very wrong. Assume we are mistakenly reducing
@ -1057,7 +1066,7 @@ grok_array_decl (array_expr, index_exp)
/* If they have an `operator[]', use that. */
if (TYPE_LANG_SPECIFIC (type)
&& TYPE_OVERLOADS_ARRAY_REF (type))
&& TYPE_OVERLOADS_ARRAY_REF (complete_type (type)))
return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
array_expr, index_exp, NULL_TREE);
@ -1108,14 +1117,24 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
tree exp, size;
int doing_vec, use_global_delete;
{
tree t = stabilize_reference (convert_from_reference (exp));
tree type = TREE_TYPE (t);
enum tree_code code = TREE_CODE (type);
tree t;
tree type;
enum tree_code code;
/* For a regular vector delete (aka, no size argument) we will pass
this down as a NULL_TREE into build_vec_delete. */
tree maxindex = NULL_TREE;
/* This is used for deleting arrays. */
tree elt_size;
if (current_template_parms)
{
t = build_min (DELETE_EXPR, void_type_node, exp, size);
DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
DELETE_EXPR_USE_VEC (t) = doing_vec;
return t;
}
t = stabilize_reference (convert_from_reference (exp));
type = TREE_TYPE (t);
code = TREE_CODE (type);
switch (doing_vec)
{
@ -1125,7 +1144,6 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
pedwarn ("anachronistic use of array size in vector delete");
/* Fall through. */
case 1:
elt_size = c_sizeof (type);
break;
default:
if (code != POINTER_TYPE)
@ -1174,7 +1192,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
#endif
if (doing_vec)
return build_vec_delete (t, maxindex, elt_size, integer_one_node,
return build_vec_delete (t, maxindex, integer_one_node,
integer_two_node, use_global_delete);
else
{
@ -1200,12 +1218,12 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
CNAME is the same here as it is for grokclassfn above. */
tree
check_classfn (ctype, cname, function)
tree ctype, cname, function;
check_classfn (ctype, function)
tree ctype, function;
{
tree fn_name = DECL_NAME (function);
tree fndecl;
tree method_vec = CLASSTYPE_METHOD_VEC (ctype);
tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
tree *methods = 0;
tree *end = 0;
@ -1229,8 +1247,8 @@ check_classfn (ctype, cname, function)
if (DECL_ASSEMBLER_NAME (function) == DECL_ASSEMBLER_NAME (fndecl))
return fndecl;
#if 0
/* This should work, but causes libg++ to fail
make check-tFix. */
/* This doesn't work for static member functions that are
pretending to be methods. */
/* We have to do more extensive argument checking here, as
the name may have been changed by asm("new_name"). */
if (decls_match (function, fndecl))
@ -1250,12 +1268,7 @@ check_classfn (ctype, cname, function)
if (comptypes (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)), 1)
&& compparms (p1, p2, 3))
{
if (DECL_STATIC_FUNCTION_P (fndecl)
&& TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
revert_static_member_fn (&function, NULL, NULL);
return fndecl;
}
return fndecl;
}
#endif
fndecl = DECL_CHAIN (fndecl);
@ -1333,7 +1346,9 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
&& TREE_CODE (declarator) == SCOPE_REF)
{
/* Access declaration */
if (TREE_COMPLEXITY (declarator) == current_class_depth)
if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0))))
;
else if (TREE_COMPLEXITY (declarator) == current_class_depth)
pop_nested_class (1);
return do_class_using_decl (declarator);
}
@ -1437,6 +1452,8 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
because `decl_const_value' would mis-interpret it
as only meaning that this VAR_DECL is defined. */
init = build1 (NOP_EXPR, TREE_TYPE (value), init);
else if (current_template_parms)
;
else if (! TREE_CONSTANT (init))
{
/* We can allow references to things that are effectively
@ -1456,6 +1473,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
/* The corresponding pop_obstacks is in cp_finish_decl. */
push_obstacks_nochange ();
if (current_template_parms && ! current_function_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
push_template_decl (value);
if (attrlist)
cplus_decl_attributes (value, TREE_PURPOSE (attrlist),
TREE_VALUE (attrlist));
@ -1476,7 +1497,8 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
DECL_ASSEMBLER_NAME (value)
= build_static_name (current_class_type, DECL_NAME (value));
}
pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);
if (! current_template_parms)
pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);
/* Static consts need not be initialized in the class definition. */
if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (value)))
@ -1495,6 +1517,8 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
}
DECL_INITIAL (value) = init;
DECL_IN_AGGR_P (value) = 1;
DECL_CONTEXT (value) = current_class_type;
DECL_CLASS_CONTEXT (value) = current_class_type;
cp_finish_decl (value, init, asmspec_tree, 1, flags);
pushdecl_class_level (value);
@ -1600,26 +1624,9 @@ grokbitfield (declarator, declspecs, width)
if (width != error_mark_node)
{
/* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
STRIP_NOPS (width);
/* detect invalid field size. */
if (TREE_CODE (width) == CONST_DECL)
width = DECL_INITIAL (width);
else if (TREE_READONLY_DECL_P (width))
width = decl_constant_value (width);
if (TREE_CODE (width) != INTEGER_CST)
{
cp_error ("structure field `%D' width not an integer constant",
value);
DECL_INITIAL (value) = NULL_TREE;
}
else
{
constant_expression_warning (width);
DECL_INITIAL (value) = width;
DECL_BIT_FIELD (value) = 1;
}
constant_expression_warning (width);
DECL_INITIAL (value) = width;
DECL_BIT_FIELD (value) = 1;
}
DECL_IN_AGGR_P (value) = 1;
@ -1963,9 +1970,7 @@ tree
constructor_name_full (thing)
tree thing;
{
if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE)
return DECL_NAME (UPT_TEMPLATE (thing));
else if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM)
if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM)
thing = TYPE_NAME (thing);
else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
{
@ -1976,7 +1981,7 @@ constructor_name_full (thing)
}
if (TREE_CODE (thing) == TYPE_DECL
|| (TREE_CODE (thing) == TEMPLATE_DECL
&& DECL_TEMPLATE_IS_CLASS (thing)))
&& TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL))
thing = DECL_NAME (thing);
my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197);
return thing;
@ -1996,8 +2001,7 @@ constructor_name (thing)
t = IDENTIFIER_TEMPLATE (thing);
if (!t)
return thing;
t = TREE_PURPOSE (t);
return DECL_NAME (t);
return t;
}
/* Cache the value of this class's main virtual function table pointer
@ -2010,7 +2014,14 @@ setup_vtbl_ptr ()
if (base_init_expr == 0
&& DECL_CONSTRUCTOR_P (current_function_decl))
emit_base_init (current_class_type, 0);
{
if (current_template_parms)
add_tree (build_min_nt
(CTOR_INITIALIZER,
current_member_init_list, current_base_init_list));
else
emit_base_init (current_class_type, 0);
}
}
/* Record the existence of an addressable inline function. */
@ -2431,7 +2442,7 @@ mark_vtable_entries (decl)
TREE_ADDRESSABLE (fn) = 1;
if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn))
TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl;
assemble_external (fn);
mark_used (fn);
}
}
@ -2701,10 +2712,10 @@ walk_sigtables (typedecl_fn, vardecl_fn)
}
/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
inline function at end-of-file. */
inline function or template instantiation at end-of-file. */
void
import_export_inline (decl)
import_export_decl (decl)
tree decl;
{
if (DECL_INTERFACE_KNOWN (decl))
@ -2712,12 +2723,17 @@ import_export_inline (decl)
if (DECL_TEMPLATE_INSTANTIATION (decl))
{
DECL_NOT_REALLY_EXTERN (decl) = 1;
if (DECL_IMPLICIT_INSTANTIATION (decl) && flag_implicit_templates)
{
if (flag_weak)
DECL_WEAK (decl) = 1;
else
TREE_PUBLIC (decl) = 0;
/* For now, leave vars public so multiple defs will break. */
if (TREE_CODE (decl) == FUNCTION_DECL)
{
if (flag_weak)
DECL_WEAK (decl) = 1;
else
TREE_PUBLIC (decl) = 0;
}
}
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
@ -2767,6 +2783,7 @@ build_cleanup (decl)
}
extern int parse_time, varconst_time;
extern tree pending_templates;
#define TIMEVAR(VAR, BODY) \
do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
@ -2786,6 +2803,8 @@ finish_file ()
tree vars;
int needs_cleaning = 0, needs_messing_up = 0;
at_eof = 1;
if (flag_detailed_statistics)
dump_tree_statistics ();
@ -3027,10 +3046,21 @@ finish_file ()
while (pending_statics)
{
tree decl = TREE_VALUE (pending_statics);
if (DECL_TEMPLATE_INSTANTIATION (decl)
&& ! DECL_IN_AGGR_P (decl))
{
import_export_decl (decl);
DECL_EXTERNAL (decl) = ! DECL_NOT_REALLY_EXTERN (decl);
}
if (TREE_USED (decl) == 1
|| TREE_READONLY (decl) == 0
|| DECL_INITIAL (decl) == 0)
rest_of_decl_compilation (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1);
{
DECL_DEFER_OUTPUT (decl) = 0;
rest_of_decl_compilation (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1);
}
pending_statics = TREE_CHAIN (pending_statics);
}
@ -3043,10 +3073,15 @@ finish_file ()
if (flag_handle_signatures)
walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
for (fnname = pending_templates; fnname; fnname = TREE_CHAIN (fnname))
{
tree decl = TREE_VALUE (fnname);
instantiate_decl (decl);
}
for (fnname = saved_inlines; fnname; fnname = TREE_CHAIN (fnname))
{
tree decl = TREE_VALUE (fnname);
import_export_inline (decl);
import_export_decl (decl);
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
&& TREE_PUBLIC (decl) && ! DECL_WEAK (decl)
&& DECL_NOT_REALLY_EXTERN (decl))
@ -3229,47 +3264,222 @@ reparse_absdcl_as_casts (decl, expr)
return expr;
}
/* Recursive helper function for reparse_decl_as_expr. It may be a good
idea to reimplement this using an explicit stack, rather than recursion. */
static tree
reparse_decl_as_expr1 (decl)
tree decl;
/* Given plain tree nodes for an expression, build up the full semantics. */
tree
build_expr_from_tree (t)
tree t;
{
switch (TREE_CODE (decl))
if (t == NULL_TREE || t == error_mark_node)
return t;
switch (TREE_CODE (t))
{
case IDENTIFIER_NODE:
return do_identifier (decl);
return do_identifier (t, 0);
case LOOKUP_EXPR:
if (LOOKUP_EXPR_GLOBAL (t))
return do_scoped_id (TREE_OPERAND (t, 0), 0);
else
return do_identifier (TREE_OPERAND (t, 0), 0);
case INDIRECT_REF:
return build_x_indirect_ref
(reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)), "unary *");
case ADDR_EXPR:
return build_x_unary_op (ADDR_EXPR,
reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)));
(build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *");
case CAST_EXPR:
return build_functional_cast
(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
case REINTERPRET_CAST_EXPR:
return build_reinterpret_cast
(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case NEGATE_EXPR:
case BIT_NOT_EXPR:
return build_x_unary_op (BIT_NOT_EXPR,
reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)));
case ABS_EXPR:
case TRUTH_NOT_EXPR:
case ADDR_EXPR:
case CONVERT_EXPR: /* Unary + */
return build_x_unary_op (TREE_CODE (t),
build_expr_from_tree (TREE_OPERAND (t, 0)));
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
case BIT_AND_EXPR:
case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case RSHIFT_EXPR:
case LSHIFT_EXPR:
case RROTATE_EXPR:
case LROTATE_EXPR:
case EQ_EXPR:
case NE_EXPR:
case MAX_EXPR:
case MIN_EXPR:
case LE_EXPR:
case GE_EXPR:
case LT_EXPR:
case GT_EXPR:
case MEMBER_REF:
return build_x_binary_op
(TREE_CODE (t),
build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree (TREE_OPERAND (t, 1)));
case DOTSTAR_EXPR:
return build_m_component_ref
(build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree (TREE_OPERAND (t, 1)));
case SCOPE_REF:
return build_offset_ref (TREE_OPERAND (decl, 0), TREE_OPERAND (decl, 1));
return build_offset_ref (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
case ARRAY_REF:
return grok_array_decl (reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)),
TREE_OPERAND (decl, 1));
if (TREE_OPERAND (t, 0) == NULL_TREE)
/* new-type-id */
return build_parse_node (ARRAY_REF, NULL_TREE,
build_expr_from_tree (TREE_OPERAND (t, 1)));
return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree (TREE_OPERAND (t, 1)));
case SIZEOF_EXPR:
{
tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
if (TREE_CODE_CLASS (TREE_CODE (r)) != 't')
r = TREE_TYPE (r);
return c_sizeof (r);
}
case MODOP_EXPR:
return build_x_modify_expr
(build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_CODE (TREE_OPERAND (t, 1)),
build_expr_from_tree (TREE_OPERAND (t, 2)));
case ARROW_EXPR:
return build_x_arrow
(build_expr_from_tree (TREE_OPERAND (t, 0)));
case NEW_EXPR:
return build_new
(build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree (TREE_OPERAND (t, 1)),
build_expr_from_tree (TREE_OPERAND (t, 2)),
NEW_EXPR_USE_GLOBAL (t));
case DELETE_EXPR:
return delete_sanity
(build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree (TREE_OPERAND (t, 1)),
DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t));
case COMPOUND_EXPR:
if (TREE_OPERAND (t, 1) == NULL_TREE)
return build_x_compound_expr
(build_expr_from_tree (TREE_OPERAND (t, 0)));
else
my_friendly_abort (42);
case METHOD_CALL_EXPR:
if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
{
tree ref = TREE_OPERAND (t, 0);
return build_scoped_method_call
(build_expr_from_tree (TREE_OPERAND (t, 1)),
build_expr_from_tree (TREE_OPERAND (ref, 0)),
TREE_OPERAND (ref, 1),
build_expr_from_tree (TREE_OPERAND (t, 2)));
}
return build_method_call
(build_expr_from_tree (TREE_OPERAND (t, 1)),
TREE_OPERAND (t, 0),
build_expr_from_tree (TREE_OPERAND (t, 2)),
NULL_TREE, LOOKUP_NORMAL);
case CALL_EXPR:
if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
{
tree ref = TREE_OPERAND (t, 0);
return build_member_call
(build_expr_from_tree (TREE_OPERAND (ref, 0)),
TREE_OPERAND (ref, 1),
build_expr_from_tree (TREE_OPERAND (t, 1)));
}
else
{
tree name = TREE_OPERAND (t, 0);
if (! really_overloaded_fn (name))
name = build_expr_from_tree (name);
return build_x_function_call
(name, build_expr_from_tree (TREE_OPERAND (t, 1)),
current_class_decl);
}
case COND_EXPR:
return build_x_conditional_expr
(build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree (TREE_OPERAND (t, 1)),
build_expr_from_tree (TREE_OPERAND (t, 2)));
case TREE_LIST:
{
tree purpose, value, chain;
if (t == void_list_node)
return t;
purpose = TREE_PURPOSE (t);
if (purpose)
purpose = build_expr_from_tree (purpose);
value = TREE_VALUE (t);
if (value)
value = build_expr_from_tree (value);
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
chain = build_expr_from_tree (chain);
return tree_cons (purpose, value, chain);
}
case COMPONENT_REF:
return build_component_ref
(build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1), NULL_TREE, 1);
default:
my_friendly_abort (5);
return NULL_TREE;
return t;
}
}
/* This is something of the form `int (*a)++' that has turned out to be an
expr. It was only converted into parse nodes, so we need to go through
and build up the semantics. Most of the work is done by
reparse_decl_as_expr1, above.
build_expr_from_tree, above.
In the above example, TYPE is `int' and DECL is `*a'. */
tree
reparse_decl_as_expr (type, decl)
tree type, decl;
{
decl = reparse_decl_as_expr1 (decl);
decl = build_expr_from_tree (decl);
if (type)
return build_functional_cast (type, build_tree_list (NULL_TREE, decl));
else
@ -3319,20 +3529,13 @@ check_cp_case_value (value)
if (value == NULL_TREE)
return value;
/* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
Strip such NOP_EXPRs. */
if (TREE_CODE (value) == NOP_EXPR
&& TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
value = TREE_OPERAND (value, 0);
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
STRIP_TYPE_NOPS (value);
if (TREE_READONLY_DECL_P (value))
{
value = decl_constant_value (value);
/* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
Strip such NOP_EXPRs. */
if (TREE_CODE (value) == NOP_EXPR
&& TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
value = TREE_OPERAND (value, 0);
STRIP_TYPE_NOPS (value);
}
value = fold (value);
@ -3431,7 +3634,7 @@ do_class_using_decl (decl)
return NULL_TREE;
}
value = build_lang_field_decl (USING_DECL, name, unknown_type_node);
value = build_lang_field_decl (USING_DECL, name, void_type_node);
DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
return value;
}
@ -3466,5 +3669,9 @@ mark_used (decl)
tree decl;
{
TREE_USED (decl) = 1;
if (current_template_parms)
return;
assemble_external (decl);
if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
instantiate_decl (decl);
}

View File

@ -212,11 +212,6 @@ dump_type (t, v)
OB_PUTID (TYPE_IDENTIFIER (t));
break;
case UNINSTANTIATED_P_TYPE:
OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));
OB_PUTS ("<...>");
break;
/* This is not always necessary for pointers and such, but doing this
reduces code size. */
case ARRAY_TYPE:
@ -230,6 +225,13 @@ dump_type (t, v)
dump_type_suffix (t, v);
break;
case TYPENAME_TYPE:
OB_PUTS ("typename ");
dump_type (TYPE_CONTEXT (t), 0);
OB_PUTS ("::");
OB_PUTID (TYPE_IDENTIFIER (t));
break;
default:
sorry ("`%s' not supported by dump_type",
tree_code_name[(int) TREE_CODE (t)]);
@ -422,10 +424,10 @@ dump_type_prefix (t, v)
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
case UNINSTANTIATED_P_TYPE:
case UNION_TYPE:
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
dump_type (t, v);
break;
@ -494,10 +496,10 @@ dump_type_suffix (t, v)
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
case UNINSTANTIATED_P_TYPE:
case UNION_TYPE:
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
break;
default:
@ -711,11 +713,8 @@ dump_decl (t, v)
OB_UNPUT (2);
OB_PUTC2 ('>', ' ');
if (DECL_TEMPLATE_IS_CLASS (t))
{
OB_PUTS ("class ");
OB_PUTID (DECL_NAME (t));
}
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
dump_type (TREE_TYPE (t), v);
else switch (NEXT_CODE (t))
{
case METHOD_TYPE:
@ -734,7 +733,8 @@ dump_decl (t, v)
break;
case CONST_DECL:
if (NEXT_CODE (t) == ENUMERAL_TYPE)
if (NEXT_CODE (t) == ENUMERAL_TYPE
|| TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_CONST_PARM)
goto general;
else
dump_expr (DECL_INITIAL (t), 0);
@ -1262,6 +1262,27 @@ dump_expr (t, nop)
break;
}
case TEMPLATE_CONST_PARM:
{
tree r = TREE_VEC_ELT (TREE_VALUE (current_template_parms),
TEMPLATE_CONST_IDX (t));
dump_decl (TREE_VALUE (r), -1);
break;
}
case IDENTIFIER_NODE:
OB_PUTID (t);
break;
case SCOPE_REF:
dump_type (TREE_OPERAND (t, 0), 0);
OB_PUTS ("::");
dump_expr (TREE_OPERAND (t, 1), 0);
break;
case CAST_EXPR:
break; /* XXX */
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
@ -1312,8 +1333,8 @@ dump_unary_op (opstring, t, nop)
}
char *
fndecl_as_string (cname, fndecl, print_ret_type_p)
tree cname, fndecl;
fndecl_as_string (fndecl, print_ret_type_p)
tree fndecl;
int print_ret_type_p;
{
return decl_as_string (fndecl, print_ret_type_p);
@ -1389,12 +1410,7 @@ cp_line_of (t)
t = TREE_TYPE (t);
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
{
if (IS_AGGR_TYPE (t))
line = CLASSTYPE_SOURCE_LINE (t);
else
line = DECL_SOURCE_LINE (TYPE_NAME (t));
}
line = DECL_SOURCE_LINE (TYPE_NAME (t));
else
line = DECL_SOURCE_LINE (t);

View File

@ -37,6 +37,7 @@ tree protect_list;
extern void (*interim_eh_hook) PROTO((tree));
rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
static void end_eh_unwinder PROTO((rtx));
/* holds the fndecl for __builtin_return_address () */
tree builtin_return_address_fndecl;
@ -90,8 +91,6 @@ output_exception_table_entry (file, start_label, end_label, eh_label)
FILE *file;
rtx start_label, end_label, eh_label;
{
char label[100];
assemble_integer (start_label, GET_MODE_SIZE (Pmode), 1);
assemble_integer (end_label, GET_MODE_SIZE (Pmode), 1);
assemble_integer (eh_label, GET_MODE_SIZE (Pmode), 1);
@ -146,7 +145,7 @@ asm (TEXT_SECTION_ASM_OP);
#endif
void
static void
exception_section ()
{
#ifdef ASM_OUTPUT_SECTION_NAME
@ -320,15 +319,15 @@ struct ehQueue {
========================================================================= */
/* Holds the pc for doing "throw" */
tree saved_pc;
static tree saved_pc;
/* Holds the type of the thing being thrown. */
tree saved_throw_type;
static tree saved_throw_type;
/* Holds the value being thrown. */
tree saved_throw_value;
static tree saved_throw_value;
/* Holds the cleanup for the value being thrown. */
tree saved_cleanup;
static tree saved_cleanup;
int throw_used;
static int throw_used;
static rtx catch_clauses;
@ -454,7 +453,8 @@ top_label_entry (labelstack)
/* Push to permanent obstack for rtl generation.
One level only! */
static struct obstack *saved_rtl_obstack;
void
static void
push_rtl_perm ()
{
extern struct obstack permanent_obstack;
@ -468,9 +468,7 @@ push_rtl_perm ()
static void
pop_rtl_from_perm ()
{
extern struct obstack permanent_obstack;
extern struct obstack *rtl_obstack;
rtl_obstack = saved_rtl_obstack;
}
@ -587,7 +585,7 @@ new_eh_stack (stack)
}
/* cheesyness to save some typing. returns the return value rtx */
rtx
static rtx
do_function_call (func, params, return_type)
tree func, params, return_type;
{
@ -603,8 +601,6 @@ static void
expand_internal_throw (pc)
rtx pc;
{
tree params;
emit_move_insn (DECL_RTL (saved_pc), pc);
#ifdef JUMP_TO_THROW
emit_indirect_jump (gen_rtx (SYMBOL_REF, Pmode, "__throw"));
@ -616,7 +612,7 @@ expand_internal_throw (pc)
/* ========================================================================= */
void
static void
lang_interim_eh (finalization)
tree finalization;
{
@ -946,7 +942,7 @@ build_eh_type (exp)
}
/* This routine creates the cleanup for the exception handling object. */
void
static void
push_eh_cleanup ()
{
/* All cleanups must last longer than normal. */
@ -973,7 +969,6 @@ expand_start_catch_block (declspecs, declarator)
rtx protect_label_rtx;
tree decl = NULL_TREE;
tree init;
tree cleanup;
if (! doing_eh (1))
return;
@ -1243,7 +1238,7 @@ do_unwind (inner_throw_label)
/* Given the return address, compute the new pc to throw. This has to
work for the current frame of the current function, and the one
above it in the case of throw. */
rtx
static rtx
eh_outer_context (addr)
rtx addr;
{
@ -1306,8 +1301,6 @@ expand_builtin_throw ()
rtx return_val_rtx;
rtx gotta_rethrow_it;
rtx gotta_call_terminate;
rtx unwind_and_throw;
rtx goto_unwind_and_throw;
rtx top_of_loop;
rtx unwind_first;
tree t;
@ -1331,8 +1324,6 @@ expand_builtin_throw ()
gotta_rethrow_it = gen_label_rtx ();
gotta_call_terminate = gen_label_rtx ();
unwind_and_throw = gen_label_rtx ();
goto_unwind_and_throw = gen_label_rtx ();
top_of_loop = gen_label_rtx ();
unwind_first = gen_label_rtx ();
@ -1421,7 +1412,7 @@ expand_start_eh_spec ()
start_protect ();
}
void
static void
expand_end_eh_spec (raises)
tree raises;
{
@ -1771,7 +1762,6 @@ emit_exception_table ()
int count = 0;
extern FILE *asm_out_file;
struct ehEntry *entry;
tree eh_node_decl;
if (! doing_eh (0))
return;
@ -1826,11 +1816,13 @@ build_throw (e)
return e;
}
void
start_eh_unwinder ()
{
start_protect ();
}
static void
end_eh_unwinder (end)
rtx end;
{

View File

@ -359,3 +359,85 @@ extract_init (decl, init)
return 1;
#endif
}
void
do_case (start, end)
tree start, end;
{
tree value1 = NULL_TREE, value2 = NULL_TREE, label;
if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
if (current_template_parms)
{
add_tree (build_min_nt (CASE_LABEL, start, end));
return;
}
if (start)
value1 = check_cp_case_value (start);
if (end)
value2 = check_cp_case_value (end);
label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
if (value1 != error_mark_node
&& value2 != error_mark_node)
{
tree duplicate;
int success;
if (end)
success = pushcase_range (value1, value2, convert_and_check,
label, &duplicate);
else if (start)
success = pushcase (value1, convert_and_check, label, &duplicate);
else
success = pushcase (NULL_TREE, 0, label, &duplicate);
if (success == 1)
{
if (end)
error ("case label not within a switch statement");
else if (start)
cp_error ("case label `%E' not within a switch statement", start);
else
error ("default label not within a switch statement");
}
else if (success == 2)
{
if (end)
{
error ("duplicate (or overlapping) case value");
cp_error_at ("this is the first entry overlapping that value",
duplicate);
}
else if (start)
{
cp_error ("duplicate case value `%E'", start);
cp_error_at ("previously used here", duplicate);
}
else
{
error ("multiple default labels in one switch");
cp_error_at ("this is the first default label", duplicate);
}
}
else if (success == 3)
warning ("case value out of range");
else if (success == 4)
warning ("empty range specified");
else if (success == 5)
{
if (end)
error ("case label within scope of cleanup or variable array");
else
cp_error ("case label `%E' within scope of cleanup or variable array", start);
}
}
if (start)
define_case_label (label);
else
define_case_label (NULL_TREE);
}

View File

@ -52,8 +52,6 @@ void expand_member_init ();
void expand_aggr_init ();
static void expand_aggr_init_1 ();
static void expand_recursive_init_1 ();
static void expand_recursive_init ();
static void expand_virtual_init PROTO((tree, tree));
tree expand_vec_init ();
@ -70,7 +68,7 @@ static tree minus_one;
/* Set up local variable for this file. MUST BE CALLED AFTER
INIT_DECL_PROCESSING. */
tree BI_header_type, BI_header_size;
static tree BI_header_type, BI_header_size;
void init_init_processing ()
{
@ -257,9 +255,8 @@ static tree
sort_member_init (t)
tree t;
{
tree x, member, name, field, init;
tree x, member, name, field;
tree init_list = NULL_TREE;
tree fields_to_unmark = NULL_TREE;
int last_pos = 0;
tree last_field;
@ -281,6 +278,8 @@ sort_member_init (t)
name = TREE_PURPOSE (x);
#if 0
/* This happens in templates, since the IDENTIFIER is replaced
with the COMPONENT_REF in tsubst_expr. */
field = (TREE_CODE (name) == COMPONENT_REF
? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name));
#else
@ -520,9 +519,7 @@ emit_base_init (t, immediately)
tree t;
int immediately;
{
extern tree in_charge_identifier;
tree member, x;
tree member;
tree mem_init_list;
tree rbase_init_list, vbase_init_list;
tree t_binfo = TYPE_BINFO (t);
@ -571,7 +568,6 @@ emit_base_init (t, immediately)
/* Now, perform initialization of non-virtual base classes. */
for (i = 0; i < n_baseclasses; i++)
{
tree base = current_class_decl;
tree base_binfo = TREE_VEC_ELT (binfos, i);
tree init = void_list_node;
@ -653,10 +649,15 @@ emit_base_init (t, immediately)
init = TREE_VALUE (mem_init_list);
from_init_list = 1;
#if 0
if (TREE_CODE (name) == COMPONENT_REF)
name = DECL_NAME (TREE_OPERAND (name, 1));
#else
/* Also see if it's ever a COMPONENT_REF here. If it is, we
need to do `expand_assignment (name, init, 0, 0);' and
a continue. */
my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349);
#endif
}
else
{
@ -993,7 +994,7 @@ expand_member_init (exp, name, init)
else
{
if (basetype != type
&& ! binfo_member (basetype, TYPE_BINFO (type))
&& ! vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type))
&& ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
{
if (IDENTIFIER_CLASS_VALUE (name))
@ -1783,6 +1784,9 @@ build_offset_ref (type, name)
tree basetypes = NULL_TREE;
int dtor = 0;
if (current_template_parms)
return build_min_nt (SCOPE_REF, type, name);
/* Handle namespace names fully here. */
if (TREE_CODE (type) == IDENTIFIER_NODE
&& get_aggr_from_typedef (type, 0) == 0)
@ -1813,7 +1817,10 @@ build_offset_ref (type, name)
if (TYPE_SIZE (type) == 0)
{
t = IDENTIFIER_CLASS_VALUE (name);
if (type == current_class_type)
t = IDENTIFIER_CLASS_VALUE (name);
else
t = NULL_TREE;
if (t == 0)
{
cp_error ("incomplete type `%T' does not have member `%D'", type,
@ -2190,12 +2197,12 @@ is_friend (type, supplicant)
if (name == TREE_PURPOSE (list))
{
tree friends = TREE_VALUE (list);
name = DECL_ASSEMBLER_NAME (supplicant);
for (; friends ; friends = TREE_CHAIN (friends))
{
if (ctype == TREE_PURPOSE (friends))
return 1;
if (name == DECL_ASSEMBLER_NAME (TREE_VALUE (friends)))
if (comptypes (TREE_TYPE (supplicant),
TREE_TYPE (TREE_VALUE (friends)), 1))
return 1;
}
break;
@ -2401,10 +2408,11 @@ make_friend_class (type, friend_type)
QUALS say what special qualifies should apply to the object
pointed to by `this'. */
tree
do_friend (ctype, declarator, decl, parmdecls, flags, quals)
do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
tree ctype, declarator, decl, parmdecls;
enum overload_flags flags;
tree quals;
int funcdef_flag;
{
/* Every decl that gets here is a friend of something. */
DECL_FRIEND_P (decl) = 1;
@ -2424,7 +2432,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
/* This will set up DECL_ARGUMENTS for us. */
grokclassfn (ctype, cname, decl, flags, quals);
if (TYPE_SIZE (ctype) != 0)
check_classfn (ctype, cname, decl);
check_classfn (ctype, decl);
if (TREE_TYPE (decl) != error_mark_node)
{
@ -2492,7 +2500,8 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
= build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
DECL_ARGUMENTS (decl) = parmdecls;
DECL_CLASS_CONTEXT (decl) = current_class_type;
if (funcdef_flag)
DECL_CLASS_CONTEXT (decl) = current_class_type;
/* We can call pushdecl here, because the TREE_CHAIN of this
FUNCTION_DECL is not needed for other purposes. */
@ -2639,6 +2648,11 @@ build_new (placement, decl, init, use_global_new)
{
if (this_nelts == NULL_TREE)
error ("new of array type fails to specify size");
else if (current_template_parms)
{
nelts = this_nelts;
absdcl = TREE_OPERAND (absdcl, 0);
}
else
{
this_nelts = save_expr (convert (sizetype, this_nelts));
@ -2704,6 +2718,21 @@ build_new (placement, decl, init, use_global_new)
decl = TYPE_NAME (type);
}
if (current_template_parms)
{
tree t;
if (has_array)
t = min_tree_cons (min_tree_cons (NULL_TREE, type, NULL_TREE),
build_min_nt (ARRAY_REF, NULL_TREE, nelts),
NULL_TREE);
else
t = type;
rval = build_min_nt (NEW_EXPR, placement, t, init);
NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
return rval;
}
/* ``A reference cannot be created by the new operator. A reference
is not an object (8.2.2, 8.4.3), so a pointer to it could not be
returned by new.'' ARM 5.3.3 */
@ -2740,6 +2769,13 @@ build_new (placement, decl, init, use_global_new)
nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1);
true_type = TREE_TYPE (true_type);
}
if (TYPE_SIZE (complete_type (true_type)) == 0)
{
incomplete_type_error (0, true_type);
return error_mark_node;
}
if (has_array)
size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type),
nelts, 1));
@ -2752,12 +2788,6 @@ build_new (placement, decl, init, use_global_new)
return error_mark_node;
}
if (TYPE_SIZE (true_type) == 0)
{
incomplete_type_error (0, true_type);
return error_mark_node;
}
if (TYPE_LANG_SPECIFIC (true_type)
&& CLASSTYPE_ABSTRACT_VIRTUALS (true_type))
{
@ -3473,7 +3503,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TREE_CODE (type) == POINTER_TYPE)
{
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
if (TYPE_SIZE (type) == 0)
if (TYPE_SIZE (complete_type (type)) == 0)
{
incomplete_type_error (0, type);
return error_mark_node;
@ -3505,7 +3535,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
return error_mark_node;
}
return build_vec_delete (addr, array_type_nelts (type),
c_sizeof_nowarn (TREE_TYPE (type)),
auto_delete, integer_two_node,
use_global_delete);
}
@ -3718,12 +3747,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|| (TREE_VIA_VIRTUAL (base_binfo) == 0
&& ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))))
{
tree virtual_size;
/* This is probably wrong. It should be the size of the virtual
object being deleted. */
virtual_size = c_sizeof_nowarn (type);
cond = build (COND_EXPR, void_type_node,
build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node),
build_builtin_call (void_type_node, BID,
@ -3834,9 +3857,9 @@ build_vbase_delete (type, decl)
confirm the size, and trap if the numbers differ; not clear that it'd
be worth bothering.) */
tree
build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
build_vec_delete (base, maxindex, auto_delete_vec, auto_delete,
use_global_delete)
tree base, maxindex, elt_size;
tree base, maxindex;
tree auto_delete_vec, auto_delete;
int use_global_delete;
{

View File

@ -47,12 +47,11 @@ Boston, MA 02111-1307, USA. */
#ifndef errno
extern int errno; /* needed for VAX. */
#endif
extern jmp_buf toplevel;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
extern struct obstack *expression_obstack, permanent_obstack;
extern struct obstack permanent_obstack;
extern struct obstack *current_obstack, *saveable_obstack;
extern double atof ();
@ -68,20 +67,11 @@ extern char *get_directive_line (); /* In c-common.c */
extern char *index ();
extern char *rindex ();
void extract_interface_info ();
void yyerror ();
/* This obstack is needed to hold text. It is not safe to use
TOKEN_BUFFER because `check_newline' calls `yylex'. */
struct obstack inline_text_obstack;
static char *inline_text_firstobj;
/* This obstack is used to hold information about methods to be
synthesized. It should go away when synthesized methods are handled
properly (i.e. only when needed). */
struct obstack synth_obstack;
static char *synth_firstobj;
int end_of_file;
@ -136,16 +126,8 @@ static tree get_time_identifier ();
static tree filename_times;
static tree this_filename_time;
/* For implementing #pragma unit. */
tree current_unit_name;
tree current_unit_language;
/* Array for holding counts of the numbers of tokens seen. */
extern int *token_count;
/* Textual definition used for default functions. */
static void default_copy_constructor_body ();
static void default_assign_ref_body ();
/* Return something to represent absolute declarators containing a *.
TARGET is the absolute declarator that the * contains.
@ -399,6 +381,8 @@ reinit_lang_specific ()
reinit_search_statistics ();
}
int *init_parse ();
void
init_lex ()
{
@ -571,9 +555,6 @@ init_lex ()
init_method ();
init_error ();
gcc_obstack_init (&inline_text_obstack);
inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
gcc_obstack_init (&synth_obstack);
synth_firstobj = (char *) obstack_alloc (&synth_obstack, 0);
/* Start it at 0, because check_newline is called at the very beginning
and will increment it to 1. */
@ -877,7 +858,10 @@ yyprint (file, yychar, yylval)
}
}
#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
static int *reduce_count;
#endif
int *token_count;
#if 0
@ -1037,8 +1021,7 @@ extract_interface_info ()
fileinfo = get_time_identifier (input_filename);
fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
interface_only = TREE_INT_CST_LOW (fileinfo);
if (!processing_template_defn || flag_external_templates)
interface_unknown = TREE_INT_CST_HIGH (fileinfo);
interface_unknown = TREE_INT_CST_HIGH (fileinfo);
}
/* Return nonzero if S is not considered part of an
@ -1118,6 +1101,7 @@ void
do_pending_inlines ()
{
struct pending_inline *t;
tree context;
/* Oops, we're still dealing with the last batch. */
if (yychar == PRE_PARSED_FUNCTION_DECL)
@ -1144,10 +1128,9 @@ do_pending_inlines ()
return;
/* Now start processing the first inline function. */
my_friendly_assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE),
226);
if (t->parm_vec)
push_template_decls (t->parm_vec, t->bindings, 0);
context = decl_function_context (t->fndecl);
if (context)
push_cp_function_context (context);
if (t->len > 0)
{
feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
@ -1169,13 +1152,6 @@ do_pending_inlines ()
/* Pass back a handle on the rest of the inline functions, so that they
can be processed later. */
yylval.ttype = build_tree_list ((tree) t, t->fndecl);
#if 0
if (flag_default_inline && t->fndecl
/* If we're working from a template, don't change
the `inline' state. */
&& t->parm_vec == NULL_TREE)
DECL_INLINE (t->fndecl) = 1;
#endif
DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
}
@ -1189,11 +1165,11 @@ void
process_next_inline (t)
tree t;
{
tree context;
struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE),
227);
if (i->parm_vec)
pop_template_decls (i->parm_vec, i->bindings, 0);
context = decl_function_context (i->fndecl);
if (context)
pop_cp_function_context (context);
i = i->next;
if (yychar == YYEMPTY)
yychar = yylex ();
@ -1215,22 +1191,14 @@ process_next_inline (t)
to_be_restored = 0;
if (i && i->fndecl != NULL_TREE)
{
my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE),
228);
if (i->parm_vec)
push_template_decls (i->parm_vec, i->bindings, 0);
context = decl_function_context (i->fndecl);
if (context)
push_cp_function_context (context);
feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0);
lineno = i->lineno;
input_filename = i->filename;
yychar = PRE_PARSED_FUNCTION_DECL;
yylval.ttype = build_tree_list ((tree) i, i->fndecl);
#if 0
if (flag_default_inline
/* If we're working from a template, don't change
the `inline' state. */
&& i->parm_vec == NULL_TREE)
DECL_INLINE (i->fndecl) = 1;
#endif
DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
}
if (i)
@ -1388,99 +1356,19 @@ yyungetc (ch, rescan)
/* This function stores away the text for an inline function that should
be processed later. It decides how much later, and may need to move
the info between obstacks; therefore, the caller should not refer to
the T parameter after calling this function.
This function also stores the list of template-parameter bindings that
will be needed for expanding the template, if any. */
the T parameter after calling this function. */
static void
store_pending_inline (decl, t)
tree decl;
struct pending_inline *t;
{
extern int processing_template_defn;
int delay_to_eof = 0;
struct pending_inline **inlines;
t->fndecl = decl;
/* Default: compile right away, and no extra bindings are needed. */
t->parm_vec = t->bindings = 0;
if (processing_template_defn)
{
tree type = current_class_type;
/* Assumption: In this (possibly) nested class sequence, only
one name will have template parms. */
while (type && TREE_CODE_CLASS (TREE_CODE (type)) == 't')
{
tree decl = TYPE_NAME (type);
tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl));
if (tmpl)
{
t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec;
t->bindings = TREE_VALUE (tmpl);
}
type = DECL_CONTEXT (decl);
}
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
|| TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
{
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
my_friendly_assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type,
233);
/* Inline functions can be compiled immediately. Other functions
will be output separately, so if we're in interface-only mode,
punt them now, or output them now if we're doing implementations
and we know no overrides will exist. Otherwise, we delay until
end-of-file, to see if the definition is really required. */
if (DECL_THIS_INLINE (decl))
/* delay_to_eof == 0 */;
else if (current_class_type && !interface_unknown)
{
if (interface_only)
{
#if 0
print_node_brief (stderr, "\ndiscarding text for ", decl, 0);
#endif
if (t->can_free)
obstack_free (&inline_text_obstack, t->buf);
DECL_PENDING_INLINE_INFO (decl) = 0;
return;
}
}
/* Don't delay the processing of virtual functions. */
else if (DECL_VINDEX (decl) == NULL_TREE)
delay_to_eof = 1;
}
else
my_friendly_abort (58);
}
if (delay_to_eof)
{
extern struct pending_inline *pending_template_expansions;
if (t->can_free)
{
char *free_to = t->buf;
t->buf = (char *) obstack_copy (&permanent_obstack, t->buf,
t->len + 1);
t = (struct pending_inline *) obstack_copy (&permanent_obstack,
(char *)t, sizeof (*t));
obstack_free (&inline_text_obstack, free_to);
}
inlines = &pending_template_expansions;
t->can_free = 0;
}
else
{
inlines = &pending_inlines;
DECL_PENDING_INLINE_INFO (decl) = t;
}
DECL_PENDING_INLINE_INFO (decl) = t;
/* Because we use obstacks, we must process these in precise order. */
t->next = *inlines;
*inlines = t;
t->next = pending_inlines;
pending_inlines = t;
}
void reinit_parse_for_block ();
@ -1494,7 +1382,7 @@ reinit_parse_for_method (yychar, decl)
int starting_lineno = lineno;
char *starting_filename = input_filename;
reinit_parse_for_block (yychar, &inline_text_obstack, 0);
reinit_parse_for_block (yychar, &inline_text_obstack);
len = obstack_object_size (&inline_text_obstack);
current_base_init_list = NULL_TREE;
@ -1523,24 +1411,22 @@ reinit_parse_for_method (yychar, decl)
t->len = len;
t->can_free = 1;
t->deja_vu = 0;
#if 0
if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
warn_if_unknown_interface (decl);
#endif
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
store_pending_inline (decl, t);
}
}
/* Consume a block -- actually, a method or template definition beginning
with `:' or `{' -- and save it away on the specified obstack.
/* Consume a block -- actually, a method beginning
with `:' or `{' -- and save it away on the specified obstack. */
Argument IS_TEMPLATE indicates which set of error messages should be
output if something goes wrong. This should really be cleaned up somehow,
without loss of clarity. */
void
reinit_parse_for_block (pyychar, obstackp, is_template)
reinit_parse_for_block (pyychar, obstackp)
int pyychar;
struct obstack *obstackp;
int is_template;
{
register int c = 0;
int blev = 1;
@ -1560,13 +1446,13 @@ reinit_parse_for_block (pyychar, obstackp, is_template)
look_for_lbrac = 1;
blev = 0;
}
else if (pyychar == RETURN && !is_template)
else if (pyychar == RETURN)
{
obstack_grow (obstackp, "return", 6);
look_for_lbrac = 1;
blev = 0;
}
else if (pyychar == TRY && !is_template)
else if (pyychar == TRY)
{
obstack_grow (obstackp, "try", 3);
look_for_lbrac = 1;
@ -1574,9 +1460,7 @@ reinit_parse_for_block (pyychar, obstackp, is_template)
}
else
{
yyerror (is_template
? "parse error in template specification"
: "parse error in method specification");
yyerror ("parse error in method specification");
obstack_1grow (obstackp, '{');
}
@ -1673,9 +1557,7 @@ reinit_parse_for_block (pyychar, obstackp, is_template)
{
if (look_for_lbrac)
{
error (is_template
? "template body missing"
: "function body for constructor missing");
error ("function body for constructor missing");
obstack_1grow (obstackp, '{');
obstack_1grow (obstackp, '}');
len += 2;
@ -1721,13 +1603,10 @@ cons_up_default_function (type, full_name, kind)
int kind;
{
extern tree void_list_node;
char *func_buf = NULL;
int func_len = 0;
tree declspecs = NULL_TREE;
tree fn, args;
tree argtype;
int retref = 0;
int complex = 0;
tree name = constructor_name (full_name);
switch (kind)
@ -1744,7 +1623,6 @@ cons_up_default_function (type, full_name, kind)
case 2:
/* Default constructor. */
args = void_list_node;
complex = TYPE_NEEDS_CONSTRUCTING (type);
break;
case 3:
@ -1758,7 +1636,6 @@ cons_up_default_function (type, full_name, kind)
build_tree_list (hash_tree_chain (argtype, NULL_TREE),
get_identifier ("_ctor_arg")),
void_list_node);
complex = TYPE_HAS_COMPLEX_INIT_REF (type);
break;
case 5:
@ -1775,7 +1652,6 @@ cons_up_default_function (type, full_name, kind)
build_tree_list (hash_tree_chain (argtype, NULL_TREE),
get_identifier ("_ctor_arg")),
void_list_node);
complex = TYPE_HAS_COMPLEX_ASSIGN_REF (type);
break;
default:
@ -1799,11 +1675,13 @@ cons_up_default_function (type, full_name, kind)
if (fn == void_type_node)
return fn;
#if 0
if (processing_template_defn)
{
SET_DECL_IMPLICIT_INSTANTIATION (fn);
repo_template_used (fn);
}
#endif
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
@ -1814,27 +1692,7 @@ cons_up_default_function (type, full_name, kind)
else
DECL_NOT_REALLY_EXTERN (fn) = 1;
#if 0
/* When on-the-fly synthesis works properly, remove the second and third
conditions here. */
if (flag_keep_inline_functions
#if 0
|| ! flag_no_inline
|| complex
#endif
|| ! DECL_EXTERNAL (fn))
{
struct pending_inline *t;
t = (struct pending_inline *)
obstack_alloc (&synth_obstack, sizeof (struct pending_inline));
t->lineno = -kind;
t->can_free = 0;
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
store_pending_inline (fn, t);
}
else
#endif
mark_inline_for_output (fn);
mark_inline_for_output (fn);
#ifdef DEBUG_DEFAULT_FUNCTIONS
{ char *fn_type = NULL;
@ -2090,8 +1948,6 @@ check_newline ()
error ("invalid #pragma unit");
goto skipline;
}
current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));
current_unit_language = current_lang_name;
if (nextchar < 0)
nextchar = getch ();
c = nextchar;
@ -2810,9 +2666,11 @@ int
identifier_type (decl)
tree decl;
{
if (TREE_CODE (decl) == TEMPLATE_DECL
&& DECL_TEMPLATE_IS_CLASS (decl))
return PTYPENAME;
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
return PTYPENAME;
}
if (TREE_CODE (decl) == NAMESPACE_DECL)
return NSNAME;
if (TREE_CODE (decl) != TYPE_DECL)
@ -2841,22 +2699,24 @@ see_typename ()
}
tree
do_identifier (token)
do_identifier (token, parsing)
register tree token;
int parsing;
{
register tree id = lastiddecl;
register tree id;
if (IDENTIFIER_OPNAME_P (token))
if (! parsing || IDENTIFIER_OPNAME_P (token))
id = lookup_name (token, 0);
else
id = lastiddecl;
if (yychar == YYEMPTY)
if (parsing && yychar == YYEMPTY)
yychar = yylex ();
/* Scope class declarations before global
declarations. */
if (id == IDENTIFIER_GLOBAL_VALUE (token)
&& current_class_type != 0
&& TYPE_SIZE (current_class_type) == 0
&& TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE)
&& TYPE_SIZE (current_class_type) == 0)
{
/* Could be from one of the base classes. */
tree field = lookup_field (current_class_type, token, 1, 0);
@ -2898,13 +2758,15 @@ do_identifier (token)
return id;
}
if (IDENTIFIER_OPNAME_P (token))
if (current_template_parms)
return build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
else if (IDENTIFIER_OPNAME_P (token))
{
if (token != ansi_opname[ERROR_MARK])
cp_error ("operator %O not defined", token);
id = error_mark_node;
}
else if (yychar == '(' || yychar == LEFT_RIGHT)
else if (parsing && (yychar == '(' || yychar == LEFT_RIGHT))
{
id = implicitly_declare (token);
}
@ -2986,10 +2848,88 @@ do_identifier (token)
cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */
}
id = DECL_INITIAL (id);
if (! current_template_parms
|| (DECL_INITIAL (id)
&& TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
id = DECL_INITIAL (id);
}
else
id = hack_identifier (id, token, yychar);
id = hack_identifier (id, token);
if (current_template_parms)
{
if (is_overloaded_fn (id))
{
tree t = build_min (LOOKUP_EXPR, unknown_type_node,
token, get_first_fn (id));
if (id != IDENTIFIER_GLOBAL_VALUE (token))
TREE_OPERAND (t, 1) = error_mark_node;
id = t;
}
else if (! TREE_PERMANENT (id) || TREE_CODE (id) == PARM_DECL
|| TREE_CODE (id) == USING_DECL)
id = build_min (LOOKUP_EXPR, TREE_TYPE (id), token, error_mark_node);
/* else just use the decl */
}
return id;
}
tree
do_scoped_id (token, parsing)
tree token;
int parsing;
{
tree id = IDENTIFIER_GLOBAL_VALUE (token);
if (parsing && yychar == YYEMPTY)
yychar = yylex ();
if (! id)
{
if (current_template_parms)
{
id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
LOOKUP_EXPR_GLOBAL (id) = 1;
return id;
}
if (parsing && yychar == '(' || yychar == LEFT_RIGHT)
id = implicitly_declare (token);
else
{
if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node)
error ("undeclared variable `%s' (first use here)",
IDENTIFIER_POINTER (token));
id = error_mark_node;
/* Prevent repeated error messages. */
IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
}
}
else
{
if (TREE_CODE (id) == ADDR_EXPR)
mark_used (TREE_OPERAND (id, 0));
else if (TREE_CODE (id) != TREE_LIST)
mark_used (id);
}
if (TREE_CODE (id) == CONST_DECL && ! current_template_parms)
{
/* XXX CHS - should we set TREE_USED of the constant? */
id = DECL_INITIAL (id);
/* This is to prevent an enum whose value is 0
from being considered a null pointer constant. */
id = build1 (NOP_EXPR, TREE_TYPE (id), id);
TREE_CONSTANT (id) = 1;
}
if (current_template_parms)
{
if (is_overloaded_fn (id))
{
id = build_min (LOOKUP_EXPR, unknown_type_node,
token, get_first_fn (id));
LOOKUP_EXPR_GLOBAL (id) = 1;
}
/* else just use the decl */
}
return id;
}
@ -3091,9 +3031,6 @@ real_yylex ()
value = END_OF_SAVED_INPUT;
else if (linemode)
value = END_OF_LINE;
else if (do_pending_expansions ())
/* this will set yychar for us */
return yychar;
else
value = ENDFILE;
break;
@ -4141,12 +4078,20 @@ real_yylex ()
len = p - token_buffer - 1;
}
#endif
if (current_template_parms)
push_obstacks (&permanent_obstack, &permanent_obstack);
yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
if (current_template_parms)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
}
else
{
if (current_template_parms)
push_obstacks (&permanent_obstack, &permanent_obstack);
yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
if (current_template_parms)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = char_array_type_node;
}
@ -4363,15 +4308,10 @@ is_rid (t)
return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
}
typedef enum
{
d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
id_kind, op_id_kind, perm_list_kind, temp_list_kind,
vec_kind, x_kind, lang_decl, lang_type, all_kinds
} tree_node_kind;
#ifdef GATHER_STATISTICS
extern int tree_node_counts[];
extern int tree_node_sizes[];
extern char *tree_node_kind_names[];
#endif
/* Place to save freed lang_decls which were allocated on the
permanent_obstack. @@ Not currently used. */
@ -4490,6 +4430,9 @@ copy_lang_decl (node)
int size;
int *pi;
if (! DECL_LANG_SPECIFIC (node))
return;
if (TREE_CODE (node) == FIELD_DECL)
size = sizeof (struct lang_decl_flags);
else

View File

@ -346,10 +346,7 @@ build_overload_nested_name (decl)
OB_PUTCP (label);
}
else /* TYPE_DECL */
{
tree name = DECL_NAME (decl);
build_overload_identifier (name);
}
build_overload_identifier (decl);
}
/* Encoding for an INTEGER_CST value. */
@ -357,6 +354,27 @@ static void
build_overload_int (value)
tree value;
{
if (TREE_CODE (value) == TEMPLATE_CONST_PARM)
{
OB_PUTC ('Y');
if (TEMPLATE_CONST_IDX (value) > 9)
OB_PUTC ('_');
icat (TEMPLATE_CONST_IDX (value));
if (TEMPLATE_CONST_IDX (value) > 9)
OB_PUTC ('_');
return;
}
else if (uses_template_parms (value))
/* We don't ever want this output, but it's inconvenient not to
be able to build the string. This should cause assembler
errors we'll notice. */
{
static int n;
sprintf (digit_buffer, " *%d", n++);
OB_PUTCP (digit_buffer);
return;
}
my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
{
@ -544,11 +562,14 @@ static void
build_overload_identifier (name)
tree name;
{
if (IDENTIFIER_TEMPLATE (name))
if (TREE_CODE (name) == TYPE_DECL
&& IS_AGGR_TYPE (TREE_TYPE (name))
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))))
{
tree template, parmlist, arglist, tname;
int i, nparms;
template = IDENTIFIER_TEMPLATE (name);
template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name));
arglist = TREE_VALUE (template);
template = TREE_PURPOSE (template);
tname = DECL_NAME (template);
@ -580,6 +601,8 @@ build_overload_identifier (name)
}
else
{
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
if (numeric_output_need_bar)
{
OB_PUTC ('_');
@ -873,8 +896,8 @@ build_overload_name (parmtypes, begin, end)
numeric_output_need_bar = 0;
build_overload_nested_name (TYPE_MAIN_DECL (parmtype));
}
else
build_overload_identifier (name);
else
build_overload_identifier (TYPE_MAIN_DECL (parmtype));
break;
}
@ -884,8 +907,15 @@ build_overload_name (parmtypes, begin, end)
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_CONST_PARM:
case UNINSTANTIATED_P_TYPE:
OB_PUTC ('X');
if (TEMPLATE_TYPE_IDX (parmtype) > 9)
OB_PUTC ('_');
icat (TEMPLATE_TYPE_IDX (parmtype));
if (TEMPLATE_TYPE_IDX (parmtype) > 9)
OB_PUTC ('_');
break;
case TYPENAME_TYPE:
/* We don't ever want this output, but it's inconvenient not to
be able to build the string. This should cause assembler
errors we'll notice. */
@ -1468,7 +1498,6 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
yychar is the pending input character (suitably encoded :-).
As a last ditch, try to look up the name as a label and return that
address.
@ -1478,11 +1507,10 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
compiler faster). */
tree
hack_identifier (value, name, yychar)
hack_identifier (value, name)
tree value, name;
int yychar;
{
tree type;
tree type, context;
if (TREE_CODE (value) == ERROR_MARK)
{
@ -1562,6 +1590,20 @@ hack_identifier (value, name, yychar)
else
mark_used (value);
if (pedantic
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL))
{
tree context = decl_function_context (value);
if (context != NULL_TREE && context != current_function_decl
&& ! TREE_STATIC (value))
{
cp_pedwarn ("use of %s from containing function",
(TREE_CODE (value) == VAR_DECL
? "`auto' variable" : "parameter"));
cp_pedwarn_at (" `%#D' declared here", value);
}
}
if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
{
if (DECL_LANG_SPECIFIC (value)
@ -1605,7 +1647,7 @@ hack_identifier (value, name, yychar)
return value;
}
if (TREE_CODE (type) == REFERENCE_TYPE)
if (TREE_CODE (type) == REFERENCE_TYPE && ! current_template_parms)
{
my_friendly_assert (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL
@ -2217,9 +2259,6 @@ do_build_assign_ref (fndecl)
pop_momentary ();
}
void push_cp_function_context ();
void pop_cp_function_context ();
void
synthesize_method (fndecl)
tree fndecl;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -72,13 +72,6 @@ print_lang_type (file, node, indent)
return;
}
if (TREE_CODE (node) == UNINSTANTIATED_P_TYPE)
{
print_node (file, "template", UPT_TEMPLATE (node), indent + 4);
print_node (file, "parameters", UPT_PARMS (node), indent + 4);
return;
}
if (! (TREE_CODE (node) == RECORD_TYPE
|| TREE_CODE (node) == UNION_TYPE))
return;

View File

@ -49,6 +49,7 @@ extern struct obstack permanent_obstack;
#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
#if 0
/* Record the flags used to compile this translation unit. */
void
@ -82,8 +83,9 @@ void
repo_class_defined (t)
tree t;
{}
#endif
tree
static tree
repo_get_id (t)
tree t;
{
@ -120,7 +122,7 @@ repo_template_used (t)
else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
{
if (IDENTIFIER_REPO_CHOSEN (id))
mark_function_instantiated (t, 0);
mark_decl_instantiated (t, 0);
}
else
my_friendly_abort (1);
@ -132,9 +134,10 @@ repo_template_used (t)
}
}
#if 0
/* Note that the vtable for a class has been used, and offer to emit it. */
void
static void
repo_vtable_used (t)
tree t;
{
@ -172,6 +175,7 @@ repo_tinfo_used (ti)
tree ti;
{
}
#endif
void
repo_template_instantiated (t, extern_p)
@ -246,7 +250,7 @@ static void
open_repo_file (filename)
char *filename;
{
register char *p, *q;
register char *p;
char *s = get_base_filename (filename);
if (s == NULL)

View File

@ -37,7 +37,7 @@ extern tree combine_strings PROTO((tree));
/* Given the expression EXP of type `class *', return the head
of the object pointed to by EXP. */
tree
static tree
build_headof (exp)
tree exp;
{
@ -156,7 +156,7 @@ get_typeid (type)
/* Get a bad_cast node for the program to throw...
See libstdc++::exception{,.cc} for __bad_cast_object */
tree
static tree
get_bad_cast_node ()
{
static tree t;
@ -179,7 +179,6 @@ build_dynamic_cast (type, expr)
enum tree_code tc = TREE_CODE (type);
tree exprtype = TREE_TYPE (expr);
enum tree_code ec = TREE_CODE (exprtype);
tree retval;
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
@ -268,7 +267,7 @@ build_dynamic_cast (type, expr)
else
{
tree retval;
tree result, td1, td2, elems, tmp1, expr1;
tree result, td1, td2, elems, expr1;
/* If we got here, we can't convert statically. Therefore,
dynamic_cast<D&>(b) (b an object) cannot succeed. */
@ -462,7 +461,7 @@ static tree
build_user_desc (tdecl)
tree tdecl;
{
tree elems, name_string, t;
tree elems, name_string;
tree tname = DECL_NAME (tdecl);
name_string = combine_strings (build_string
@ -481,13 +480,15 @@ build_class_desc (tdecl, type)
tree name_string;
int i = CLASSTYPE_N_BASECLASSES (type);
int n_base = i;
int base_cnt = 0;
tree binfos = TYPE_BINFO_BASETYPES (type);
#if 0
/* See code below that used these. */
tree vb = CLASSTYPE_VBASECLASSES (type);
int n_base = i;
#endif
tree base, elems, access, offset, isvir;
tree base_list, off_list, acc_list, isvir_list;
tree t;
static tree acc_pub = NULL_TREE;
static tree acc_pro = NULL_TREE;
static tree acc_pri = NULL_TREE;
@ -516,7 +517,6 @@ build_class_desc (tdecl, type)
tree t = BINFO_TYPE (binfo);
char *name;
tree field;
int off;
name = (char *) alloca (TYPE_NAME_LENGTH (t)+sizeof (VBASE_NAME)+1);
sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (t));
@ -659,9 +659,8 @@ build_func_desc (tdecl)
/* Build an initializer for a __ptmf_type_info node. */
static tree
build_ptmf_desc (tdecl, type)
build_ptmf_desc (tdecl)
tree tdecl;
tree type;
{
tree elems, name_string;
tree tname = DECL_NAME (tdecl);
@ -711,7 +710,7 @@ add_uninstantiated_desc (type)
objects, we do that here. Return the type to link against if such a
link exists, otherwise just return TYPE. */
tree
static tree
get_def_to_follow (type)
tree type;
{
@ -735,10 +734,8 @@ build_t_desc (type, definition)
tree type;
int definition;
{
tree tdecl;
tree tname, name_string;
tree elems;
tree t, tt, taggr;
tree tdecl, tname;
tree t, taggr;
if (__ptmd_desc_type_node == NULL_TREE)
{
@ -841,13 +838,9 @@ build_t_desc (type, definition)
else if (IS_AGGR_TYPE (type))
{
if (TYPE_PTRMEMFUNC_P (type))
{
t = build_ptmf_desc (tdecl, type);
}
t = build_ptmf_desc (tdecl);
else
{
t = build_class_desc (tdecl, type);
}
t = build_class_desc (tdecl, type);
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
t = build_func_desc (tdecl);

View File

@ -34,7 +34,6 @@ Boston, MA 02111-1307, USA. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
void init_search ();
extern struct obstack *current_obstack;
extern tree abort_fndecl;
@ -82,8 +81,7 @@ static void dfs_unmark ();
static void dfs_init_vbase_pointers ();
static tree vbase_types;
static tree vbase_decl, vbase_decl_ptr;
static tree vbase_decl_ptr_intermediate;
static tree vbase_decl_ptr_intermediate, vbase_decl_ptr;
static tree vbase_init_result;
/* Allocate a level of searching. */
@ -141,12 +139,14 @@ extern int flag_memoize_lookups, flag_save_memoized_contexts;
static int my_memoized_entry_counter;
static int memoized_fast_finds[2], memoized_adds[2], memoized_fast_rejects[2];
static int memoized_fields_searched[2];
#ifdef GATHER_STATISTICS
static int n_fields_searched;
static int n_calls_lookup_field, n_calls_lookup_field_1;
static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;
static int n_calls_get_base_type;
static int n_outer_fields_searched;
static int n_contexts_saved;
#endif
/* Local variables to help save memoization contexts. */
static tree prev_type_memoized;
@ -249,7 +249,7 @@ my_new_memoized_entry (chain)
/* Make an entry in the memoized table for type TYPE
that the entry for NAME is FIELD. */
tree
static tree
make_memoized_table_entry (type, name, function_p)
tree type, name;
int function_p;
@ -492,10 +492,10 @@ get_binfo (parent, binfo, protect)
/* This is the newer depth first get_base_distance routine. */
static int
get_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,
get_base_distance_recursive (binfo, depth, is_private, rval,
rval_private_ptr, new_binfo_ptr, parent, path_ptr,
protect, via_virtual_ptr, via_virtual)
tree binfo, basetype_path, *new_binfo_ptr, parent, *path_ptr;
tree binfo, *new_binfo_ptr, parent, *path_ptr;
int *rval_private_ptr, depth, is_private, rval, protect, *via_virtual_ptr,
via_virtual;
{
@ -569,7 +569,7 @@ get_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,
was = WATCH_VALUES (rval, *via_virtual_ptr);
rval = get_base_distance_recursive (base_binfo, depth, via_private,
binfo, rval, rval_private_ptr,
rval, rval_private_ptr,
new_binfo_ptr, parent, path_ptr,
protect, via_virtual_ptr,
this_virtual);
@ -619,8 +619,11 @@ get_base_distance (parent, binfo, protect, path_ptr)
int via_virtual;
int watch_access = protect;
/* Should we be completing types here? */
if (TREE_CODE (parent) != TREE_VEC)
parent = TYPE_MAIN_VARIANT (parent);
parent = complete_type (TYPE_MAIN_VARIANT (parent));
else
complete_type (TREE_TYPE (parent));
if (TREE_CODE (binfo) == TREE_VEC)
type = BINFO_TYPE (binfo);
@ -647,7 +650,7 @@ get_base_distance (parent, binfo, protect, path_ptr)
if (path_ptr)
watch_access = 1;
rval = get_base_distance_recursive (binfo, 0, 0, NULL_TREE, -1,
rval = get_base_distance_recursive (binfo, 0, 0, -1,
&rval_private, &new_binfo, parent,
path_ptr, watch_access, &via_virtual, 0);
@ -721,6 +724,8 @@ lookup_field_1 (type, name)
if (TYPE_VIRTUAL_P (type))
return CLASSTYPE_VFIELD (type);
}
if (name == constructor_name (type))
return TYPE_STUB_DECL (type);
return NULL_TREE;
}
@ -1081,8 +1086,8 @@ lookup_field (xbasetype, name, protect, want_type)
}
else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
{
type = xbasetype;
basetype_path = TYPE_BINFO (xbasetype);
type = complete_type (xbasetype);
basetype_path = TYPE_BINFO (type);
BINFO_VIA_PUBLIC (basetype_path) = 1;
BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
}
@ -1132,7 +1137,10 @@ lookup_field (xbasetype, name, protect, want_type)
{
if (TREE_CODE (rval) != TYPE_DECL)
{
rval = purpose_member (name, CLASSTYPE_TAGS (type));
if (name == constructor_name (type))
rval = type;
else
rval = purpose_member (name, CLASSTYPE_TAGS (type));
if (rval)
rval = TYPE_MAIN_DECL (TREE_VALUE (rval));
}
@ -1314,7 +1322,10 @@ lookup_field (xbasetype, name, protect, want_type)
{
if (TREE_CODE (rval) != TYPE_DECL)
{
rval = purpose_member (name, CLASSTYPE_TAGS (type));
if (name == constructor_name (type))
rval = type;
else
rval = purpose_member (name, CLASSTYPE_TAGS (type));
if (rval)
rval = TYPE_MAIN_DECL (TREE_VALUE (rval));
}
@ -1577,7 +1588,7 @@ lookup_fnfields (basetype_path, name, complain)
binfo = basetype_path;
binfo_h = binfo;
type = BINFO_TYPE (basetype_path);
type = complete_type (BINFO_TYPE (basetype_path));
/* The memoization code is in need of maintenance. */
if (!find_all && CLASSTYPE_MTABLE_ENTRY (type))
@ -1826,7 +1837,7 @@ lookup_fnfields (basetype_path, name, complain)
QFN, if non-NULL, is a predicate dictating whether the type should
even be queued. */
HOST_WIDE_INT
static HOST_WIDE_INT
breadth_first_search (binfo, testfn, qfn)
tree binfo;
int (*testfn)();
@ -1932,7 +1943,8 @@ static tree get_virtual_destructor (binfo, i)
return 0;
}
int tree_has_any_destructor_p (binfo, i)
static int
tree_has_any_destructor_p (binfo, i)
tree binfo;
int i;
{
@ -2297,7 +2309,9 @@ dfs_walk (binfo, fn, qfn)
if (qfn == 0 || (*qfn)(base_binfo))
{
if (fn == dfs_init_vbase_pointers)
if (TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TYPE_PARM)
/* Pass */;
else if (fn == dfs_init_vbase_pointers)
{
/* When traversing an arbitrary MI hierarchy, we need to keep
a record of the path we took to get down to the final base
@ -2334,8 +2348,9 @@ dfs_walk (binfo, fn, qfn)
dfs_walk (base_binfo, fn, qfn);
vbase_decl_ptr_intermediate = saved_vbase_decl_ptr_intermediate;
} else
dfs_walk (base_binfo, fn, qfn);
}
else
dfs_walk (base_binfo, fn, qfn);
}
}
@ -2350,31 +2365,37 @@ static int unnumberedp (binfo) tree binfo;
static int markedp (binfo) tree binfo;
{ return BINFO_MARKED (binfo); }
static int bfs_markedp (binfo, i) tree binfo; int i;
{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
static int unmarkedp (binfo) tree binfo;
{ return BINFO_MARKED (binfo) == 0; }
#if 0
static int bfs_markedp (binfo, i) tree binfo; int i;
{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
static int bfs_unmarkedp (binfo, i) tree binfo; int i;
{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
static int marked_vtable_pathp (binfo) tree binfo;
{ return BINFO_VTABLE_PATH_MARKED (binfo); }
static int bfs_marked_vtable_pathp (binfo, i) tree binfo; int i;
{ return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); }
static int unmarked_vtable_pathp (binfo) tree binfo;
{ return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
static int bfs_unmarked_vtable_pathp (binfo, i) tree binfo; int i;
{ return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
static int marked_new_vtablep (binfo) tree binfo;
{ return BINFO_NEW_VTABLE_MARKED (binfo); }
static int bfs_marked_new_vtablep (binfo, i) tree binfo; int i;
{ return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); }
static int unmarked_new_vtablep (binfo) tree binfo;
{ return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
static int bfs_unmarked_new_vtablep (binfo, i) tree binfo; int i;
{ return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
#endif
static int marked_vtable_pathp (binfo) tree binfo;
{ return BINFO_VTABLE_PATH_MARKED (binfo); }
static int unmarked_vtable_pathp (binfo) tree binfo;
{ return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
static int marked_new_vtablep (binfo) tree binfo;
{ return BINFO_NEW_VTABLE_MARKED (binfo); }
static int unmarked_new_vtablep (binfo) tree binfo;
{ return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
#if 0
static int dfs_search_slot_nonempty_p (binfo) tree binfo;
{ return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
#endif
static int dfs_debug_unmarkedp (binfo) tree binfo;
{ return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; }
@ -2400,14 +2421,17 @@ dfs_unnumber (binfo)
BINFO_CID (binfo) = 0;
}
#if 0
static void
dfs_mark (binfo) tree binfo;
{ SET_BINFO_MARKED (binfo); }
#endif
static void
dfs_unmark (binfo) tree binfo;
{ CLEAR_BINFO_MARKED (binfo); }
#if 0
static void
dfs_mark_vtable_path (binfo) tree binfo;
{ SET_BINFO_VTABLE_PATH_MARKED (binfo); }
@ -2427,6 +2451,7 @@ dfs_unmark_new_vtable (binfo) tree binfo;
static void
dfs_clear_search_slot (binfo) tree binfo;
{ CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
#endif
static void
dfs_debug_mark (binfo)
@ -2571,9 +2596,7 @@ init_vbase_pointers (type, decl_ptr)
tree binfo = TYPE_BINFO (type);
flag_this_is_variable = -2;
vbase_types = CLASSTYPE_VBASECLASSES (type);
vbase_decl_ptr = decl_ptr;
vbase_decl = build_indirect_ref (decl_ptr, NULL_PTR);
vbase_decl_ptr_intermediate = vbase_decl_ptr;
vbase_decl_ptr = vbase_decl_ptr_intermediate = decl_ptr;
vbase_init_result = NULL_TREE;
dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp);
dfs_walk (binfo, dfs_init_vbase_pointers, marked_vtable_pathp);
@ -2800,7 +2823,7 @@ fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, ori
offsets are valid to store vtables. When zero, we must store new
vtables through virtual baseclass pointers.
We setup and use the globals: vbase_decl, vbase_decl_ptr, vbase_types
We setup and use the globals: vbase_decl_ptr, vbase_types
ICK! */
void
@ -2816,7 +2839,6 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
tree vbases = CLASSTYPE_VBASECLASSES (type);
vbase_types = vbases;
vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, NULL_PTR);
dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep);
@ -2840,7 +2862,8 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
if (flag_vtable_thunks)
{
/* We don't have dynamic thunks yet! So for now, just fail silently. */
/* We don't have dynamic thunks yet!
So for now, just fail silently. */
}
else
{
@ -3270,13 +3293,9 @@ void
push_class_decls (type)
tree type;
{
tree id;
struct obstack *ambient_obstack = current_obstack;
search_stack = push_search_level (search_stack, &search_obstack);
id = TYPE_IDENTIFIER (type);
/* Push class fields into CLASS_VALUE scope, and mark. */
dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
@ -3351,8 +3370,7 @@ unuse_fields (type)
}
void
pop_class_decls (type)
tree type;
pop_class_decls ()
{
/* We haven't pushed a search level when dealing with cached classes,
so we'd better not try to pop it. */
@ -3400,7 +3418,7 @@ init_search_processing ()
/* This gives us room to build our chains of basetypes,
whether or not we decide to memoize them. */
type_stack = push_type_level (0, &type_obstack);
type_stack = push_type_level ((struct stack_level *)0, &type_obstack);
_vptr_name = get_identifier ("_vptr");
}
@ -3416,12 +3434,14 @@ reinit_search_statistics ()
memoized_fast_rejects[1] = 0;
memoized_fields_searched[0] = 0;
memoized_fields_searched[1] = 0;
#ifdef GATHER_STATISTICS
n_fields_searched = 0;
n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
n_calls_get_base_type = 0;
n_outer_fields_searched = 0;
n_contexts_saved = 0;
#endif
}
static tree conversions;

View File

@ -534,7 +534,7 @@ build_signature_table_constructor (sig_ty, rhs)
{
error ("class `%s' does not contain a method conforming to `%s'",
TYPE_NAME_STRING (rhstype),
fndecl_as_string (NULL, sig_method, 1));
fndecl_as_string (sig_method, 1));
undo_casts (sig_ty);
return error_mark_node;
}
@ -1000,7 +1000,7 @@ build_signature_method_call (basetype, instance, function, parms)
&& (!deflt_call || deflt_call == error_mark_node)))
{
compiler_error ("cannot build call of signature member function `%s'",
fndecl_as_string (NULL, function, 1));
fndecl_as_string (function, 1));
return error_mark_node;
}

View File

@ -295,8 +295,8 @@ yylex()
if (lastiddecl != trrr)
{
lastiddecl = trrr;
if (got_scope || got_object)
tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
if (got_scope)
tmp_token.yylval.ttype = trrr;
}
break;
case IDENTIFIER:
@ -307,7 +307,7 @@ yylex()
break;
case NSNAME:
lastiddecl = trrr;
if (got_scope || got_object)
if (got_scope)
tmp_token.yylval.ttype = trrr;
break;
default:
@ -352,6 +352,7 @@ yylex()
consume_token();
}
got_object = NULL_TREE;
yylval = tmp_token.yylval;
yychar = tmp_token.yychar;
end_of_file = tmp_token.end_of_file;

View File

@ -26,6 +26,11 @@ Boston, MA 02111-1307, USA. */
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#define CEIL(x,y) (((x) + (y) - 1) / (y))
@ -202,10 +207,9 @@ lvalue_or_else (ref, string)
and return it so that it can be processed by language-independent
and language-specific expression expanders. */
tree
build_cplus_new (type, init, with_cleanup_p)
build_cplus_new (type, init)
tree type;
tree init;
int with_cleanup_p;
{
tree slot;
tree rval;
@ -234,7 +238,7 @@ break_out_cleanups (exp)
if (TREE_CODE (tmp) == CALL_EXPR
&& TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp)))
return build_cplus_new (TREE_TYPE (tmp), tmp, 1);
return build_cplus_new (TREE_TYPE (tmp), tmp);
while (TREE_CODE (tmp) == NOP_EXPR
|| TREE_CODE (tmp) == CONVERT_EXPR
@ -245,7 +249,7 @@ break_out_cleanups (exp)
{
TREE_OPERAND (tmp, 0)
= build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)),
TREE_OPERAND (tmp, 0), 1);
TREE_OPERAND (tmp, 0));
break;
}
else
@ -412,7 +416,14 @@ build_cplus_array_type (elt_type, index_type)
saveable_obstack = &permanent_obstack;
}
t = build_array_type (elt_type, index_type);
if (current_template_parms)
{
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
TYPE_DOMAIN (t) = index_type;
}
else
t = build_array_type (elt_type, index_type);
/* Push these needs up so that initialization takes place
more easily. */
@ -568,7 +579,6 @@ layout_vbasetypes (rec, max)
register unsigned const_size = 0;
register tree var_size = 0;
int nonvirtual_const_size;
tree nonvirtual_var_size;
CLASSTYPE_VBASECLASSES (rec) = vbase_types;
@ -578,7 +588,6 @@ layout_vbasetypes (rec, max)
var_size = TYPE_SIZE (rec);
nonvirtual_const_size = const_size;
nonvirtual_var_size = var_size;
while (vbase_types)
{
@ -1403,10 +1412,7 @@ build_exception_variant (type, raises)
tree type;
tree raises;
{
int i;
tree v = TYPE_MAIN_VARIANT (type);
tree t, t2, cname;
tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree));
int constp = TYPE_READONLY (type);
int volatilep = TYPE_VOLATILE (type);
@ -1435,6 +1441,7 @@ build_exception_variant (type, raises)
raises = copy_list (raises);
pop_obstacks ();
}
TYPE_RAISES_EXCEPTIONS (v) = raises;
return v;
}
@ -1449,7 +1456,6 @@ mapcar (t, func)
tree t;
tree (*func)();
{
enum tree_code code;
tree tmp;
if (t == NULL_TREE)
@ -1458,7 +1464,7 @@ mapcar (t, func)
if (tmp = func (t), tmp != NULL_TREE)
return tmp;
switch (code = TREE_CODE (t))
switch (TREE_CODE (t))
{
case ERROR_MARK:
return error_mark_node;
@ -1552,6 +1558,8 @@ mapcar (t, func)
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case CALL_EXPR:
case ARRAY_REF:
case SCOPE_REF:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
@ -1646,15 +1654,24 @@ copy_to_permanent (t)
return t;
}
#ifdef GATHER_STATISTICS
extern int depth_reached;
#endif
void
print_lang_statistics ()
{
extern struct obstack maybepermanent_obstack;
extern struct obstack maybepermanent_obstack, decl_obstack;
print_obstack_statistics ("class_obstack", &class_obstack);
print_obstack_statistics ("decl_obstack", &decl_obstack);
print_obstack_statistics ("permanent_obstack", &permanent_obstack);
print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
print_search_statistics ();
print_class_statistics ();
#ifdef GATHER_STATISTICS
fprintf (stderr, "maximum template instantiation depth reached: %d\n",
depth_reached);
#endif
}
/* This is used by the `assert' macro. It is provided in libgcc.a,
@ -1720,7 +1737,7 @@ bot_manip (t)
return t;
else if (TREE_CODE (t) == TARGET_EXPR)
return build_cplus_new (TREE_TYPE (t),
break_out_target_exprs (TREE_OPERAND (t, 1)), 0);
break_out_target_exprs (TREE_OPERAND (t, 1)));
return NULL_TREE;
}
@ -1819,3 +1836,151 @@ cp_expand_decl_cleanup (decl, cleanup)
{
return expand_decl_cleanup (decl, unsave_expr (cleanup));
}
/* Obstack used for allocating nodes in template function and variable
definitions. */
extern struct obstack *expression_obstack;
/* Similar to `build_nt', except we build
on the permanent_obstack, regardless. */
tree
build_min_nt VPROTO((enum tree_code code, ...))
{
#ifndef __STDC__
enum tree_code code;
#endif
register struct obstack *ambient_obstack = expression_obstack;
va_list p;
register tree t;
register int length;
register int i;
VA_START (p, code);
#ifndef __STDC__
code = va_arg (p, enum tree_code);
#endif
expression_obstack = &permanent_obstack;
t = make_node (code);
length = tree_code_length[(int) code];
TREE_COMPLEXITY (t) = lineno;
for (i = 0; i < length; i++)
{
tree x = va_arg (p, tree);
TREE_OPERAND (t, i) = copy_to_permanent (x);
}
va_end (p);
expression_obstack = ambient_obstack;
return t;
}
/* Similar to `build', except we build
on the permanent_obstack, regardless. */
tree
build_min VPROTO((enum tree_code code, tree tt, ...))
{
#ifndef __STDC__
enum tree_code code;
tree tt;
#endif
register struct obstack *ambient_obstack = expression_obstack;
va_list p;
register tree t;
register int length;
register int i;
VA_START (p, tt);
#ifndef __STDC__
code = va_arg (p, enum tree_code);
tt = va_arg (p, tree);
#endif
expression_obstack = &permanent_obstack;
t = make_node (code);
length = tree_code_length[(int) code];
TREE_TYPE (t) = tt;
TREE_COMPLEXITY (t) = lineno;
for (i = 0; i < length; i++)
{
tree x = va_arg (p, tree);
TREE_OPERAND (t, i) = copy_to_permanent (x);
}
va_end (p);
expression_obstack = ambient_obstack;
return t;
}
/* Same as `tree_cons' but make a permanent object. */
tree
min_tree_cons (purpose, value, chain)
tree purpose, value, chain;
{
register tree node;
register struct obstack *ambient_obstack = current_obstack;
current_obstack = &permanent_obstack;
node = tree_cons (purpose, value, chain);
current_obstack = ambient_obstack;
return node;
}
tree
get_type_decl (t)
tree t;
{
if (TREE_CODE (t) == IDENTIFIER_NODE)
return identifier_typedecl_value (t);
if (TREE_CODE (t) == TYPE_DECL)
return t;
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
return TYPE_STUB_DECL (t);
my_friendly_abort (42);
}
int
can_free (obstack, t)
struct obstack *obstack;
tree t;
{
int size;
if (TREE_CODE (t) == TREE_VEC)
size = (TREE_VEC_LENGTH (t)-1) * sizeof (tree) + sizeof (struct tree_vec);
else
my_friendly_abort (42);
#define ROUND(x) ((x + obstack_alignment_mask (obstack)) \
& ~ obstack_alignment_mask (obstack))
if ((char *)t + ROUND (size) == obstack_next_free (obstack))
return 1;
#undef ROUND
return 0;
}
/* Return first vector element whose BINFO_TYPE is ELEM.
Return 0 if ELEM is not in VEC. */
tree
vec_binfo_member (elem, vec)
tree elem, vec;
{
int i;
for (i = 0; i < TREE_VEC_LENGTH (vec); ++i)
if (elem == BINFO_TYPE (TREE_VEC_ELT (vec, i)))
return TREE_VEC_ELT (vec, i);
return NULL_TREE;
}

View File

@ -79,7 +79,12 @@ tree
require_complete_type (value)
tree value;
{
tree type = TREE_TYPE (value);
tree type;
if (current_template_parms)
return value;
type = TREE_TYPE (value);
/* First, detect a valid value with a complete type. */
if (TYPE_SIZE (type) != 0
@ -105,10 +110,35 @@ require_complete_type (value)
return require_complete_type (value);
}
if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
{
instantiate_class_template (type);
if (TYPE_SIZE (type) != 0)
return value;
}
incomplete_type_error (value, type);
return error_mark_node;
}
tree
complete_type (type)
tree type;
{
if (TYPE_SIZE (type) != NULL_TREE)
;
else if (TREE_CODE (type) == ARRAY_TYPE)
{
tree t = complete_type (TREE_TYPE (type));
if (TYPE_SIZE (t) != NULL_TREE)
type = build_cplus_array_type (t, TYPE_DOMAIN (type));
}
else if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
instantiate_class_template (type);
return type;
}
/* Return truthvalue of whether type of EXP is instantiated. */
int
type_unknown_p (exp)
@ -309,6 +339,11 @@ common_type (t1, t2)
if (TREE_CODE (t2) == ENUMERAL_TYPE)
t2 = type_for_size (TYPE_PRECISION (t2), 1);
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
if (TYPE_PTRMEMFUNC_P (t2))
t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
code1 = TREE_CODE (t1);
code2 = TREE_CODE (t2);
@ -471,7 +506,8 @@ common_type (t1, t2)
tree b1 = TYPE_OFFSET_BASETYPE (t1);
tree b2 = TYPE_OFFSET_BASETYPE (t2);
if (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))
if (comptypes (b1, b2, 1)
|| (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))
basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
else
{
@ -516,9 +552,8 @@ common_type (t1, t2)
/* Return 1 if TYPE1 and TYPE2 raise the same exceptions. */
int
compexcepttypes (t1, t2, strict)
compexcepttypes (t1, t2)
tree t1, t2;
int strict;
{
return TYPE_RAISES_EXCEPTIONS (t1) == TYPE_RAISES_EXCEPTIONS (t2);
}
@ -611,6 +646,11 @@ comptypes (type1, type2, strict)
return 1;
}
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
if (TYPE_PTRMEMFUNC_P (t2))
t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
/* Different classes of types can't be compatible. */
if (TREE_CODE (t1) != TREE_CODE (t2))
@ -660,6 +700,28 @@ comptypes (type1, type2, strict)
{
case RECORD_TYPE:
case UNION_TYPE:
if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
&& CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2))
{
int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1));
tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0);
tree *p2 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t2), 0);
while (i--)
{
if (TREE_CODE_CLASS (TREE_CODE (p1[i])) == 't')
{
if (! comptypes (p1[i], p2[i], 1))
return 0;
}
else
{
if (simple_cst_equal (p1[i], p2[i]) <= 0)
return 0;
}
}
return 1;
}
if (strict <= 0)
goto look_hard;
return 0;
@ -671,7 +733,7 @@ comptypes (type1, type2, strict)
break;
case METHOD_TYPE:
if (! compexcepttypes (t1, t2, strict))
if (! compexcepttypes (t1, t2))
return 0;
/* This case is anti-symmetrical!
@ -719,7 +781,7 @@ comptypes (type1, type2, strict)
break;
case FUNCTION_TYPE:
if (! compexcepttypes (t1, t2, strict))
if (! compexcepttypes (t1, t2))
return 0;
val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
@ -734,30 +796,6 @@ comptypes (type1, type2, strict)
case TEMPLATE_TYPE_PARM:
return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2);
case UNINSTANTIATED_P_TYPE:
if (UPT_TEMPLATE (t1) != UPT_TEMPLATE (t2))
return 0;
{
int i = TREE_VEC_LENGTH (UPT_PARMS (t1));
tree *p1 = &TREE_VEC_ELT (UPT_PARMS (t1), 0);
tree *p2 = &TREE_VEC_ELT (UPT_PARMS (t2), 0);
while (i--)
{
if (TREE_CODE_CLASS (TREE_CODE (p1[i])) == 't')
{
if (! comptypes (p1[i], p2[i], 1))
return 0;
}
else
{
if (simple_cst_equal (p1[i], p2[i]) <= 0)
return 0;
}
}
}
return 1;
}
return attrval == 2 && val == 1 ? 2 : val;
}
@ -889,7 +927,7 @@ tree
common_base_type (tt1, tt2)
tree tt1, tt2;
{
tree best = NULL_TREE, tmp;
tree best = NULL_TREE;
int i;
/* If one is a baseclass of another, that's good enough. */
@ -1215,6 +1253,9 @@ c_sizeof (type)
enum tree_code code = TREE_CODE (type);
tree t;
if (current_template_parms)
return build_min (SIZEOF_EXPR, sizetype, type);
if (code == FUNCTION_TYPE)
{
if (pedantic || warn_pointer_arith)
@ -1259,9 +1300,9 @@ c_sizeof (type)
return size_int (0);
}
if (TYPE_SIZE (type) == 0)
if (TYPE_SIZE (complete_type (type)) == 0)
{
error ("`sizeof' applied to an incomplete type");
cp_error ("`sizeof' applied to incomplete type `%T'", type);
return size_int (0);
}
@ -1274,6 +1315,36 @@ c_sizeof (type)
return t;
}
tree
expr_sizeof (e)
tree e;
{
if (current_template_parms)
return build_min (SIZEOF_EXPR, sizetype, e);
if (TREE_CODE (e) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (e, 1)))
error ("sizeof applied to a bit-field");
/* ANSI says arrays and functions are converted inside comma.
But we can't really convert them in build_compound_expr
because that would break commas in lvalues.
So do the conversion here if operand was a comma. */
if (TREE_CODE (e) == COMPOUND_EXPR
&& (TREE_CODE (TREE_TYPE (e)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (e)) == FUNCTION_TYPE))
e = default_conversion (e);
else if (TREE_CODE (e) == TREE_LIST)
{
tree t = TREE_VALUE (e);
if (t != NULL_TREE
&& ((TREE_TYPE (t)
&& TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
|| is_overloaded_fn (t)))
pedwarn ("ANSI C++ forbids taking the sizeof a function type");
}
return c_sizeof (TREE_TYPE (e));
}
tree
c_sizeof_nowarn (type)
tree type;
@ -1657,10 +1728,13 @@ build_component_ref (datum, component, basetype_path, protect)
int protect;
{
register tree basetype = TREE_TYPE (datum);
register enum tree_code code = TREE_CODE (basetype);
register enum tree_code code;
register tree field = NULL;
register tree ref;
if (current_template_parms)
return build_min_nt (COMPONENT_REF, datum, component);
/* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it. */
switch (TREE_CODE (datum))
{
@ -1680,6 +1754,8 @@ build_component_ref (datum, component, basetype_path, protect)
basetype_path, protect));
}
code = TREE_CODE (basetype);
if (code == REFERENCE_TYPE)
{
datum = convert_from_reference (datum);
@ -1703,7 +1779,7 @@ build_component_ref (datum, component, basetype_path, protect)
return error_mark_node;
}
if (TYPE_SIZE (basetype) == 0)
if (TYPE_SIZE (complete_type (basetype)) == 0)
{
incomplete_type_error (0, basetype);
return error_mark_node;
@ -1888,7 +1964,12 @@ build_x_indirect_ref (ptr, errorstring)
tree ptr;
char *errorstring;
{
tree rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE, NULL_TREE);
tree rval;
if (current_template_parms)
return build_min_nt (INDIRECT_REF, ptr);
rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE, NULL_TREE);
if (rval)
return rval;
return build_indirect_ref (ptr, errorstring);
@ -1984,8 +2065,6 @@ tree
build_array_ref (array, idx)
tree array, idx;
{
tree itype;
if (idx == 0)
{
error ("subscript missing in array reference");
@ -1996,8 +2075,6 @@ build_array_ref (array, idx)
|| TREE_TYPE (idx) == error_mark_node)
return error_mark_node;
itype = TREE_TYPE (idx);
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
&& TREE_CODE (array) != INDIRECT_REF)
{
@ -2145,6 +2222,9 @@ build_x_function_call (function, params, decl)
if (function == error_mark_node)
return error_mark_node;
if (current_template_parms)
return build_min_nt (CALL_EXPR, function, params, 0);
type = TREE_TYPE (function);
is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE
@ -2818,8 +2898,13 @@ build_x_binary_op (code, arg1, arg2)
enum tree_code code;
tree arg1, arg2;
{
tree rval = build_opfncall (code, LOOKUP_SPECULATIVELY,
arg1, arg2, NULL_TREE);
tree rval;
if (current_template_parms)
return build_min_nt (code, arg1, arg2);
rval = build_opfncall (code, LOOKUP_SPECULATIVELY,
arg1, arg2, NULL_TREE);
if (rval)
return build_opfncall (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
if (code == MEMBER_REF)
@ -2841,7 +2926,6 @@ build_binary_op (code, arg1, arg2, convert_p)
if (convert_p)
{
tree args_save [2];
tree type0, type1;
args[0] = decay_conversion (args[0]);
args[1] = decay_conversion (args[1]);
@ -3483,7 +3567,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
it never happens because available widths are 2**N. */
&& (!TREE_UNSIGNED (final_type)
|| unsigned_arg
|| ((unsigned) 2 * TYPE_PRECISION (TREE_TYPE (arg0))
|| (((unsigned) 2 * TYPE_PRECISION (TREE_TYPE (arg0)))
<= TYPE_PRECISION (result_type))))
{
/* Do an unsigned shift if the operand was zero-extended. */
@ -3578,8 +3662,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
have all bits set that are set in the ~ operand when it is
extended. */
if (TREE_CODE (primop0) == BIT_NOT_EXPR
^ TREE_CODE (primop1) == BIT_NOT_EXPR)
if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
^ (TREE_CODE (primop1) == BIT_NOT_EXPR))
{
if (TREE_CODE (primop0) == BIT_NOT_EXPR)
primop0 = get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
@ -3705,7 +3789,7 @@ pointer_int_sum (resultcode, ptrop, intop)
size_exp = integer_one_node;
}
else
size_exp = size_in_bytes (TREE_TYPE (result_type));
size_exp = size_in_bytes (complete_type (TREE_TYPE (result_type)));
/* Needed to make OOPS V2R3 work. */
intop = folded;
@ -3863,6 +3947,9 @@ build_x_unary_op (code, xarg)
enum tree_code code;
tree xarg;
{
if (current_template_parms)
return build_min_nt (code, xarg, NULL_TREE);
/* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
error message. */
if (code == ADDR_EXPR
@ -3887,7 +3974,10 @@ tree
condition_conversion (expr)
tree expr;
{
tree t = convert (boolean_type_node, expr);
tree t;
if (current_template_parms)
return expr;
t = convert (boolean_type_node, expr);
t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
return t;
}
@ -4018,7 +4108,7 @@ build_unary_op (code, xarg, noconvert)
if (TREE_CODE (argtype) == POINTER_TYPE)
{
enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype));
if (TYPE_SIZE (TREE_TYPE (argtype)) == 0)
if (TYPE_SIZE (complete_type (TREE_TYPE (argtype))) == 0)
cp_error ("cannot %s a pointer to incomplete type `%T'",
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
@ -4420,7 +4510,7 @@ unary_complex_lvalue (code, arg)
if (TREE_CODE (arg) == SAVE_EXPR)
targ = arg;
else
targ = build_cplus_new (TREE_TYPE (arg), arg, 1);
targ = build_cplus_new (TREE_TYPE (arg), arg);
return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
}
@ -4531,6 +4621,9 @@ build_x_conditional_expr (ifexp, op1, op2)
{
tree rval = NULL_TREE;
if (current_template_parms)
return build_min_nt (COND_EXPR, ifexp, op1, op2);
/* See comments in `build_x_binary_op'. */
if (op1 != 0)
rval = build_opfncall (COND_EXPR, LOOKUP_SPECULATIVELY, ifexp, op1, op2);
@ -4838,6 +4931,9 @@ build_x_compound_expr (list)
tree rest = TREE_CHAIN (list);
tree result;
if (current_template_parms)
return build_min_nt (COMPOUND_EXPR, list, NULL_TREE);
if (rest == NULL_TREE)
return build_compound_expr (list);
@ -4915,6 +5011,13 @@ tree build_reinterpret_cast (type, expr)
if (TYPE_PTRMEMFUNC_P (type))
type = TYPE_PTRMEMFUNC_FN_TYPE (type);
if (current_template_parms)
{
tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
return t;
}
if (TYPE_PTRMEMFUNC_P (intype))
intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
@ -5080,6 +5183,13 @@ build_c_cast (type, expr, allow_nonconverting)
&& TREE_CHAIN (value) == NULL_TREE)
value = TREE_VALUE (value);
if (current_template_parms)
{
tree t = build_min (CAST_EXPR, type,
min_tree_cons (NULL_TREE, value, NULL_TREE));
return t;
}
if (TREE_CODE (type) == VOID_TYPE)
value = build1 (CONVERT_EXPR, type, value);
else if (TREE_TYPE (value) == NULL_TREE
@ -5625,7 +5735,7 @@ build_modify_expr (lhs, modifycode, rhs)
NULL_TREE, 0);
if (TREE_CODE (newrhs) == CALL_EXPR
&& TYPE_NEEDS_CONSTRUCTING (lhstype))
newrhs = build_cplus_new (lhstype, newrhs, 0);
newrhs = build_cplus_new (lhstype, newrhs);
/* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice, and possibly result in
@ -5700,6 +5810,25 @@ build_modify_expr (lhs, modifycode, rhs)
NULL_TREE, 0);
}
tree
build_x_modify_expr (lhs, modifycode, rhs)
tree lhs;
enum tree_code modifycode;
tree rhs;
{
if (current_template_parms)
return build_min_nt (MODOP_EXPR, lhs,
build_min_nt (modifycode, 0, 0), rhs);
if (modifycode != NOP_EXPR)
{
tree rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
make_node (modifycode));
if (rval)
return rval;
}
return build_modify_expr (lhs, modifycode, rhs);
}
/* Return 0 if EXP is not a valid lvalue in this language
even though `lvalue_or_else' would accept it. */
@ -6216,8 +6345,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
for (; ; ttl = TREE_TYPE (ttl), ttr = TREE_TYPE (ttr))
{
nptrs -= 1;
const_parity |= TYPE_READONLY (ttl) < TYPE_READONLY (ttr);
volatile_parity |= TYPE_VOLATILE (ttl) < TYPE_VOLATILE (ttr);
const_parity |= (TYPE_READONLY (ttl) < TYPE_READONLY (ttr));
volatile_parity |= (TYPE_VOLATILE (ttl) < TYPE_VOLATILE (ttr));
if (! left_const
&& (TYPE_READONLY (ttl) > TYPE_READONLY (ttr)
@ -6525,7 +6654,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
cleanups if it is used. */
if (TREE_CODE (rhs) == CALL_EXPR)
{
rhs = build_cplus_new (type, rhs, 0);
rhs = build_cplus_new (type, rhs);
return rhs;
}
/* Handle the case of default parameter initialization and
@ -6542,7 +6671,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
= build_unary_op (ADDR_EXPR, exp, 0);
}
else
rhs = build_cplus_new (type, TREE_OPERAND (rhs, 0), 0);
rhs = build_cplus_new (type, TREE_OPERAND (rhs, 0));
return rhs;
}
else if (TYPE_HAS_TRIVIAL_INIT_REF (type))
@ -6562,7 +6691,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
if (exp == 0)
{
exp = build_cplus_new (type, init, 0);
exp = build_cplus_new (type, init);
return exp;
}
@ -6675,7 +6804,6 @@ c_expand_return (retval)
extern tree dtor_label, ctor_label;
tree result = DECL_RESULT (current_function_decl);
tree valtype = TREE_TYPE (result);
register int use_temp = 0;
int returns_value = 1;
if (TREE_THIS_VOLATILE (current_function_decl))
@ -6687,6 +6815,12 @@ c_expand_return (retval)
return;
}
if (current_template_parms)
{
add_tree (build_min_nt (RETURN_STMT, retval));
return;
}
if (retval == NULL_TREE)
{
/* A non-named return value does not count. */
@ -6827,10 +6961,7 @@ c_expand_return (retval)
if (TYPE_MODE (valtype) != BLKmode
&& any_pending_cleanups (1))
{
retval = get_temp_regvar (valtype, retval);
use_temp = obey_regdecls;
}
retval = get_temp_regvar (valtype, retval);
}
else if (IS_AGGR_TYPE (valtype) && current_function_returns_struct)
{
@ -6855,7 +6986,6 @@ c_expand_return (retval)
{
retval = get_temp_regvar (valtype, retval);
expand_cleanups_to (NULL_TREE);
use_temp = obey_regdecls;
result = 0;
}
else

View File

@ -468,8 +468,8 @@ initializer_constant_valid_p (value, endtype)
return 0;
case PLUS_EXPR:
if (TREE_CODE (endtype) == INTEGER_TYPE
&& TYPE_PRECISION (endtype) < POINTER_SIZE)
if ((TREE_CODE (endtype) == INTEGER_TYPE)
&& (TYPE_PRECISION (endtype) < POINTER_SIZE))
return 0;
{
tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
@ -485,8 +485,8 @@ initializer_constant_valid_p (value, endtype)
}
case MINUS_EXPR:
if (TREE_CODE (endtype) == INTEGER_TYPE
&& TYPE_PRECISION (endtype) < POINTER_SIZE)
if ((TREE_CODE (endtype) == INTEGER_TYPE)
&& (TYPE_PRECISION (endtype) < POINTER_SIZE))
return 0;
{
tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
@ -1287,6 +1287,9 @@ build_x_arrow (datum)
if (type == error_mark_node)
return error_mark_node;
if (current_template_parms)
return build_min_nt (ARROW_EXPR, rval);
if (TREE_CODE (rval) == OFFSET_REF)
{
rval = resolve_offset_ref (datum);
@ -1299,7 +1302,7 @@ build_x_arrow (datum)
type = TREE_TYPE (rval);
}
if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (type))
if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (complete_type (type)))
{
while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval, NULL_TREE, NULL_TREE)))
{
@ -1359,6 +1362,9 @@ build_m_component_ref (datum, component)
tree rettype;
tree binfo;
if (current_template_parms)
return build_min_nt (DOTSTAR_EXPR, datum, component);
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
{
type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
@ -1445,6 +1451,9 @@ build_functional_cast (exp, parms)
else
type = exp;
if (current_template_parms)
return build_min (CAST_EXPR, type, parms);
if (IS_SIGNATURE (type))
{
error ("signature type not allowed in cast or constructor expression");
@ -1480,7 +1489,7 @@ build_functional_cast (exp, parms)
name = DECL_NESTED_TYPENAME (name);
}
if (TYPE_SIZE (type) == NULL_TREE)
if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
{
cp_error ("type `%T' is not yet defined", type);
return error_mark_node;
@ -1495,7 +1504,7 @@ build_functional_cast (exp, parms)
if (expr_as_ctor == error_mark_node)
return error_mark_node;
return build_cplus_new (type, expr_as_ctor, 1);
return build_cplus_new (type, expr_as_ctor);
}
/* Return the character string for the name that encodes the

View File

@ -183,7 +183,7 @@ GNU_xref_end (ect)
if (xf == NULL) return;
while (cur_scope != NULL)
GNU_xref_end_scope(cur_scope->gid,0,0,0,0);
GNU_xref_end_scope(cur_scope->gid,0,0,0);
doing_xref = 0;
@ -275,10 +275,10 @@ GNU_xref_start_scope (id)
TRNS is ??? */
void
GNU_xref_end_scope (id,inid,prm,keep,trns)
GNU_xref_end_scope (id,inid,prm,keep)
HOST_WIDE_INT id;
HOST_WIDE_INT inid;
int prm,keep,trns;
int prm,keep;
{
XREF_FILE xf;
XREF_SCOPE xs,lxs,oxs;
@ -400,7 +400,7 @@ GNU_xref_decl (fndecl,decl)
}
else if (TREE_CODE (decl) == TEMPLATE_DECL)
{
if (DECL_TEMPLATE_IS_CLASS (decl))
if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
cls = "CLASSTEMP";
else if (TREE_CODE (DECL_RESULT (decl)) == FUNCTION_DECL)
cls = "FUNCTEMP";
@ -599,7 +599,9 @@ GNU_xref_member(cls, fld)
char *prot;
int confg, pure;
char *d;
#ifdef XREF_SHORT_MEMBER_NAMES
int i;
#endif
char buf[1024], bufa[1024];
if (!doing_xref) return;
@ -622,7 +624,9 @@ GNU_xref_member(cls, fld)
d = IDENTIFIER_POINTER(cls);
sprintf(buf, "%d%s", strlen(d), d);
#ifdef XREF_SHORT_MEMBER_NAMES
i = strlen(buf);
#endif
strcpy(bufa, declname(fld));
#ifdef XREF_SHORT_MEMBER_NAMES