parent
067aea74e2
commit
42976354a6
132
gcc/cp/ChangeLog
132
gcc/cp/ChangeLog
|
@ -1,3 +1,126 @@
|
|||
Wed Jul 23 13:36:25 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (struct cp_function): Add static_labelno.
|
||||
(push_cp_function_context): Save it.
|
||||
(pop_cp_function_context): Restore it.
|
||||
|
||||
Tue Jul 22 14:43:29 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* typeck.c (build_component_ref_1): Convert from reference.
|
||||
|
||||
Tue Jul 22 11:06:23 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* parse.y (current_declspecs, prefix_attributes): Initialize to
|
||||
NULL_TREE.
|
||||
|
||||
* parse.y (initdcl0): Make sure CURRENT_DECLSPECS is non-nil
|
||||
before we try to force it to be a TREE_LIST.
|
||||
(decl): Make sure $1.t is non-nil.
|
||||
|
||||
Sun Jul 20 11:53:07 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* pt.c (uses_template_parms): Handle template first-parse codes.
|
||||
|
||||
* decl.c (cp_finish_decl): Only warn about user-defined statics.
|
||||
|
||||
Fri Jul 18 17:56:08 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* pt.c (unify): Handle BOOLEAN_TYPE.
|
||||
|
||||
* cp-tree.h: Lose PARM_DEFAULT_FROM_TEMPLATE.
|
||||
* pt.c (tsubst): Don't set it.
|
||||
* call.c (build_over_call): Use uses_template_parms.
|
||||
|
||||
Thu Jul 17 18:06:30 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* method.c (build_overload_nested_name): Use static_labelno
|
||||
instead of var_labelno.
|
||||
(build_qualified_name): New fn.
|
||||
(build_overload_name): Split out from here.
|
||||
(build_static_name): Use build_qualified_name.
|
||||
* decl.c (cp_finish_decl): Statics in extern inline functions
|
||||
have comdat linkage.
|
||||
(start_function): Initialize static_labelno.
|
||||
|
||||
Thu Jul 17 11:20:17 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
|
||||
|
||||
* class.c (finish_struct_methods): add check of warn_ctor_dtor_privacy
|
||||
before "all member functions in class [] are private"
|
||||
|
||||
Wed Jul 16 23:47:08 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* lex.c (do_scoped_id): convert_from_reference.
|
||||
* init.c (build_offset_ref): Likewise.
|
||||
|
||||
Wed Jul 16 15:57:42 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
|
||||
|
||||
* parse.y (empty_parms): Only use VOID_LIST_NODE for the PARMS if
|
||||
we're in a C++ struct/class, not if we're doing `extern "C"'.
|
||||
|
||||
Wed Jul 16 12:34:29 1997 Benjamin Kosnik <bkoz@lisa.cygnus.com>
|
||||
|
||||
* error.c (dump_expr): Check TREE_OPERAND before dump_expr_list.
|
||||
|
||||
Mon Jul 14 03:23:46 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* typeck.c (get_member_function_from_ptrfunc): Promote index
|
||||
before saving it.
|
||||
|
||||
Sun Jul 13 00:11:52 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* tree.c (layout_basetypes): Move non-virtual destructor warning.
|
||||
* decl.c (xref_basetypes): Remove non-virtual destructor warning.
|
||||
|
||||
Sat Jul 12 12:47:12 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (grokdeclarator): Call add_defarg_fn for the function
|
||||
type, too.
|
||||
* lex.c (add_defarg_fn): Adjust.
|
||||
(do_pending_defargs): Adjust. Don't skip the first parm.
|
||||
|
||||
Fri Jul 11 01:39:50 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (build_enumerator): Global enumerators are also readonly.
|
||||
|
||||
* rtti.c (build_dynamic_cast_1): Renamed from build_dynamic_cast.
|
||||
(build_dynamic_cast): Call it and convert_from_reference.
|
||||
|
||||
* lex.c (add_defarg_fn): New fn.
|
||||
(snarf_defarg): Don't add to defarg_types.
|
||||
(do_pending_defargs): Lose defarg_types. All fns we process now
|
||||
have defargs.
|
||||
* decl.c (grokfndecl): Call add_defarg_fn.
|
||||
|
||||
* Makefile.in (CONFLICTS): Expect 18 s/r conflicts.
|
||||
* cp-tree.def: Add DEFAULT_ARG.
|
||||
* spew.c (yylex): Call snarf_defarg as appropriate.
|
||||
* parse.y: New tokens DEFARG and DEFARG_MARKER.
|
||||
(defarg_again, pending_defargs, defarg, defarg1): New rules.
|
||||
(structsp): Use pending_defargs.
|
||||
(parms, full_parm): Use defarg.
|
||||
* lex.c (init_lex): Initialize inline_text_firstobj.
|
||||
(do_pending_inlines): Never pass the obstack to feed_input.
|
||||
(process_next_inline): Call end_input instead of restore_pending_input.
|
||||
(clear_inline_text_obstack, reinit_parse_for_expr, do_pending_defargs,
|
||||
finish_defarg, feed_defarg, snarf_defarg, maybe_snarf_defarg): New fns.
|
||||
* input.c (end_input): New fn.
|
||||
(sub_getch): At the end of some fed input, just keep returning EOF
|
||||
until someone calls end_input.
|
||||
Remove 'obstack' field from struct input_source.
|
||||
* decl.c (grokparms): Handle DEFAULT_ARG.
|
||||
(replace_defarg): New fn.
|
||||
* cp-tree.h (DEFARG_LENGTH, DEFARG_POINTER): New macros.
|
||||
|
||||
Wed Jul 9 13:44:12 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (implicit_conversion): If nothing else works, try binding
|
||||
an rvalue to a reference.
|
||||
|
||||
Wed Jul 9 13:04:38 1997 Geoffrey Noer <noer@cygnus.com>
|
||||
|
||||
* decl.c (init_decl_processing): fix Jun 30 patch -- move
|
||||
ifndef for Cygwin32 to include SIGSEGV.
|
||||
|
||||
Thu Jul 3 01:44:05 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* class.c (finish_struct_1): Only complain about pointers without
|
||||
|
@ -16,10 +139,11 @@ Thu Jul 3 01:44:05 1997 Jason Merrill <jason@yorick.cygnus.com>
|
|||
|
||||
Mon Jun 30 17:53:21 1997 Geoffrey Noer <noer@cygnus.com>
|
||||
|
||||
* decl.c: Stop trying to catch signals other than SIGABRT
|
||||
since the Cygwin32 library doesn't support them correctly
|
||||
yet. This fixes a situation in which g++ causes a hang on
|
||||
SIGSEGVs and other such signals in our Win32-hosted tools.
|
||||
* decl.c (init_decl_processing): Stop trying to catch signals
|
||||
other than SIGABRT since the Cygwin32 library doesn't support
|
||||
them correctly yet. This fixes a situation in which g++ causes
|
||||
a hang on SIGSEGVs and other such signals in our Win32-hosted
|
||||
tools.
|
||||
|
||||
Mon Jun 30 14:50:01 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
|
|
|
@ -195,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 16 shift/reduce conflicts and 39 reduce/reduce conflicts.
|
||||
CONFLICTS = expect 18 shift/reduce conflicts and 39 reduce/reduce conflicts.
|
||||
$(PARSE_H) : $(PARSE_C)
|
||||
$(PARSE_C) : $(srcdir)/parse.y
|
||||
@echo $(CONFLICTS)
|
||||
|
|
|
@ -3281,14 +3281,19 @@ implicit_conversion (to, from, expr, flags)
|
|||
conv = cand->second_conv;
|
||||
if ((! conv || ICS_BAD_FLAG (conv))
|
||||
&& TREE_CODE (to) == REFERENCE_TYPE
|
||||
&& TYPE_READONLY (TREE_TYPE (to))
|
||||
&& ! TYPE_VOLATILE (TREE_TYPE (to))
|
||||
&& (flags & LOOKUP_NO_TEMP_BIND) == 0)
|
||||
{
|
||||
cand = build_user_type_conversion_1
|
||||
(TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
|
||||
if (cand)
|
||||
conv = build_conv (REF_BIND, to, cand->second_conv);
|
||||
{
|
||||
if (! TYPE_READONLY (TREE_TYPE (to))
|
||||
|| TYPE_VOLATILE (TREE_TYPE (to)))
|
||||
ICS_BAD_FLAG (cand->second_conv) = 1;
|
||||
if (!conv || (ICS_BAD_FLAG (conv)
|
||||
> ICS_BAD_FLAG (cand->second_conv)))
|
||||
conv = build_conv (REF_BIND, to, cand->second_conv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5108,10 +5113,11 @@ build_over_call (fn, convs, args, flags)
|
|||
{
|
||||
tree arg = TREE_PURPOSE (parm);
|
||||
|
||||
if (PARM_DEFAULT_FROM_TEMPLATE (parm))
|
||||
if (DECL_TEMPLATE_INFO (fn) && uses_template_parms (arg))
|
||||
/* This came from a template. Instantiate the default arg here,
|
||||
not in tsubst. */
|
||||
arg = tsubst_expr (arg, &TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
|
||||
arg = tsubst_expr (arg,
|
||||
&TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
|
||||
TREE_VEC_LENGTH (DECL_TI_ARGS (fn)), NULL_TREE);
|
||||
converted_args = tree_cons
|
||||
(NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),
|
||||
|
|
|
@ -2011,7 +2011,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
|
|||
nonprivate_method = 1;
|
||||
break;
|
||||
}
|
||||
if (nonprivate_method == 0)
|
||||
if (nonprivate_method == 0
|
||||
&& warn_ctor_dtor_privacy)
|
||||
cp_warning ("all member functions in class `%T' are private", t);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,11 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
|
|||
This is not an alias, but is later expanded into multiple aliases. */
|
||||
DEFTREECODE (USING_DECL, "using_decl", "d", 0)
|
||||
|
||||
/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */
|
||||
DEFTREECODE (DEFAULT_ARG, "default_arg", "c", 2)
|
||||
|
||||
/* A whole bunch of tree codes for the initial, superficial parsing of
|
||||
templates. */
|
||||
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
|
||||
DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
|
||||
DEFTREECODE (CAST_EXPR, "cast_expr", "1", 1)
|
||||
|
|
|
@ -1094,10 +1094,6 @@ struct lang_decl
|
|||
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
|
||||
#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
|
||||
|
||||
/* For a TREE_LIST node representing a function parm type and its default arg,
|
||||
did the default arg come from a template? */
|
||||
#define PARM_DEFAULT_FROM_TEMPLATE(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. */
|
||||
#define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE))
|
||||
|
@ -1418,6 +1414,10 @@ extern int flag_new_for_scope;
|
|||
#define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE))
|
||||
#define UPT_PARMS(NODE) TREE_VALUE(TYPE_VALUES(NODE))
|
||||
|
||||
/* An un-parsed default argument looks like an identifier. */
|
||||
#define DEFARG_LENGTH(NODE) IDENTIFIER_LENGTH(NODE)
|
||||
#define DEFARG_POINTER(NODE) IDENTIFIER_POINTER(NODE)
|
||||
|
||||
#define builtin_function(NAME, TYPE, CODE, LIBNAME) \
|
||||
define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME)
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ extern int current_class_depth;
|
|||
|
||||
extern tree static_ctors, static_dtors;
|
||||
|
||||
extern int static_labelno;
|
||||
|
||||
/* Stack of places to restore the search obstack back to. */
|
||||
|
||||
/* Obstack used for remembering local class declarations (like
|
||||
|
@ -4672,12 +4674,12 @@ init_decl_processing ()
|
|||
current_binding_level = NULL_BINDING_LEVEL;
|
||||
free_binding_level = NULL_BINDING_LEVEL;
|
||||
|
||||
#ifndef __CYGWIN32__
|
||||
/* Because most segmentation signals can be traced back into user
|
||||
code, catch them and at least give the user a chance of working
|
||||
around compiler bugs. */
|
||||
signal (SIGSEGV, signal_catch);
|
||||
|
||||
#ifndef __CYGWIN32__
|
||||
/* We will also catch aborts in the back-end through signal_catch and
|
||||
give the user a chance to see where the error might be, and to defeat
|
||||
aborts in the back-end when there have been errors previously in their
|
||||
|
@ -6532,6 +6534,32 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|
|||
if (was_temp)
|
||||
end_temporary_allocation ();
|
||||
|
||||
/* Extern inline function static data has external linkage. */
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& TREE_STATIC (decl)
|
||||
&& current_function_decl
|
||||
&& DECL_CONTEXT (decl) == current_function_decl
|
||||
&& DECL_THIS_INLINE (current_function_decl)
|
||||
&& DECL_PUBLIC (current_function_decl))
|
||||
{
|
||||
/* We can only do this if we can use common or weak, and we
|
||||
can't if it has been initialized and we don't support weak. */
|
||||
if (DECL_INITIAL (decl) == NULL_TREE
|
||||
|| DECL_INITIAL (decl) == error_mark_node)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_COMMON (decl) = 1;
|
||||
}
|
||||
else if (flag_weak)
|
||||
make_decl_one_only (decl);
|
||||
|
||||
if (TREE_PUBLIC (decl))
|
||||
DECL_ASSEMBLER_NAME (decl)
|
||||
= build_static_name (current_function_decl, DECL_NAME (decl));
|
||||
else if (! DECL_ARTIFICIAL (decl))
|
||||
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
|
||||
make_decl_rtl (decl, NULL_PTR, toplev);
|
||||
else if (TREE_CODE (decl) == VAR_DECL
|
||||
|
@ -7067,6 +7095,7 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
{
|
||||
tree cname, decl;
|
||||
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
|
||||
tree t;
|
||||
|
||||
if (ctype)
|
||||
cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL
|
||||
|
@ -7128,6 +7157,14 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
if (ctype && hack_decl_function_context (decl))
|
||||
DECL_NO_STATIC_CHAIN (decl) = 1;
|
||||
|
||||
for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
|
||||
if (TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
|
||||
{
|
||||
add_defarg_fn (decl);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Caller will do the rest of this. */
|
||||
if (check < 0)
|
||||
return decl;
|
||||
|
@ -8672,6 +8709,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
/* ANSI says that `const int foo ();'
|
||||
does not make the function foo const. */
|
||||
type = build_function_type (type, arg_types);
|
||||
|
||||
{
|
||||
tree t;
|
||||
for (t = arg_types; t; t = TREE_CHAIN (t))
|
||||
if (TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
|
||||
{
|
||||
add_defarg_fn (type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -9858,6 +9906,9 @@ grokparms (first_parm, funcdef_flag)
|
|||
PARM_DECL_EXPR (init) = 1;
|
||||
else if (processing_template_decl)
|
||||
;
|
||||
/* Unparsed default arg from in-class decl. */
|
||||
else if (TREE_CODE (init) == DEFAULT_ARG)
|
||||
;
|
||||
else if (TREE_CODE (init) == VAR_DECL
|
||||
|| TREE_CODE (init) == PARM_DECL)
|
||||
{
|
||||
|
@ -9877,6 +9928,7 @@ grokparms (first_parm, funcdef_flag)
|
|||
else
|
||||
init = require_instantiated_type (type, init, integer_zero_node);
|
||||
if (! processing_template_decl
|
||||
&& TREE_CODE (init) != DEFAULT_ARG
|
||||
&& ! can_convert_arg (type, TREE_TYPE (init), init))
|
||||
cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
|
||||
TREE_TYPE (init), decl);
|
||||
|
@ -9931,6 +9983,21 @@ grokparms (first_parm, funcdef_flag)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Called from the parser to update an element of TYPE_ARG_TYPES for some
|
||||
FUNCTION_TYPE with the newly parsed version of its default argument, which
|
||||
was previously digested as text. See snarf_defarg et al in lex.c. */
|
||||
|
||||
void
|
||||
replace_defarg (arg, init)
|
||||
tree arg, init;
|
||||
{
|
||||
if (! processing_template_decl
|
||||
&& ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init))
|
||||
cp_pedwarn ("invalid type `%T' for default argument to `%T'",
|
||||
TREE_TYPE (init), TREE_VALUE (arg));
|
||||
TREE_PURPOSE (arg) = init;
|
||||
}
|
||||
|
||||
int
|
||||
copy_args_p (d)
|
||||
|
@ -10595,13 +10662,6 @@ xref_basetypes (code_type_node, name, ref, binfo)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Effective C++ rule 14. The case of virtual functions but
|
||||
non-virtual dtor is handled in finish_struct_1. */
|
||||
if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
|
||||
&& TYPE_HAS_DESTRUCTOR (basetype))
|
||||
cp_warning ("base class `%#T' has a non-virtual destructor",
|
||||
basetype);
|
||||
|
||||
/* Note that the BINFO records which describe individual
|
||||
inheritances are *not* shared in the lattice! They
|
||||
cannot be shared because a given baseclass may be
|
||||
|
@ -10891,6 +10951,7 @@ build_enumerator (name, value)
|
|||
a function could mean local to a class method. */
|
||||
decl = build_decl (CONST_DECL, name, integer_type_node);
|
||||
DECL_INITIAL (decl) = value;
|
||||
TREE_READONLY (decl) = 1;
|
||||
|
||||
pushdecl (decl);
|
||||
GNU_xref_decl (current_function_decl, decl);
|
||||
|
@ -10988,6 +11049,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
|||
current_base_init_list = NULL_TREE;
|
||||
current_member_init_list = NULL_TREE;
|
||||
ctor_label = dtor_label = NULL_TREE;
|
||||
static_labelno = 0;
|
||||
|
||||
clear_temp_name ();
|
||||
|
||||
|
@ -12606,6 +12668,7 @@ struct cp_function
|
|||
rtx result_rtx;
|
||||
struct cp_function *next;
|
||||
struct binding_level *binding_level;
|
||||
int static_labelno;
|
||||
};
|
||||
|
||||
static struct cp_function *cp_function_chain;
|
||||
|
@ -12647,6 +12710,7 @@ push_cp_function_context (context)
|
|||
p->member_init_list = current_member_init_list;
|
||||
p->current_class_ptr = current_class_ptr;
|
||||
p->current_class_ref = current_class_ref;
|
||||
p->static_labelno = static_labelno;
|
||||
}
|
||||
|
||||
/* Restore the variables used during compilation of a C++ function. */
|
||||
|
@ -12688,6 +12752,7 @@ pop_cp_function_context (context)
|
|||
current_member_init_list = p->member_init_list;
|
||||
current_class_ptr = p->current_class_ptr;
|
||||
current_class_ref = p->current_class_ref;
|
||||
static_labelno = p->static_labelno;
|
||||
|
||||
free (p);
|
||||
}
|
||||
|
|
|
@ -1081,7 +1081,8 @@ dump_expr (t, nop)
|
|||
case NEW_EXPR:
|
||||
OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
|
||||
OB_PUTC ('(');
|
||||
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
|
||||
if (TREE_OPERAND (t, 1))
|
||||
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
|
||||
OB_PUTC (')');
|
||||
break;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ Questions and comments to Mike Stump @code{<mrs@@cygnus.com>}.
|
|||
* Copying Objects::
|
||||
* Exception Handling::
|
||||
* Free Store::
|
||||
* Mangling:: Function name mangling for C++ and Java
|
||||
* Concept Index::
|
||||
@end menu
|
||||
|
||||
|
@ -1472,7 +1473,7 @@ would do the hard work of fixing up the registers, adjusting the stack
|
|||
pointer, frame pointer, arg pointer and so on.
|
||||
|
||||
|
||||
@node Free Store, Concept Index, Exception Handling, Top
|
||||
@node Free Store, Mangling, Exception Handling, Top
|
||||
@section Free Store
|
||||
|
||||
@code{operator new []} adds a magic cookie to the beginning of arrays
|
||||
|
@ -1518,8 +1519,246 @@ The linkage code in g++ is horribly twisted in order to meet two design goals:
|
|||
To meet the first goal, we defer emission of inlines and vtables until
|
||||
the end of the translation unit, where we can decide whether or not they
|
||||
are needed, and how to emit them if they are.
|
||||
|
||||
@node Mangling, Concept Index, Free Store, Top
|
||||
@section Function name mangling for C++ and Java
|
||||
|
||||
Both C++ and Jave provide overloaded function and methods,
|
||||
which are methods with the same types but different parameter lists.
|
||||
Selecting the correct version is done at compile time.
|
||||
Though the overloaded functions have the same name in the source code,
|
||||
they need to be translated into different assembler-level names,
|
||||
since typical assemblers and linkers cannot handle overloading.
|
||||
This process of encoding the parameter types with the method name
|
||||
into a unique name is called @dfn{name mangling}. The inverse
|
||||
process is called @dfn{demangling}.
|
||||
|
||||
It is convenient that C++ and Java use compatible mangling schemes,
|
||||
since the makes life easier for tools such as gdb, and it eases
|
||||
integration between C++ and Java.
|
||||
|
||||
Note there is also a standard "Jave Native Interface" (JNI) which
|
||||
implements a different calling convention, and uses a different
|
||||
mangling scheme. The JNI is a rather abstract ABI so Java can call methods
|
||||
written in C or C++;
|
||||
we are concerned here about a lower-level interface primarily
|
||||
intended for methods written in Java, but that can also be used for C++
|
||||
(and less easily C).
|
||||
|
||||
@subsection Method name mangling
|
||||
|
||||
C++ mangles a method by emitting the function name, followed by @code{__},
|
||||
followed by encodings of any method qualifiers (such as @code{const}),
|
||||
followed by the mangling of the method's class,
|
||||
followed by the mangling of the parameters, in order.
|
||||
|
||||
For example @code{Foo::bar(int, long) const} is mangled
|
||||
as @samp{bar__C3Fooil}.
|
||||
|
||||
For a constructor, the method name is left out.
|
||||
That is @code{Foo::Foo(int, long) const} is mangled
|
||||
as @samp{__C3Fooil}.
|
||||
|
||||
GNU Java does the same.
|
||||
|
||||
@subsection Primitive types
|
||||
|
||||
The C++ types @code{int}, @code{long}, @code{short}, @code{char},
|
||||
and @code{long long} are mangled as @samp{i}, @samp{l},
|
||||
@samp{s}, @samp{c}, and @samp{x}, respectively.
|
||||
The corresponding unsigned types have @samp{U} prefixed
|
||||
to the mangling. The type @code{signed char} is mangled @samp{Sc}.
|
||||
|
||||
The C++ and Java floating-point types @code{float} and @code{double}
|
||||
are mangled as @samp{f} and @samp{d} respectively.
|
||||
|
||||
The C++ @code{bool} type and the Java @code{boolean} type are
|
||||
mangled as @samp{b}.
|
||||
|
||||
The C++ @code{wchar_t} and the Java @code{char} types are
|
||||
mangled as @samp{w}.
|
||||
|
||||
The Java integral types @code{byte}, @code{short}, @code{int}
|
||||
and @code{long} are mangled as @samp{c}, @samp{s}, @samp{i},
|
||||
and @samp{x}, respectively.
|
||||
|
||||
C++ code that has included @code{javatypes.h} will mangle
|
||||
the typedefs @code{jbyte}, @code{jshort}, @code{jint}
|
||||
and @code{jlong} as respectively @samp{c}, @samp{s}, @samp{i},
|
||||
and @samp{x}. (This has not been implemented yet.)
|
||||
|
||||
@subsection Mangling of simple names
|
||||
|
||||
A simple class, package, template, or namespace name is
|
||||
encoded as the number of characters in the name, followed by
|
||||
the actual characters. Thus the class @code{Foo}
|
||||
is encoded as @samp{3Foo}.
|
||||
|
||||
If any of the characters in the name are not alphanumeric
|
||||
(i.e not one of the standard ASCII letters, digits, or '_'),
|
||||
or the initial character is a digit, then the name is
|
||||
mangled as a sequence of encoded Unicode letters.
|
||||
A Unicode encoding starts with a @samp{U} to indicate
|
||||
that Unicode escapes are used, followed by the number of
|
||||
bytes used by the Unicode encoding, followed by the bytes
|
||||
representing the encoding. ASSCI letters and
|
||||
non-initial digits are encoded without change. However, all
|
||||
other characters (including underscore and initial digits) are
|
||||
translated into a sequence starting with an underscore,
|
||||
followed by the big-endian 4-hex-digit lower-case encoding of the character.
|
||||
|
||||
If a method name contains Unicode-escaped characters, the
|
||||
entire mangled method name is followed by a @samp{U}.
|
||||
|
||||
For example, the method @code{X\u0319::M\u002B(int)} is encoded as
|
||||
@samp{M_002b__U6X_0319iU}.
|
||||
|
||||
@subsection Pointer and reference types
|
||||
|
||||
A C++ pointer type is mangled as @samp{P} followed by the
|
||||
mangling of the type pointed to.
|
||||
|
||||
A C++ reference type as mangled as @samp{R} followed by the
|
||||
mangling of the type referenced.
|
||||
|
||||
A Java object reference type is equivalent
|
||||
to a C++ pointer parameter, so we mangle such an parameter type
|
||||
as @samp{P} followed by the mangling of the class name.
|
||||
|
||||
@subsection Qualified names
|
||||
|
||||
Both C++ and Java allow a class to be lexically nested inside another
|
||||
class. C++ also supports namespaces (not yet implemented by G++).
|
||||
Java also supports packages.
|
||||
|
||||
These are all mangled the same way: First the letter @samp{Q}
|
||||
indicates that we are emitting a qualified name.
|
||||
That is followed by the number of parts in the qualified name.
|
||||
If that number is 9 or less, it is emitted with no delimiters.
|
||||
Otherwise, an underscore is written before and after the count.
|
||||
Then follows each part of the qualified name, as described above.
|
||||
|
||||
For example @code{Foo::\u0319::Bar} is encoded as
|
||||
@samp{Q33FooU5_03193Bar}.
|
||||
|
||||
@subsection Templates
|
||||
|
||||
A template instantiation is encoded as the letter @samp{t},
|
||||
followed by the encoding of the template name, followed
|
||||
the number of template parameters, followed by encoding of the template
|
||||
parameters. If a template parameter is a type, it is written
|
||||
as a @samp{Z} followed by the encoding of the type.
|
||||
|
||||
@subsection Arrays
|
||||
|
||||
C++ array types are mangled by emitting @samp{A}, followed by
|
||||
the length of the array, followed by an @samp{_}, followed by
|
||||
the mangling of the element type. Of course, normally
|
||||
array parameter types decay into a pointer types, so you
|
||||
don't see this.
|
||||
|
||||
Java arrays are objects. A Java type @code{T[]} is mangled
|
||||
as if it were the C++ type @code{JArray<T>}.
|
||||
For example @code{java.lang.String[]} is encoded as
|
||||
@samp{Pt6JArray1ZPQ34java4lang6String}.
|
||||
|
||||
@subsection Table of demangling code characters
|
||||
|
||||
The following special characters are used in mangling:
|
||||
|
||||
@table @samp
|
||||
@item A
|
||||
Indicates a C++ array type.
|
||||
|
||||
@item b
|
||||
Encodes the C++ @code{bool} type,
|
||||
and the Java @code{boolean} type.
|
||||
|
||||
@item c
|
||||
Encodes the C++ @code{char} type, and the Java @code{byte} type.
|
||||
|
||||
@item C
|
||||
A modifier to indicate a @code{const} type.
|
||||
Also used to indicate a @code{const} member function
|
||||
(in which cases it precedes the encoding of the method's class).
|
||||
|
||||
@item d
|
||||
Encodes the C++ and Java @code{double} types.
|
||||
|
||||
@item e
|
||||
Indicates extra unknown arguments @code{...}.
|
||||
|
||||
@item f
|
||||
Encodes the C++ and Java @code{float} types.
|
||||
|
||||
@item F
|
||||
Used to indicate a function type.
|
||||
|
||||
@item i
|
||||
Encodes the C++ and Java @code{int} types.
|
||||
|
||||
@item J
|
||||
Indicates a complex type.
|
||||
|
||||
@item l
|
||||
Encodes the C++ @code{long} type.
|
||||
|
||||
@item P
|
||||
Indicates a pointer type. Followed by the type pointed to.
|
||||
|
||||
@item Q
|
||||
Used to mangle qualified names, which arise from nested classes.
|
||||
Should also be used for namespaces (?).
|
||||
In Java used to mangle package-qualified names, and inner classes.
|
||||
|
||||
@item r
|
||||
Encodes the GNU C++ @code{long double} type.
|
||||
|
||||
@item R
|
||||
Indicates a reference type. Followed by the referenced type.
|
||||
|
||||
@item s
|
||||
Encodes the C++ and java @code{short} types.
|
||||
|
||||
@item S
|
||||
A modifier that indicates that the following integer type is signed.
|
||||
Only used with @code{char}.
|
||||
|
||||
Also used as a modifier to indicate a static member function.
|
||||
|
||||
@item t
|
||||
Indicates a template instantiation.
|
||||
|
||||
@item T
|
||||
A back reference to a previously seen type.
|
||||
|
||||
@item U
|
||||
A modifier that indicates that the following integer type is unsigned.
|
||||
Also used to indicate that the following class or namespace name
|
||||
is encoded using Unicode-mangling.
|
||||
|
||||
@item v
|
||||
Encodes the C++ and Java @code{void} types.
|
||||
|
||||
@item V
|
||||
A modified for a @code{const} type or method.
|
||||
|
||||
@item w
|
||||
Encodes the C++ @code{wchar_t} type, and the Java @code{char} types.
|
||||
|
||||
@item x
|
||||
Encodes the GNU C++ @code{long long} type, and the Java @code{long} type.
|
||||
|
||||
@item Z
|
||||
Used for template type parameters.
|
||||
|
||||
@end table
|
||||
|
||||
The letters @samp{G}, @samp{M}, @samp{O}, and @samp{p}
|
||||
also seem to be used for obscure purposes ...
|
||||
|
||||
@node Concept Index, , Mangling, Top
|
||||
|
||||
@node Concept Index, , Free Store, Top
|
||||
@section Concept Index
|
||||
|
||||
@printindex cp
|
||||
|
|
|
@ -1963,7 +1963,7 @@ build_offset_ref (type, name)
|
|||
if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
|
||||
{
|
||||
mark_used (t);
|
||||
return t;
|
||||
return convert_from_reference (t);
|
||||
}
|
||||
|
||||
if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t))
|
||||
|
|
|
@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */
|
|||
inlining). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "obstack.h"
|
||||
|
||||
extern FILE *finput;
|
||||
|
||||
|
@ -43,8 +42,6 @@ struct input_source {
|
|||
int length;
|
||||
/* current position, when reading as input */
|
||||
int offset;
|
||||
/* obstack to free this input string from when finished, if any */
|
||||
struct obstack *obstack;
|
||||
/* linked list maintenance */
|
||||
struct input_source *next;
|
||||
/* values to restore after reading all of current string */
|
||||
|
@ -78,7 +75,6 @@ allocate_input ()
|
|||
}
|
||||
inp = (struct input_source *) xmalloc (sizeof (struct input_source));
|
||||
inp->next = 0;
|
||||
inp->obstack = 0;
|
||||
return inp;
|
||||
}
|
||||
|
||||
|
@ -86,9 +82,6 @@ static inline void
|
|||
free_input (inp)
|
||||
struct input_source *inp;
|
||||
{
|
||||
if (inp->obstack)
|
||||
obstack_free (inp->obstack, inp->str);
|
||||
inp->obstack = 0;
|
||||
inp->str = 0;
|
||||
inp->length = 0;
|
||||
inp->next = free_inputs;
|
||||
|
@ -102,10 +95,9 @@ static int putback_char = -1;
|
|||
|
||||
inline
|
||||
void
|
||||
feed_input (str, len, delete)
|
||||
feed_input (str, len)
|
||||
char *str;
|
||||
int len;
|
||||
struct obstack *delete;
|
||||
{
|
||||
struct input_source *inp = allocate_input ();
|
||||
|
||||
|
@ -115,7 +107,6 @@ feed_input (str, len, delete)
|
|||
|
||||
inp->str = str;
|
||||
inp->length = len;
|
||||
inp->obstack = delete;
|
||||
inp->offset = 0;
|
||||
inp->next = input;
|
||||
inp->filename = input_filename;
|
||||
|
@ -129,6 +120,22 @@ feed_input (str, len, delete)
|
|||
struct pending_input *to_be_restored; /* XXX */
|
||||
extern int end_of_file;
|
||||
|
||||
static inline void
|
||||
end_input ()
|
||||
{
|
||||
struct input_source *inp = input;
|
||||
|
||||
end_of_file = 0;
|
||||
input = inp->next;
|
||||
input_filename = inp->filename;
|
||||
lineno = inp->lineno;
|
||||
/* Get interface/implementation back in sync. */
|
||||
extract_interface_info ();
|
||||
putback_char = inp->putback_char;
|
||||
restore_pending_input (inp->input);
|
||||
free_input (inp);
|
||||
}
|
||||
|
||||
static inline int
|
||||
sub_getch ()
|
||||
{
|
||||
|
@ -140,30 +147,12 @@ sub_getch ()
|
|||
}
|
||||
if (input)
|
||||
{
|
||||
if (input->offset == input->length)
|
||||
if (input->offset >= input->length)
|
||||
{
|
||||
struct input_source *inp = input;
|
||||
my_friendly_assert (putback_char == -1, 223);
|
||||
to_be_restored = inp->input;
|
||||
input->offset++;
|
||||
return EOF;
|
||||
}
|
||||
else if (input->offset > input->length)
|
||||
{
|
||||
struct input_source *inp = input;
|
||||
|
||||
end_of_file = 0;
|
||||
input = inp->next;
|
||||
input_filename = inp->filename;
|
||||
lineno = inp->lineno;
|
||||
/* Get interface/implementation back in sync. */
|
||||
extract_interface_info ();
|
||||
putback_char = inp->putback_char;
|
||||
free_input (inp);
|
||||
return getch ();
|
||||
}
|
||||
if (input)
|
||||
return (unsigned char)input->str[input->offset++];
|
||||
return (unsigned char)input->str[input->offset++];
|
||||
}
|
||||
return getc (finput);
|
||||
}
|
||||
|
|
276
gcc/cp/lex.c
276
gcc/cp/lex.c
|
@ -72,6 +72,7 @@ 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;
|
||||
char *inline_text_firstobj;
|
||||
|
||||
int end_of_file;
|
||||
|
||||
|
@ -91,7 +92,7 @@ extern struct obstack token_obstack;
|
|||
#else
|
||||
extern void put_back (/* int */);
|
||||
extern int input_redirected ();
|
||||
extern void feed_input (/* char *, int, struct obstack * */);
|
||||
extern void feed_input (/* char *, int */);
|
||||
#endif
|
||||
|
||||
/* Holds translations from TREE_CODEs to operator name strings,
|
||||
|
@ -575,6 +576,7 @@ init_lex ()
|
|||
init_method ();
|
||||
init_error ();
|
||||
gcc_obstack_init (&inline_text_obstack);
|
||||
inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
|
||||
|
||||
/* Start it at 0, because check_newline is called at the very beginning
|
||||
and will increment it to 1. */
|
||||
|
@ -1170,7 +1172,7 @@ do_pending_inlines ()
|
|||
push_cp_function_context (context);
|
||||
if (t->len > 0)
|
||||
{
|
||||
feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
|
||||
feed_input (t->buf, t->len);
|
||||
lineno = t->lineno;
|
||||
#if 0
|
||||
if (input_filename != t->filename)
|
||||
|
@ -1192,7 +1194,6 @@ do_pending_inlines ()
|
|||
DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
|
||||
}
|
||||
|
||||
extern struct pending_input *to_be_restored;
|
||||
static int nextchar = -1;
|
||||
|
||||
/* Called from the fndecl rule in the parser when the function just parsed
|
||||
|
@ -1222,16 +1223,13 @@ process_next_inline (t)
|
|||
nextchar = -1;
|
||||
}
|
||||
yychar = YYEMPTY;
|
||||
if (to_be_restored == 0)
|
||||
my_friendly_abort (123);
|
||||
restore_pending_input (to_be_restored);
|
||||
to_be_restored = 0;
|
||||
end_input ();
|
||||
if (i && i->fndecl != NULL_TREE)
|
||||
{
|
||||
context = hack_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);
|
||||
feed_input (i->buf, i->len);
|
||||
lineno = i->lineno;
|
||||
input_filename = i->filename;
|
||||
yychar = PRE_PARSED_FUNCTION_DECL;
|
||||
|
@ -1392,6 +1390,12 @@ yyungetc (ch, rescan)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
clear_inline_text_obstack ()
|
||||
{
|
||||
obstack_free (&inline_text_obstack, inline_text_firstobj);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
@ -1448,7 +1452,6 @@ reinit_parse_for_method (yychar, decl)
|
|||
t->token_value = 0;
|
||||
t->buf = buf;
|
||||
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))
|
||||
|
@ -1625,6 +1628,259 @@ reinit_parse_for_block (pyychar, obstackp)
|
|||
obstack_1grow (obstackp, '\0');
|
||||
}
|
||||
|
||||
/* Consume a no-commas expression -- actually, a default argument -- and
|
||||
save it away on the specified obstack. */
|
||||
|
||||
static void
|
||||
reinit_parse_for_expr (obstackp)
|
||||
struct obstack *obstackp;
|
||||
{
|
||||
register int c = 0;
|
||||
int starting_lineno = lineno;
|
||||
char *starting_filename = input_filename;
|
||||
int len;
|
||||
int look_for_semicolon = 0;
|
||||
int look_for_lbrac = 0;
|
||||
int plev = 0;
|
||||
|
||||
if (nextchar != EOF)
|
||||
{
|
||||
c = nextchar;
|
||||
nextchar = EOF;
|
||||
}
|
||||
else
|
||||
c = getch ();
|
||||
|
||||
while (c != EOF)
|
||||
{
|
||||
int this_lineno = lineno;
|
||||
|
||||
c = skip_white_space (c);
|
||||
|
||||
/* Don't lose our cool if there are lots of comments. */
|
||||
if (lineno == this_lineno + 1)
|
||||
obstack_1grow (obstackp, '\n');
|
||||
else if (lineno == this_lineno)
|
||||
;
|
||||
else if (lineno - this_lineno < 10)
|
||||
{
|
||||
int i;
|
||||
for (i = lineno - this_lineno; i > 0; --i)
|
||||
obstack_1grow (obstackp, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[16];
|
||||
sprintf (buf, "\n# %d \"", lineno);
|
||||
len = strlen (buf);
|
||||
obstack_grow (obstackp, buf, len);
|
||||
|
||||
len = strlen (input_filename);
|
||||
obstack_grow (obstackp, input_filename, len);
|
||||
obstack_1grow (obstackp, '\"');
|
||||
obstack_1grow (obstackp, '\n');
|
||||
}
|
||||
|
||||
while (c > ' ') /* ASCII dependent... */
|
||||
{
|
||||
if (plev <= 0 && (c == ')' || c == ','))
|
||||
{
|
||||
put_back (c);
|
||||
goto done;
|
||||
}
|
||||
obstack_1grow (obstackp, c);
|
||||
if (c == '(' || c == '[')
|
||||
++plev;
|
||||
else if (c == ']' || c == ')')
|
||||
--plev;
|
||||
else if (c == '\\')
|
||||
{
|
||||
/* Don't act on the next character...e.g, doing an escaped
|
||||
double-quote. */
|
||||
c = getch ();
|
||||
if (c == EOF)
|
||||
{
|
||||
error_with_file_and_line (starting_filename,
|
||||
starting_lineno,
|
||||
"end of file read inside definition");
|
||||
goto done;
|
||||
}
|
||||
obstack_1grow (obstackp, c);
|
||||
}
|
||||
else if (c == '\"')
|
||||
consume_string (obstackp, c);
|
||||
else if (c == '\'')
|
||||
consume_string (obstackp, c);
|
||||
c = getch ();
|
||||
}
|
||||
|
||||
if (c == EOF)
|
||||
{
|
||||
error_with_file_and_line (starting_filename,
|
||||
starting_lineno,
|
||||
"end of file read inside definition");
|
||||
goto done;
|
||||
}
|
||||
else if (c != '\n')
|
||||
{
|
||||
obstack_1grow (obstackp, c);
|
||||
c = getch ();
|
||||
}
|
||||
}
|
||||
done:
|
||||
obstack_1grow (obstackp, '\0');
|
||||
}
|
||||
|
||||
int do_snarf_defarg;
|
||||
|
||||
/* Decide whether the default argument we are about to see should be
|
||||
gobbled up as text for later parsing. */
|
||||
|
||||
void
|
||||
maybe_snarf_defarg ()
|
||||
{
|
||||
if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
|
||||
do_snarf_defarg = 1;
|
||||
}
|
||||
|
||||
/* When we see a default argument in a method declaration, we snarf it as
|
||||
text using snarf_defarg. When we get up to namespace scope, we then go
|
||||
through and parse all of them using do_pending_defargs. Since yacc
|
||||
parsers are not reentrant, we retain defargs state in these two
|
||||
variables so that subsequent calls to do_pending_defargs can resume
|
||||
where the previous call left off. */
|
||||
|
||||
tree defarg_fns;
|
||||
tree defarg_parm;
|
||||
|
||||
tree
|
||||
snarf_defarg ()
|
||||
{
|
||||
int len;
|
||||
char *buf;
|
||||
tree arg;
|
||||
struct pending_inline *t;
|
||||
|
||||
reinit_parse_for_expr (&inline_text_obstack);
|
||||
len = obstack_object_size (&inline_text_obstack);
|
||||
buf = obstack_finish (&inline_text_obstack);
|
||||
|
||||
push_obstacks (&inline_text_obstack, &inline_text_obstack);
|
||||
arg = make_node (DEFAULT_ARG);
|
||||
DEFARG_LENGTH (arg) = len - 1;
|
||||
DEFARG_POINTER (arg) = buf;
|
||||
pop_obstacks ();
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
/* Called from grokfndecl to note a function decl with unparsed default
|
||||
arguments for later processing. Also called from grokdeclarator
|
||||
for function types with unparsed defargs; the call from grokfndecl
|
||||
will always come second, so we can overwrite the entry from the type. */
|
||||
|
||||
void
|
||||
add_defarg_fn (decl)
|
||||
tree decl;
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
TREE_VALUE (defarg_fns) = decl;
|
||||
else
|
||||
{
|
||||
push_obstacks (&inline_text_obstack, &inline_text_obstack);
|
||||
defarg_fns = tree_cons (current_class_type, decl, defarg_fns);
|
||||
pop_obstacks ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for do_pending_defargs. Starts the parsing of a default arg. */
|
||||
|
||||
static void
|
||||
feed_defarg (f, p)
|
||||
tree f, p;
|
||||
{
|
||||
tree d = TREE_PURPOSE (p);
|
||||
feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
|
||||
if (TREE_CODE (f) == FUNCTION_DECL)
|
||||
{
|
||||
lineno = DECL_SOURCE_LINE (f);
|
||||
input_filename = DECL_SOURCE_FILE (f);
|
||||
}
|
||||
yychar = DEFARG_MARKER;
|
||||
yylval.ttype = p;
|
||||
}
|
||||
|
||||
/* Helper for do_pending_defargs. Ends the parsing of a default arg. */
|
||||
|
||||
static void
|
||||
finish_defarg ()
|
||||
{
|
||||
if (yychar == YYEMPTY)
|
||||
yychar = yylex ();
|
||||
if (yychar != END_OF_SAVED_INPUT)
|
||||
{
|
||||
error ("parse error at end of saved function text");
|
||||
|
||||
/* restore_pending_input will abort unless yychar is either
|
||||
END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
|
||||
hosed, feed back YYEMPTY. We also need to discard nextchar,
|
||||
since that may have gotten set as well. */
|
||||
nextchar = -1;
|
||||
}
|
||||
yychar = YYEMPTY;
|
||||
end_input ();
|
||||
}
|
||||
|
||||
/* Main function for deferred parsing of default arguments. Called from
|
||||
the parser. */
|
||||
|
||||
void
|
||||
do_pending_defargs ()
|
||||
{
|
||||
if (defarg_parm)
|
||||
finish_defarg ();
|
||||
|
||||
for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
|
||||
{
|
||||
tree defarg_fn = TREE_VALUE (defarg_fns);
|
||||
if (defarg_parm == NULL_TREE)
|
||||
{
|
||||
tree p;
|
||||
|
||||
push_nested_class (TREE_PURPOSE (defarg_fns), 1);
|
||||
pushlevel (0);
|
||||
|
||||
if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
|
||||
{
|
||||
#if 0
|
||||
for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
|
||||
pushdecl (copy_node (p));
|
||||
#endif
|
||||
defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
|
||||
}
|
||||
else
|
||||
defarg_parm = TYPE_ARG_TYPES (defarg_fn);
|
||||
}
|
||||
else
|
||||
defarg_parm = TREE_CHAIN (defarg_parm);
|
||||
|
||||
for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
|
||||
if (TREE_PURPOSE (defarg_parm))
|
||||
{
|
||||
my_friendly_assert (TREE_CODE (TREE_PURPOSE (defarg_parm))
|
||||
== DEFAULT_ARG, 2349);
|
||||
feed_defarg (defarg_fn, defarg_parm);
|
||||
|
||||
/* Return to the parser, which will process this defarg
|
||||
and call us again. */
|
||||
return;
|
||||
}
|
||||
|
||||
poplevel (0, 0, 0);
|
||||
pop_nested_class (1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a default function named NAME for type TYPE.
|
||||
KIND says what to build.
|
||||
|
||||
|
@ -2716,7 +2972,7 @@ do_scoped_id (token, parsing)
|
|||
}
|
||||
/* else just use the decl */
|
||||
}
|
||||
return id;
|
||||
return convert_from_reference (id);
|
||||
}
|
||||
|
||||
tree
|
||||
|
|
124
gcc/cp/method.c
124
gcc/cp/method.c
|
@ -43,6 +43,8 @@ Boston, MA 02111-1307, USA. */
|
|||
processed. */
|
||||
struct pending_inline *pending_inlines;
|
||||
|
||||
int static_labelno;
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
|
||||
|
@ -371,18 +373,15 @@ build_overload_nested_name (decl)
|
|||
{
|
||||
tree name = DECL_ASSEMBLER_NAME (decl);
|
||||
char *label;
|
||||
extern int var_labelno;
|
||||
|
||||
ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
|
||||
var_labelno++;
|
||||
ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno);
|
||||
static_labelno++;
|
||||
|
||||
if (numeric_output_need_bar)
|
||||
{
|
||||
OB_PUTC ('_');
|
||||
numeric_output_need_bar = 0;
|
||||
}
|
||||
OB_PUTC ('_');
|
||||
icat (strlen (label));
|
||||
OB_PUTCP (label);
|
||||
numeric_output_need_bar = 1;
|
||||
}
|
||||
else /* TYPE_DECL */
|
||||
build_overload_identifier (decl);
|
||||
|
@ -669,6 +668,49 @@ build_overload_identifier (name)
|
|||
}
|
||||
}
|
||||
|
||||
/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce
|
||||
the mangling for it. Used by build_overload_name and build_static_name. */
|
||||
|
||||
static void
|
||||
build_qualified_name (decl)
|
||||
tree decl;
|
||||
{
|
||||
tree context;
|
||||
int i = 1;
|
||||
|
||||
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')
|
||||
decl = TYPE_NAME (decl);
|
||||
|
||||
/* If DECL_ASSEMBLER_NAME has been set properly, use it. */
|
||||
if (TREE_CODE (decl) == TYPE_DECL
|
||||
&& DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
|
||||
{
|
||||
OB_PUTID (DECL_ASSEMBLER_NAME (decl));
|
||||
return;
|
||||
}
|
||||
|
||||
context = decl;
|
||||
while (DECL_CONTEXT (context))
|
||||
{
|
||||
i += 1;
|
||||
context = DECL_CONTEXT (context);
|
||||
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
|
||||
context = TYPE_NAME (context);
|
||||
}
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
OB_PUTC ('Q');
|
||||
if (i > 9)
|
||||
OB_PUTC ('_');
|
||||
icat (i);
|
||||
if (i > 9)
|
||||
OB_PUTC ('_');
|
||||
numeric_output_need_bar = 0;
|
||||
}
|
||||
build_overload_nested_name (decl);
|
||||
}
|
||||
|
||||
/* Given a list of parameters in PARMTYPES, create an unambiguous
|
||||
overload string. Should distinguish any type that C (or C++) can
|
||||
distinguish. I.e., pointers to functions are treated correctly.
|
||||
|
@ -931,41 +973,15 @@ build_overload_name (parmtypes, begin, end)
|
|||
common:
|
||||
{
|
||||
tree name = TYPE_NAME (parmtype);
|
||||
int i = 1;
|
||||
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
if (TREE_CODE (name) == IDENTIFIER_NODE)
|
||||
{
|
||||
tree context = name;
|
||||
build_overload_identifier (TYPE_NAME (parmtype));
|
||||
break;
|
||||
}
|
||||
my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248);
|
||||
|
||||
/* If DECL_ASSEMBLER_NAME has been set properly, use it. */
|
||||
if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
|
||||
{
|
||||
OB_PUTID (DECL_ASSEMBLER_NAME (context));
|
||||
break;
|
||||
}
|
||||
while (DECL_CONTEXT (context))
|
||||
{
|
||||
i += 1;
|
||||
context = DECL_CONTEXT (context);
|
||||
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
|
||||
context = TYPE_NAME (context);
|
||||
}
|
||||
name = DECL_NAME (name);
|
||||
}
|
||||
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
|
||||
if (i > 1)
|
||||
{
|
||||
OB_PUTC ('Q');
|
||||
if (i > 9)
|
||||
OB_PUTC ('_');
|
||||
icat (i);
|
||||
if (i > 9)
|
||||
OB_PUTC ('_');
|
||||
numeric_output_need_bar = 0;
|
||||
build_overload_nested_name (TYPE_NAME (parmtype));
|
||||
}
|
||||
else
|
||||
build_overload_identifier (TYPE_NAME (parmtype));
|
||||
build_qualified_name (name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1015,17 +1031,29 @@ build_overload_name (parmtypes, begin, end)
|
|||
return (char *)obstack_base (&scratch_obstack);
|
||||
}
|
||||
|
||||
/* Produce the mangling for a variable named NAME in CONTEXT, which can
|
||||
be either a class TYPE or a FUNCTION_DECL. */
|
||||
|
||||
tree
|
||||
build_static_name (basetype, name)
|
||||
tree basetype, name;
|
||||
build_static_name (context, name)
|
||||
tree context, name;
|
||||
{
|
||||
char *basename = build_overload_name (basetype, 1, 1);
|
||||
char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)
|
||||
+ sizeof (STATIC_NAME_FORMAT)
|
||||
+ strlen (basename));
|
||||
sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));
|
||||
return get_identifier (buf);
|
||||
}
|
||||
OB_INIT ();
|
||||
numeric_output_need_bar = 0;
|
||||
#ifdef JOINER
|
||||
OB_PUTC ('_');
|
||||
build_qualified_name (context);
|
||||
OB_PUTC (JOINER);
|
||||
#else
|
||||
OB_PUTS ("__static_");
|
||||
build_qualified_name (context);
|
||||
OB_PUTC (' ');
|
||||
#endif
|
||||
OB_PUTID (name);
|
||||
OB_FINISH ();
|
||||
|
||||
return get_identifier ((char *)obstack_base (&scratch_obstack));
|
||||
}
|
||||
|
||||
/* Change the name of a function definition so that it may be
|
||||
overloaded. NAME is the name of the function to overload,
|
||||
|
|
|
@ -89,7 +89,10 @@ empty_parms ()
|
|||
tree parms;
|
||||
|
||||
if (strict_prototype
|
||||
|| current_class_type != NULL)
|
||||
/* Only go ahead with using the void list node if we're actually
|
||||
parsing a class in C++, not a struct in extern "C" mode. */
|
||||
|| (current_class_type != NULL
|
||||
&& current_lang_name == lang_name_cplusplus))
|
||||
parms = void_list_node;
|
||||
else
|
||||
parms = NULL_TREE;
|
||||
|
@ -201,7 +204,7 @@ empty_parms ()
|
|||
%type <ttype> declmods
|
||||
%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
|
||||
%type <itype> initdecls notype_initdecls initdcl /* C++ modification */
|
||||
%type <ttype> init initlist maybeasm maybe_init
|
||||
%type <ttype> init initlist maybeasm maybe_init defarg defarg1
|
||||
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
|
||||
%type <ttype> maybe_attribute attributes attribute attribute_list attrib
|
||||
%type <ttype> any_word
|
||||
|
@ -236,7 +239,7 @@ empty_parms ()
|
|||
/* C++ extensions */
|
||||
%token <ttype> TYPENAME_ELLIPSIS PTYPENAME
|
||||
%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
|
||||
%token <ttype> PRE_PARSED_CLASS_DECL
|
||||
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
|
||||
%type <ttype> fn.def1 /* Not really! */ component_constructor_declarator
|
||||
%type <ttype> fn.def2 return_id fn.defpen constructor_declarator
|
||||
%type <itype> ctor_initializer_opt
|
||||
|
@ -284,13 +287,13 @@ empty_parms ()
|
|||
|
||||
%{
|
||||
/* List of types and structure classes of the current declaration. */
|
||||
static tree current_declspecs;
|
||||
static tree current_declspecs = NULL_TREE;
|
||||
/* List of prefix attributes in effect.
|
||||
Prefix attributes are parsed by the reserved_declspecs and declmods
|
||||
rules. They create a list that contains *both* declspecs and attrs. */
|
||||
/* ??? It is not clear yet that all cases where an attribute can now appear in
|
||||
a declspec list have been updated. */
|
||||
static tree prefix_attributes;
|
||||
static tree prefix_attributes = NULL_TREE;
|
||||
|
||||
/* When defining an aggregate, this is the most recent one being defined. */
|
||||
static tree current_aggr;
|
||||
|
@ -1661,7 +1664,7 @@ decl:
|
|||
typespec initdecls ';'
|
||||
{
|
||||
resume_momentary ($2);
|
||||
if (IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))
|
||||
if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))
|
||||
note_got_semicolon ($1.t);
|
||||
}
|
||||
| typed_declspecs initdecls ';'
|
||||
|
@ -1907,7 +1910,8 @@ initdcl0:
|
|||
declarator maybeasm maybe_attribute '='
|
||||
{ split_specs_attrs ($<ttype>0, ¤t_declspecs,
|
||||
&prefix_attributes);
|
||||
if (TREE_CODE (current_declspecs) != TREE_LIST)
|
||||
if (current_declspecs
|
||||
&& TREE_CODE (current_declspecs) != TREE_LIST)
|
||||
current_declspecs = get_decl_list (current_declspecs);
|
||||
if (have_extern_spec && !used_extern_spec)
|
||||
{
|
||||
|
@ -1927,7 +1931,8 @@ initdcl0:
|
|||
{ tree d;
|
||||
split_specs_attrs ($<ttype>0, ¤t_declspecs,
|
||||
&prefix_attributes);
|
||||
if (TREE_CODE (current_declspecs) != TREE_LIST)
|
||||
if (current_declspecs
|
||||
&& TREE_CODE (current_declspecs) != TREE_LIST)
|
||||
current_declspecs = get_decl_list (current_declspecs);
|
||||
if (have_extern_spec && !used_extern_spec)
|
||||
{
|
||||
|
@ -2119,6 +2124,20 @@ pending_inlines:
|
|||
eat_saved_input
|
||||
;
|
||||
|
||||
/* A regurgitated default argument. The value of DEFARG_MARKER will be
|
||||
the TREE_LIST node for the parameter in question. */
|
||||
defarg_again:
|
||||
DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT
|
||||
{ replace_defarg ($1, $2); }
|
||||
|
||||
pending_defargs:
|
||||
/* empty */ %prec EMPTY
|
||||
| pending_defargs defarg_again
|
||||
{ do_pending_defargs (); }
|
||||
| pending_defargs error
|
||||
{ do_pending_defargs (); }
|
||||
;
|
||||
|
||||
structsp:
|
||||
ENUM identifier '{'
|
||||
{ $<itype>3 = suspend_momentary ();
|
||||
|
@ -2188,13 +2207,22 @@ structsp:
|
|||
|
||||
if (! semi)
|
||||
check_for_missing_semicolon ($1);
|
||||
if (current_scope () == current_function_decl)
|
||||
do_pending_defargs ($1);
|
||||
}
|
||||
pending_defargs
|
||||
{
|
||||
if (pending_inlines
|
||||
&& current_scope () == current_function_decl)
|
||||
do_pending_inlines ();
|
||||
}
|
||||
pending_inlines
|
||||
{ $$.t = $<ttype>6;
|
||||
$$.new_type_flag = 1; }
|
||||
{
|
||||
$$.t = $<ttype>6;
|
||||
$$.new_type_flag = 1;
|
||||
if (current_scope () == current_function_decl)
|
||||
clear_inline_text_obstack ();
|
||||
}
|
||||
| class_head %prec EMPTY
|
||||
{
|
||||
$$.t = $1;
|
||||
|
@ -3951,14 +3979,27 @@ complex_parmlist:
|
|||
}
|
||||
;
|
||||
|
||||
/* A default argument to a */
|
||||
defarg:
|
||||
'='
|
||||
{ maybe_snarf_defarg (); }
|
||||
defarg1
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
defarg1:
|
||||
DEFARG
|
||||
| init
|
||||
;
|
||||
|
||||
/* A nonempty list of parameter declarations or type names. */
|
||||
parms:
|
||||
named_parm
|
||||
{ check_for_new_type ("in a parameter list", $1);
|
||||
$$ = build_tree_list (NULL_TREE, $1.t); }
|
||||
| parm '=' init
|
||||
| parm defarg
|
||||
{ check_for_new_type ("in a parameter list", $1);
|
||||
$$ = build_tree_list ($3, $1.t); }
|
||||
$$ = build_tree_list ($2, $1.t); }
|
||||
| parms_comma full_parm
|
||||
{ check_for_new_type ("in a parameter list", $2);
|
||||
$$ = chainon ($$, $2.t); }
|
||||
|
@ -4005,7 +4046,10 @@ named_parm:
|
|||
;
|
||||
|
||||
full_parm:
|
||||
parm maybe_init
|
||||
parm
|
||||
{ $$.t = build_tree_list (NULL_TREE, $1.t);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
| parm defarg
|
||||
{ $$.t = build_tree_list ($2, $1.t);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
;
|
||||
|
|
16
gcc/cp/pt.c
16
gcc/cp/pt.c
|
@ -962,6 +962,18 @@ uses_template_parms (t)
|
|||
return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
|
||||
return uses_template_parms (TREE_OPERAND (t, 1));
|
||||
|
||||
case MODOP_EXPR:
|
||||
case CAST_EXPR:
|
||||
case REINTERPRET_CAST_EXPR:
|
||||
case CONST_CAST_EXPR:
|
||||
case STATIC_CAST_EXPR:
|
||||
case DYNAMIC_CAST_EXPR:
|
||||
case SIZEOF_EXPR:
|
||||
case ARROW_EXPR:
|
||||
case DOTSTAR_EXPR:
|
||||
case TYPEID_EXPR:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (t)))
|
||||
{
|
||||
|
@ -1849,9 +1861,6 @@ tsubst (t, args, nargs, in_decl)
|
|||
tree purpose = TREE_PURPOSE (values);
|
||||
tree x = build_tree_list (purpose, value);
|
||||
|
||||
if (purpose)
|
||||
PARM_DEFAULT_FROM_TEMPLATE (x) = 1;
|
||||
|
||||
if (first)
|
||||
TREE_CHAIN (last) = x;
|
||||
else
|
||||
|
@ -2828,6 +2837,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
|
|||
case REAL_TYPE:
|
||||
case COMPLEX_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
if (TREE_CODE (arg) != TREE_CODE (parm))
|
||||
return 1;
|
||||
|
||||
|
|
|
@ -405,8 +405,8 @@ ifnonnull (test, result)
|
|||
/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
|
||||
paper. */
|
||||
|
||||
tree
|
||||
build_dynamic_cast (type, expr)
|
||||
static tree
|
||||
build_dynamic_cast_1 (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
enum tree_code tc = TREE_CODE (type);
|
||||
|
@ -628,6 +628,13 @@ build_dynamic_cast (type, expr)
|
|||
expr, exprtype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
tree
|
||||
build_dynamic_cast (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
return convert_from_reference (build_dynamic_cast_1 (type, expr));
|
||||
}
|
||||
|
||||
/* Build and initialize various sorts of descriptors. Every descriptor
|
||||
node has a name associated with it (the name created by mangling).
|
||||
|
|
|
@ -215,6 +215,7 @@ probe_obstack (h, obj, nlevels)
|
|||
Value is 0 if we treat this name in a default fashion. */
|
||||
extern int looking_for_typename;
|
||||
int looking_for_template;
|
||||
extern int do_snarf_defarg;
|
||||
|
||||
extern struct obstack *current_obstack, *saveable_obstack;
|
||||
tree got_scope;
|
||||
|
@ -227,6 +228,8 @@ peekyylex ()
|
|||
return nth_token (0)->yychar;
|
||||
}
|
||||
|
||||
extern tree snarf_defarg ();
|
||||
|
||||
int
|
||||
yylex ()
|
||||
{
|
||||
|
@ -242,8 +245,18 @@ yylex ()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (do_snarf_defarg)
|
||||
{
|
||||
my_friendly_assert (num_tokens () == 0, 2837);
|
||||
tmp_token.yychar = DEFARG;
|
||||
tmp_token.yylval.ttype = snarf_defarg ();
|
||||
tmp_token.end_of_file = 0;
|
||||
do_snarf_defarg = 0;
|
||||
add_token (&tmp_token);
|
||||
}
|
||||
|
||||
/* if we've got tokens, send them */
|
||||
if (num_tokens ())
|
||||
else if (num_tokens ())
|
||||
{
|
||||
tmp_token= *nth_token (0);
|
||||
|
||||
|
|
|
@ -832,20 +832,18 @@ layout_basetypes (rec, binfos)
|
|||
BINFO_VPTR_FIELD (base_binfo) = decl;
|
||||
vbase_decls = decl;
|
||||
|
||||
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
|
||||
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
|
||||
{
|
||||
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
|
||||
"destructor `%s' non-virtual");
|
||||
warning ("in inheritance relationship `%s: virtual %s'",
|
||||
TYPE_NAME_STRING (rec),
|
||||
TYPE_NAME_STRING (basetype));
|
||||
}
|
||||
got_it:
|
||||
/* The space this decl occupies has already been accounted for. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P
|
||||
here because the case of virtual functions but non-virtual
|
||||
dtor is handled in finish_struct_1. */
|
||||
if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
|
||||
&& TYPE_HAS_DESTRUCTOR (basetype))
|
||||
cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
|
||||
|
||||
if (const_size == 0)
|
||||
offset = integer_zero_node;
|
||||
else
|
||||
|
@ -854,22 +852,6 @@ layout_basetypes (rec, binfos)
|
|||
const_size = CEIL (const_size, TYPE_ALIGN (basetype))
|
||||
* TYPE_ALIGN (basetype);
|
||||
offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
|
||||
|
||||
#if 0
|
||||
/* bpk: Disabled this check until someone is willing to
|
||||
claim it as theirs and explain exactly what circumstances
|
||||
warrant the warning. */
|
||||
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
|
||||
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
|
||||
{
|
||||
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
|
||||
"destructor `%s' non-virtual");
|
||||
warning ("in inheritance relationship `%s:%s %s'",
|
||||
TYPE_NAME_STRING (rec),
|
||||
TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "",
|
||||
TYPE_NAME_STRING (basetype));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
BINFO_OFFSET (base_binfo) = offset;
|
||||
if (CLASSTYPE_VSIZE (basetype))
|
||||
|
|
|
@ -1652,15 +1652,17 @@ build_object_ref (datum, basetype, field)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Like `build_component_ref, but uses an already found field.
|
||||
Must compute access for current_class_ref. Otherwise, ok. */
|
||||
/* Like `build_component_ref, but uses an already found field, and converts
|
||||
from a reference. Must compute access for current_class_ref.
|
||||
Otherwise, ok. */
|
||||
|
||||
tree
|
||||
build_component_ref_1 (datum, field, protect)
|
||||
tree datum, field;
|
||||
int protect;
|
||||
{
|
||||
return build_component_ref (datum, field, NULL_TREE, protect);
|
||||
return convert_from_reference
|
||||
(build_component_ref (datum, field, NULL_TREE, protect));
|
||||
}
|
||||
|
||||
/* Given a COND_EXPR in T, return it in a form that we can, for
|
||||
|
@ -2484,11 +2486,17 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
|
|||
function = save_expr (function);
|
||||
|
||||
fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
|
||||
idx = save_expr (build_component_ref (function,
|
||||
index_identifier,
|
||||
NULL_TREE, 0));
|
||||
e1 = fold (build (GT_EXPR, boolean_type_node, idx,
|
||||
cp_convert (delta_type_node, integer_zero_node)));
|
||||
|
||||
/* Promoting idx before saving it improves performance on RISC
|
||||
targets. Without promoting, the first compare used
|
||||
load-with-sign-extend, while the second used normal load then
|
||||
shift to sign-extend. An optimizer flaw, perhaps, but it's easier
|
||||
to make this change. */
|
||||
idx = save_expr (default_conversion
|
||||
(build_component_ref (function,
|
||||
index_identifier,
|
||||
NULL_TREE, 0)));
|
||||
e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
|
||||
delta = cp_convert (ptrdiff_type_node,
|
||||
build_component_ref (function, delta_identifier, NULL_TREE, 0));
|
||||
delta2 = DELTA2_FROM_PTRMEMFUNC (function);
|
||||
|
|
Loading…
Reference in New Issue