merging
From-SVN: r12700
This commit is contained in:
parent
55df28b8f2
commit
c11b6f21eb
19 changed files with 1186 additions and 887 deletions
238
gcc/cp/ChangeLog
238
gcc/cp/ChangeLog
|
@ -1,3 +1,52 @@
|
|||
Wed Sep 11 22:38:13 1996 Gerald Baumgartner <gb@cs.purdue.edu>
|
||||
|
||||
* call.c (build_method_call): When calling a signature
|
||||
default implementation, as in other cases, let instance_ptr simply
|
||||
be instance.
|
||||
|
||||
Wed Sep 11 22:14:44 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* parse.y (simple_stmt): Cleanup and use do_poplevel ().
|
||||
|
||||
Wed Sep 11 22:10:48 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c (expand_start_catch_block): Add a pushlevel so that -g
|
||||
works on hppa and SPARC.
|
||||
|
||||
Wed Sep 11 10:18:06 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* typeck.c (build_indirect_ref): Catch PTR being an error_mark_node.
|
||||
|
||||
Mon Sep 9 19:51:14 1996 Gerald Baumgartner <gb@cs.purdue.edu>
|
||||
|
||||
* call.c (build_over_call): Check first whether DECL_CONTEXT exists
|
||||
before testing whether it's a signature.
|
||||
|
||||
Sun Sep 8 16:06:57 1996 Gerald Baumgartner <gb@cs.purdue.edu>
|
||||
|
||||
* call.c (build_new_method_call): Don't complain about signature
|
||||
pointers and references not being an aggr type.
|
||||
(build_this): If a signature pointer or reference was passed in,
|
||||
just return it.
|
||||
(build_new_method_call): If instance is a signature pointer, set
|
||||
basetype to the signature type of instance.
|
||||
* sig.c (build_signature_method_call): Deleted basetype and
|
||||
instance parameters, they can be found as the DECL_CONTEXT of
|
||||
function and as the first argument passed in.
|
||||
* cp-tree.h: Changed declaration of build_signature_method_call.
|
||||
* call.c (build_method_call): Deleted first two arguments in call
|
||||
of build_signature_method_call.
|
||||
(build_over_call): Added call to build_signature_method_call.
|
||||
|
||||
Thu Sep 5 16:51:28 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* typeck.c (build_c_cast): Don't tack a non_lvalue_expr onto a
|
||||
target_expr.
|
||||
|
||||
Thu Sep 5 10:05:38 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* cvt.c (convert_to_reference): Use %#T, not %#D, for error.
|
||||
|
||||
Wed Sep 4 17:16:09 1996 Bob Manson <manson@charmed.cygnus.com>
|
||||
|
||||
* except.c (expand_start_try_stmts): Move to except.c in the backend.
|
||||
|
@ -7,6 +56,191 @@ Wed Sep 4 17:16:09 1996 Bob Manson <manson@charmed.cygnus.com>
|
|||
of directly manipulating lists.
|
||||
(emit_base_init): Ditto.
|
||||
|
||||
Wed Sep 4 12:14:36 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c (expand_exception_blocks): Always make sure USE and
|
||||
CLOBBER insns that came at the end still do, the backend relies
|
||||
upon this.
|
||||
|
||||
Wed Sep 4 07:44:48 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (build_over_call): We can only use a TARGET_EXPR of the
|
||||
right type.
|
||||
|
||||
Tue Sep 3 19:26:05 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* cvt.c (convert_to_reference): Revert last change, don't complain
|
||||
about temp without target decl.
|
||||
|
||||
Tue Sep 3 10:22:56 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl.c (grokdeclarator): Don't core dump when void() is given.
|
||||
|
||||
Tue Sep 3 02:38:56 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (copy_args_p): Don't crash.
|
||||
|
||||
Fri Aug 30 14:26:57 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* pt.c (tsubst): And support template args inside the exception
|
||||
specification.
|
||||
|
||||
* pt.c (tsubst): Add support for exception specifications in
|
||||
template functions.
|
||||
|
||||
Fri Aug 30 10:01:55 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* cp-tree.def (DECL_STMT): Eliminate the throw spec field, only 3
|
||||
fields now.
|
||||
* cp-tree.h (start_decl): Eliminate the throw spec parameter.
|
||||
(start_function): Likewise.
|
||||
(start_method): Likewise.
|
||||
(grokfield): Likewise.
|
||||
(make_call_declarator): Add throw spec parameter.
|
||||
(set_quals_and_spec): Add routine.
|
||||
* lex.c (set_quals_and_spec): Likewise.
|
||||
* decl.h (grokdeclarator): Eliminate the throw spec parameter.
|
||||
* decl.c (shadow_tag): Eliminate the throw spec parameter to
|
||||
grokdeclarator.
|
||||
(groktypename): Likewise.
|
||||
(start_decl): Eliminate the throw spec parameter. Eliminate the
|
||||
throw spec parameter to grokdeclarator. Eliminate the throw spec
|
||||
field in DECL_STMT.
|
||||
(cp_finish_decl): Eliminate the throw spec field in DECL_STMT.
|
||||
(grokfndecl): Remove useless set of raises.
|
||||
(grokdeclarator): Eliminate the throw spec parameter. Eliminate
|
||||
the throw spec parameter to start_decl. Pull the throw spec out
|
||||
of the call declarator.
|
||||
(grokparms): Eliminate the throw spec parameter to grokdeclarator.
|
||||
(start_function): Eliminate the throw spec parameter. Eliminate
|
||||
the throw spec parameter to grokdeclarator.
|
||||
(start_method): Likewise.
|
||||
* decl2.c (grokfield): Likewise.
|
||||
(grokbitfield): Eliminate the throw spec parameter to grokdeclarator.
|
||||
(grokoptypename): Likewise.
|
||||
(finish_file): Eliminate the throw spec parameter to
|
||||
start_function. Add throw spec to make_call_declarator.
|
||||
* except.c (init_exception_processing): Add throw spec to
|
||||
make_call_declarator. Eliminate the throw spec parameter to
|
||||
start_decl.
|
||||
(expand_start_catch_block): Eliminate the throw spec parameter to
|
||||
grokdeclarator.
|
||||
(expand_builtin_throw): Add throw spec to make_call_declarator.
|
||||
Eliminate the throw spec parameter to start_function.
|
||||
(start_anon_func): Likewise.
|
||||
* lex.c (make_call_declarator): Add throw spec parameter.
|
||||
(set_quals_and_spec): New routine.
|
||||
(cons_up_default_function): Add throw spec to make_call_declarator.
|
||||
Eliminate the throw spec parameter to grokfield.
|
||||
* method.c (synthesize_method): Eliminate the throw spec parameter
|
||||
to start_function.
|
||||
* pt.c (process_template_parm): Eliminate the throw spec parameter
|
||||
to grokdeclarator.
|
||||
(tsubst): Add throw spec to make_call_declarator.
|
||||
(tsubst_expr): Eliminate the throw spec parameter to start_decl.
|
||||
(do_function_instantiation): Eliminate the throw spec parameter to
|
||||
grokdeclarator. Eliminate the throw spec parameter to
|
||||
start_function.
|
||||
* rtti.c (synthesize_tinfo_fn): Eliminate the throw spec parameter
|
||||
to start_function.
|
||||
* parse.y (datadef): Remove non-winning optimization.
|
||||
(decl): Likewise.
|
||||
(fndef): Remove ambiguous error productions uncovered by grammer
|
||||
fixing.
|
||||
(constructor_declarator): Add exception_specification_opt here.
|
||||
(component_constructor_declarator): Likewise.
|
||||
(direct_after_type_declarator): Likewise.
|
||||
(complex_direct_notype_declarator): Likewise.
|
||||
(direct_abstract_declarator): Likewise.
|
||||
(fn.def1): Remove exception_specification_opt.
|
||||
(fn.def2): Likewise.
|
||||
(condition): Likewise.
|
||||
(initdcl0): Likewise.
|
||||
(initdcl): Likewise.
|
||||
(notype_initdcl0): Likewise.
|
||||
(nomods_initdcl0): Likewise.
|
||||
(component_decl_1): Likewise.
|
||||
(component_declarator): Likewise.
|
||||
(after_type_component_declarator0): Likewise.
|
||||
(after_type_component_declarator): Likewise.
|
||||
(notype_component_declarator): Likewise.
|
||||
|
||||
Wed Aug 28 01:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (build_over_call): Also use an INIT_EXPR when
|
||||
initializing anything from an rvalue.
|
||||
|
||||
* call.c (build_over_call): Call stabilize_reference when building
|
||||
an INIT_EXPR instead of calling the copy ctor.
|
||||
|
||||
* call.c (joust): Extend the previous change to all comparisons.
|
||||
|
||||
* decl2.c, method.c, lex.c: Use MAKE_DECL_ONE_ONLY and
|
||||
NO_LINKAGE_HEURISTICS.
|
||||
|
||||
* decl2.c (finish_file): Emit any statics that weren't already.
|
||||
|
||||
* typeck.c (build_static_cast): Implement.
|
||||
* tree.c (build_cplus_new): Handle getting a TARGET_EXPR.
|
||||
* decl.c (grokparms): Use can_convert_arg instead of
|
||||
implicit_conversion directly.
|
||||
(copy_args_p): New fn.
|
||||
* cvt.c (convert_to_reference): Don't complain about temp with
|
||||
static_cast.
|
||||
(build_up_reference): Handle TARGET_EXPRs.
|
||||
* call.c (build_over_call): Elide unnecessary temps.
|
||||
(can_convert*): Use new overloading code.
|
||||
|
||||
Tue Aug 27 13:12:21 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c: Move TYPE_PTR*_MACROS ...
|
||||
* cp-tree.h: To here.
|
||||
* typeck.c (build_reinterpret_cast): Implement.
|
||||
|
||||
* call.c (add_builtin_candidate): Use TYPE_PTROB_P instead of
|
||||
ptr_complete_ob.
|
||||
(joust): If we're comparing a function to a builtin and the worst
|
||||
conversion for the builtin is worse than the worst conversion for the
|
||||
function, take the function.
|
||||
|
||||
* typeck.c (build_const_cast): Implement.
|
||||
(comp_ptr_ttypes_const): Like comp_ptr_ttypes, for const_cast.
|
||||
(comp_ptr_ttypes_reinterpret): Like cpt, for reinterpret_cast.
|
||||
|
||||
Tue Aug 27 13:14:58 1996 Bob Manson <manson@charmed.cygnus.com>
|
||||
|
||||
* rtti.c (build_dynamic_cast): Don't try to dereference exprtype
|
||||
too early. Make sure we explode if exprtype turns out to be a
|
||||
NULL_TREE when it shouldn't be.
|
||||
|
||||
Tue Aug 27 10:56:21 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* cp-tree.h: New routine make_call_declarator.
|
||||
* lex.c (make_call_declarator): Define it.
|
||||
* except.c (init_exception_processing): Use it.
|
||||
(expand_builtin_throw): Likewise.
|
||||
(start_anon_func): Likewise.
|
||||
* decl2.c (finish_file): Likewise.
|
||||
* lex.c (cons_up_default_function): Likewise.
|
||||
* parse.y: Likewise.
|
||||
* pt.c (tsubst): Likewise.
|
||||
|
||||
Mon Aug 26 17:40:03 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl2.c (groktypefield): Remove unused code.
|
||||
|
||||
Mon Aug 26 17:00:33 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* gxx.gperf: Change TYPE_QUAL into CV_QUALIFIER.
|
||||
* parse.y: Likewise. Change maybe_type_qual into maybe_cv_qualifier.
|
||||
Change type_quals into cv_qualifiers. Change nonempty_type_quals into
|
||||
nonempty_cv_qualifiers.
|
||||
* hash.h: Rebuild.
|
||||
|
||||
* lex.c (make_pointer_declarator): Change type_quals into
|
||||
cv_qualifiers.
|
||||
(make_reference_declarator): Likewise.
|
||||
|
||||
Thu Aug 22 01:09:22 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (start_function): Only check interface_* for templates
|
||||
|
@ -122,10 +356,6 @@ Tue Aug 13 12:16:10 1996 Jason Merrill <jason@yorick.cygnus.com>
|
|||
(import_export_decl): Use it.
|
||||
* method.c (make_thunk): Use it.
|
||||
|
||||
Sat Aug 17 15:23:39 1996 Geoffrey Noer <noer@cygnus.com>
|
||||
|
||||
* g++.c: Update test for win32 (&& ! cygwin32).
|
||||
|
||||
Mon Aug 12 00:09:18 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* pt.c (end_template_decl): If we don't actually have parms, return.
|
||||
|
|
205
gcc/cp/call.c
205
gcc/cp/call.c
|
@ -668,24 +668,6 @@ user_harshness (type, parmtype)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
can_convert (to, from)
|
||||
tree to, from;
|
||||
{
|
||||
struct harshness_code h;
|
||||
h = convert_harshness (to, from, NULL_TREE);
|
||||
return (h.code < USER_CODE) && (h.distance >= 0);
|
||||
}
|
||||
|
||||
int
|
||||
can_convert_arg (to, from, arg)
|
||||
tree to, from, arg;
|
||||
{
|
||||
struct harshness_code h;
|
||||
h = convert_harshness (to, from, arg);
|
||||
return (h.code < USER_CODE) && (h.distance >= 0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MATCHING
|
||||
static char *
|
||||
print_harshness (h)
|
||||
|
@ -1865,8 +1847,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
&& TYPE_IDENTIFIER (basetype) != name)
|
||||
{
|
||||
basetype = SIGNATURE_TYPE (basetype);
|
||||
instance_ptr = build_optr_ref (instance);
|
||||
instance_ptr = convert (build_pointer_type (basetype), instance_ptr);
|
||||
instance_ptr = instance;
|
||||
basetype_path = TYPE_BINFO (basetype);
|
||||
}
|
||||
else
|
||||
|
@ -2462,7 +2443,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
basetype, save_name);
|
||||
return error_mark_node;
|
||||
}
|
||||
return build_signature_method_call (basetype, instance, function, parms);
|
||||
return build_signature_method_call (function, parms);
|
||||
}
|
||||
|
||||
function = DECL_MAIN_VARIANT (function);
|
||||
|
@ -3461,27 +3442,6 @@ add_conv_candidate (candidates, fn, obj, arglist)
|
|||
return cand;
|
||||
}
|
||||
|
||||
int
|
||||
ptr_complete_ob (t)
|
||||
tree t;
|
||||
{
|
||||
return (TREE_CODE (t) == POINTER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (t)) != OFFSET_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (t)) != FUNCTION_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (t)) != VOID_TYPE
|
||||
&& TYPE_SIZE (complete_type (TREE_TYPE (t))) != NULL_TREE);
|
||||
}
|
||||
|
||||
#define TYPE_PTRMEM_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) == OFFSET_TYPE)
|
||||
#define TYPE_PTR_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) != OFFSET_TYPE)
|
||||
#define TYPE_PTROB_P(NODE) \
|
||||
(TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE)
|
||||
|
||||
static struct z_candidate *
|
||||
build_builtin_candidate (candidates, fnname, type1, type2,
|
||||
args, argtypes, flags)
|
||||
|
@ -3598,7 +3558,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|
|||
case POSTINCREMENT_EXPR:
|
||||
case PREINCREMENT_EXPR:
|
||||
if ((ARITHMETIC_TYPE_P (type1) && TREE_CODE (type1) != ENUMERAL_TYPE)
|
||||
|| ptr_complete_ob (type1))
|
||||
|| TYPE_PTROB_P (type1))
|
||||
{
|
||||
type1 = build_reference_type (type1);
|
||||
break;
|
||||
|
@ -3616,7 +3576,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|
|||
|
||||
case INDIRECT_REF:
|
||||
if (TREE_CODE (type1) == POINTER_TYPE
|
||||
&& (ptr_complete_ob (type1)
|
||||
&& (TYPE_PTROB_P (type1)
|
||||
|| TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
|
||||
break;
|
||||
return candidates;
|
||||
|
@ -3713,9 +3673,9 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|
|||
bool operator!=(T, T); */
|
||||
|
||||
case MINUS_EXPR:
|
||||
if (ptr_complete_ob (type1) && ptr_complete_ob (type2))
|
||||
if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2))
|
||||
break;
|
||||
if (ptr_complete_ob (type1) && INTEGRAL_TYPE_P (type2))
|
||||
if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
|
||||
{
|
||||
type2 = ptrdiff_type_node;
|
||||
break;
|
||||
|
@ -3768,12 +3728,12 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|
|||
if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
|
||||
break;
|
||||
case ARRAY_REF:
|
||||
if (INTEGRAL_TYPE_P (type1) && ptr_complete_ob (type2))
|
||||
if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2))
|
||||
{
|
||||
type1 = ptrdiff_type_node;
|
||||
break;
|
||||
}
|
||||
if (ptr_complete_ob (type1) && INTEGRAL_TYPE_P (type2))
|
||||
if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
|
||||
{
|
||||
type2 = ptrdiff_type_node;
|
||||
break;
|
||||
|
@ -3842,7 +3802,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|
|||
{
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
if (ptr_complete_ob (type1) && INTEGRAL_TYPE_P (type2))
|
||||
if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
|
||||
{
|
||||
type2 = ptrdiff_type_node;
|
||||
break;
|
||||
|
@ -4164,7 +4124,11 @@ build_this (obj)
|
|||
tree obj;
|
||||
{
|
||||
/* Fix this to work on non-lvalues. */
|
||||
return build_unary_op (ADDR_EXPR, obj, 0);
|
||||
if (IS_SIGNATURE_POINTER (TREE_TYPE (obj))
|
||||
|| IS_SIGNATURE_REFERENCE (TREE_TYPE (obj)))
|
||||
return obj;
|
||||
else
|
||||
return build_unary_op (ADDR_EXPR, obj, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5096,6 +5060,67 @@ build_over_call (fn, convs, args, flags)
|
|||
|
||||
converted_args = nreverse (converted_args);
|
||||
|
||||
/* Avoid actually calling copy constructors and copy assignment operators,
|
||||
if possible. */
|
||||
if (DECL_CONSTRUCTOR_P (fn)
|
||||
&& TREE_VEC_LENGTH (convs) == 1
|
||||
&& copy_args_p (fn))
|
||||
{
|
||||
tree targ = NULL_TREE;
|
||||
arg = TREE_VALUE (TREE_CHAIN (converted_args));
|
||||
|
||||
/* Pull out the real argument, disregarding const-correctness. */
|
||||
if (TREE_CODE (arg) == ADDR_EXPR)
|
||||
{
|
||||
targ = TREE_OPERAND (arg, 0);
|
||||
if (! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))),
|
||||
TYPE_MAIN_VARIANT (TREE_TYPE (targ)), 1))
|
||||
targ = NULL_TREE;
|
||||
}
|
||||
|
||||
if (targ)
|
||||
arg = targ;
|
||||
else
|
||||
arg = build_indirect_ref (arg, 0);
|
||||
|
||||
/* If we're creating a temp and we already have one, don't create a
|
||||
new one. If we're not creating a temp but we get one, use
|
||||
INIT_EXPR to collapse the temp into our target. Otherwise, if the
|
||||
ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
|
||||
temp or an INIT_EXPR otherwise. */
|
||||
if (integer_zerop (TREE_VALUE (args)))
|
||||
{
|
||||
if (! real_lvalue_p (arg))
|
||||
return arg;
|
||||
else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
|
||||
{
|
||||
val = build (VAR_DECL, DECL_CONTEXT (fn));
|
||||
layout_decl (val, 0);
|
||||
return build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0);
|
||||
}
|
||||
}
|
||||
else if (! real_lvalue_p (arg)
|
||||
|| TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
|
||||
{
|
||||
tree to = stabilize_reference
|
||||
(build_indirect_ref (TREE_VALUE (args), 0));
|
||||
val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
|
||||
TREE_SIDE_EFFECTS (val) = 1;
|
||||
return build_unary_op (ADDR_EXPR, val, 0);
|
||||
}
|
||||
}
|
||||
else if (DECL_NAME (fn) == ansi_opname[MODIFY_EXPR]
|
||||
&& copy_args_p (fn)
|
||||
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
|
||||
{
|
||||
tree to = stabilize_reference
|
||||
(build_indirect_ref (TREE_VALUE (converted_args), 0));
|
||||
arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
|
||||
val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
|
||||
TREE_SIDE_EFFECTS (val) = 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
|
||||
if (pedantic && DECL_THIS_INLINE (fn) && ! DECL_ARTIFICIAL (fn)
|
||||
|
@ -5104,7 +5129,9 @@ build_over_call (fn, convs, args, flags)
|
|||
&& TREE_LANG_FLAG_0 (DECL_TEMPLATE_INFO (fn))))
|
||||
cp_warning ("inline function `%#D' called before definition", fn);
|
||||
|
||||
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
|
||||
if (DECL_CONTEXT (fn) && IS_SIGNATURE (DECL_CONTEXT (fn)))
|
||||
return build_signature_method_call (fn, converted_args);
|
||||
else if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
|
||||
{
|
||||
tree t, *p = &TREE_VALUE (converted_args);
|
||||
tree binfo = get_binfo
|
||||
|
@ -5153,7 +5180,10 @@ build_new_method_call (instance, name, args, basetype_path, flags)
|
|||
basetype = TREE_TYPE (instance);
|
||||
|
||||
/* XXX this should be handled before we get here. */
|
||||
if (! IS_AGGR_TYPE (basetype))
|
||||
if (! IS_AGGR_TYPE (basetype)
|
||||
&& ! (TYPE_LANG_SPECIFIC (basetype)
|
||||
&& (IS_SIGNATURE_POINTER (basetype)
|
||||
|| IS_SIGNATURE_REFERENCE (basetype))))
|
||||
{
|
||||
if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
|
||||
cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
|
||||
|
@ -5161,6 +5191,14 @@ build_new_method_call (instance, name, args, basetype_path, flags)
|
|||
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* If `instance' is a signature pointer/reference and `name' is
|
||||
not a constructor, we are calling a signature member function.
|
||||
In that case set the `basetype' to the signature type. */
|
||||
if ((IS_SIGNATURE_POINTER (basetype)
|
||||
|| IS_SIGNATURE_REFERENCE (basetype))
|
||||
&& TYPE_IDENTIFIER (basetype) != name)
|
||||
basetype = SIGNATURE_TYPE (basetype);
|
||||
}
|
||||
|
||||
if (basetype_path == NULL_TREE)
|
||||
|
@ -5587,7 +5625,10 @@ joust (cand1, cand2)
|
|||
if (comp != 0)
|
||||
{
|
||||
if (winner && comp != winner)
|
||||
return 0;
|
||||
{
|
||||
winner = 0;
|
||||
goto tweak;
|
||||
}
|
||||
winner = comp;
|
||||
}
|
||||
}
|
||||
|
@ -5621,7 +5662,7 @@ joust (cand1, cand2)
|
|||
if (! winner && cand1->fn == cand2->fn
|
||||
&& TREE_CODE (cand1->fn) == IDENTIFIER_NODE)
|
||||
{
|
||||
for (i = 0; i < TREE_VEC_LENGTH (cand1->convs); ++i)
|
||||
for (i = 0; i < len; ++i)
|
||||
if (! comptypes (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)),
|
||||
TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)), 1))
|
||||
break;
|
||||
|
@ -5646,6 +5687,28 @@ joust (cand1, cand2)
|
|||
}
|
||||
}
|
||||
|
||||
tweak:
|
||||
|
||||
/* Extension: If the worst conversion for one candidate is worse than the
|
||||
worst conversion for the other, take the first. */
|
||||
if (! winner && ! pedantic)
|
||||
{
|
||||
int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
if (ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)) > rank1)
|
||||
rank1 = ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1));
|
||||
if (ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)) > rank2)
|
||||
rank2 = ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2));
|
||||
}
|
||||
|
||||
if (rank1 < rank2)
|
||||
return 1;
|
||||
if (rank1 > rank2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return winner;
|
||||
}
|
||||
|
||||
|
@ -5698,3 +5761,37 @@ tourney (candidates)
|
|||
|
||||
return champ;
|
||||
}
|
||||
|
||||
int
|
||||
can_convert (to, from)
|
||||
tree to, from;
|
||||
{
|
||||
if (flag_ansi_overloading)
|
||||
{
|
||||
tree t = implicit_conversion (to, from, NULL_TREE, LOOKUP_NORMAL);
|
||||
return (t && ! ICS_BAD_FLAG (t));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct harshness_code h;
|
||||
h = convert_harshness (to, from, NULL_TREE);
|
||||
return (h.code < USER_CODE) && (h.distance >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
can_convert_arg (to, from, arg)
|
||||
tree to, from, arg;
|
||||
{
|
||||
if (flag_ansi_overloading)
|
||||
{
|
||||
tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
|
||||
return (t && ! ICS_BAD_FLAG (t));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct harshness_code h;
|
||||
h = convert_harshness (to, from, arg);
|
||||
return (h.code < USER_CODE) && (h.distance >= 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ 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 (DECL_STMT, "decl_stmt", "e", 3)
|
||||
DEFTREECODE (IF_STMT, "if_stmt", "e", 3)
|
||||
DEFTREECODE (FOR_STMT, "for_stmt", "e", 4)
|
||||
DEFTREECODE (WHILE_STMT, "while_stmt", "e", 2)
|
||||
|
|
|
@ -1265,6 +1265,21 @@ extern int flag_new_for_scope;
|
|||
#define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \
|
||||
(TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE))
|
||||
|
||||
#define TYPE_PTRMEM_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) == OFFSET_TYPE)
|
||||
#define TYPE_PTR_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) != OFFSET_TYPE)
|
||||
#define TYPE_PTROB_P(NODE) \
|
||||
(TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE)
|
||||
#define TYPE_PTROBV_P(NODE) \
|
||||
(TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE)
|
||||
#define TYPE_PTRFN_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
|
||||
|
||||
/* Nonzero for _TYPE node means that this type is a pointer to member
|
||||
function type. */
|
||||
#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
|
||||
|
@ -2047,7 +2062,7 @@ extern int init_type_desc PROTO((void));
|
|||
extern void shadow_tag PROTO((tree));
|
||||
extern int grok_ctor_properties PROTO((tree, tree));
|
||||
extern tree groktypename PROTO((tree));
|
||||
extern tree start_decl PROTO((tree, tree, int, tree));
|
||||
extern tree start_decl PROTO((tree, tree, int));
|
||||
extern void cp_finish_decl PROTO((tree, tree, tree, int, int));
|
||||
extern void expand_static_init PROTO((tree, tree));
|
||||
extern int complete_array_type PROTO((tree, tree, int));
|
||||
|
@ -2061,13 +2076,13 @@ extern tree start_enum PROTO((tree));
|
|||
extern tree finish_enum PROTO((tree, tree));
|
||||
extern tree build_enumerator PROTO((tree, tree));
|
||||
extern tree grok_enum_decls PROTO((tree, tree));
|
||||
extern int start_function PROTO((tree, tree, tree, tree, int));
|
||||
extern int start_function PROTO((tree, tree, tree, int));
|
||||
extern void store_parm_decls PROTO((void));
|
||||
extern void expand_start_early_try_stmts PROTO((void));
|
||||
extern void store_in_parms PROTO((struct rtx_def *));
|
||||
extern void store_return_init PROTO((tree, tree));
|
||||
extern void finish_function PROTO((int, int, int));
|
||||
extern tree start_method PROTO((tree, tree, tree));
|
||||
extern tree start_method PROTO((tree, tree));
|
||||
extern tree finish_method PROTO((tree));
|
||||
extern void hack_incomplete_structures PROTO((tree));
|
||||
extern tree maybe_build_cleanup PROTO((tree));
|
||||
|
@ -2092,7 +2107,7 @@ 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));
|
||||
extern tree grokfield PROTO((tree, tree, tree, tree, tree, tree));
|
||||
extern tree grokfield PROTO((tree, tree, tree, tree, tree));
|
||||
extern tree grokbitfield PROTO((tree, tree, tree));
|
||||
extern tree groktypefield PROTO((tree, tree));
|
||||
extern tree grokoptypename PROTO((tree, tree));
|
||||
|
@ -2192,6 +2207,8 @@ extern tree build_vec_delete PROTO((tree, tree, tree, tree, int));
|
|||
/* in lex.c */
|
||||
extern tree make_pointer_declarator PROTO((tree, tree));
|
||||
extern tree make_reference_declarator PROTO((tree, tree));
|
||||
extern tree make_call_declarator PROTO((tree, tree, tree, tree));
|
||||
extern void set_quals_and_spec PROTO((tree, tree, tree));
|
||||
extern char *operator_name_string PROTO((tree));
|
||||
extern void lang_init PROTO((void));
|
||||
extern void lang_finish PROTO((void));
|
||||
|
@ -2345,7 +2362,7 @@ extern tree get_template_base PROTO((tree, tree));
|
|||
extern tree build_signature_pointer_type PROTO((tree, int, int));
|
||||
extern tree build_signature_reference_type PROTO((tree, int, int));
|
||||
extern tree build_signature_pointer_constructor PROTO((tree, tree));
|
||||
extern tree build_signature_method_call PROTO((tree, tree, tree, tree));
|
||||
extern tree build_signature_method_call PROTO((tree, tree));
|
||||
extern tree build_optr_ref PROTO((tree));
|
||||
extern tree build_sptr_ref PROTO((tree));
|
||||
extern void append_signature_fields PROTO((tree));
|
||||
|
|
12
gcc/cp/cvt.c
12
gcc/cp/cvt.c
|
@ -594,6 +594,11 @@ build_up_reference (type, arg, flags, checkconst)
|
|||
TREE_REFERENCE_EXPR (rval) = 1;
|
||||
return rval;
|
||||
|
||||
case TARGET_EXPR:
|
||||
TREE_ADDRESSABLE (targ) = 1;
|
||||
put_var_into_stack (TREE_OPERAND (targ, 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -742,15 +747,14 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
|||
ttr = cp_build_type_variant (TREE_TYPE (expr), r, v);
|
||||
}
|
||||
|
||||
if (! real_lvalue_p (expr) &&
|
||||
(decl == NULL_TREE || ! TYPE_READONLY (ttl)))
|
||||
if (! real_lvalue_p (expr) && ! TYPE_READONLY (ttl))
|
||||
{
|
||||
if (decl)
|
||||
/* Ensure semantics of [dcl.init.ref] */
|
||||
cp_pedwarn ("initialization of non-const `%T' from rvalue `%T'",
|
||||
cp_pedwarn ("initialization of non-const reference `%#T' from rvalue `%T'",
|
||||
reftype, intype);
|
||||
else
|
||||
cp_pedwarn ("conversion to `%T' from rvalue `%T'",
|
||||
cp_pedwarn ("conversion to non-const `%T' from rvalue `%T'",
|
||||
reftype, intype);
|
||||
}
|
||||
else if (! (convtype & CONV_CONST))
|
||||
|
|
|
@ -5700,7 +5700,7 @@ shadow_tag (declspecs)
|
|||
if (TYPE_FIELDS (t))
|
||||
{
|
||||
tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0,
|
||||
NULL_TREE, NULL_TREE);
|
||||
NULL_TREE);
|
||||
finish_anon_union (decl);
|
||||
}
|
||||
}
|
||||
|
@ -5739,7 +5739,7 @@ groktypename (typename)
|
|||
return typename;
|
||||
return grokdeclarator (TREE_VALUE (typename),
|
||||
TREE_PURPOSE (typename),
|
||||
TYPENAME, 0, NULL_TREE, NULL_TREE);
|
||||
TYPENAME, 0, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Decode a declarator in an ordinary declaration or data definition.
|
||||
|
@ -5764,10 +5764,9 @@ int debug_temp_inits = 1;
|
|||
void start_decl_1 ();
|
||||
|
||||
tree
|
||||
start_decl (declarator, declspecs, initialized, raises)
|
||||
start_decl (declarator, declspecs, initialized)
|
||||
tree declarator, declspecs;
|
||||
int initialized;
|
||||
tree raises;
|
||||
{
|
||||
register tree decl;
|
||||
register tree type, tem;
|
||||
|
@ -5788,7 +5787,7 @@ start_decl (declarator, declspecs, initialized, raises)
|
|||
used_extern_spec = 1;
|
||||
}
|
||||
|
||||
decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, raises,
|
||||
decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
|
||||
NULL_TREE);
|
||||
if (decl == NULL_TREE || decl == void_type_node)
|
||||
return NULL_TREE;
|
||||
|
@ -5923,7 +5922,7 @@ start_decl (declarator, declspecs, initialized, raises)
|
|||
DECL_VINDEX (decl)
|
||||
= build_min_nt (DECL_STMT, copy_to_permanent (declarator),
|
||||
copy_to_permanent (declspecs),
|
||||
copy_to_permanent (raises), NULL_TREE);
|
||||
NULL_TREE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6249,7 +6248,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|
|||
{
|
||||
tree stmt = DECL_VINDEX (decl);
|
||||
DECL_VINDEX (decl) = NULL_TREE;
|
||||
TREE_OPERAND (stmt, 3) = copy_to_permanent (init);
|
||||
TREE_OPERAND (stmt, 2) = copy_to_permanent (init);
|
||||
add_tree (stmt);
|
||||
}
|
||||
|
||||
|
@ -7111,8 +7110,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
if (raises)
|
||||
{
|
||||
type = build_exception_variant (type, raises);
|
||||
raises = TYPE_RAISES_EXCEPTIONS (type);
|
||||
}
|
||||
|
||||
decl = build_lang_decl (FUNCTION_DECL, declarator, type);
|
||||
/* propagate volatile out from type to decl */
|
||||
if (TYPE_VOLATILE (type))
|
||||
|
@ -7447,12 +7446,12 @@ build_ptrmemfunc_type (type)
|
|||
enum return_types { return_normal, return_ctor, return_dtor, return_conversion };
|
||||
|
||||
tree
|
||||
grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrlist)
|
||||
grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
tree declspecs;
|
||||
tree declarator;
|
||||
enum decl_context decl_context;
|
||||
int initialized;
|
||||
tree raises, attrlist;
|
||||
tree attrlist;
|
||||
{
|
||||
RID_BIT_TYPE specbits;
|
||||
int nclasses = 0;
|
||||
|
@ -7489,6 +7488,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
|
|||
tree ctor_return_type = NULL_TREE;
|
||||
enum overload_flags flags = NO_SPECIAL;
|
||||
tree quals = NULL_TREE;
|
||||
tree raises = NULL_TREE;
|
||||
|
||||
RIDBIT_RESET_ALL (specbits);
|
||||
if (decl_context == FUNCDEF)
|
||||
|
@ -7579,7 +7579,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
|
|||
*next = TREE_OPERAND (decl, 0);
|
||||
init = TREE_OPERAND (decl, 1);
|
||||
|
||||
decl = start_decl (declarator, declspecs, 1, NULL_TREE);
|
||||
decl = start_decl (declarator, declspecs, 1);
|
||||
finish_decl (decl, init, NULL_TREE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -7587,6 +7587,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
|
|||
if (decl_context == FIELD && ctype == NULL_TREE)
|
||||
ctype = current_class_type;
|
||||
if (ctype
|
||||
&& TREE_OPERAND (decl, 0)
|
||||
&& (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL
|
||||
&& ((DECL_NAME (TREE_OPERAND (decl, 0))
|
||||
== constructor_name_full (ctype))
|
||||
|
@ -8529,6 +8530,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
|
|||
/* Pick up type qualifiers which should be applied to `this'. */
|
||||
quals = TREE_OPERAND (declarator, 2);
|
||||
|
||||
/* Pick up the exception specifications. */
|
||||
raises = TREE_TYPE (declarator);
|
||||
|
||||
/* Say it's a definition only for the CALL_EXPR
|
||||
closest to the identifier. */
|
||||
funcdecl_p =
|
||||
|
@ -9776,11 +9780,10 @@ grokparms (first_parm, funcdef_flag)
|
|||
|
||||
if (decl != void_type_node)
|
||||
{
|
||||
/* @@ May need to fetch out a `raises' here. */
|
||||
decl = grokdeclarator (TREE_VALUE (decl),
|
||||
TREE_PURPOSE (decl),
|
||||
PARM, init != NULL_TREE,
|
||||
NULL_TREE, NULL_TREE);
|
||||
NULL_TREE);
|
||||
if (! decl)
|
||||
continue;
|
||||
type = TREE_TYPE (decl);
|
||||
|
@ -9878,7 +9881,7 @@ grokparms (first_parm, funcdef_flag)
|
|||
else
|
||||
init = require_instantiated_type (type, init, integer_zero_node);
|
||||
if (! current_template_parms
|
||||
&& ! implicit_conversion (type, TREE_TYPE (init), init, LOOKUP_NORMAL))
|
||||
&& ! can_convert_arg (type, TREE_TYPE (init), init))
|
||||
cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
|
||||
TREE_TYPE (init), decl);
|
||||
}
|
||||
|
@ -9933,6 +9936,21 @@ grokparms (first_parm, funcdef_flag)
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
copy_args_p (d)
|
||||
tree d;
|
||||
{
|
||||
tree t = FUNCTION_ARG_CHAIN (d);
|
||||
if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
|
||||
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
|
||||
== DECL_CLASS_CONTEXT (d))
|
||||
&& (TREE_CHAIN (t) == NULL_TREE
|
||||
|| TREE_CHAIN (t) == void_list_node
|
||||
|| TREE_PURPOSE (TREE_CHAIN (t))))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* These memoizing functions keep track of special properties which
|
||||
a class may have. `grok_ctor_properties' notices whether a class
|
||||
has a constructor of the form X(X&), and also complains
|
||||
|
@ -10880,8 +10898,8 @@ static int function_depth;
|
|||
@@ something we had previously. */
|
||||
|
||||
int
|
||||
start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
|
||||
tree declspecs, declarator, raises, attrs;
|
||||
start_function (declspecs, declarator, attrs, pre_parsed_p)
|
||||
tree declspecs, declarator, attrs;
|
||||
int pre_parsed_p;
|
||||
{
|
||||
tree decl1;
|
||||
|
@ -10957,8 +10975,6 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
|
|||
doing_friend = 1;
|
||||
}
|
||||
|
||||
raises = TYPE_RAISES_EXCEPTIONS (fntype);
|
||||
|
||||
/* In a fcn definition, arg types must be complete. */
|
||||
require_complete_types_for_parms (DECL_ARGUMENTS (decl1));
|
||||
|
||||
|
@ -10975,8 +10991,7 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
|
|||
}
|
||||
else
|
||||
{
|
||||
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, raises,
|
||||
NULL_TREE);
|
||||
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE);
|
||||
/* If the declarator is not suitable for a function definition,
|
||||
cause a syntax error. */
|
||||
if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) return 0;
|
||||
|
@ -12109,10 +12124,10 @@ finish_function (lineno, call_poplevel, nested)
|
|||
CHANGES TO CODE IN `grokfield'. */
|
||||
|
||||
tree
|
||||
start_method (declspecs, declarator, raises)
|
||||
tree declarator, declspecs, raises;
|
||||
start_method (declspecs, declarator)
|
||||
tree declarator, declspecs;
|
||||
{
|
||||
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, raises,
|
||||
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
|
||||
NULL_TREE);
|
||||
|
||||
/* Something too ugly to handle. */
|
||||
|
|
|
@ -31,7 +31,7 @@ enum decl_context
|
|||
};
|
||||
|
||||
/* We need this in here to get the decl_context definition. */
|
||||
extern tree grokdeclarator PROTO((tree, tree, enum decl_context, int, tree, tree));
|
||||
extern tree grokdeclarator PROTO((tree, tree, enum decl_context, int, tree));
|
||||
|
||||
/* C++: Keep these around to reduce calls to `get_identifier'.
|
||||
Identifiers for `this' in member functions and the auto-delete
|
||||
|
|
231
gcc/cp/decl2.c
231
gcc/cp/decl2.c
|
@ -37,10 +37,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "lex.h"
|
||||
#include "output.h"
|
||||
|
||||
#ifndef SUPPORTS_ONE_ONLY
|
||||
#define SUPPORTS_ONE_ONLY 0
|
||||
#endif
|
||||
|
||||
extern tree get_file_function_name ();
|
||||
extern tree cleanups_this_call;
|
||||
static void grok_function_init PROTO((tree, tree));
|
||||
|
@ -1339,8 +1335,8 @@ check_classfn (ctype, function)
|
|||
CHANGES TO CODE IN `start_method'. */
|
||||
|
||||
tree
|
||||
grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
|
||||
tree declarator, declspecs, raises, init, asmspec_tree, attrlist;
|
||||
grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
|
||||
tree declarator, declspecs, init, asmspec_tree, attrlist;
|
||||
{
|
||||
register tree value;
|
||||
char *asmspec = 0;
|
||||
|
@ -1376,8 +1372,7 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
|
|||
&& TREE_CHAIN (init) == NULL_TREE)
|
||||
init = NULL_TREE;
|
||||
|
||||
value = grokdeclarator (declarator, declspecs, FIELD, init != 0,
|
||||
raises, NULL_TREE);
|
||||
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, NULL_TREE);
|
||||
if (! value)
|
||||
return value; /* friend or constructor went bad. */
|
||||
|
||||
|
@ -1593,7 +1588,7 @@ grokbitfield (declarator, declspecs, width)
|
|||
tree declarator, declspecs, width;
|
||||
{
|
||||
register tree value = grokdeclarator (declarator, declspecs, BITFIELD,
|
||||
0, NULL_TREE, NULL_TREE);
|
||||
0, NULL_TREE);
|
||||
|
||||
if (! value) return NULL_TREE; /* friends went bad. */
|
||||
|
||||
|
@ -1640,194 +1635,11 @@ grokbitfield (declarator, declspecs, width)
|
|||
return value;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Like GROKFIELD, except that the declarator has been
|
||||
buried in DECLSPECS. Find the declarator, and
|
||||
return something that looks like it came from
|
||||
GROKFIELD. */
|
||||
|
||||
tree
|
||||
groktypefield (declspecs, parmlist)
|
||||
tree declspecs;
|
||||
tree parmlist;
|
||||
{
|
||||
tree spec = declspecs;
|
||||
tree prev = NULL_TREE;
|
||||
|
||||
tree type_id = NULL_TREE;
|
||||
tree quals = NULL_TREE;
|
||||
tree lengths = NULL_TREE;
|
||||
tree decl = NULL_TREE;
|
||||
|
||||
while (spec)
|
||||
{
|
||||
register tree id = TREE_VALUE (spec);
|
||||
|
||||
if (TREE_CODE (spec) != TREE_LIST)
|
||||
/* Certain parse errors slip through. For example,
|
||||
`int class ();' is not caught by the parser. Try
|
||||
weakly to recover here. */
|
||||
return NULL_TREE;
|
||||
|
||||
if (TREE_CODE (id) == TYPE_DECL
|
||||
|| (TREE_CODE (id) == IDENTIFIER_NODE && TREE_TYPE (id)))
|
||||
{
|
||||
/* We have a constructor/destructor or
|
||||
conversion operator. Use it. */
|
||||
if (prev)
|
||||
TREE_CHAIN (prev) = TREE_CHAIN (spec);
|
||||
else
|
||||
declspecs = TREE_CHAIN (spec);
|
||||
|
||||
type_id = id;
|
||||
goto found;
|
||||
}
|
||||
prev = spec;
|
||||
spec = TREE_CHAIN (spec);
|
||||
}
|
||||
|
||||
/* Nope, we have a conversion operator to a scalar type or something
|
||||
else, that includes things like constructor declarations for
|
||||
templates. */
|
||||
spec = declspecs;
|
||||
while (spec)
|
||||
{
|
||||
tree id = TREE_VALUE (spec);
|
||||
|
||||
if (TREE_CODE (id) == IDENTIFIER_NODE)
|
||||
{
|
||||
if (id == ridpointers[(int)RID_INT]
|
||||
|| id == ridpointers[(int)RID_DOUBLE]
|
||||
|| id == ridpointers[(int)RID_FLOAT]
|
||||
|| id == ridpointers[(int)RID_WCHAR])
|
||||
{
|
||||
if (type_id)
|
||||
error ("extra `%s' ignored",
|
||||
IDENTIFIER_POINTER (id));
|
||||
else
|
||||
type_id = id;
|
||||
}
|
||||
else if (id == ridpointers[(int)RID_LONG]
|
||||
|| id == ridpointers[(int)RID_SHORT]
|
||||
|| id == ridpointers[(int)RID_CHAR])
|
||||
{
|
||||
lengths = tree_cons (NULL_TREE, id, lengths);
|
||||
}
|
||||
else if (id == ridpointers[(int)RID_VOID])
|
||||
{
|
||||
if (type_id)
|
||||
error ("spurious `void' type ignored");
|
||||
else
|
||||
error ("conversion to `void' type invalid");
|
||||
}
|
||||
else if (id == ridpointers[(int)RID_AUTO]
|
||||
|| id == ridpointers[(int)RID_REGISTER]
|
||||
|| id == ridpointers[(int)RID_TYPEDEF]
|
||||
|| id == ridpointers[(int)RID_CONST]
|
||||
|| id == ridpointers[(int)RID_VOLATILE])
|
||||
{
|
||||
error ("type specifier `%s' used invalidly",
|
||||
IDENTIFIER_POINTER (id));
|
||||
}
|
||||
else if (id == ridpointers[(int)RID_FRIEND]
|
||||
|| id == ridpointers[(int)RID_VIRTUAL]
|
||||
|| id == ridpointers[(int)RID_INLINE]
|
||||
|| id == ridpointers[(int)RID_UNSIGNED]
|
||||
|| id == ridpointers[(int)RID_SIGNED]
|
||||
|| id == ridpointers[(int)RID_STATIC]
|
||||
|| id == ridpointers[(int)RID_EXTERN])
|
||||
{
|
||||
quals = tree_cons (NULL_TREE, id, quals);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Happens when we have a global typedef
|
||||
and a class-local member function with
|
||||
the same name. */
|
||||
type_id = id;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (id) == RECORD_TYPE)
|
||||
{
|
||||
type_id = TYPE_NAME (id);
|
||||
if (TREE_CODE (type_id) == TYPE_DECL)
|
||||
type_id = DECL_NAME (type_id);
|
||||
if (type_id == NULL_TREE)
|
||||
error ("identifier for aggregate type conversion omitted");
|
||||
}
|
||||
else if (TREE_CODE_CLASS (TREE_CODE (id)) == 't')
|
||||
error ("`operator' missing on conversion operator or tag missing from type");
|
||||
else
|
||||
my_friendly_abort (194);
|
||||
spec = TREE_CHAIN (spec);
|
||||
}
|
||||
|
||||
if (type_id)
|
||||
declspecs = chainon (lengths, quals);
|
||||
else if (lengths)
|
||||
{
|
||||
if (TREE_CHAIN (lengths))
|
||||
error ("multiple length specifiers");
|
||||
type_id = ridpointers[(int)RID_INT];
|
||||
declspecs = chainon (lengths, quals);
|
||||
}
|
||||
else if (quals)
|
||||
{
|
||||
error ("no type given, defaulting to `operator int ...'");
|
||||
type_id = ridpointers[(int)RID_INT];
|
||||
declspecs = quals;
|
||||
}
|
||||
else
|
||||
return NULL_TREE;
|
||||
|
||||
found:
|
||||
decl = grokdeclarator (build_parse_node (CALL_EXPR, type_id, parmlist, NULL_TREE),
|
||||
declspecs, FIELD, 0, NULL_TREE, NULL_TREE);
|
||||
if (decl == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CHAIN (decl) != NULL_TREE)
|
||||
{
|
||||
/* Need a fresh node here so that we don't get circularity
|
||||
when we link these together. */
|
||||
decl = copy_node (decl);
|
||||
}
|
||||
|
||||
if (decl == void_type_node
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& TREE_CODE (TREE_TYPE (decl)) != METHOD_TYPE))
|
||||
/* bunch of friends. */
|
||||
return decl;
|
||||
|
||||
if (DECL_IN_AGGR_P (decl))
|
||||
{
|
||||
cp_error ("`%D' already defined in the class ", decl);
|
||||
return void_type_node;
|
||||
}
|
||||
|
||||
cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0, 0);
|
||||
|
||||
/* If this declaration is common to another declaration
|
||||
complain about such redundancy, and return NULL_TREE
|
||||
so that we don't build a circular list. */
|
||||
if (DECL_CHAIN (decl))
|
||||
{
|
||||
cp_error ("function `%D' declared twice in class %T", decl,
|
||||
DECL_CONTEXT (decl));
|
||||
return NULL_TREE;
|
||||
}
|
||||
DECL_IN_AGGR_P (decl) = 1;
|
||||
return decl;
|
||||
}
|
||||
#endif
|
||||
|
||||
tree
|
||||
grokoptypename (declspecs, declarator)
|
||||
tree declspecs, declarator;
|
||||
{
|
||||
tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0,
|
||||
NULL_TREE, NULL_TREE);
|
||||
tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE);
|
||||
return build_typename_overload (t);
|
||||
}
|
||||
|
||||
|
@ -2486,12 +2298,9 @@ comdat_linkage (decl)
|
|||
{
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
|
||||
#ifdef DECL_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
{
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
}
|
||||
#ifdef MAKE_DECL_ONE_ONLY
|
||||
MAKE_DECL_ONE_ONLY (decl);
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
#endif
|
||||
|
||||
if (flag_weak)
|
||||
|
@ -2499,7 +2308,6 @@ comdat_linkage (decl)
|
|||
DECL_WEAK (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
|
||||
|
@ -2585,8 +2393,8 @@ finish_prevtable_vardecl (prev, vars)
|
|||
tree ctype = DECL_CONTEXT (vars);
|
||||
import_export_template (ctype);
|
||||
|
||||
#ifndef NO_LINKAGE_HEURISTICS
|
||||
if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype)
|
||||
&& ! (SUPPORTS_ONE_ONLY > 1)
|
||||
&& ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
|
||||
{
|
||||
tree method;
|
||||
|
@ -2604,6 +2412,7 @@ finish_prevtable_vardecl (prev, vars)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
import_export_vtable (vars, ctype, 1);
|
||||
return 1;
|
||||
|
@ -2785,9 +2594,8 @@ import_export_decl (decl)
|
|||
{
|
||||
/* Statically initialized vars are weak or comdat, if
|
||||
supported. */
|
||||
#ifdef DECL_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
#ifdef MAKE_DECL_ONE_ONLY
|
||||
MAKE_DECL_ONE_ONLY (decl);
|
||||
#endif
|
||||
if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
|
@ -2991,6 +2799,9 @@ finish_file ()
|
|||
}
|
||||
}
|
||||
|
||||
for (vars = static_aggregates; vars; vars = TREE_CHAIN (vars))
|
||||
if (! TREE_ASM_WRITTEN (TREE_VALUE (vars)))
|
||||
rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1);
|
||||
vars = static_aggregates;
|
||||
|
||||
if (static_ctors || vars || exception_table_p ())
|
||||
|
@ -3017,9 +2828,9 @@ finish_file ()
|
|||
|
||||
fnname = get_file_function_name ('D');
|
||||
start_function (void_list_node,
|
||||
build_parse_node (CALL_EXPR, fnname, void_list_node,
|
||||
NULL_TREE),
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
make_call_declarator (fnname, void_list_node, NULL_TREE,
|
||||
NULL_TREE),
|
||||
NULL_TREE, 0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
|
@ -3083,9 +2894,9 @@ finish_file ()
|
|||
{
|
||||
fnname = get_file_function_name ('I');
|
||||
start_function (void_list_node,
|
||||
build_parse_node (CALL_EXPR, fnname,
|
||||
void_list_node, NULL_TREE),
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
make_call_declarator (fnname, void_list_node, NULL_TREE,
|
||||
NULL_TREE),
|
||||
NULL_TREE, 0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
|
|
|
@ -312,36 +312,36 @@ init_exception_processing ()
|
|||
|
||||
declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);
|
||||
d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_pc"));
|
||||
d = start_decl (d, declspecs, 0, NULL_TREE);
|
||||
d = start_decl (d, declspecs, 0);
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_pc = lookup_name (get_identifier ("__eh_pc"), 0);
|
||||
|
||||
declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);
|
||||
d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_type"));
|
||||
d = start_decl (d, declspecs, 0, NULL_TREE);
|
||||
d = start_decl (d, declspecs, 0);
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_throw_type = lookup_name (get_identifier ("__eh_type"), 0);
|
||||
|
||||
declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);
|
||||
d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_value"));
|
||||
d = start_decl (d, declspecs, 0, NULL_TREE);
|
||||
d = start_decl (d, declspecs, 0);
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_throw_value = lookup_name (get_identifier ("__eh_value"), 0);
|
||||
|
||||
declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);
|
||||
d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_cleanup"));
|
||||
d = build_parse_node (CALL_EXPR, d, void_list_node, NULL_TREE);
|
||||
d = start_decl (d, declspecs, 0, NULL_TREE);
|
||||
d = make_call_declarator (d, void_list_node, NULL_TREE, NULL_TREE);
|
||||
d = start_decl (d, declspecs, 0);
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_cleanup = lookup_name (get_identifier ("__eh_cleanup"), 0);
|
||||
|
||||
declspecs = tree_cons (NULL_TREE, get_identifier ("bool"), NULL_TREE);
|
||||
d = get_identifier ("__eh_in_catch");
|
||||
d = start_decl (d, declspecs, 0, NULL_TREE);
|
||||
d = start_decl (d, declspecs, 0);
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_in_catch = lookup_name (get_identifier ("__eh_in_catch"), 0);
|
||||
|
@ -429,6 +429,7 @@ expand_start_catch_block (declspecs, declarator)
|
|||
return;
|
||||
|
||||
/* Create a binding level for the parm. */
|
||||
pushlevel (0);
|
||||
expand_start_bindings (0);
|
||||
|
||||
false_label_rtx = gen_label_rtx ();
|
||||
|
@ -440,8 +441,7 @@ expand_start_catch_block (declspecs, declarator)
|
|||
rtx call_rtx, return_value_rtx;
|
||||
tree init_type;
|
||||
|
||||
decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1,
|
||||
NULL_TREE, NULL_TREE);
|
||||
decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE);
|
||||
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
|
@ -545,8 +545,8 @@ void expand_end_catch_block ()
|
|||
expand_leftover_cleanups ();
|
||||
|
||||
/* Cleanup the EH parameter. */
|
||||
decls = getdecls ();
|
||||
expand_end_bindings (decls, decls != NULL_TREE, 0);
|
||||
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
||||
poplevel (kept_level_p (), 1, 0);
|
||||
|
||||
/* label we emit to jump to if this catch block didn't match. */
|
||||
/* This the closing } in the `if (eq) {' of the documentation. */
|
||||
|
@ -671,10 +671,11 @@ expand_builtin_throw ()
|
|||
return;
|
||||
|
||||
params = void_list_node;
|
||||
t = build_parse_node (CALL_EXPR, get_identifier ("__throw"), params, NULL_TREE);
|
||||
t = make_call_declarator (get_identifier ("__throw"), params, NULL_TREE,
|
||||
NULL_TREE);
|
||||
start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"),
|
||||
void_list_node),
|
||||
t, NULL_TREE, NULL_TREE, 0);
|
||||
t, NULL_TREE, 0);
|
||||
store_parm_decls ();
|
||||
pushlevel (0);
|
||||
clear_last_expr ();
|
||||
|
@ -868,7 +869,7 @@ void
|
|||
expand_exception_blocks ()
|
||||
{
|
||||
rtx funcend;
|
||||
rtx insns;
|
||||
rtx insn, insns;
|
||||
rtx eh_spec_insns = NULL_RTX;
|
||||
|
||||
start_sequence ();
|
||||
|
@ -957,7 +958,14 @@ expand_exception_blocks ()
|
|||
store_after_parms (eh_spec_insns);
|
||||
#endif
|
||||
|
||||
emit_insns (insns);
|
||||
insn = get_last_insn ();
|
||||
while (GET_CODE (insn) == NOTE
|
||||
|| (GET_CODE (insn) == INSN
|
||||
&& (GET_CODE (PATTERN (insn)) == USE
|
||||
|| GET_CODE (PATTERN (insn)) == CLOBBER)))
|
||||
insn = PREV_INSN (insn);
|
||||
|
||||
emit_insns_after (insns, insn);
|
||||
}
|
||||
|
||||
tree
|
||||
|
@ -980,10 +988,11 @@ start_anon_func ()
|
|||
params = void_list_node;
|
||||
/* tcf stands for throw clean funciton. */
|
||||
sprintf (name, "__tcf_%d", counter++);
|
||||
t = build_parse_node (CALL_EXPR, get_identifier (name), params, NULL_TREE);
|
||||
t = make_call_declarator (get_identifier (name), params, NULL_TREE,
|
||||
NULL_TREE);
|
||||
start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"),
|
||||
void_list_node),
|
||||
t, NULL_TREE, NULL_TREE, 0);
|
||||
t, NULL_TREE, 0);
|
||||
store_parm_decls ();
|
||||
pushlevel (0);
|
||||
clear_last_expr ();
|
||||
|
|
|
@ -9,8 +9,8 @@ __asm, GCC_ASM_KEYWORD, NORID
|
|||
__asm__, GCC_ASM_KEYWORD, NORID
|
||||
__attribute, ATTRIBUTE, NORID
|
||||
__attribute__, ATTRIBUTE, NORID
|
||||
__const, TYPE_QUAL, RID_CONST
|
||||
__const__, TYPE_QUAL, RID_CONST
|
||||
__const, CV_QUALIFIER, RID_CONST
|
||||
__const__, CV_QUALIFIER, RID_CONST
|
||||
__extension__, EXTENSION, NORID
|
||||
__inline, SCSPEC, RID_INLINE
|
||||
__inline__, SCSPEC, RID_INLINE
|
||||
|
@ -22,8 +22,8 @@ __signed__, TYPESPEC, RID_SIGNED
|
|||
__sigof__, SIGOF, NORID /* Extension */,
|
||||
__typeof, TYPEOF, NORID
|
||||
__typeof__, TYPEOF, NORID
|
||||
__volatile, TYPE_QUAL, RID_VOLATILE
|
||||
__volatile__, TYPE_QUAL, RID_VOLATILE
|
||||
__volatile, CV_QUALIFIER, RID_VOLATILE
|
||||
__volatile__, CV_QUALIFIER, RID_VOLATILE
|
||||
__wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,
|
||||
asm, ASM_KEYWORD, NORID,
|
||||
and, ANDAND, NORID,
|
||||
|
@ -38,7 +38,7 @@ catch, CATCH, NORID,
|
|||
char, TYPESPEC, RID_CHAR,
|
||||
class, AGGR, RID_CLASS,
|
||||
compl, '~', NORID,
|
||||
const, TYPE_QUAL, RID_CONST,
|
||||
const, CV_QUALIFIER, RID_CONST,
|
||||
const_cast, CONST_CAST, NORID,
|
||||
continue, CONTINUE, NORID,
|
||||
default, DEFAULT, NORID,
|
||||
|
@ -97,7 +97,7 @@ unsigned, TYPESPEC, RID_UNSIGNED,
|
|||
using, USING, NORID,
|
||||
virtual, SCSPEC, RID_VIRTUAL,
|
||||
void, TYPESPEC, RID_VOID,
|
||||
volatile, TYPE_QUAL, RID_VOLATILE,
|
||||
volatile, CV_QUALIFIER, RID_VOLATILE,
|
||||
while, WHILE, NORID,
|
||||
xor, '^', NORID,
|
||||
xor_eq, ASSIGN, NORID,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* C code produced by gperf version 2.5 (GNU C++ version) */
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ /yorick/splunge/jason/g++/small/devo/gcc/cp/gxx.gperf */
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf */
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */
|
||||
struct resword { char *name; short token; enum rid rid;};
|
||||
|
||||
|
@ -123,7 +123,7 @@ is_reserved_word (str, len)
|
|||
{"mutable", SCSPEC, RID_MUTABLE,},
|
||||
{"short", TYPESPEC, RID_SHORT,},
|
||||
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
|
||||
{"const", TYPE_QUAL, RID_CONST,},
|
||||
{"const", CV_QUALIFIER, RID_CONST,},
|
||||
{"static", SCSPEC, RID_STATIC,},
|
||||
{"",}, {"",},
|
||||
{"for", FOR, NORID,},
|
||||
|
@ -149,11 +149,11 @@ is_reserved_word (str, len)
|
|||
{"",}, {"",}, {"",},
|
||||
{"signed", TYPESPEC, RID_SIGNED,},
|
||||
{"this", THIS, NORID,},
|
||||
{"__const", TYPE_QUAL, RID_CONST},
|
||||
{"__const__", TYPE_QUAL, RID_CONST},
|
||||
{"__volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"__const", CV_QUALIFIER, RID_CONST},
|
||||
{"__const__", CV_QUALIFIER, RID_CONST},
|
||||
{"__volatile", CV_QUALIFIER, RID_VOLATILE},
|
||||
{"__null", CONSTANT, RID_NULL},
|
||||
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
|
||||
{"__volatile__", CV_QUALIFIER, RID_VOLATILE},
|
||||
{"__typeof__", TYPEOF, NORID},
|
||||
{"or_eq", ASSIGN, NORID,},
|
||||
{"",},
|
||||
|
@ -178,7 +178,7 @@ is_reserved_word (str, len)
|
|||
{"bitor", '|', NORID,},
|
||||
{"",},
|
||||
{"do", DO, NORID,},
|
||||
{"volatile", TYPE_QUAL, RID_VOLATILE,},
|
||||
{"volatile", CV_QUALIFIER, RID_VOLATILE,},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"if", IF, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
|
|
67
gcc/cp/lex.c
67
gcc/cp/lex.c
|
@ -131,35 +131,35 @@ extern int *token_count;
|
|||
|
||||
/* Return something to represent absolute declarators containing a *.
|
||||
TARGET is the absolute declarator that the * contains.
|
||||
TYPE_QUALS is a list of modifiers such as const or volatile
|
||||
CV_QUALIFIERS is a list of modifiers such as const or volatile
|
||||
to apply to the pointer type, represented as identifiers.
|
||||
|
||||
We return an INDIRECT_REF whose "contents" are TARGET
|
||||
and whose type is the modifier list. */
|
||||
|
||||
tree
|
||||
make_pointer_declarator (type_quals, target)
|
||||
tree type_quals, target;
|
||||
make_pointer_declarator (cv_qualifiers, target)
|
||||
tree cv_qualifiers, target;
|
||||
{
|
||||
if (target && TREE_CODE (target) == IDENTIFIER_NODE
|
||||
&& ANON_AGGRNAME_P (target))
|
||||
error ("type name expected before `*'");
|
||||
target = build_parse_node (INDIRECT_REF, target);
|
||||
TREE_TYPE (target) = type_quals;
|
||||
TREE_TYPE (target) = cv_qualifiers;
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Return something to represent absolute declarators containing a &.
|
||||
TARGET is the absolute declarator that the & contains.
|
||||
TYPE_QUALS is a list of modifiers such as const or volatile
|
||||
CV_QUALIFIERS is a list of modifiers such as const or volatile
|
||||
to apply to the reference type, represented as identifiers.
|
||||
|
||||
We return an ADDR_EXPR whose "contents" are TARGET
|
||||
and whose type is the modifier list. */
|
||||
|
||||
tree
|
||||
make_reference_declarator (type_quals, target)
|
||||
tree type_quals, target;
|
||||
make_reference_declarator (cv_qualifiers, target)
|
||||
tree cv_qualifiers, target;
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
|
@ -177,9 +177,26 @@ make_reference_declarator (type_quals, target)
|
|||
error ("type name expected before `&'");
|
||||
}
|
||||
target = build_parse_node (ADDR_EXPR, target);
|
||||
TREE_TYPE (target) = type_quals;
|
||||
TREE_TYPE (target) = cv_qualifiers;
|
||||
return target;
|
||||
}
|
||||
|
||||
tree
|
||||
make_call_declarator (target, parms, cv_qualifiers, exception_specification)
|
||||
tree target, parms, cv_qualifiers, exception_specification;
|
||||
{
|
||||
target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
|
||||
TREE_TYPE (target) = exception_specification;
|
||||
return target;
|
||||
}
|
||||
|
||||
void
|
||||
set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
|
||||
tree call_declarator, cv_qualifiers, exception_specification;
|
||||
{
|
||||
TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
|
||||
TREE_TYPE (call_declarator) = exception_specification;
|
||||
}
|
||||
|
||||
/* Build names and nodes for overloaded operators. */
|
||||
|
||||
|
@ -1681,12 +1698,11 @@ cons_up_default_function (type, full_name, kind)
|
|||
TREE_PARMLIST (args) = 1;
|
||||
|
||||
{
|
||||
tree declarator = build_parse_node (CALL_EXPR, name, args, NULL_TREE);
|
||||
tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
|
||||
if (retref)
|
||||
declarator = build_parse_node (ADDR_EXPR, declarator);
|
||||
|
||||
fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE,
|
||||
NULL_TREE, NULL_TREE);
|
||||
fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
|
||||
if (fn == void_type_node)
|
||||
|
@ -2444,20 +2460,6 @@ readescape (ignore_ptr)
|
|||
Value is 0 if we treat this name in a default fashion. */
|
||||
int looking_for_typename = 0;
|
||||
|
||||
#if 0
|
||||
/* NO LONGER USED: Value is -1 if we must not see a type name. */
|
||||
void
|
||||
dont_see_typename ()
|
||||
{
|
||||
looking_for_typename = -1;
|
||||
if (yychar == TYPENAME || yychar == PTYPENAME)
|
||||
{
|
||||
yychar = IDENTIFIER;
|
||||
lastiddecl = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
extern __inline int identifier_type ();
|
||||
__inline
|
||||
|
@ -4363,11 +4365,6 @@ handle_cp_pragma (pname)
|
|||
main_filename = TREE_STRING_POINTER (yylval.ttype);
|
||||
}
|
||||
|
||||
#ifdef SUPPORTS_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY > 1)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
while (token != END_OF_LINE)
|
||||
{
|
||||
if (!warned_already && extra_warnings)
|
||||
|
@ -4378,6 +4375,7 @@ handle_cp_pragma (pname)
|
|||
token = real_yylex ();
|
||||
}
|
||||
|
||||
#ifndef NO_LINKAGE_HEURISTICS
|
||||
write_virtuals = 3;
|
||||
|
||||
if (impl_file_chain == 0)
|
||||
|
@ -4404,6 +4402,7 @@ handle_cp_pragma (pname)
|
|||
interface_unknown = 0;
|
||||
TREE_INT_CST_LOW (fileinfo) = interface_only;
|
||||
TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
|
||||
#endif /* NO_LINKAGE_HEURISTICS */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -4436,11 +4435,7 @@ handle_cp_pragma (pname)
|
|||
token = real_yylex ();
|
||||
}
|
||||
|
||||
#ifdef SUPPORTS_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY > 1)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifndef NO_LINKAGE_HEURISTICS
|
||||
if (write_virtuals == 3)
|
||||
{
|
||||
struct impl_files *ifiles = impl_file_chain;
|
||||
|
@ -4485,6 +4480,8 @@ handle_cp_pragma (pname)
|
|||
#endif
|
||||
TREE_INT_CST_LOW (fileinfo) = interface_only;
|
||||
TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
|
||||
#endif /* NO_LINKAGE_HEURISTICS */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "hard-reg-set.h"
|
||||
#include "flags.h"
|
||||
|
||||
#ifndef SUPPORTS_ONE_ONLY
|
||||
#define SUPPORTS_ONE_ONLY 0
|
||||
#endif
|
||||
|
||||
/* TREE_LIST of the current inline functions that need to be
|
||||
processed. */
|
||||
struct pending_inline *pending_inlines;
|
||||
|
@ -2179,7 +2175,7 @@ synthesize_method (fndecl)
|
|||
push_cp_function_context (context);
|
||||
|
||||
interface_unknown = 1;
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, NULL_TREE, 1);
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
|
||||
if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])
|
||||
|
|
719
gcc/cp/parse.y
719
gcc/cp/parse.y
File diff suppressed because it is too large
Load diff
62
gcc/cp/pt.c
62
gcc/cp/pt.c
|
@ -118,7 +118,7 @@ process_template_parm (list, next)
|
|||
my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
|
||||
/* is a const-param */
|
||||
parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
|
||||
PARM, 0, NULL_TREE, NULL_TREE);
|
||||
PARM, 0, NULL_TREE);
|
||||
/* A template parameter is not modifiable. */
|
||||
TREE_READONLY (parm) = 1;
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (parm))
|
||||
|
@ -1761,7 +1761,8 @@ tsubst (t, args, nargs, in_decl)
|
|||
{
|
||||
tree values = TYPE_ARG_TYPES (t);
|
||||
tree context = TYPE_CONTEXT (t);
|
||||
tree new_value;
|
||||
tree raises = TYPE_RAISES_EXCEPTIONS (t);
|
||||
tree fntype;
|
||||
|
||||
/* Don't bother recursing if we know it won't change anything. */
|
||||
if (values != void_list_node)
|
||||
|
@ -1777,7 +1778,7 @@ tsubst (t, args, nargs, in_decl)
|
|||
tree value
|
||||
= tsubst (TREE_VALUE (values), args, nargs, in_decl);
|
||||
tree purpose = tsubst_expr (TREE_PURPOSE (values),
|
||||
args, nargs, in_decl);
|
||||
args, nargs, in_decl);
|
||||
tree x = build_tree_list (purpose, value);
|
||||
|
||||
if (first)
|
||||
|
@ -1807,34 +1808,39 @@ tsubst (t, args, nargs, in_decl)
|
|||
if (TREE_CODE (t) == FUNCTION_TYPE
|
||||
&& context == NULL_TREE)
|
||||
{
|
||||
new_value = build_function_type (type, values);
|
||||
fntype = build_function_type (type, values);
|
||||
}
|
||||
else if (context == NULL_TREE)
|
||||
{
|
||||
tree base = tsubst (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))),
|
||||
args, nargs, in_decl);
|
||||
new_value = build_cplus_method_type (base, type,
|
||||
TREE_CHAIN (values));
|
||||
fntype = build_cplus_method_type (base, type,
|
||||
TREE_CHAIN (values));
|
||||
}
|
||||
else
|
||||
{
|
||||
new_value = make_node (TREE_CODE (t));
|
||||
TREE_TYPE (new_value) = type;
|
||||
TYPE_CONTEXT (new_value) = context;
|
||||
TYPE_VALUES (new_value) = values;
|
||||
TYPE_SIZE (new_value) = TYPE_SIZE (t);
|
||||
TYPE_ALIGN (new_value) = TYPE_ALIGN (t);
|
||||
TYPE_MODE (new_value) = TYPE_MODE (t);
|
||||
fntype = make_node (TREE_CODE (t));
|
||||
TREE_TYPE (fntype) = type;
|
||||
TYPE_CONTEXT (fntype) = context;
|
||||
TYPE_VALUES (fntype) = values;
|
||||
TYPE_SIZE (fntype) = TYPE_SIZE (t);
|
||||
TYPE_ALIGN (fntype) = TYPE_ALIGN (t);
|
||||
TYPE_MODE (fntype) = TYPE_MODE (t);
|
||||
if (TYPE_METHOD_BASETYPE (t))
|
||||
TYPE_METHOD_BASETYPE (new_value) = tsubst (TYPE_METHOD_BASETYPE (t),
|
||||
args, nargs, in_decl);
|
||||
TYPE_METHOD_BASETYPE (fntype) = tsubst (TYPE_METHOD_BASETYPE (t),
|
||||
args, nargs, in_decl);
|
||||
/* Need to generate hash value. */
|
||||
my_friendly_abort (84);
|
||||
}
|
||||
new_value = build_type_variant (new_value,
|
||||
TYPE_READONLY (t),
|
||||
TYPE_VOLATILE (t));
|
||||
return new_value;
|
||||
fntype = build_type_variant (fntype,
|
||||
TYPE_READONLY (t),
|
||||
TYPE_VOLATILE (t));
|
||||
if (raises)
|
||||
{
|
||||
raises = tsubst (raises, args, nargs, in_decl);
|
||||
fntype = build_exception_variant (fntype, raises);
|
||||
}
|
||||
return fntype;
|
||||
}
|
||||
case ARRAY_TYPE:
|
||||
{
|
||||
|
@ -1880,9 +1886,11 @@ tsubst (t, args, nargs, in_decl)
|
|||
tsubst_expr (TREE_OPERAND (t, 1), args, nargs, in_decl));
|
||||
|
||||
case CALL_EXPR:
|
||||
return build_parse_node
|
||||
(CALL_EXPR, tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
|
||||
tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl), NULL_TREE);
|
||||
return make_call_declarator
|
||||
(tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
|
||||
tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl),
|
||||
TREE_OPERAND (t, 2),
|
||||
tsubst (TREE_TYPE (t), args, nargs, in_decl));
|
||||
|
||||
case SCOPE_REF:
|
||||
return build_parse_node
|
||||
|
@ -2182,9 +2190,8 @@ tsubst_expr (t, args, nargs, in_decl)
|
|||
dcl = start_decl
|
||||
(tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
|
||||
tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl),
|
||||
TREE_OPERAND (t, 3) != 0,
|
||||
tsubst (TREE_OPERAND (t, 2), args, nargs, in_decl));
|
||||
init = tsubst_expr (TREE_OPERAND (t, 3), args, nargs, in_decl);
|
||||
TREE_OPERAND (t, 2) != 0);
|
||||
init = tsubst_expr (TREE_OPERAND (t, 2), args, nargs, in_decl);
|
||||
cp_finish_decl
|
||||
(dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0);
|
||||
resume_momentary (i);
|
||||
|
@ -3057,8 +3064,7 @@ void
|
|||
do_function_instantiation (declspecs, declarator, storage)
|
||||
tree declspecs, declarator, storage;
|
||||
{
|
||||
tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0,
|
||||
NULL_TREE, NULL_TREE);
|
||||
tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE);
|
||||
tree name;
|
||||
tree fn;
|
||||
tree result = NULL_TREE;
|
||||
|
@ -3354,7 +3360,7 @@ instantiate_decl (d)
|
|||
lineno = DECL_SOURCE_LINE (d);
|
||||
input_filename = DECL_SOURCE_FILE (d);
|
||||
|
||||
start_function (NULL_TREE, d, NULL_TREE, NULL_TREE, 1);
|
||||
start_function (NULL_TREE, d, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
|
||||
if (t && TREE_CODE (t) == RETURN_INIT)
|
||||
|
|
|
@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "cp-tree.h"
|
||||
#include "flags.h"
|
||||
#include "output.h"
|
||||
#include "assert.h"
|
||||
|
||||
#undef NULL
|
||||
#define NULL 0
|
||||
|
@ -348,7 +349,7 @@ build_dynamic_cast (type, expr)
|
|||
{
|
||||
enum tree_code tc = TREE_CODE (type);
|
||||
tree exprtype = TREE_TYPE (expr);
|
||||
enum tree_code ec = TREE_CODE (exprtype);
|
||||
enum tree_code ec;
|
||||
tree dcast_fn;
|
||||
|
||||
if (type == error_mark_node || expr == error_mark_node)
|
||||
|
@ -360,6 +361,9 @@ build_dynamic_cast (type, expr)
|
|||
return t;
|
||||
}
|
||||
|
||||
assert (exprtype != NULL_TREE);
|
||||
ec = TREE_CODE (exprtype);
|
||||
|
||||
switch (tc)
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
|
@ -977,7 +981,7 @@ synthesize_tinfo_fn (fndecl)
|
|||
DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
|
||||
cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
|
||||
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, NULL_TREE, 1);
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
clear_last_expr ();
|
||||
push_momentary ();
|
||||
|
|
|
@ -919,17 +919,19 @@ save_this (instance)
|
|||
/* Build a signature member function call. Looks up the signature table
|
||||
entry corresponding to FUNCTION. Depending on the value of the CODE
|
||||
field, either call the function in PFN directly, or use OFFSET to
|
||||
index INSTANCE's virtual function table. */
|
||||
index the object's virtual function table. */
|
||||
|
||||
tree
|
||||
build_signature_method_call (basetype, instance, function, parms)
|
||||
tree basetype, instance, function, parms;
|
||||
build_signature_method_call (function, parms)
|
||||
tree function, parms;
|
||||
{
|
||||
tree instance = TREE_VALUE (parms);
|
||||
tree saved_instance = save_this (instance); /* Create temp for `this'. */
|
||||
tree object_ptr = build_optr_ref (saved_instance);
|
||||
tree new_object_ptr, new_parms;
|
||||
tree signature_tbl_ptr = build_sptr_ref (saved_instance);
|
||||
tree sig_field_name = DECL_NAME (DECL_MEMFUNC_POINTER_TO (function));
|
||||
tree basetype = DECL_CONTEXT (function);
|
||||
tree basetype_path = TYPE_BINFO (basetype);
|
||||
tree tbl_entry = build_component_ref (build1 (INDIRECT_REF, basetype,
|
||||
signature_tbl_ptr),
|
||||
|
|
|
@ -215,6 +215,9 @@ build_cplus_new (type, init)
|
|||
tree slot;
|
||||
tree rval;
|
||||
|
||||
if (TREE_CODE (init) == TARGET_EXPR || init == error_mark_node)
|
||||
return init;
|
||||
|
||||
slot = build (VAR_DECL, type);
|
||||
layout_decl (slot, 0);
|
||||
rval = build (NEW_EXPR, type,
|
||||
|
|
355
gcc/cp/typeck.c
355
gcc/cp/typeck.c
|
@ -1966,9 +1966,14 @@ build_indirect_ref (ptr, errorstring)
|
|||
tree ptr;
|
||||
char *errorstring;
|
||||
{
|
||||
register tree pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE ?
|
||||
ptr : default_conversion (ptr));
|
||||
register tree type = TREE_TYPE (pointer);
|
||||
register tree pointer, type;
|
||||
|
||||
if (ptr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
|
||||
? ptr : default_conversion (ptr));
|
||||
type = TREE_TYPE (pointer);
|
||||
|
||||
if (ptr == current_class_ptr)
|
||||
return current_class_ref;
|
||||
|
@ -5054,20 +5059,106 @@ tree
|
|||
build_static_cast (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
tree intype, binfo;
|
||||
int ok;
|
||||
|
||||
if (type == error_mark_node || expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (expr) == OFFSET_REF)
|
||||
expr = resolve_offset_ref (expr);
|
||||
|
||||
if (current_template_parms)
|
||||
{
|
||||
tree t = build_min (STATIC_CAST_EXPR, type, expr);
|
||||
return t;
|
||||
}
|
||||
|
||||
return build_c_cast (type, expr, 0);
|
||||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||
Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
|
||||
if (TREE_CODE (type) != REFERENCE_TYPE
|
||||
&& TREE_CODE (expr) == NOP_EXPR
|
||||
&& TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
|
||||
if (TREE_CODE (type) == VOID_TYPE)
|
||||
return build1 (CONVERT_EXPR, type, expr);
|
||||
|
||||
if (type_unknown_p (expr))
|
||||
{
|
||||
expr = instantiate_type (type, expr, 1);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
return (convert_from_reference
|
||||
(convert_to_reference (type, expr, CONV_STATIC|CONV_IMPLICIT,
|
||||
LOOKUP_COMPLAIN, NULL_TREE)));
|
||||
|
||||
if (IS_AGGR_TYPE (type))
|
||||
return build_cplus_new
|
||||
(type, (build_method_call
|
||||
(NULL_TREE, ctor_identifier, build_tree_list (NULL_TREE, expr),
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL)));
|
||||
|
||||
expr = decay_conversion (expr);
|
||||
intype = TREE_TYPE (expr);
|
||||
|
||||
/* FIXME handle casting to array type. */
|
||||
|
||||
ok = 0;
|
||||
if (can_convert_arg (type, intype, expr))
|
||||
ok = 1;
|
||||
else if (TYPE_PTROB_P (type) && TYPE_PTROB_P (intype))
|
||||
{
|
||||
tree binfo;
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
|
||||
&& (TYPE_READONLY (TREE_TYPE (type))
|
||||
>= TYPE_READONLY (TREE_TYPE (intype)))
|
||||
&& (TYPE_VOLATILE (TREE_TYPE (type))
|
||||
>= TYPE_VOLATILE (TREE_TYPE (intype)))
|
||||
&& (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
|
||||
&& ! TREE_VIA_VIRTUAL (binfo))
|
||||
ok = 1;
|
||||
}
|
||||
else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|
||||
{
|
||||
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))),
|
||||
TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype))), 1)
|
||||
&& (TYPE_READONLY (TREE_TYPE (TREE_TYPE (type)))
|
||||
>= TYPE_READONLY (TREE_TYPE (TREE_TYPE (intype))))
|
||||
&& (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (type)))
|
||||
>= TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (intype))))
|
||||
&& (binfo = get_binfo (TYPE_OFFSET_BASETYPE (intype),
|
||||
TYPE_OFFSET_BASETYPE (type), 0))
|
||||
&& ! TREE_VIA_VIRTUAL (binfo))
|
||||
ok = 1;
|
||||
}
|
||||
else if (TREE_CODE (intype) != BOOLEAN_TYPE
|
||||
&& TREE_CODE (type) != ARRAY_TYPE
|
||||
&& TREE_CODE (type) != FUNCTION_TYPE
|
||||
&& can_convert (intype, type))
|
||||
ok = 1;
|
||||
|
||||
if (ok)
|
||||
return build_c_cast (type, expr, 0);
|
||||
|
||||
cp_error ("static_cast from `%T' to `%T'", intype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
tree
|
||||
build_reinterpret_cast (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
tree intype = TREE_TYPE (expr);
|
||||
tree intype;
|
||||
|
||||
if (type == error_mark_node || expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (expr) == OFFSET_REF)
|
||||
expr = resolve_offset_ref (expr);
|
||||
|
||||
if (current_template_parms)
|
||||
{
|
||||
|
@ -5075,118 +5166,140 @@ build_reinterpret_cast (type, expr)
|
|||
return t;
|
||||
}
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
if (TYPE_PTRMEMFUNC_P (intype))
|
||||
return build1 (NOP_EXPR, type, expr);
|
||||
if (TREE_CODE (type) != REFERENCE_TYPE)
|
||||
{
|
||||
expr = decay_conversion (expr);
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
type = TYPE_PTRMEMFUNC_FN_TYPE (type);
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (intype))
|
||||
intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
|
||||
|
||||
if (! POINTER_TYPE_P (type) && ! TREE_CODE (type) == INTEGER_TYPE)
|
||||
{
|
||||
cp_error ("reinterpret_cast cannot convert to type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (! POINTER_TYPE_P (intype) && ! TREE_CODE (intype) == INTEGER_TYPE)
|
||||
{
|
||||
cp_error ("reinterpret_cast cannot convert from type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (type) == INTEGER_TYPE && TREE_CODE (intype) != POINTER_TYPE)
|
||||
{
|
||||
cp_error ("reinterpret_cast cannot convert non-pointer type `%T' to `%T'",
|
||||
intype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (intype) == INTEGER_TYPE && TREE_CODE (type) != POINTER_TYPE)
|
||||
{
|
||||
cp_error ("reinterpret_cast cannot convert `%T' to non-pointer type `%T'",
|
||||
intype, type);
|
||||
return error_mark_node;
|
||||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||
Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
|
||||
if (TREE_CODE (expr) == NOP_EXPR
|
||||
&& TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (intype) == POINTER_TYPE)
|
||||
expr = convert (ptr_type_node, expr);
|
||||
if (type_unknown_p (expr))
|
||||
{
|
||||
expr = instantiate_type (type, expr, 1);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return build_c_cast (type, expr, 0);
|
||||
intype = TREE_TYPE (expr);
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
if (! real_lvalue_p (expr))
|
||||
{
|
||||
cp_error ("reinterpret_cast from `%T' rvalue to `%T'", intype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
if (expr != error_mark_node)
|
||||
expr = build_reinterpret_cast
|
||||
(build_pointer_type (TREE_TYPE (type)), expr);
|
||||
if (expr != error_mark_node)
|
||||
expr = build_indirect_ref (expr, 0);
|
||||
return expr;
|
||||
}
|
||||
else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
|
||||
return build_static_cast (type, expr);
|
||||
|
||||
if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE
|
||||
|| TREE_CODE (intype) == ENUMERAL_TYPE))
|
||||
/* OK */;
|
||||
else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype))
|
||||
{
|
||||
if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
|
||||
cp_pedwarn ("reinterpret_cast from `%T' to `%T' loses precision",
|
||||
intype, type);
|
||||
}
|
||||
else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|
||||
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
|
||||
{
|
||||
if (TREE_READONLY_DECL_P (expr))
|
||||
expr = decl_constant_value (expr);
|
||||
return fold (build1 (NOP_EXPR, type, expr));
|
||||
}
|
||||
else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|
||||
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
|
||||
{
|
||||
if (! comp_ptr_ttypes_reinterpret (TREE_TYPE (type), TREE_TYPE (intype)))
|
||||
cp_pedwarn ("reinterpret_cast from `%T' to `%T' casts away const (or volatile)",
|
||||
intype, type);
|
||||
|
||||
if (TREE_READONLY_DECL_P (expr))
|
||||
expr = decl_constant_value (expr);
|
||||
return fold (build1 (NOP_EXPR, type, expr));
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_error ("reinterpret_cast from `%T' to `%T'", intype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return convert (type, expr);
|
||||
}
|
||||
|
||||
tree
|
||||
build_const_cast (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
tree intype = TREE_TYPE (expr);
|
||||
tree t1, t2;
|
||||
tree intype;
|
||||
|
||||
if (type == error_mark_node || expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (expr) == OFFSET_REF)
|
||||
expr = resolve_offset_ref (expr);
|
||||
|
||||
if (current_template_parms)
|
||||
{
|
||||
tree t = build_min (CONST_CAST_EXPR, type, expr);
|
||||
return t;
|
||||
}
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
type = TYPE_PTRMEMFUNC_FN_TYPE (type);
|
||||
if (TYPE_PTRMEMFUNC_P (intype))
|
||||
intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
|
||||
if (TREE_CODE (type) != REFERENCE_TYPE)
|
||||
{
|
||||
expr = decay_conversion (expr);
|
||||
|
||||
if (! POINTER_TYPE_P (type))
|
||||
{
|
||||
cp_error ("const_cast cannot convert to non-pointer type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE && ! real_lvalue_p (expr))
|
||||
{
|
||||
cp_error ("const_cast cannot convert rvalue to type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (intype) != POINTER_TYPE)
|
||||
{
|
||||
cp_error ("const_cast cannot convert non-pointer type `%T' to type `%T'",
|
||||
intype, type);
|
||||
return error_mark_node;
|
||||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||
Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
|
||||
if (TREE_CODE (expr) == NOP_EXPR
|
||||
&& TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
if (type_unknown_p (expr))
|
||||
{
|
||||
t1 = TREE_TYPE (type);
|
||||
t2 = intype;
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 = TREE_TYPE (type);
|
||||
t2 = TREE_TYPE (intype);
|
||||
|
||||
for (; TREE_CODE (t1) == POINTER_TYPE && TREE_CODE (t2) == POINTER_TYPE;
|
||||
t1 = TREE_TYPE (t1), t2 = TREE_TYPE (t2))
|
||||
;
|
||||
expr = instantiate_type (type, expr, 1);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (TREE_CODE (t1) == OFFSET_TYPE && TREE_CODE (t2) == OFFSET_TYPE)
|
||||
intype = TREE_TYPE (expr);
|
||||
|
||||
if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
|
||||
return build_static_cast (type, expr);
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
if (TYPE_OFFSET_BASETYPE (t1) != TYPE_OFFSET_BASETYPE (t2))
|
||||
if (! real_lvalue_p (expr))
|
||||
{
|
||||
cp_error ("const_cast cannot convert between pointers to members of different types `%T' and `%T'",
|
||||
TYPE_OFFSET_BASETYPE (t2), TYPE_OFFSET_BASETYPE (t1));
|
||||
cp_error ("const_cast from `%T' rvalue to `%T'", intype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
t1 = TREE_TYPE (t1);
|
||||
t2 = TREE_TYPE (t2);
|
||||
}
|
||||
|
||||
if (TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2))
|
||||
{
|
||||
cp_error ("const_cast cannot convert unrelated type `%T' to `%T'",
|
||||
t2, t1);
|
||||
return error_mark_node;
|
||||
if (comp_ptr_ttypes_const (TREE_TYPE (type), intype))
|
||||
return (convert_from_reference
|
||||
(convert_to_reference (type, expr, CONV_CONST|CONV_IMPLICIT,
|
||||
LOOKUP_COMPLAIN, NULL_TREE)));
|
||||
}
|
||||
else if (TREE_CODE (type) == POINTER_TYPE
|
||||
&& TREE_CODE (intype) == POINTER_TYPE
|
||||
&& comp_ptr_ttypes_const (TREE_TYPE (type), TREE_TYPE (intype)))
|
||||
return convert (type, expr);
|
||||
|
||||
return build_c_cast (type, expr, 0);
|
||||
cp_error ("const_cast from `%T' to `%T'", intype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Build an expression representing a cast to type TYPE of expression EXPR.
|
||||
|
@ -5348,15 +5461,9 @@ build_c_cast (type, expr, allow_nonconverting)
|
|||
}
|
||||
|
||||
/* Always produce some operator for an explicit cast,
|
||||
so we can tell (for -pedantic) that the cast is no lvalue.
|
||||
Also, pedantically, don't let (void *) (FOO *) 0 be a null
|
||||
pointer constant. */
|
||||
if (TREE_CODE (type) != REFERENCE_TYPE
|
||||
&& (value == expr
|
||||
|| (pedantic
|
||||
&& TREE_CODE (value) == INTEGER_CST
|
||||
&& TREE_CODE (expr) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)))
|
||||
so we can tell (for -pedantic) that the cast is no lvalue. */
|
||||
if (TREE_CODE (type) != REFERENCE_TYPE && value == expr
|
||||
&& real_lvalue_p (value))
|
||||
value = non_lvalue (value);
|
||||
|
||||
return value;
|
||||
|
@ -7261,7 +7368,8 @@ comp_ptr_ttypes_real (to, from, constp)
|
|||
return 0;
|
||||
|
||||
if (TREE_CODE (from) == OFFSET_TYPE
|
||||
&& TYPE_OFFSET_BASETYPE (from) == TYPE_OFFSET_BASETYPE (to))
|
||||
&& comptypes (TYPE_OFFSET_BASETYPE (from),
|
||||
TYPE_OFFSET_BASETYPE (to), 1))
|
||||
continue;
|
||||
|
||||
/* Const and volatile mean something different for function types,
|
||||
|
@ -7317,3 +7425,62 @@ ptr_reasonably_similar (to, from)
|
|||
(TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Like comp_ptr_ttypes, for const_cast. */
|
||||
|
||||
int
|
||||
comp_ptr_ttypes_const (to, from)
|
||||
tree to, from;
|
||||
{
|
||||
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
|
||||
{
|
||||
if (TREE_CODE (to) != TREE_CODE (from))
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (from) == OFFSET_TYPE
|
||||
&& comptypes (TYPE_OFFSET_BASETYPE (from),
|
||||
TYPE_OFFSET_BASETYPE (to), 1))
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (to) != POINTER_TYPE)
|
||||
return comptypes (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Like comp_ptr_ttypes, for reinterpret_cast. */
|
||||
|
||||
int
|
||||
comp_ptr_ttypes_reinterpret (to, from)
|
||||
tree to, from;
|
||||
{
|
||||
int constp = 1;
|
||||
|
||||
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
|
||||
{
|
||||
if (TREE_CODE (from) == OFFSET_TYPE)
|
||||
from = TREE_TYPE (from);
|
||||
if (TREE_CODE (to) == OFFSET_TYPE)
|
||||
to = TREE_TYPE (to);
|
||||
|
||||
if (TREE_CODE (to) != TREE_CODE (from))
|
||||
return 1;
|
||||
|
||||
/* Const and volatile mean something different for function types,
|
||||
so the usual checks are not appropriate. */
|
||||
if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
|
||||
{
|
||||
if (TYPE_READONLY (from) > TYPE_READONLY (to)
|
||||
|| TYPE_VOLATILE (from) > TYPE_VOLATILE (to))
|
||||
return 0;
|
||||
|
||||
if (! constp
|
||||
&& (TYPE_READONLY (to) > TYPE_READONLY (from)
|
||||
|| TYPE_VOLATILE (to) > TYPE_READONLY (from)))
|
||||
return 0;
|
||||
constp &= TYPE_READONLY (to);
|
||||
}
|
||||
|
||||
if (TREE_CODE (to) != POINTER_TYPE)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue