summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1994-05-19 20:19:03 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1994-05-19 20:19:03 +0000
commitbb0726a148f7adef1517311f8a5037cb525e0f39 (patch)
tree6821be58065899a0af95c7612b289e6fe83ca054
parentdd0637857dcaec160c42e0bf1ba437961d7d2e0d (diff)
downloadppe42-gcc-bb0726a148f7adef1517311f8a5037cb525e0f39.tar.gz
ppe42-gcc-bb0726a148f7adef1517311f8a5037cb525e0f39.zip
38th Cygnus<->FSF merge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7337 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog204
-rw-r--r--gcc/cp/call.c1480
-rw-r--r--gcc/cp/class.c47
-rw-r--r--gcc/cp/class.h55
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/cvt.c167
-rw-r--r--gcc/cp/decl.c99
-rw-r--r--gcc/cp/decl2.c69
-rw-r--r--gcc/cp/errfn.c2
-rw-r--r--gcc/cp/error.c7
-rw-r--r--gcc/cp/gxx.gperf3
-rw-r--r--gcc/cp/hash.h194
-rw-r--r--gcc/cp/init.c5
-rw-r--r--gcc/cp/lex.c9
-rw-r--r--gcc/cp/lex.h1
-rw-r--r--gcc/cp/method.c16
-rw-r--r--gcc/cp/parse.y249
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/search.c37
-rw-r--r--gcc/cp/tree.c13
-rw-r--r--gcc/cp/typeck.c376
-rw-r--r--gcc/cp/typeck2.c29
22 files changed, 1067 insertions, 2021 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bd2be26f9ca..f4b142407d3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,207 @@
+Thu May 19 12:08:48 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cvt.c (type_promotes_to): Make sure bool promotes to int rather
+ than unsigned on platforms where sizeof(char)==sizeof(int).
+
+Wed May 18 14:27:06 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * typeck.c (build_c_cast): Tack on a NOP_EXPR when casting to
+ another variant.
+ (build_modify_expr): Don't strip NOP_EXPRs, and don't get tricky
+ and treat them as lvalues.
+
+ * decl.c (shadow_tag): Do complain about forward declarations of
+ enums and empty declarations.
+ * parse.y: Don't complain about forward declarations of enums and
+ empty declarations.
+
+ * typeck.c (convert_for_assignment): Complain about changing
+ the signedness of a pointer's target type.
+
+ * parse.y (stmt): Move duplicated code for checking case values from
+ here.
+ * decl2.c (check_cp_case_value): To here. And add a call to
+ constant_expression_warning.
+
+ * typeck.c (convert_for_assignment): Don't complain about assigning
+ a negative value to bool.
+
+ * decl.c (init_decl_processing): Make bool unsigned.
+
+ * class.c (finish_struct): Allow bool bitfields.
+
+Wed May 18 14:41:59 1994 Mike Stump (mrs@cygnus.com)
+
+ * class.c (finish_base_struct): Make sure we set BINFO_VTABLE and
+ BINFO_VIRTUALS when we choose a new base class to inherit from.
+ * class.c (modify_one_vtable): Use get_vfield_offset to get the
+ offset to the most base class subobject that we derived this binfo
+ from.
+ * class.c (finish_struct): Move code to calculate the
+ DECL_FIELD_BITPOS of the vfield up, as we need might need it for
+ new calls to get_vfield_offset in modify_one_vtable.
+
+Wed May 18 12:35:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Make-lang.in (c++.install-man): Get g++.1 from $(srcdir)/cp.
+
+Wed May 18 03:28:35 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cvt.c (build_type_conversion): Lose special handling of
+ truthvalues.
+
+ * search.c (dfs_pushdecls): Improve shadowing warning.
+
+Tue May 17 13:34:46 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * init.c (build_delete): Throw away const and volatile on `this'.
+
+ * decl.c (finish_enum): Put the constants in TYPE_VALUES again,
+ rather than the enumerators.
+ (pushtag): s/cdecl/c_decl/g
+
+Mon May 16 23:04:01 1994 Stephen R. van den Berg (berg@pool.informatik.rwth-aachen.de)
+
+ * cp/typeck.c (common_type): Attribute merging.
+ (comp_types): Utilise COMP_TYPE_ATTRIBUTES macro.
+
+ * cp/parse.y: Revamp attribute parsing.
+
+Mon May 16 01:40:34 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl.c (shadow_tag): Also check for inappropriate use of auto and
+ register.
+
+ * method.c (build_overload_name): Clarify that the illegal case is a
+ pointer or reference to array of unknown bound.
+
+ * error.c (dump_type_prefix): Print references to arrays properly.
+
+ * typeck.c (various): Be more helpful in pointer
+ comparison diagnostics.
+
+ * tree.c (lvalue_p): MODIFY_EXPRs are lvalues again. Isn't this
+ fun?
+
+ * parse.y: Also catch an error after valid stmts.
+
+ * search.c (dfs_init_vbase_pointers): Don't abort because `this' is
+ const.
+
+ * typeck.c (convert_for_initialization): If call to
+ convert_to_reference generated a diagnostic, print out the parm
+ number and function decl if any.
+
+ * errfn.c (cp_thing): Check atarg1 to determine whether or not we're
+ specifying a line, not atarg.
+
+ * tree.c (build_cplus_method_type): Always make `this' const.
+
+ * decl2.c (grokclassfn): If -fthis-is-variable and this function is
+ a constructor or destructor, make `this' non-const.
+
+ * typeck.c (build_modify_expr): Don't warn specially about
+ assignment to `this' here anymore, since it will be caught by the
+ usual machinery.
+
+ * various: Disallow specific GNU extensions (variable-size arrays,
+ etc.) when flag_ansi is set, not necessarily when pedantic is set,
+ so that people can compile with -pedantic-errors for tighter const
+ checking and such without losing desirable extensions.
+
+ * typeck2.c (build_functional_cast): Call build_method_call with
+ LOOKUP_PROTECT.
+ (process_init_constructor): Only process FIELD_DECLs.
+
+ * decl.c (finish_decl): Also force static consts with no explicit
+ initializer that need constructing into the data segment.
+
+ * init.c (build_delete): Undo last patch, as it interferes with
+ automatic cleanups.
+
+Sat May 14 01:59:31 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * call.c, class.h, cp-tree.h, cvt.c, decl2.c: Lose old overloading
+ code.
+
+ * init.c (build_delete): pedwarn about using plain delete to delete
+ an array.
+
+Fri May 13 16:45:07 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * typeck.c (comp_target_types): Be more helpful in contravariance
+ warnings, and make them pedwarns.
+
+ * decl.c (grokdeclarator): Use decl_context to decide whether or not
+ this is an access declaration.
+
+ * class.c (finish_struct_bits): Set TYPE_HAS_INT_CONVERSION if it
+ has a conversion to enum or bool, too.
+
+Fri May 13 16:31:27 1994 Mike Stump (mrs@cygnus.com)
+
+ * method.c (emit_thunk): Make declaration for
+ current_call_is_indirect local (needed for hppa).
+
+Fri May 13 16:16:37 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * pt.c (uses_template_parms): Grok BOOLEAN_TYPE.
+ (tsubst): Ditto.
+
+Fri May 13 16:23:32 1994 Mike Stump (mrs@cygnus.com)
+
+ * pt.c (tsubst): If there is already a function for this expansion,
+ use it.
+ * pt.c (instantiate_template): Ditto.
+
+Fri May 13 10:30:42 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * parse.y (implicitly_scoped_stmt, simple_stmt case): Use
+ kept_level_p for MARK_ENDS argument to expand_end_bindings, to avoid
+ generating debug info for unemitted symbols on some systems.
+
+ * cp-tree.h (build_static_cast, build_reinterpret_cast,
+ build_const_cast): Add declarations.
+
+Fri May 13 09:50:31 1994 Mike Stump (mrs@cygnus.com)
+
+ * search.c (expand_indirect_vtbls_init): Fix breakage from Apr 27
+ fix. We now try get_binfo, and if that doesn't find what we want,
+ we go back to the old method, which still sometimes fails.
+
+Fri May 13 01:43:18 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * parse.y (initdcl): Call cplus_decl_attributes on the right
+ variable.
+ * decl2.c (cplus_decl_attributes): Don't call decl_attributes for
+ void_type_node.
+
+ * typeck.c (build_binary_op_nodefault): Change result_type for
+ comparison ops to bool.
+ (build_binary_op): Convert args of && and || to bool.
+ * cvt.c (build_default_binary_type_conversion): Convert args of &&
+ and || to bool.
+ (build_default_unary_type_conversion): Convert arg of ! to bool.
+ (type_promotes_to): bool promotes to int.
+
+Fri May 13 01:43:18 1994 Mike Stump (mrs@cygnus.com)
+
+ Implement the new builtin `bool' type.
+ * typeck.c (build_binary_op_nodefault): Convert args of && and || to
+ bool.
+ (build_unary_op): Convert arg of ! to bool.
+ * parse.y: Know true and false. Use bool_truthvalue_conversion.
+ * method.c (build_overload_value): Know bool.
+ (build_overload_name): Ditto.
+ * lex.c (init_lex): Set up RID_BOOL.
+ * gxx.gperf: Add bool, true, false.
+ * error.c (*): Know bool.
+ * decl.c (init_decl_processing): Set up bool, true, false.
+ * cvt.c (cp_convert): Handle conversion to bool.
+ (build_type_conversion): Ditto.
+ * *.c: Accept bool where integers and enums are accepted (use
+ INTEGRAL_CODE_P macro).
+
Thu May 12 19:13:54 1994 Richard Earnshaw (rwe11@cl.cam.ac.uk)
* g++.c: Use #ifdef for __MSDOS__, not #if.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 6700f87e87e..e957776711d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -44,38 +44,17 @@ extern tree unary_complex_lvalue ();
/* Compute the ease with which a conversion can be performed
between an expected and the given type. */
-static int convert_harshness_old ();
-static struct harshness_code convert_harshness_ansi ();
-
-/* OLD METHOD */
-/* Note the old method also uses USER_HARSHNESS, BASE_DERIVED_HARSHNESS,
- CONST_HARSHNESS. */
-#define EVIL 1
-#define TRIVIAL 0
-#define EVIL_HARSHNESS(ARG) ((ARG) & 1)
-#define ELLIPSIS_HARSHNESS(ARG) ((ARG) & 2)
-#define CONTRAVARIANT_HARSHNESS(ARG) ((ARG) & 8)
-#define INT_TO_BD_HARSHNESS(ARG) (((ARG) << 5) | 16)
-#define INT_FROM_BD_HARSHNESS(ARG) ((ARG) >> 5)
-#define INT_TO_EASY_HARSHNESS(ARG) ((ARG) << 5)
-#define INT_FROM_EASY_HARSHNESS(ARG) ((ARG) >> 5)
-#define ONLY_EASY_HARSHNESS(ARG) (((ARG) & 31) == 0)
-
-
-/* NEW METHOD */
+static struct harshness_code convert_harshness ();
+
#define EVIL_RETURN(ARG) ((ARG).code = EVIL_CODE, (ARG))
#define QUAL_RETURN(ARG) ((ARG).code = QUAL_CODE, (ARG))
#define TRIVIAL_RETURN(ARG) ((ARG).code = TRIVIAL_CODE, (ARG))
#define ZERO_RETURN(ARG) ((ARG).code = 0, (ARG))
-#define USER_HARSHNESS(ARG) ((ARG) & 4)
-#define BASE_DERIVED_HARSHNESS(ARG) ((ARG) & 16)
-#define CONST_HARSHNESS(ARG) ((ARG) & 2048)
-
/* Ordering function for overload resolution. Compare two candidates
by gross quality. */
int
-rank_for_overload_ansi (x, y)
+rank_for_overload (x, y)
struct candidate *x, *y;
{
if (y->h.code & (EVIL_CODE|ELLIPSIS_CODE|USER_CODE))
@@ -85,8 +64,8 @@ rank_for_overload_ansi (x, y)
/* This is set by compute_conversion_costs, for calling a non-const
member function from a const member function. */
- if ((y->v.ansi_harshness[0].code & CONST_CODE) ^ (x->v.ansi_harshness[0].code & CONST_CODE))
- return y->v.ansi_harshness[0].code - x->v.ansi_harshness[0].code;
+ if ((y->harshness[0].code & CONST_CODE) ^ (x->harshness[0].code & CONST_CODE))
+ return y->harshness[0].code - x->harshness[0].code;
if (y->h.code & STD_CODE)
{
@@ -100,33 +79,6 @@ rank_for_overload_ansi (x, y)
return y->h.code - x->h.code;
}
-int
-rank_for_overload_old (x, y)
- struct candidate *x, *y;
-{
- if (y->evil - x->evil)
- return y->evil - x->evil;
- if (CONST_HARSHNESS (y->v.old_harshness[0]) ^ CONST_HARSHNESS (x->v.old_harshness[0]))
- return y->v.old_harshness[0] - x->v.old_harshness[0];
- if (y->ellipsis - x->ellipsis)
- return y->ellipsis - x->ellipsis;
- if (y->user - x->user)
- return y->user - x->user;
- if (y->b_or_d - x->b_or_d)
- return y->b_or_d - x->b_or_d;
- return y->easy - x->easy;
-}
-
-int
-rank_for_overload (x, y)
- struct candidate *x, *y;
-{
- if (flag_ansi_overloading)
- return rank_for_overload_ansi (x, y);
- else
- return rank_for_overload_old (x, y);
-}
-
/* Compare two candidates, argument by argument. */
int
rank_for_ideal (x, y)
@@ -139,17 +91,17 @@ rank_for_ideal (x, y)
for (i = 0; i < x->h_len; i++)
{
- if (y->v.ansi_harshness[i].code - x->v.ansi_harshness[i].code)
- return y->v.ansi_harshness[i].code - x->v.ansi_harshness[i].code;
- if ((y->v.ansi_harshness[i].code & STD_CODE)
- && (y->v.ansi_harshness[i].distance - x->v.ansi_harshness[i].distance))
- return y->v.ansi_harshness[i].distance - x->v.ansi_harshness[i].distance;
+ if (y->harshness[i].code - x->harshness[i].code)
+ return y->harshness[i].code - x->harshness[i].code;
+ if ((y->harshness[i].code & STD_CODE)
+ && (y->harshness[i].distance - x->harshness[i].distance))
+ return y->harshness[i].distance - x->harshness[i].distance;
/* They're both the same code. Now see if we're dealing with an
integral promotion that needs a finer grain of accuracy. */
- if (y->v.ansi_harshness[0].code & PROMO_CODE
- && (y->v.ansi_harshness[i].int_penalty ^ x->v.ansi_harshness[i].int_penalty))
- return y->v.ansi_harshness[i].int_penalty - x->v.ansi_harshness[i].int_penalty;
+ if (y->harshness[0].code & PROMO_CODE
+ && (y->harshness[i].int_penalty ^ x->harshness[i].int_penalty))
+ return y->harshness[i].int_penalty - x->harshness[i].int_penalty;
}
return 0;
}
@@ -158,7 +110,7 @@ rank_for_ideal (x, y)
we have to work with. We use a somewhat arbitrary cost function
to measure this conversion. */
static struct harshness_code
-convert_harshness_ansi (type, parmtype, parm)
+convert_harshness (type, parmtype, parm)
register tree type, parmtype;
tree parm;
{
@@ -213,7 +165,7 @@ convert_harshness_ansi (type, parmtype, parm)
/* Compare return types. */
p1 = TREE_TYPE (type);
p2 = TREE_TYPE (parmtype);
- h2 = convert_harshness_ansi (p1, p2, NULL_TREE);
+ h2 = convert_harshness (p1, p2, NULL_TREE);
if (h2.code & EVIL_CODE)
return h2;
@@ -262,7 +214,7 @@ convert_harshness_ansi (type, parmtype, parm)
while (p1 && TREE_VALUE (p1) != void_type_node
&& p2 && TREE_VALUE (p2) != void_type_node)
{
- h2 = convert_harshness_ansi (TREE_VALUE (p1), TREE_VALUE (p2),
+ h2 = convert_harshness (TREE_VALUE (p1), TREE_VALUE (p2),
NULL_TREE);
if (h2.code & EVIL_CODE)
return h2;
@@ -341,7 +293,7 @@ convert_harshness_ansi (type, parmtype, parm)
if (coder == VOID_TYPE)
return EVIL_RETURN (h);
- if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE)
+ if (INTEGRAL_CODE_P (codel))
{
/* Control equivalence of ints an enums. */
@@ -356,7 +308,7 @@ convert_harshness_ansi (type, parmtype, parm)
/* else enums and ints (almost) freely interconvert. */
- if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
+ if (INTEGRAL_CODE_P (coder))
{
if (TYPE_MAIN_VARIANT (type)
== TYPE_MAIN_VARIANT (type_promotes_to (parmtype)))
@@ -395,7 +347,7 @@ convert_harshness_ansi (type, parmtype, parm)
return h;
}
- else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
+ else if (INTEGRAL_CODE_P (coder))
{
h.code = STD_CODE;
h.distance = 0;
@@ -625,12 +577,11 @@ convert_harshness_ansi (type, parmtype, parm)
matter if we make life easier for the programmer
by creating a temporary variable with which to
hold the result. */
- if (parm && (coder == INTEGER_TYPE
- || coder == ENUMERAL_TYPE
+ if (parm && (INTEGRAL_CODE_P (coder)
|| coder == REAL_TYPE)
&& ! lvalue_p (parm))
{
- h = convert_harshness_ansi (ttl, ttr, NULL_TREE);
+ h = convert_harshness (ttl, ttr, NULL_TREE);
if (penalty > 2 || h.code != 0)
h.code |= STD_CODE;
else
@@ -672,7 +623,7 @@ convert_harshness_ansi (type, parmtype, parm)
if (parm && codel != REFERENCE_TYPE)
{
- h = convert_harshness_ansi (ttl, ttr, NULL_TREE);
+ h = convert_harshness (ttl, ttr, NULL_TREE);
if (penalty == 2)
h.code |= QUAL_CODE;
else if (penalty == 4)
@@ -731,468 +682,6 @@ convert_harshness_ansi (type, parmtype, parm)
return EVIL_RETURN (h);
}
-/* TYPE is the type we wish to convert to. PARM is the parameter
- we have to work with. We use a somewhat arbitrary cost function
- to measure this conversion. */
-static int
-convert_harshness_old (type, parmtype, parm)
- register tree type, parmtype;
- tree parm;
-{
- register enum tree_code codel;
- register enum tree_code coder;
-
-#ifdef GATHER_STATISTICS
- n_convert_harshness++;
-#endif
-
- if (TYPE_PTRMEMFUNC_P (type))
- type = TYPE_PTRMEMFUNC_FN_TYPE (type);
- if (TYPE_PTRMEMFUNC_P (parmtype))
- parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
-
- codel = TREE_CODE (type);
- coder = TREE_CODE (parmtype);
-
- if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type))
- return TRIVIAL;
-
- if (coder == ERROR_MARK)
- return EVIL;
-
- if (codel == POINTER_TYPE && fntype_p (parmtype))
- {
- tree p1, p2;
- int harshness, new_harshness;
-
- /* Get to the METHOD_TYPE or FUNCTION_TYPE that this might be. */
- type = TREE_TYPE (type);
-
- if (coder == POINTER_TYPE)
- {
- parmtype = TREE_TYPE (parmtype);
- coder = TREE_CODE (parmtype);
- }
-
- if (coder != TREE_CODE (type))
- return EVIL;
-
- harshness = 0;
-
- /* We allow the default conversion between function type
- and pointer-to-function type for free. */
- if (type == parmtype)
- return TRIVIAL;
-
- /* Compare return types. */
- p1 = TREE_TYPE (type);
- p2 = TREE_TYPE (parmtype);
- new_harshness = convert_harshness_old (p1, p2, NULL_TREE);
- if (EVIL_HARSHNESS (new_harshness))
- return EVIL;
-
- if (BASE_DERIVED_HARSHNESS (new_harshness))
- {
- tree binfo;
-
- /* This only works for pointers. */
- if (TREE_CODE (p1) != POINTER_TYPE
- && TREE_CODE (p1) != REFERENCE_TYPE)
- return EVIL;
-
- p1 = TREE_TYPE (p1);
- p2 = TREE_TYPE (p2);
- /* Don't die if we happen to be dealing with void*. */
- if (!IS_AGGR_TYPE (p1) || !IS_AGGR_TYPE (p2))
- return EVIL;
- if (CONTRAVARIANT_HARSHNESS (new_harshness))
- binfo = get_binfo (p2, p1, 0);
- else
- binfo = get_binfo (p1, p2, 0);
-
- if (! BINFO_OFFSET_ZEROP (binfo))
- {
- static int explained = 0;
- if (CONTRAVARIANT_HARSHNESS (new_harshness))
- message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p2, p1);
- else
- message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p1, p2);
-
- if (! explained++)
- sorry ("(because pointer values change during conversion)");
- return EVIL;
- }
- }
-
- harshness |= new_harshness;
-
- p1 = TYPE_ARG_TYPES (type);
- p2 = TYPE_ARG_TYPES (parmtype);
- while (p1 && TREE_VALUE (p1) != void_type_node
- && p2 && TREE_VALUE (p2) != void_type_node)
- {
- new_harshness = convert_harshness_old (TREE_VALUE (p1),
- TREE_VALUE (p2), NULL_TREE);
- if (EVIL_HARSHNESS (new_harshness))
- return EVIL;
-
- if (BASE_DERIVED_HARSHNESS (new_harshness))
- {
- /* This only works for pointers and references. */
- if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE
- && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE)
- return EVIL;
- new_harshness ^= CONTRAVARIANT_HARSHNESS (new_harshness);
- harshness |= new_harshness;
- }
- /* This trick allows use to accumulate easy type
- conversions without messing up the bits that encode
- info about more involved things. */
- else if (ONLY_EASY_HARSHNESS (new_harshness))
- harshness += new_harshness;
- else
- harshness |= new_harshness;
- p1 = TREE_CHAIN (p1);
- p2 = TREE_CHAIN (p2);
- }
- if (p1 == p2)
- return harshness;
- if (p2)
- return p1 ? EVIL : (harshness | ELLIPSIS_HARSHNESS (-1));
- if (p1)
- return harshness | (TREE_PURPOSE (p1) == NULL_TREE);
- }
- else if (codel == POINTER_TYPE && coder == OFFSET_TYPE)
- {
- /* XXX: Note this is set a few times, but it's never actually
- used! (bpk) */
- int harshness;
-
- /* Get to the OFFSET_TYPE that this might be. */
- type = TREE_TYPE (type);
-
- if (coder != TREE_CODE (type))
- return EVIL;
-
- harshness = 0;
-
- if (TYPE_OFFSET_BASETYPE (type) == TYPE_OFFSET_BASETYPE (parmtype))
- harshness = 0;
- else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (type),
- TYPE_OFFSET_BASETYPE (parmtype)))
- harshness = INT_TO_BD_HARSHNESS (1);
- else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (parmtype),
- TYPE_OFFSET_BASETYPE (type)))
- harshness = CONTRAVARIANT_HARSHNESS (-1);
- else
- return EVIL;
- /* Now test the OFFSET_TYPE's target compatibility. */
- type = TREE_TYPE (type);
- parmtype = TREE_TYPE (parmtype);
- }
-
- if (coder == UNKNOWN_TYPE)
- {
- if (codel == FUNCTION_TYPE
- || codel == METHOD_TYPE
- || (codel == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)))
- return TRIVIAL;
- return EVIL;
- }
-
- if (coder == VOID_TYPE)
- return EVIL;
-
- if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE)
- {
- /* Control equivalence of ints an enums. */
-
- if (codel == ENUMERAL_TYPE
- && flag_int_enum_equivalence == 0)
- {
- /* Enums can be converted to ints, but not vice-versa. */
- if (coder != ENUMERAL_TYPE
- || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype))
- return EVIL;
- }
-
- /* else enums and ints (almost) freely interconvert. */
-
- if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
- {
- int easy = TREE_UNSIGNED (type) ^ TREE_UNSIGNED (parmtype);
- if (codel != coder)
- easy += 1;
- if (TYPE_MODE (type) != TYPE_MODE (parmtype))
- easy += 2;
- return INT_TO_EASY_HARSHNESS (easy);
- }
- else if (coder == REAL_TYPE)
- return INT_TO_EASY_HARSHNESS (4);
- }
-
- if (codel == REAL_TYPE)
- if (coder == REAL_TYPE)
- /* Shun converting between float and double if a choice exists. */
- {
- if (TYPE_MODE (type) != TYPE_MODE (parmtype))
- return INT_TO_EASY_HARSHNESS (2);
- return TRIVIAL;
- }
- else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
- return INT_TO_EASY_HARSHNESS (4);
-
- /* convert arrays which have not previously been converted. */
- if (codel == ARRAY_TYPE)
- codel = POINTER_TYPE;
- if (coder == ARRAY_TYPE)
- coder = POINTER_TYPE;
-
- /* Conversions among pointers */
- if (codel == POINTER_TYPE && coder == POINTER_TYPE)
- {
- register tree ttl = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- register tree ttr = TYPE_MAIN_VARIANT (TREE_TYPE (parmtype));
- int penalty = 4 * (ttl != ttr);
- /* Anything converts to void *. void * converts to anything.
- Since these may be `const void *' (etc.) use VOID_TYPE
- instead of void_type_node.
- Otherwise, the targets must be the same,
- except that we do allow (at some cost) conversion
- between signed and unsinged pointer types. */
-
- if ((TREE_CODE (ttl) == METHOD_TYPE
- || TREE_CODE (ttl) == FUNCTION_TYPE)
- && TREE_CODE (ttl) == TREE_CODE (ttr))
- {
- if (comptypes (ttl, ttr, -1))
- return INT_TO_EASY_HARSHNESS (penalty);
- return EVIL;
- }
-
- if (!(TREE_CODE (ttl) == VOID_TYPE
- || TREE_CODE (ttr) == VOID_TYPE
- || (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (ttr)
- && (ttl = unsigned_type (ttl),
- ttr = unsigned_type (ttr),
- penalty = 10, 0))
- || (comp_target_types (ttl, ttr, 0))))
- return EVIL;
-
- if (penalty == 10)
- return INT_TO_EASY_HARSHNESS (10);
- if (ttr == ttl)
- return INT_TO_BD_HARSHNESS (0);
-
- if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
- {
- int b_or_d = get_base_distance (ttl, ttr, 0, 0);
- if (b_or_d < 0)
- {
- b_or_d = get_base_distance (ttr, ttl, 0, 0);
- if (b_or_d < 0)
- return EVIL;
- return CONTRAVARIANT_HARSHNESS (-1);
- }
- return INT_TO_BD_HARSHNESS (b_or_d);
- }
- /* If converting from a `class*' to a `void*', make it
- less favorable than any inheritance relationship. */
- if (TREE_CODE (ttl) == VOID_TYPE && IS_AGGR_TYPE (ttr))
- return INT_TO_BD_HARSHNESS (CLASSTYPE_MAX_DEPTH (ttr)+1);
- return INT_TO_EASY_HARSHNESS (penalty);
- }
-
- if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
- {
- /* This is not a bad match, but don't let it beat
- integer-enum combinations. */
- if (parm && integer_zerop (parm))
- return INT_TO_EASY_HARSHNESS (4);
- }
-
- /* C++: Since the `this' parameter of a signature member function
- is represented as a signature pointer to handle default implementations
- correctly, we can have the case that `type' is a signature pointer
- while `parmtype' is a pointer to a signature table. We don't really
- do any conversions in this case, so just return 0. */
-
- if (codel == RECORD_TYPE && coder == POINTER_TYPE
- && IS_SIGNATURE_POINTER (type) && IS_SIGNATURE (TREE_TYPE (parmtype)))
- return 0;
-
- /* C++: one of the types must be a reference type. */
- {
- tree ttl, ttr;
- register tree intype = TYPE_MAIN_VARIANT (parmtype);
- register enum tree_code form = TREE_CODE (intype);
- int penalty;
-
- if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE)
- {
- ttl = TYPE_MAIN_VARIANT (type);
-
- if (codel == REFERENCE_TYPE)
- {
- ttl = TREE_TYPE (ttl);
-
- /* When passing a non-const argument into a const reference,
- dig it a little, so a non-const reference is preferred over
- this one. (mrs) */
- if (parm && TREE_READONLY (ttl) && ! TREE_READONLY (parm))
- penalty = 2;
- else
- penalty = 0;
-
- ttl = TYPE_MAIN_VARIANT (ttl);
-
- if (form == OFFSET_TYPE)
- {
- intype = TREE_TYPE (intype);
- form = TREE_CODE (intype);
- }
-
- if (form == REFERENCE_TYPE)
- {
- intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype));
-
- if (ttl == intype)
- return TRIVIAL;
- penalty = 2;
- }
- else
- {
- /* Can reference be built up? */
- if (ttl == intype && penalty == 0) {
- /* Because the READONLY bits and VIRTUAL bits are not always
- in the type, this extra check is necessary. The problem
- should be fixed someplace else, and this extra code
- removed.
-
- Also, if type if a reference, the readonly bits could
- either be in the outer type (with reference) or on the
- inner type (the thing being referenced). (mrs) */
- if (parm
- && ((TREE_READONLY (parm)
- && ! (TYPE_READONLY (type)
- || (TREE_CODE (type) == REFERENCE_TYPE
- && TYPE_READONLY (TREE_TYPE (type)))))
- || (TREE_SIDE_EFFECTS (parm)
- && ! (TYPE_VOLATILE (type)
- || (TREE_CODE (type) == REFERENCE_TYPE
- && TYPE_VOLATILE (TREE_TYPE (type)))))))
- penalty = 2;
- else
- return TRIVIAL;
- }
- else
- penalty = 2;
- }
- }
- else if (form == REFERENCE_TYPE)
- {
- if (parm)
- {
- tree tmp = convert_from_reference (parm);
- intype = TYPE_MAIN_VARIANT (TREE_TYPE (tmp));
- }
- else
- {
- intype = parmtype;
- do
- {
- intype = TREE_TYPE (intype);
- }
- while (TREE_CODE (intype) == REFERENCE_TYPE);
- intype = TYPE_MAIN_VARIANT (intype);
- }
-
- if (ttl == intype)
- return TRIVIAL;
- else
- penalty = 2;
- }
-
- if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
- {
- ttl = unsigned_type (ttl);
- intype = unsigned_type (intype);
- penalty += 2;
- }
-
- ttr = intype;
-
- /* If the initializer is not an lvalue, then it does not
- matter if we make life easier for the programmer
- by creating a temporary variable with which to
- hold the result. */
- if (parm && (coder == INTEGER_TYPE
- || coder == ENUMERAL_TYPE
- || coder == REAL_TYPE)
- && ! lvalue_p (parm))
- return (convert_harshness_old (ttl, ttr, NULL_TREE)
- | INT_TO_EASY_HARSHNESS (penalty));
-
- if (ttl == ttr)
- {
- if (penalty)
- return INT_TO_EASY_HARSHNESS (penalty);
- return INT_TO_BD_HARSHNESS (0);
- }
-
- /* Pointers to voids always convert for pointers. But
- make them less natural than more specific matches. */
- if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE)
- if (TREE_TYPE (ttl) == void_type_node
- || TREE_TYPE (ttr) == void_type_node)
- return INT_TO_EASY_HARSHNESS (penalty+1);
-
- if (parm && codel != REFERENCE_TYPE)
- return (convert_harshness_old (ttl, ttr, NULL_TREE)
- | INT_TO_EASY_HARSHNESS (penalty));
-
- /* Here it does matter. If this conversion is from
- derived to base, allow it. Otherwise, types must
- be compatible in the strong sense. */
- if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
- {
- int b_or_d = get_base_distance (ttl, ttr, 0, 0);
- if (b_or_d < 0)
- {
- b_or_d = get_base_distance (ttr, ttl, 0, 0);
- if (b_or_d < 0)
- return EVIL;
- return CONTRAVARIANT_HARSHNESS (-1);
- }
- /* Say that this conversion is relatively painless.
- If it turns out that there is a user-defined X(X&)
- constructor, then that will be invoked, but that's
- preferable to dealing with other user-defined conversions
- that may produce surprising results. */
- return INT_TO_BD_HARSHNESS (b_or_d);
- }
-
- if (comp_target_types (ttl, intype, 1))
- return INT_TO_EASY_HARSHNESS (penalty);
- }
- }
- if (codel == RECORD_TYPE && coder == RECORD_TYPE)
- {
- int b_or_d = get_base_distance (type, parmtype, 0, 0);
- if (b_or_d < 0)
- {
- b_or_d = get_base_distance (parmtype, type, 0, 0);
- if (b_or_d < 0)
- return EVIL;
- return CONTRAVARIANT_HARSHNESS (-1);
- }
- return INT_TO_BD_HARSHNESS (b_or_d);
- }
- return EVIL;
-}
-
#ifdef DEBUG_MATCHING
static char *
print_harshness (h)
@@ -1243,7 +732,7 @@ print_harshness (h)
must be unique. */
void
-compute_conversion_costs_ansi (function, tta_in, cp, arglen)
+compute_conversion_costs (function, tta_in, cp, arglen)
tree function;
tree tta_in;
struct candidate *cp;
@@ -1274,7 +763,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
cp->h.code = 0;
cp->h.distance = 0;
cp->h.int_penalty = 0;
- bzero (cp->v.ansi_harshness,
+ bzero (cp->harshness,
(cp->h_len + 1) * sizeof (struct harshness_code));
while (ttf && tta)
@@ -1305,7 +794,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
if (TREE_CODE (rhs) == ERROR_MARK)
h.code = EVIL_CODE;
else
- h = convert_harshness_ansi (lhstype, TREE_TYPE (rhs), rhs);
+ h = convert_harshness (lhstype, TREE_TYPE (rhs), rhs);
}
else
{
@@ -1323,7 +812,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
TREE_VALUE (ttf));
#endif
- h = convert_harshness_ansi (TREE_VALUE (ttf),
+ h = convert_harshness (TREE_VALUE (ttf),
TREE_TYPE (TREE_VALUE (tta)),
TREE_VALUE (tta));
@@ -1332,7 +821,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
#endif
}
- cp->v.ansi_harshness[strike_index] = h;
+ cp->harshness[strike_index] = h;
if ((h.code & EVIL_CODE)
|| ((h.code & STD_CODE) && h.distance < 0))
{
@@ -1342,7 +831,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
else if (h.code & ELLIPSIS_CODE)
ellipsis_strikes += 1;
#if 0
- /* This is never set by `convert_harshness_ansi'. */
+ /* This is never set by `convert_harshness'. */
else if (h.code & USER_CODE)
{
user_strikes += 1;
@@ -1385,7 +874,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
h.distance = 0;
h.int_penalty = 0;
for (; l; --l)
- cp->v.ansi_harshness[strike_index++] = h;
+ cp->harshness[strike_index++] = h;
}
}
else if (ttf && ttf != void_list_node)
@@ -1398,10 +887,10 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
return;
}
/* Store index of first default. */
- cp->v.ansi_harshness[arglen].distance = strike_index+1;
+ cp->harshness[arglen].distance = strike_index+1;
}
else
- cp->v.ansi_harshness[arglen].distance = 0;
+ cp->harshness[arglen].distance = 0;
/* Argument list lengths work out, so don't need to check them again. */
if (evil_strikes)
@@ -1431,7 +920,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
if (ttf == void_list_node)
break;
- lose = cp->v.ansi_harshness[strike_index];
+ lose = cp->harshness[strike_index];
if ((lose.code & EVIL_CODE)
|| ((lose.code & STD_CODE) && lose.distance < 0))
{
@@ -1510,7 +999,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
if (win == 1)
{
user_strikes += 1;
- cp->v.ansi_harshness[strike_index].code
+ cp->harshness[strike_index].code
= USER_CODE | (extra_conversions ? STD_CODE : 0);
win = 0;
}
@@ -1543,7 +1032,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
? TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (this_parm))))
: TYPE_READONLY (TREE_TYPE (this_parm)))
{
- cp->v.ansi_harshness[0].code |= TRIVIAL_CODE;
+ cp->harshness[0].code |= TRIVIAL_CODE;
++easy_strikes;
}
else
@@ -1554,7 +1043,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
harshness to a maximum value. */
if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE
&& (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in))))))
- cp->v.ansi_harshness[0].code |= CONST_CODE;
+ cp->harshness[0].code |= CONST_CODE;
}
}
@@ -1569,636 +1058,6 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
#endif
}
-void
-compute_conversion_costs_old (function, tta_in, cp, arglen)
- tree function;
- tree tta_in;
- struct candidate *cp;
- int arglen;
-{
- tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function));
- tree ttf = ttf_in;
- tree tta = tta_in;
-
- /* Start out with no strikes against. */
- int evil_strikes = 0;
- int ellipsis_strikes = 0;
- int user_strikes = 0;
- int b_or_d_strikes = 0;
- int easy_strikes = 0;
-
- int strike_index = 0, win, lose;
-
-#ifdef GATHER_STATISTICS
- n_compute_conversion_costs++;
-#endif
-
- cp->function = function;
- cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE;
- cp->u.bad_arg = 0; /* optimistic! */
-
- bzero (cp->v.old_harshness, (cp->h_len + 1) * sizeof (unsigned short));
-
- while (ttf && tta)
- {
- int harshness;
-
- if (ttf == void_list_node)
- break;
-
- if (type_unknown_p (TREE_VALUE (tta)))
- {
- /* Must perform some instantiation here. */
- tree rhs = TREE_VALUE (tta);
- tree lhstype = TREE_VALUE (ttf);
-
- /* Keep quiet about possible contravariance violations. */
- int old_inhibit_warnings = inhibit_warnings;
- inhibit_warnings = 1;
-
- /* @@ This is to undo what `grokdeclarator' does to
- parameter types. It really should go through
- something more general. */
-
- TREE_TYPE (tta) = unknown_type_node;
- rhs = instantiate_type (lhstype, rhs, 0);
- inhibit_warnings = old_inhibit_warnings;
-
- if (TREE_CODE (rhs) == ERROR_MARK)
- harshness = 1;
- else
- {
- harshness = convert_harshness_old (lhstype, TREE_TYPE (rhs),
- rhs);
- /* harshness |= 2; */
- }
- }
- else
- harshness = convert_harshness_old (TREE_VALUE (ttf),
- TREE_TYPE (TREE_VALUE (tta)),
- TREE_VALUE (tta));
-
- cp->v.old_harshness[strike_index] = harshness;
- if (EVIL_HARSHNESS (harshness)
- || CONTRAVARIANT_HARSHNESS (harshness))
- {
- cp->u.bad_arg = strike_index;
- evil_strikes = 1;
- }
- else if (ELLIPSIS_HARSHNESS (harshness))
- {
- ellipsis_strikes += 1;
- }
-#if 0
- /* This is never set by `convert_harshness_old'. */
- else if (USER_HARSHNESS (harshness))
- {
- user_strikes += 1;
- }
-#endif
- else if (BASE_DERIVED_HARSHNESS (harshness))
- {
- b_or_d_strikes += INT_FROM_BD_HARSHNESS (harshness);
- }
- else
- easy_strikes += INT_FROM_EASY_HARSHNESS (harshness);
- ttf = TREE_CHAIN (ttf);
- tta = TREE_CHAIN (tta);
- strike_index += 1;
- }
-
- if (tta)
- {
- /* ran out of formals, and parmlist is fixed size. */
- if (ttf /* == void_type_node */)
- {
- cp->evil = 1;
- cp->u.bad_arg = -1;
- return;
- }
- else ellipsis_strikes += list_length (tta);
- }
- else if (ttf && ttf != void_list_node)
- {
- /* ran out of actuals, and no defaults. */
- if (TREE_PURPOSE (ttf) == NULL_TREE)
- {
- cp->evil = 1;
- cp->u.bad_arg = -2;
- return;
- }
- /* Store index of first default. */
- cp->v.old_harshness[arglen] = strike_index+1;
- }
- else
- cp->v.old_harshness[arglen] = 0;
-
- /* Argument list lengths work out, so don't need to check them again. */
- if (evil_strikes)
- {
- /* We do not check for derived->base conversions here, since in
- no case would they give evil strike counts, unless such conversions
- are somehow ambiguous. */
-
- /* See if any user-defined conversions apply.
- But make sure that we do not loop. */
- static int dont_convert_types = 0;
-
- if (dont_convert_types)
- {
- cp->evil = 1;
- return;
- }
-
- win = 0; /* Only get one chance to win. */
- ttf = TYPE_ARG_TYPES (TREE_TYPE (function));
- tta = tta_in;
- strike_index = 0;
- evil_strikes = 0;
-
- while (ttf && tta)
- {
- if (ttf == void_list_node)
- break;
-
- lose = cp->v.old_harshness[strike_index];
- if (EVIL_HARSHNESS (lose)
- || CONTRAVARIANT_HARSHNESS (lose))
- {
- tree actual_type = TREE_TYPE (TREE_VALUE (tta));
- tree formal_type = TREE_VALUE (ttf);
-
- dont_convert_types = 1;
-
- if (TREE_CODE (formal_type) == REFERENCE_TYPE)
- formal_type = TREE_TYPE (formal_type);
- if (TREE_CODE (actual_type) == REFERENCE_TYPE)
- actual_type = TREE_TYPE (actual_type);
-
- if (formal_type != error_mark_node
- && actual_type != error_mark_node)
- {
- formal_type = TYPE_MAIN_VARIANT (formal_type);
- actual_type = TYPE_MAIN_VARIANT (actual_type);
-
- if (TYPE_HAS_CONSTRUCTOR (formal_type))
- {
- /* If it has a constructor for this type, try to use it. */
- if (convert_to_aggr (formal_type, TREE_VALUE (tta), 0, 1)
- != error_mark_node)
- {
- /* @@ There is no way to save this result yet.
- @@ So success is NULL_TREE for now. */
- win++;
- }
- }
- if (TYPE_LANG_SPECIFIC (actual_type) && TYPE_HAS_CONVERSION (actual_type))
- {
- if (TREE_CODE (formal_type) == INTEGER_TYPE
- && TYPE_HAS_INT_CONVERSION (actual_type))
- win++;
- else if (TREE_CODE (formal_type) == REAL_TYPE
- && TYPE_HAS_REAL_CONVERSION (actual_type))
- win++;
- else
- {
- tree conv = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0);
- if (conv)
- {
- if (conv == error_mark_node)
- win += 2;
- else
- win++;
- }
- else if (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE)
- {
- conv = build_type_conversion (CALL_EXPR, formal_type, TREE_VALUE (tta), 0);
- if (conv)
- {
- if (conv == error_mark_node)
- win += 2;
- else
- win++;
- }
- }
- }
- }
- }
- dont_convert_types = 0;
-
- if (win == 1)
- {
- user_strikes += 1;
- cp->v.old_harshness[strike_index] = USER_HARSHNESS (-1);
- win = 0;
- }
- else
- {
- if (cp->u.bad_arg > strike_index)
- cp->u.bad_arg = strike_index;
-
- evil_strikes = win ? 2 : 1;
- break;
- }
- }
-
- ttf = TREE_CHAIN (ttf);
- tta = TREE_CHAIN (tta);
- strike_index += 1;
- }
- }
-
- /* Const member functions get a small penalty because defaulting
- to const is less useful than defaulting to non-const. */
- /* This is bogus, it does not correspond to anything in the ARM.
- This code will be fixed when this entire section is rewritten
- to conform to the ARM. (mrs) */
- if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
- {
- tree this_parm = TREE_VALUE (ttf_in);
-
- if (TREE_CODE (this_parm) == RECORD_TYPE /* Is `this' a sig ptr? */
- ? TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (this_parm))))
- : TYPE_READONLY (TREE_TYPE (this_parm)))
- {
- cp->v.old_harshness[0] += INT_TO_EASY_HARSHNESS (1);
- ++easy_strikes;
- }
- else
- {
- /* Calling a non-const member function from a const member function
- is probably invalid, but for now we let it only draw a warning.
- We indicate that such a mismatch has occurred by setting the
- harshness to a maximum value. */
- if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE
- && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in))))))
- cp->v.old_harshness[0] |= CONST_HARSHNESS (-1);
- }
- }
-
- cp->evil = evil_strikes;
- cp->ellipsis = ellipsis_strikes;
- cp->user = user_strikes;
- cp->b_or_d = b_or_d_strikes;
- cp->easy = easy_strikes;
-}
-
-void
-compute_conversion_costs (function, tta_in, cp, arglen)
- tree function;
- tree tta_in;
- struct candidate *cp;
- int arglen;
-{
- if (flag_ansi_overloading)
- compute_conversion_costs_ansi (function, tta_in, cp, arglen);
- else
- compute_conversion_costs_old (function, tta_in, cp, arglen);
-}
-
-/* When one of several possible overloaded functions and/or methods
- can be called, choose the best candidate for overloading.
-
- BASETYPE is the context from which we start method resolution
- or NULL if we are comparing overloaded functions.
- CANDIDATES is the array of candidates we have to choose from.
- N_CANDIDATES is the length of CANDIDATES.
- PARMS is a TREE_LIST of parameters to the function we'll ultimately
- choose. It is modified in place when resolving methods. It is not
- modified in place when resolving overloaded functions.
- LEN is the length of the parameter list. */
-
-static struct candidate *
-ideal_candidate_old (basetype, candidates, n_candidates, parms, len)
- tree basetype;
- struct candidate *candidates;
- int n_candidates;
- tree parms;
- int len;
-{
- struct candidate *cp = candidates + n_candidates;
- int index, i;
- tree ttf;
-
- qsort (candidates, /* char *base */
- n_candidates, /* int nel */
- sizeof (struct candidate), /* int width */
- rank_for_overload); /* int (*compar)() */
-
- /* If the best candidate requires user-defined conversions,
- and its user-defined conversions are a strict subset
- of all other candidates requiring user-defined conversions,
- then it is, in fact, the best. */
- for (i = -1; cp + i != candidates; i--)
- if (cp[i].user == 0)
- break;
-
- if (i < -1)
- {
- tree ttf0;
-
- /* Check that every other candidate requires those conversions
- as a strict subset of their conversions. */
- if (cp[i].user == cp[-1].user)
- goto non_subset;
-
- /* Look at subset relationship more closely. */
- while (i != -1)
- {
- for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)),
- ttf0 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)),
- index = 0; index < len; index++)
- {
- if (USER_HARSHNESS (cp[i].v.old_harshness[index]))
- {
- /* If our "best" candidate also needs a conversion,
- it must be the same one. */
- if (USER_HARSHNESS (cp[-1].v.old_harshness[index])
- && TREE_VALUE (ttf) != TREE_VALUE (ttf0))
- goto non_subset;
- }
- ttf = TREE_CHAIN (ttf);
- ttf0 = TREE_CHAIN (ttf0);
- /* Handle `...' gracefully. */
- if (ttf == NULL_TREE || ttf0 == NULL_TREE)
- break;
- }
- i++;
- }
- /* The best was the best. */
- return cp - 1;
- non_subset:
- /* Use other rules for determining "bestness". */
- ;
- }
-
- /* If the best two candidates we find require user-defined
- conversions, we may need to report and error message. */
- if (cp[-1].user && cp[-2].user
- && (cp[-1].b_or_d || cp[-2].b_or_d == 0))
- {
- /* If the best two methods found involved user-defined
- type conversions, then we must see whether one
- of them is exactly what we wanted. If not, then
- we have an ambiguity. */
- int best = 0;
- tree tta = parms;
- tree f1;
-#if 0
- /* for LUCID */
- tree p1;
-#endif
-
- /* Stash all of our parameters in safe places
- so that we can perform type conversions in place. */
- while (tta)
- {
- TREE_PURPOSE (tta) = TREE_VALUE (tta);
- tta = TREE_CHAIN (tta);
- }
-
- i = 0;
- do
- {
- int exact_conversions = 0;
-
- i -= 1;
- tta = parms;
- if (DECL_STATIC_FUNCTION_P (cp[i].function))
- tta = TREE_CHAIN (tta);
- /* special note, we don't go through len parameters, because we
- may only need len-1 parameters because of a call to a static
- member. */
- for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), index = 0;
- tta;
- tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++)
- {
- /* If this is a varargs function, there's no conversion to do,
- but don't accept an arg that needs a copy ctor. */
- if (ttf == NULL_TREE)
- {
- /* FIXME: verify that we cannot get here with an
- arg that needs a ctor. */
- break;
- }
-
- if (USER_HARSHNESS (cp[i].v.old_harshness[index]))
- {
- tree this_parm = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_PURPOSE (tta), 2);
- if (basetype != NULL_TREE)
- TREE_VALUE (tta) = this_parm;
- if (this_parm)
- {
- if (TREE_CODE (this_parm) != CONVERT_EXPR
- && (TREE_CODE (this_parm) != NOP_EXPR
- || comp_target_types (TREE_TYPE (this_parm),
- TREE_TYPE (TREE_OPERAND (this_parm, 0)), 1)))
- exact_conversions += 1;
- }
- else if (PROMOTES_TO_AGGR_TYPE (TREE_VALUE (ttf), REFERENCE_TYPE))
- {
- /* To get here we had to have succeeded via
- a constructor. */
- TREE_VALUE (tta) = TREE_PURPOSE (tta);
- exact_conversions += 1;
- }
- }
- }
- if (exact_conversions == cp[i].user)
- {
- if (best == 0)
- {
- best = i;
- f1 = cp[best].function;
-#if 0
- /* For LUCID */
- p1 = TYPE_ARG_TYPES (TREE_TYPE (f1));
-#endif
- }
- else
- {
- /* Don't complain if next best is from base class. */
- tree f2 = cp[i].function;
-
- if (TREE_CODE (TREE_TYPE (f1)) == METHOD_TYPE
- && TREE_CODE (TREE_TYPE (f2)) == METHOD_TYPE
- && BASE_DERIVED_HARSHNESS (cp[i].v.old_harshness[0])
- && cp[best].v.old_harshness[0] < cp[i].v.old_harshness[0])
- {
-#if 0
- tree p2 = TYPE_ARG_TYPES (TREE_TYPE (f2));
- /* For LUCID. */
- if (! compparms (TREE_CHAIN (p1), TREE_CHAIN (p2), 1))
- goto ret0;
- else
-#endif
- continue;
- }
- else
- {
- /* Ensure that there's nothing ambiguous about these
- two fns. */
- int identical = 1;
- for (index = 0; index < len; index++)
- {
- /* Type conversions must be piecewise equivalent. */
- if (USER_HARSHNESS (cp[best].v.old_harshness[index])
- != USER_HARSHNESS (cp[i].v.old_harshness[index]))
- goto ret0;
- /* If there's anything we like better about the
- other function, consider it ambiguous. */
- if (cp[i].v.old_harshness[index] < cp[best].v.old_harshness[index])
- goto ret0;
- /* If any single one it diffent, then the whole is
- not identical. */
- if (cp[i].v.old_harshness[index] != cp[best].v.old_harshness[index])
- identical = 0;
- }
-
- /* If we can't tell the difference between the two, it
- is ambiguous. */
- if (identical)
- goto ret0;
-
- /* If we made it to here, it means we're satisfied that
- BEST is still best. */
- continue;
- }
- }
- }
- } while (cp + i != candidates);
-
- if (best)
- {
- int exact_conversions = cp[best].user;
- tta = parms;
- if (DECL_STATIC_FUNCTION_P (cp[best].function))
- tta = TREE_CHAIN (parms);
- for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[best].function)), index = 0;
- exact_conversions > 0;
- tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++)
- {
- if (USER_HARSHNESS (cp[best].v.old_harshness[index]))
- {
- /* We must now fill in the slot we left behind.
- @@ This could be optimized to use the value previously
- @@ computed by build_type_conversion in some cases. */
- if (basetype != NULL_TREE)
- TREE_VALUE (tta) = convert (TREE_VALUE (ttf), TREE_PURPOSE (tta));
- exact_conversions -= 1;
- }
- else
- TREE_VALUE (tta) = TREE_PURPOSE (tta);
- }
- return cp + best;
- }
- goto ret0;
- }
- /* If the best two candidates we find both use default parameters,
- we may need to report and error. Don't need to worry if next-best
- candidate is forced to use user-defined conversion when best is not. */
- if (cp[-2].user == 0
- && cp[-1].v.old_harshness[len] != 0 && cp[-2].v.old_harshness[len] != 0)
- {
- tree tt1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function));
- tree tt2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function));
- unsigned i = cp[-1].v.old_harshness[len];
-
- if (cp[-2].v.old_harshness[len] < i)
- i = cp[-2].v.old_harshness[len];
- while (--i > 0)
- {
- if (TYPE_MAIN_VARIANT (TREE_VALUE (tt1))
- != TYPE_MAIN_VARIANT (TREE_VALUE (tt2)))
- /* These lists are not identical, so we can choose our best candidate. */
- return cp - 1;
- tt1 = TREE_CHAIN (tt1);
- tt2 = TREE_CHAIN (tt2);
- }
- /* To get here, both lists had the same parameters up to the defaults
- which were used. This is an ambiguous request. */
- goto ret0;
- }
-
- /* Otherwise, return our best candidate. Note that if we get candidates
- from independent base classes, we have an ambiguity, even if one
- argument list look a little better than another one. */
- if (cp[-1].b_or_d && basetype && TYPE_USES_MULTIPLE_INHERITANCE (basetype))
- {
- int i = n_candidates - 1, best = i;
- tree base1 = NULL_TREE;
-
- if (TREE_CODE (TREE_TYPE (candidates[i].function)) == FUNCTION_TYPE)
- return cp - 1;
-
- for (; i >= 0 && candidates[i].user == 0 && candidates[i].evil == 0; i--)
- {
- if (TREE_CODE (TREE_TYPE (candidates[i].function)) == METHOD_TYPE)
- {
- tree newbase = DECL_CLASS_CONTEXT (candidates[i].function);
-
- if (base1 != NULL_TREE)
- {
- /* newbase could be a base or a parent of base1 */
- if (newbase != base1 && ! UNIQUELY_DERIVED_FROM_P (newbase, base1)
- && ! UNIQUELY_DERIVED_FROM_P (base1, newbase))
- {
- cp_error ("ambiguous request for function from distinct base classes of type `%T'", basetype);
- cp_error_at (" first candidate is `%#D'",
- candidates[best].function);
- cp_error_at (" second candidate is `%#D'",
- candidates[i].function);
- cp[-1].evil = 1;
- return cp - 1;
- }
- }
- else
- {
- best = i;
- base1 = newbase;
- }
- }
- else
- return cp - 1;
- }
- }
-
- /* Don't accept a candidate as being ideal if it's indistinguishable
- from another candidate. */
- if (rank_for_overload (cp-1, cp-2) == 0)
- {
- /* If the types are distinguishably different (like
- `long' vs. `unsigned long'), that's ok. But if they are arbitrarily
- different, such as `int (*)(void)' vs. `void (*)(int)',
- that's not ok. */
- tree p1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function));
- tree p2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function));
- while (p1 && p2)
- {
- if (TREE_CODE (TREE_VALUE (p1)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_VALUE (p1))) == FUNCTION_TYPE
- && TREE_VALUE (p1) != TREE_VALUE (p2))
- return NULL;
- p1 = TREE_CHAIN (p1);
- p2 = TREE_CHAIN (p2);
- }
- if (p1 || p2)
- return NULL;
- }
-
- return cp - 1;
-
- ret0:
- /* In the case where there is no ideal candidate, restore
- TREE_VALUE slots of PARMS from TREE_PURPOSE slots. */
- while (parms)
- {
- TREE_VALUE (parms) = TREE_PURPOSE (parms);
- parms = TREE_CHAIN (parms);
- }
- return NULL;
-}
-
/* Subroutine of ideal_candidate. See if X or Y is a better match
than the other. */
static int
@@ -2216,8 +1075,20 @@ strictly_better (x, y)
return 0;
}
+/* When one of several possible overloaded functions and/or methods
+ can be called, choose the best candidate for overloading.
+
+ BASETYPE is the context from which we start method resolution
+ or NULL if we are comparing overloaded functions.
+ CANDIDATES is the array of candidates we have to choose from.
+ N_CANDIDATES is the length of CANDIDATES.
+ PARMS is a TREE_LIST of parameters to the function we'll ultimately
+ choose. It is modified in place when resolving methods. It is not
+ modified in place when resolving overloaded functions.
+ LEN is the length of the parameter list. */
+
static struct candidate *
-ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len)
+ideal_candidate (basetype, candidates, n_candidates, parms, len)
tree basetype;
struct candidate *candidates;
int n_candidates;
@@ -2278,27 +1149,27 @@ ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len)
rank_for_ideal);
for (i = 0; i < len; i++)
{
- if (cp[-1].v.ansi_harshness[i].code < cp[-2].v.ansi_harshness[i].code)
+ if (cp[-1].harshness[i].code < cp[-2].harshness[i].code)
better = 1;
- else if (cp[-1].v.ansi_harshness[i].code > cp[-2].v.ansi_harshness[i].code)
+ else if (cp[-1].harshness[i].code > cp[-2].harshness[i].code)
worse = 1;
- else if (cp[-1].v.ansi_harshness[i].code & STD_CODE)
+ else if (cp[-1].harshness[i].code & STD_CODE)
{
/* If it involves a standard conversion, let the
inheritance lattice be the final arbiter. */
- if (cp[-1].v.ansi_harshness[i].distance > cp[-2].v.ansi_harshness[i].distance)
+ if (cp[-1].harshness[i].distance > cp[-2].harshness[i].distance)
worse = 1;
- else if (cp[-1].v.ansi_harshness[i].distance < cp[-2].v.ansi_harshness[i].distance)
+ else if (cp[-1].harshness[i].distance < cp[-2].harshness[i].distance)
better = 1;
}
- else if (cp[-1].v.ansi_harshness[i].code & PROMO_CODE)
+ else if (cp[-1].harshness[i].code & PROMO_CODE)
{
/* For integral promotions, take into account a finer
granularity for determining which types should be favored
over others in such promotions. */
- if (cp[-1].v.ansi_harshness[i].int_penalty > cp[-2].v.ansi_harshness[i].int_penalty)
+ if (cp[-1].harshness[i].int_penalty > cp[-2].harshness[i].int_penalty)
worse = 1;
- else if (cp[-1].v.ansi_harshness[i].int_penalty < cp[-2].v.ansi_harshness[i].int_penalty)
+ else if (cp[-1].harshness[i].int_penalty < cp[-2].harshness[i].int_penalty)
better = 1;
}
}
@@ -2309,22 +1180,6 @@ ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len)
return cp-1;
}
-static struct candidate *
-ideal_candidate (basetype, candidates, n_candidates, parms, len)
- tree basetype;
- struct candidate *candidates;
- int n_candidates;
- tree parms;
- int len;
-{
- if (flag_ansi_overloading)
- return ideal_candidate_ansi (basetype, candidates, n_candidates, parms,
- len);
- else
- return ideal_candidate_old (basetype, candidates, n_candidates, parms,
- len);
-}
-
/* Assume that if the class referred to is not in the
current class hierarchy, that it may be remote.
PARENT is assumed to be of aggregate type here. */
@@ -3252,12 +2107,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
my_friendly_abort (167);
cp->h_len = len;
- if (flag_ansi_overloading)
- cp->v.ansi_harshness = (struct harshness_code *)
- alloca ((len + 1) * sizeof (struct harshness_code));
- else
- cp->v.old_harshness = (unsigned short *)
- alloca ((len + 1) * sizeof (unsigned short));
+ cp->harshness = (struct harshness_code *)
+ alloca ((len + 1) * sizeof (struct harshness_code));
result = build_overload_call (name, friend_parms, 0, cp);
/* If it turns out to be the one we were actually looking for
@@ -3266,30 +2117,16 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (TREE_CODE (result) == CALL_EXPR)
return result;
- if (flag_ansi_overloading)
- while ((cp->h.code & EVIL_CODE) == 0)
- {
- /* non-standard uses: set the field to 0 to indicate
- we are using a non-member function. */
- cp->u.field = 0;
- if (cp->v.ansi_harshness[len].distance == 0
- && cp->h.code < best)
- best = cp->h.code;
- cp += 1;
- }
- else
- while (cp->evil == 0)
- {
- /* non-standard uses: set the field to 0 to indicate
- we are using a non-member function. */
- cp->u.field = 0;
- if (cp->v.old_harshness[len] == 0
- && cp->v.old_harshness[len] == 0
- && cp->ellipsis == 0 && cp->user == 0 && cp->b_or_d == 0
- && cp->easy < best)
- best = cp->easy;
- cp += 1;
- }
+ while ((cp->h.code & EVIL_CODE) == 0)
+ {
+ /* non-standard uses: set the field to 0 to indicate
+ we are using a non-member function. */
+ cp->u.field = 0;
+ if (cp->harshness[len].distance == 0
+ && cp->h.code < best)
+ best = cp->h.code;
+ cp += 1;
+ }
}
}
@@ -3357,22 +2194,14 @@ build_method_call (instance, name, parms, basetype_path, flags)
n_inner_fields_searched++;
#endif
cp->h_len = len;
- if (flag_ansi_overloading)
- cp->v.ansi_harshness = (struct harshness_code *)
- alloca ((len + 1) * sizeof (struct harshness_code));
- else
- cp->v.old_harshness = (unsigned short *)
- alloca ((len + 1) * sizeof (unsigned short));
+ cp->harshness = (struct harshness_code *)
+ alloca ((len + 1) * sizeof (struct harshness_code));
if (DECL_STATIC_FUNCTION_P (function))
these_parms = TREE_CHAIN (these_parms);
compute_conversion_costs (function, these_parms, cp, len);
- if (!flag_ansi_overloading)
- cp->b_or_d += b_or_d;
-
- if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0)
- || (!flag_ansi_overloading && cp->evil == 0))
+ if ((cp->h.code & EVIL_CODE) == 0)
{
cp->u.field = function;
cp->function = function;
@@ -3380,10 +2209,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* No "two-level" conversions. */
if (flags & LOOKUP_NO_CONVERSION
- && ((flag_ansi_overloading
- && (cp->h.code & USER_CODE))
- || (!flag_ansi_overloading
- && cp->user != 0)))
+ && (cp->h.code & USER_CODE))
continue;
/* If we used default parameters, we must
@@ -3391,14 +2217,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
use them also, and report a possible
ambiguity. */
if (! TYPE_USES_MULTIPLE_INHERITANCE (save_basetype)
- && ((flag_ansi_overloading
- && cp->v.ansi_harshness[len].distance == 0
- && cp->h.code < best)
- || (!flag_ansi_overloading
- && cp->v.old_harshness[len] == 0
- && CONST_HARSHNESS (cp->v.old_harshness[0]) == 0
- && cp->ellipsis == 0 && cp->user == 0 && cp->b_or_d == 0
- && cp->easy < best)))
+ && cp->harshness[len].distance == 0
+ && cp->h.code < best)
{
if (! DECL_STATIC_FUNCTION_P (function))
TREE_VALUE (parms) = cp->arg;
@@ -3472,12 +2292,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
return error_mark_node;
}
- if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
- || (!flag_ansi_overloading && cp->evil))
+ if (cp->h.code & EVIL_CODE)
return error_mark_node;
}
- else if ((flag_ansi_overloading && (cp[-1].h.code & EVIL_CODE))
- || (!flag_ansi_overloading && cp[-1].evil == 2))
+ else if (cp[-1].h.code & EVIL_CODE)
{
if (flags & LOOKUP_COMPLAIN)
cp_error ("ambiguous type conversion requested for %s `%D'",
@@ -3546,10 +2364,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
continue;
found_and_maybe_warn:
- if (((flag_ansi_overloading
- && (cp->v.ansi_harshness[0].code & CONST_CODE))
- || (!flag_ansi_overloading
- && CONST_HARSHNESS (cp->v.old_harshness[0])))
+ if ((cp->harshness[0].code & CONST_CODE)
/* 12.1p2: Constructors can be called for const objects. */
&& ! DECL_CONSTRUCTOR_P (cp->function))
{
@@ -3869,24 +2684,11 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
if (final_cp)
{
- if (flag_ansi_overloading)
- {
- final_cp[0].h.code = 0;
- final_cp[0].h.distance = 0;
- final_cp[0].function = 0;
- /* end marker. */
- final_cp[1].h.code = EVIL_CODE;
- }
- else
- {
- final_cp[0].evil = 0;
- final_cp[0].user = 0;
- final_cp[0].b_or_d = 0;
- final_cp[0].easy = 0;
- final_cp[0].function = 0;
- /* end marker. */
- final_cp[1].evil = 1;
- }
+ final_cp[0].h.code = 0;
+ final_cp[0].h.distance = 0;
+ final_cp[0].function = 0;
+ /* end marker. */
+ final_cp[1].h.code = EVIL_CODE;
}
for (parm = parms; parm; parm = TREE_CHAIN (parm))
@@ -3896,12 +2698,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
if (t == error_mark_node)
{
if (final_cp)
- {
- if (flag_ansi_overloading)
- final_cp->h.code = EVIL_CODE;
- else
- final_cp->evil = 1;
- }
+ final_cp->h.code = EVIL_CODE;
return error_mark_node;
}
if (TREE_CODE (t) == ARRAY_TYPE || TREE_CODE (t) == OFFSET_TYPE)
@@ -3920,26 +2717,6 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
else
parmtypes = void_list_node;
- if (! flag_ansi_overloading)
- {
- tree fn;
-
- /* This is a speed improvement that ends up not working properly in
- the situation of fns with and without default parameters. I turned
- this off in the new method so it'll go through the argument matching
- code to properly diagnose a match/failure. (bpk) */
- overload_name = build_decl_overload (fnname, parmtypes, 0);
- fn = lookup_name_nonclass (overload_name);
-
- /* Now check to see whether or not we can win.
- Note that if we are called from `build_method_call',
- then we cannot have a mis-match, because we would have
- already found such a winning case. */
-
- if (fn && TREE_CODE (fn) == FUNCTION_DECL)
- return build_function_call (DECL_MAIN_VARIANT (fn), parms);
- }
-
functions = lookup_name_nonclass (fnname);
if (functions == NULL_TREE)
@@ -3949,12 +2726,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
if (flags & LOOKUP_COMPLAIN)
error ("only member functions apply");
if (final_cp)
- {
- if (flag_ansi_overloading)
- final_cp->h.code = EVIL_CODE;
- else
- final_cp->evil = 1;
- }
+ final_cp->h.code = EVIL_CODE;
return error_mark_node;
}
@@ -3982,12 +2754,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
cp_error ("function `%D' declared overloaded, but no instances of that function declared",
TREE_PURPOSE (functions));
if (final_cp)
- {
- if (flag_ansi_overloading)
- final_cp->h.code = EVIL_CODE;
- else
- final_cp->evil = 1;
- }
+ final_cp->h.code = EVIL_CODE;
return error_mark_node;
}
@@ -4061,10 +2828,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
/* Unconverted template -- failed match. */
cp->function = function;
cp->u.bad_arg = -4;
- if (flag_ansi_overloading)
- cp->h.code = EVIL_CODE;
- else
- cp->evil = 1;
+ cp->h.code = EVIL_CODE;
}
else
{
@@ -4086,60 +2850,30 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
/* Can't use alloca here, since result might be
passed to calling function. */
cp->h_len = parmlength;
- if (flag_ansi_overloading)
- cp->v.ansi_harshness = (struct harshness_code *)
- oballoc ((parmlength + 1) * sizeof (struct harshness_code));
- else
- cp->v.old_harshness = (unsigned short *)
- oballoc ((parmlength + 1) * sizeof (unsigned short));
+ cp->harshness = (struct harshness_code *)
+ oballoc ((parmlength + 1) * sizeof (struct harshness_code));
compute_conversion_costs (function, parms, cp, parmlength);
- if (flag_ansi_overloading)
- /* Make sure this is clear as well. */
- cp->h.int_penalty += template_cost;
- else
- /* Should really add another field... */
- cp->easy = cp->easy * 128 + template_cost;
+ /* Make sure this is clear as well. */
+ cp->h.int_penalty += template_cost;
- /* It seemed easier to have both if stmts in here, rather
- than excluding the hell out of it with flag_ansi_overloading
- everywhere. (bpk) */
- if (flag_ansi_overloading)
- {
- if ((cp[0].h.code & EVIL_CODE) == 0)
- {
- cp[1].h.code = EVIL_CODE;
-
- /* int_penalty is set by convert_harshness_ansi for cases
- where we need to know about any penalties that would
- otherwise make a TRIVIAL_CODE pass. */
- if (final_cp
- && template_cost == 0
- && cp[0].h.code <= TRIVIAL_CODE
- && cp[0].h.int_penalty == 0)
- {
- final_cp[0].h = cp[0].h;
- return function;
- }
- cp++;
- }
- }
- else
+ if ((cp[0].h.code & EVIL_CODE) == 0)
{
- if (cp[0].evil == 0)
+ cp[1].h.code = EVIL_CODE;
+
+ /* int_penalty is set by convert_harshness_ansi for cases
+ where we need to know about any penalties that would
+ otherwise make a TRIVIAL_CODE pass. */
+ if (final_cp
+ && template_cost == 0
+ && cp[0].h.code <= TRIVIAL_CODE
+ && cp[0].h.int_penalty == 0)
{
- cp[1].evil = 1;
- if (final_cp
- && cp[0].user == 0 && cp[0].b_or_d == 0
- && template_cost == 0
- && cp[0].easy <= 1)
- {
- final_cp[0].easy = cp[0].easy;
- return function;
- }
- cp++;
+ final_cp[0].h = cp[0].h;
+ return function;
}
+ cp++;
}
}
}
@@ -4149,10 +2883,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
tree rval = error_mark_node;
/* Leave marker. */
- if (flag_ansi_overloading)
- cp[0].h.code = EVIL_CODE;
- else
- cp[0].evil = 1;
+ cp[0].h.code = EVIL_CODE;
if (cp - candidates > 1)
{
struct candidate *best_cp
@@ -4173,8 +2904,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
else
{
cp -= 1;
- if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
- || (!flag_ansi_overloading && cp->evil > 1))
+ if (cp->h.code & EVIL_CODE)
{
if (flags & LOOKUP_COMPLAIN)
error ("type conversion ambiguous");
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 27e9a4b0d8c..4fab523b25f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1490,6 +1490,12 @@ finish_base_struct (t, b, t_binfo)
if (b->has_virtual == 0)
{
first_vfn_base_index = i;
+
+ /* Update these two, now that we know what vtable we are
+ going to extend. This is so that we can add virtual
+ functions, and override them properly. */
+ BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
+ BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
b->has_virtual = CLASSTYPE_VSIZE (basetype);
b->vfield = CLASSTYPE_VFIELD (basetype);
CLASSTYPE_VFIELD (t) = b->vfield;
@@ -1678,7 +1684,9 @@ finish_struct_bits (t, max_has_virtual)
else
conv_index = ptr_conv;
}
- else if (typecode_p (return_type, INTEGER_TYPE))
+ else if (typecode_p (return_type, INTEGER_TYPE)
+ || typecode_p (return_type, BOOLEAN_TYPE)
+ || typecode_p (return_type, ENUMERAL_TYPE))
{
TYPE_HAS_INT_CONVERSION (t) = 1;
conv_index = int_conv;
@@ -2160,9 +2168,11 @@ modify_one_vtable (binfo, t, fndecl, pfn)
}
}
- /* Find the right offset for the this pointer based on the base
- class we just found. */
- base_offset = BINFO_OFFSET (binfo);
+ /* Find the right offset for the this pointer based on the
+ base class we just found. We have to take into
+ consideration the virtual base class pointers that we
+ stick in before the virtual function table pointer. */
+ base_offset = get_vfield_offset (binfo);
this_offset = size_binop (MINUS_EXPR, offset, base_offset);
/* Make sure we can modify the derived association with immunity. */
@@ -2929,10 +2939,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
/* Invalid bit-field size done by grokfield. */
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
- && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
+ && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
{
- cp_error_at ("bit-field `%D' has invalid type", x);
+ cp_error_at ("bit-field `%#D' with non-integral type", x);
DECL_INITIAL (x) = NULL;
}
@@ -3499,6 +3508,27 @@ finish_struct (t, list_of_fieldlists, warn_anon)
}
}
+ /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
+ might need to know it for setting up the offsets in the vtable
+ (or in thunks) below. */
+ if (vfield != NULL_TREE
+ && DECL_FIELD_CONTEXT (vfield) != t)
+ {
+ tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
+ tree offset = BINFO_OFFSET (binfo);
+
+ vfield = copy_node (vfield);
+ copy_lang_decl (vfield);
+
+ if (! integer_zerop (offset))
+ offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
+ DECL_FIELD_CONTEXT (vfield) = t;
+ DECL_CLASS_CONTEXT (vfield) = t;
+ DECL_FIELD_BITPOS (vfield)
+ = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
+ CLASSTYPE_VFIELD (t) = vfield;
+ }
+
#ifdef NOTQUITE
cp_warning ("Doing hard virtuals for %T...", t);
#endif
@@ -3739,6 +3769,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
DECL_REGISTER (vtbl_ptr) = 1;
CLASSTYPE_VTBL_PTR (t) = vtbl_ptr;
}
+#if 0
+ /* This is now done above. */
if (DECL_FIELD_CONTEXT (vfield) != t)
{
tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
@@ -3755,6 +3787,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
= size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
CLASSTYPE_VFIELD (t) = vfield;
}
+#endif
/* In addition to this one, all the other vfields should be listed. */
/* Before that can be done, we have to have FIELD_DECLs for them, and
diff --git a/gcc/cp/class.h b/gcc/cp/class.h
index 7e138243c01..6f31e15ee83 100644
--- a/gcc/cp/class.h
+++ b/gcc/cp/class.h
@@ -39,34 +39,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
and one uses pointers of strictly higher type (derived where
another uses base), then that alternative is silently chosen.
- If two candidates have a non-monotonic derived/base pointer
- relationship, and/or a non-monotonic easy conversion relationship,
- then a warning is emitted to show which paths are possible, and
- which one is being chosen.
-
- For example:
-
- int i;
- double x;
-
- overload f;
- int f (int, int);
- double f (double, double);
-
- f (i, x); // draws a warning
-
- struct B
- {
- f (int);
- } *bb;
- struct D : B
- {
- f (double);
- } *dd;
-
- dd->f (x); // exact match
- dd->f (i); // draws warning
-
Note that this technique really only works for 255 arguments. Perhaps
this is not enough. */
@@ -102,36 +74,19 @@ struct harshness_code
struct candidate
{
- /* OLD METHOD */
- unsigned char evil; /* !0 if this will never convert. */
- unsigned char ellipsis; /* !0 if a match against an ellipsis occurred */
- unsigned char user; /* !0 if at least one user-defined type conv. */
- unsigned short b_or_d; /* count number of derived->base or
- base->derived conv. */
- unsigned short easy; /* count number of builtin type conv. */
-
- /* NEW METHOD */
struct harshness_code h; /* Used for single-argument conversions. */
int h_len; /* The length of the harshness vector. */
- /* Both methods. */
tree function; /* A FUNCTION_DECL */
tree basetypes; /* The path to function. */
tree arg; /* first parm to function. */
- /* This union is only here while we maintain both the old and new
- argument matching schemes. When it goes away, all v.ansi_harshness
- references will be just `harshness'. */
- union
- {
- /* Indexed by argument number, encodes evil, user, d_to_b, and easy
- strikes for that argument. At end of array, we store the index+1
- of where we started using default parameters, or 0 if there are
- none. */
- struct harshness_code *ansi_harshness; /* NEW METHOD */
- unsigned short *old_harshness; /* OLD METHOD */
- } v;
+ /* Indexed by argument number, encodes evil, user, d_to_b, and easy
+ strikes for that argument. At end of array, we store the index+1
+ of where we started using default parameters, or 0 if there are
+ none. */
+ struct harshness_code *harshness;
union
{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5d7cfa763d7..061c7f1e28a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -280,11 +280,6 @@ extern int flag_ansi;
extern int flag_handle_exceptions;
-/* Nonzero means do argument matching for overloading according to the
- ANSI rules, rather than what g++ used to believe to be correct. */
-
-extern int flag_ansi_overloading;
-
/* Nonzero means recognize and handle signature language constructs. */
extern int flag_handle_signatures;
@@ -1132,6 +1127,10 @@ struct lang_decl
|| TYPE_MAIN_VARIANT (t) == short_integer_type_node \
|| TYPE_MAIN_VARIANT (t) == short_unsigned_type_node))
+#define INTEGRAL_CODE_P(CODE) \
+ (CODE == INTEGER_TYPE || CODE == ENUMERAL_TYPE || CODE == BOOLEAN_TYPE)
+#define ARITHMETIC_TYPE_P(TYPE) (INTEGRAL_TYPE_P (TYPE) || FLOAT_TYPE_P (TYPE))
+
/* Mark which labels are explicitly declared.
These may be shadowed, and may be referenced from nested functions. */
#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label)
@@ -1367,6 +1366,7 @@ extern tree delta_type_node;
extern tree long_long_integer_type_node, long_long_unsigned_type_node;
/* For building calls to `delete'. */
extern tree integer_two_node, integer_three_node;
+extern tree bool_type_node, true_node, false_node;
/* in except.c */
extern tree current_exception_type;
@@ -1938,6 +1938,7 @@ extern tree reparse_absdcl_as_casts PROTO((tree, tree));
extern tree reparse_decl_as_expr PROTO((tree, tree));
extern tree finish_decl_parsing PROTO((tree));
extern tree lookup_name_nonclass PROTO((tree));
+extern tree check_cp_case_value PROTO((tree));
/* in edsel.c */
@@ -2217,6 +2218,7 @@ extern tree array_type_nelts_total PROTO((tree));
extern tree array_type_nelts_top PROTO((tree));
/* in typeck.c */
+extern tree bool_truthvalue_conversion PROTO((tree));
extern tree target_type PROTO((tree));
extern tree require_complete_type PROTO((tree));
extern int type_unknown_p PROTO((tree));
@@ -2262,6 +2264,9 @@ extern tree build_x_conditional_expr PROTO((tree, tree, tree));
extern tree build_conditional_expr PROTO((tree, tree, tree));
extern tree build_x_compound_expr PROTO((tree));
extern tree build_compound_expr PROTO((tree));
+extern tree build_static_cast PROTO((tree, tree));
+extern tree build_reinterpret_cast PROTO((tree, tree));
+extern tree build_const_cast PROTO((tree, tree));
extern tree build_c_cast PROTO((tree, tree));
extern tree build_modify_expr PROTO((tree, enum tree_code, tree));
extern int language_lvalue_valid PROTO((tree));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index d614c70dbb8..7bfe80233a8 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -186,7 +186,7 @@ cp_convert_to_pointer (type, expr)
return expr;
}
- if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
+ if (INTEGRAL_CODE_P (form))
{
if (type_precision (intype) == POINTER_SIZE)
return build1 (CONVERT_EXPR, type, expr);
@@ -950,16 +950,11 @@ convert_to_aggr (type, expr, msgp, protect)
{
function = fndecl;
cp->h_len = 2;
- if (flag_ansi_overloading)
- cp->v.ansi_harshness = (struct harshness_code *)
- alloca (3 * sizeof (struct harshness_code));
- else
- cp->v.old_harshness = (unsigned short *)
- alloca (3 * sizeof (short));
+ cp->harshness = (struct harshness_code *)
+ alloca (3 * sizeof (struct harshness_code));
compute_conversion_costs (fndecl, parmlist, cp, 2);
- if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0)
- || (!flag_ansi_overloading && cp->evil == 0))
+ if ((cp->h.code & EVIL_CODE) == 0)
{
cp->u.field = fndecl;
if (protect)
@@ -983,10 +978,7 @@ convert_to_aggr (type, expr, msgp, protect)
|| purpose_member (basetype, DECL_ACCESS (fndecl)))
: 1)
{
- if ((flag_ansi_overloading && cp->h.code <= TRIVIAL_CODE)
- || (!flag_ansi_overloading
- && cp->user == 0 && cp->b_or_d == 0
- && cp->easy <= 1))
+ if (cp->h.code <= TRIVIAL_CODE)
goto found_and_ok;
cp++;
}
@@ -1014,8 +1006,7 @@ convert_to_aggr (type, expr, msgp, protect)
rank_for_overload); /* int (*compar)() */
--cp;
- if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
- || (!flag_ansi_overloading && cp->evil > 1))
+ if (cp->h.code & EVIL_CODE)
{
if (msgp)
*msgp = "ambiguous type conversion possible for `%s'";
@@ -1235,15 +1226,14 @@ cp_convert (type, expr, convtype, flags)
else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
e = convert_from_reference (e);
- if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
+ if (INTEGRAL_CODE_P (code))
{
tree intype = TREE_TYPE (expr);
enum tree_code form = TREE_CODE (intype);
/* enum = enum, enum = int, enum = float are all errors. */
if (flag_int_enum_equivalence == 0
&& TREE_CODE (type) == ENUMERAL_TYPE
- && (form == INTEGER_TYPE || form == REAL_TYPE
- || form == ENUMERAL_TYPE))
+ && ARITHMETIC_TYPE_P (intype))
{
cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type);
@@ -1258,9 +1248,23 @@ cp_convert (type, expr, convtype, flags)
tree rval;
rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
if (rval) return rval;
- cp_error ("`%#T' used where an `int' was expected", intype);
+ if (code == BOOLEAN_TYPE)
+ cp_error ("`%#T' used where a `bool' was expected", intype);
+ else
+ cp_error ("`%#T' used where an `int' was expected", intype);
return error_mark_node;
}
+ if (code == BOOLEAN_TYPE)
+ {
+ tree newe = truthvalue_conversion (e);
+ /* Avoid stupid (infinite) recursion from backend. */
+ if (TREE_CODE (newe) != NOP_EXPR || e != TREE_OPERAND (newe, 0))
+ e = newe;
+ if (TREE_TYPE (e) == bool_type_node)
+ return e;
+ else
+ return build1 (NOP_EXPR, bool_type_node, e);
+ }
return fold (convert_to_integer (type, e));
}
if (code == POINTER_TYPE)
@@ -1554,6 +1558,14 @@ build_type_conversion (code, xtype, expr, for_sure)
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
+ if (TYPE_PTRMEMFUNC_P (basetype) && TREE_CODE (xtype) == BOOLEAN_TYPE)
+ {
+ /* We convert a pointer to member function into a boolean,
+ by just checking the index value, for == 0, we want false, for
+ != 0, we want true. */
+ return convert (xtype, build_component_ref (expr, index_identifier, 0, 0));
+ }
+
basetype = TYPE_MAIN_VARIANT (basetype);
if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype))
return NULL_TREE;
@@ -1651,6 +1663,30 @@ build_type_conversion (code, xtype, expr, for_sure)
if (exact_conversion)
return NULL_TREE;
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
+ {
+ tree as_int = build_type_conversion (code, long_long_unsigned_type_node, expr, 0);
+ tree as_ptr = build_type_conversion (code, ptr_type_node, expr, 0);
+ /* We are missing the conversion to pointer to member type. */
+ /* We are missing the conversion to floating type. */
+ if (as_int && as_ptr && for_sure)
+ {
+ cp_error ("ambiguous conversion from `%T' to `bool', can convert to integral type or pointer", TREE_TYPE (expr));
+ return error_mark_node;
+ }
+ if (as_int)
+ {
+ as_int = build_type_conversion (code, long_long_unsigned_type_node, expr, for_sure+exact_conversion*2);
+ return convert (xtype, as_int);
+ }
+ if (as_ptr)
+ {
+ as_ptr = build_type_conversion (code, ptr_type_node, expr, for_sure+exact_conversion*2);
+ return convert (xtype, as_ptr);
+ }
+ return NULL_TREE;
+ }
+
/* No perfect match found, try default. */
#if 0 /* This is wrong; there is no standard conversion from void* to
anything. -jason */
@@ -1686,8 +1722,6 @@ build_type_conversion (code, xtype, expr, for_sure)
}
}
- try_pointer:
-
if (TREE_CODE (type) == POINTER_TYPE && TYPE_READONLY (TREE_TYPE (type)))
{
/* Try converting to some other const pointer type and then using
@@ -1747,7 +1781,7 @@ build_type_conversion (code, xtype, expr, for_sure)
{
/* Only accept using an operator double() if there isn't a conflicting
operator int(). */
- if (flag_ansi_overloading && TYPE_HAS_INT_CONVERSION (basetype))
+ if (TYPE_HAS_INT_CONVERSION (basetype))
{
error ("two possible conversions for type `%s'",
TYPE_NAME_STRING (type));
@@ -1758,17 +1792,6 @@ build_type_conversion (code, xtype, expr, for_sure)
return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
}
- /* THIS IS A KLUDGE. */
- if (TREE_CODE (type) != POINTER_TYPE
- && (code == TRUTH_ANDIF_EXPR
- || code == TRUTH_ORIF_EXPR
- || code == TRUTH_NOT_EXPR))
- {
- /* Here's when we can convert to a pointer. */
- type = ptr_type_node;
- goto try_pointer;
- }
-
/* THESE ARE TOTAL KLUDGES. */
/* Default promotion yields no new alternatives, try
conversions which are anti-default, such as
@@ -1777,7 +1800,7 @@ build_type_conversion (code, xtype, expr, for_sure)
*/
if (type_default == type
- && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE))
+ && (INTEGRAL_TYPE_P (type) || TREE_CODE (type) == REAL_TYPE))
{
int not_again = 0;
@@ -1819,19 +1842,10 @@ build_type_conversion (code, xtype, expr, for_sure)
/* Now, try C promotions...
float -> int
- int -> float, void *
- void * -> int
-
- Truthvalue conversions let us try to convert
- to pointer if we were going for int, and to int
- if we were looking for pointer. */
+ int -> float */
basetype = save_basetype;
- if (TREE_CODE (type) == REAL_TYPE
- || (TREE_CODE (type) == POINTER_TYPE
- && (code == TRUTH_ANDIF_EXPR
- || code == TRUTH_ORIF_EXPR
- || code == TRUTH_NOT_EXPR)))
+ if (TREE_CODE (type) == REAL_TYPE)
type = integer_type_node;
else if (TREE_CODE (type) == INTEGER_TYPE)
if (TYPE_HAS_REAL_CONVERSION (basetype))
@@ -1917,11 +1931,17 @@ build_default_binary_type_conversion (code, arg1, arg2)
return 0;
}
- if (TYPE_HAS_INT_CONVERSION (type1) && TYPE_HAS_REAL_CONVERSION (type1))
- cp_warning ("ambiguous type conversion for type `%T', defaulting to int",
- type1);
- if (TYPE_HAS_INT_CONVERSION (type1))
+ if (code == TRUTH_ANDIF_EXPR
+ || code == TRUTH_ORIF_EXPR)
{
+ *arg1 = convert (bool_type_node, *arg1);
+ *arg2 = convert (bool_type_node, *arg2);
+ }
+ else if (TYPE_HAS_INT_CONVERSION (type1))
+ {
+ if (TYPE_HAS_REAL_CONVERSION (type1))
+ cp_pedwarn ("ambiguous type conversion for type `%T', defaulting to int",
+ type1);
*arg1 = build_type_conversion (code, integer_type_node, *arg1, 1);
*arg2 = build_type_conversion (code, integer_type_node, *arg2, 1);
}
@@ -1956,7 +1976,7 @@ build_default_binary_type_conversion (code, arg1, arg2)
return 1;
}
-/* Must convert two aggregate types to non-aggregate type.
+/* Must convert an aggregate type to non-aggregate type.
Attempts to find a non-ambiguous, "best" type conversion.
Return 1 on success, 0 on failure.
@@ -1970,21 +1990,22 @@ build_default_unary_type_conversion (code, arg)
tree *arg;
{
tree type = TREE_TYPE (*arg);
- tree id = TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
- ? TYPE_IDENTIFIER (type) : TYPE_NAME (type);
- char *name = IDENTIFIER_POINTER (id);
if (! TYPE_HAS_CONVERSION (type))
{
- error ("type conversion required for type `%s'", name);
+ cp_error ("type conversion required for type `%T'", type);
return 0;
}
- if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type))
- warning ("ambiguous type conversion for type `%s', defaulting to int",
- name);
- if (TYPE_HAS_INT_CONVERSION (type))
- *arg = build_type_conversion (code, integer_type_node, *arg, 1);
+ if (code == TRUTH_NOT_EXPR)
+ *arg = convert (bool_type_node, *arg);
+ else if (TYPE_HAS_INT_CONVERSION (type))
+ {
+ if (TYPE_HAS_REAL_CONVERSION (type))
+ cp_pedwarn ("ambiguous type conversion for type `%T', defaulting to int",
+ type);
+ *arg = build_type_conversion (code, integer_type_node, *arg, 1);
+ }
else if (TYPE_HAS_REAL_CONVERSION (type))
*arg = build_type_conversion (code, double_type_node, *arg, 1);
else
@@ -1995,7 +2016,7 @@ build_default_unary_type_conversion (code, arg)
}
if (*arg == NULL_TREE)
{
- error ("default type conversion for type `%s' failed", name);
+ cp_error ("default type conversion for type `%T' failed", type);
return 0;
}
return 1;
@@ -2009,17 +2030,21 @@ type_promotes_to (type)
int constp = TYPE_READONLY (type);
int volatilep = TYPE_VOLATILE (type);
type = TYPE_MAIN_VARIANT (type);
-
- /* Normally convert enums to int,
- but convert wide enums to something wider. */
- if (TREE_CODE (type) == ENUMERAL_TYPE
- || type == wchar_type_node)
- type = type_for_size (MAX (TYPE_PRECISION (type),
- TYPE_PRECISION (integer_type_node)),
- ((flag_traditional
- || (TYPE_PRECISION (type)
- >= TYPE_PRECISION (integer_type_node)))
- && TREE_UNSIGNED (type)));
+
+ /* bool always promotes to int (not unsigned), even if it's the same
+ size. */
+ if (type == bool_type_node)
+ type = integer_type_node;
+
+ /* Normally convert enums to int, but convert wide enums to something
+ wider. */
+ else if (TREE_CODE (type) == ENUMERAL_TYPE
+ || type == wchar_type_node)
+ type = type_for_size
+ (MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)),
+ (flag_traditional
+ || (TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node)))
+ && TREE_UNSIGNED (type));
else if (C_PROMOTING_INTEGER_TYPE_P (type))
{
/* Traditionally, unsignedness is preserved in default promotions.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1c9905f7b36..fd73388d65d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -204,6 +204,9 @@ tree int_array_type_node;
tree wchar_array_type_node;
+/* The bool data type, and constants */
+tree bool_type_node, true_node, false_node;
+
/* type `int ()' -- used for implicit declaration of functions. */
tree default_function_type;
@@ -412,9 +415,7 @@ extern int flag_no_builtin;
extern int flag_implement_inlines;
-/* Nonzero means handle things in ANSI, instead of GNU fashion. This
- flag should be tested for language behavior that's different between
- ANSI and GNU, but not so horrible as to merit a PEDANTIC label. */
+/* Nonzero means disable GNU extensions. */
extern int flag_ansi;
@@ -1709,7 +1710,7 @@ pushtag (name, type, globalize)
{
register struct binding_level *b;
tree context = 0;
- tree cdecl = 0;
+ tree c_decl = 0;
b = inner_binding_level;
while (b->tag_transparent
@@ -1727,7 +1728,7 @@ pushtag (name, type, globalize)
if (! context && ! globalize)
context = current_scope ();
if (context)
- cdecl = TREE_CODE (context) == FUNCTION_DECL
+ c_decl = TREE_CODE (context) == FUNCTION_DECL
? context : TYPE_NAME (context);
/* Record the identifier as the type's name if it has none. */
@@ -1746,7 +1747,7 @@ pushtag (name, type, globalize)
if (b->parm_flag != 2
|| TYPE_SIZE (current_class_type) != NULL_TREE)
{
- d = lookup_nested_type (type, cdecl);
+ d = lookup_nested_type (type, c_decl);
if (d == NULL_TREE)
{
@@ -1824,7 +1825,7 @@ pushtag (name, type, globalize)
else if (context && TREE_CODE (context) == FUNCTION_DECL)
{
/* Function-nested class. */
- set_nested_typename (d, DECL_ASSEMBLER_NAME (cdecl),
+ set_nested_typename (d, DECL_ASSEMBLER_NAME (c_decl),
name, type);
/* This builds the links for classes nested in fn scope. */
DECL_CONTEXT (d) = context;
@@ -1834,7 +1835,7 @@ pushtag (name, type, globalize)
else if (context && TREE_CODE (context) == RECORD_TYPE)
{
/* Class-nested class. */
- set_nested_typename (d, DECL_NESTED_TYPENAME (cdecl),
+ set_nested_typename (d, DECL_NESTED_TYPENAME (c_decl),
name, type);
/* This builds the links for classes nested in type scope. */
DECL_CONTEXT (d) = context;
@@ -4373,6 +4374,14 @@ init_decl_processing ()
TREE_TYPE (integer_three_node) = integer_type_node;
empty_init_node = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
+ bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+ TREE_SET_CODE (bool_type_node, BOOLEAN_TYPE);
+ record_builtin_type (RID_BOOL, "bool", bool_type_node);
+ false_node = build_int_2 (0, 0);
+ TREE_TYPE (false_node) = bool_type_node;
+ true_node = build_int_2 (1, 0);
+ TREE_TYPE (true_node) = bool_type_node;
+
/* These are needed by stor-layout.c. */
size_zero_node = size_int (0);
size_one_node = size_int (1);
@@ -5007,7 +5016,7 @@ shadow_tag (declspecs)
{
int found_tag = 0;
int warned = 0;
- int static_or_extern = 0;
+ tree ob_modifier = NULL_TREE;
register tree link;
register enum tree_code code, ok_code = ERROR_MARK;
register tree t = NULL_TREE;
@@ -5018,11 +5027,12 @@ shadow_tag (declspecs)
code = TREE_CODE (value);
if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE)
- /* Used to test also that TYPE_SIZE (value) != 0.
- That caused warning for `struct foo;' at top level in the file. */
{
register tree name = TYPE_NAME (value);
+ if (code == ENUMERAL_TYPE && TYPE_SIZE (value) == 0)
+ cp_error ("forward declaration of `%#T'", value);
+
if (name == NULL_TREE)
name = lookup_tag_reverse (value, NULL_TREE);
@@ -5041,7 +5051,6 @@ shadow_tag (declspecs)
pushtag (name, t, 0);
pop_obstacks ();
ok_code = code;
- break;
}
else if (name != NULL_TREE || code == ENUMERAL_TYPE)
ok_code = code;
@@ -5056,8 +5065,10 @@ shadow_tag (declspecs)
}
}
else if (value == ridpointers[(int) RID_STATIC]
- || value == ridpointers[(int) RID_EXTERN])
- static_or_extern = 1;
+ || value == ridpointers[(int) RID_EXTERN]
+ || value == ridpointers[(int) RID_AUTO]
+ || value == ridpointers[(int) RID_REGISTER])
+ ob_modifier = value;
}
/* This is where the variables in an anonymous union are
@@ -5086,9 +5097,10 @@ shadow_tag (declspecs)
else
{
/* Anonymous unions are objects, that's why we only check for
- static/extern specifiers in this branch. */
- if (static_or_extern)
- error ("static/extern can only be specified for objects and functions");
+ inappropriate specifiers in this branch. */
+ if (ob_modifier)
+ cp_error ("`%D' can only be specified for objects and functions",
+ ob_modifier);
if (ok_code == RECORD_TYPE
&& found_tag == 1
@@ -5113,8 +5125,10 @@ shadow_tag (declspecs)
pop_obstacks ();
}
}
+ else if (found_tag == 0)
+ pedwarn ("abstract declarator used as declaration");
else if (!warned && found_tag > 1)
- warning ("multiple types in one declaration");
+ pedwarn ("multiple types in one declaration");
}
}
@@ -5967,14 +5981,16 @@ finish_decl (decl, init, asmspec_tree, need_pop)
&& (TYPE_READONLY (type) || TREE_READONLY (decl)))
cp_error ("uninitialized const `%D'", decl);
- /* Initialize variables in need of static initialization
- with `empty_init_node' to keep assemble_variable from putting them
- in the wrong program space. (Common storage is okay for non-public
- uninitialized data; the linker can't match it with storage from other
- files, and we may save some disk space.) */
+ /* Initialize variables in need of static initialization with
+ `empty_init_node' to keep assemble_variable from putting them in
+ the wrong program space. Common storage is okay for non-public
+ uninitialized data; the linker can't match it with storage from
+ other files, and we may save some disk space. Consts have to go
+ into data, though, since the backend would put them in text
+ otherwise. */
if (flag_pic == 0
&& TREE_STATIC (decl)
- && TREE_PUBLIC (decl)
+ && (TREE_PUBLIC (decl) || was_readonly)
&& ! DECL_EXTERNAL (decl)
&& TREE_CODE (decl) == VAR_DECL
&& TYPE_NEEDS_CONSTRUCTING (type)
@@ -7341,6 +7357,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
goto found;
}
+ if (id == ridpointers[(int) RID_BOOL])
+ {
+ if (type)
+ error ("extraneous `bool' ignored");
+ else
+ {
+ type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
+ }
+ goto found;
+ }
if (id == ridpointers[(int) RID_WCHAR])
{
if (type)
@@ -7445,7 +7471,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
/* Save warning until we know what is really going on. */
warn_about_return_type = 1;
}
- else if (class_binding_level && declarator
+ else if (decl_context == FIELD && declarator
&& TREE_CODE (declarator) == SCOPE_REF)
/* OK -- access declaration */;
else if (declspecs == NULL_TREE &&
@@ -8007,7 +8033,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
if (TREE_READONLY_DECL_P (size))
size = decl_constant_value (size);
- if (pedantic && integer_zerop (size))
+ if (flag_ansi && integer_zerop (size))
cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", dname);
if (TREE_CONSTANT (size))
{
@@ -8022,7 +8048,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
else
{
- if (pedantic)
+ if (flag_ansi)
cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
dname);
dont_grok_size:
@@ -8909,7 +8935,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
initialize the named nonstatic member.... This (or an
initializer list) is the only way to initialize
nonstatic const and reference members. */
- else if (pedantic || flag_ansi || ! constp)
+ else if (flag_ansi || ! constp)
pedwarn ("ANSI C++ forbids initialization of %s `%s'",
constp ? "const member" : "member",
IDENTIFIER_POINTER (declarator));
@@ -9061,7 +9087,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if (RIDBIT_SETP (RID_EXTERN, specbits))
{
current_extern_inline = 1;
- if (flag_ansi || pedantic || flag_pedantic_errors)
+ if (flag_ansi)
pedwarn ("ANSI C++ does not permit `extern inline'");
}
}
@@ -10245,31 +10271,34 @@ finish_enum (enumtype, values)
register HOST_WIDE_INT minvalue = 0;
register HOST_WIDE_INT i;
- TYPE_VALUES (enumtype) = values;
-
/* Calculate the maximum value of any enumerator in this type. */
if (values)
{
/* Speed up the main loop by performing some precalculations */
- HOST_WIDE_INT value = TREE_INT_CST_LOW (TREE_VALUE (values));
+ HOST_WIDE_INT value;
TREE_TYPE (TREE_VALUE (values)) = enumtype;
TREE_TYPE (DECL_INITIAL (TREE_VALUE (values))) = enumtype;
+ TREE_VALUE (values) = DECL_INITIAL (TREE_VALUE (values));
+ value = TREE_INT_CST_LOW (TREE_VALUE (values));
minvalue = maxvalue = value;
for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
{
+ TREE_TYPE (TREE_VALUE (pair)) = enumtype;
+ TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype;
+ TREE_VALUE (pair) = DECL_INITIAL (TREE_VALUE (pair));
value = TREE_INT_CST_LOW (TREE_VALUE (pair));
if (value > maxvalue)
maxvalue = value;
else if (value < minvalue)
minvalue = value;
- TREE_TYPE (TREE_VALUE (pair)) = enumtype;
- TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype;
}
}
+ TYPE_VALUES (enumtype) = values;
+
if (flag_short_enums)
{
/* Determine the precision this type needs, lay it out, and define
@@ -10970,7 +10999,7 @@ store_return_init (return_id, init)
{
tree decl = DECL_RESULT (current_function_decl);
- if (pedantic)
+ if (flag_ansi)
/* Give this error as many times as there are occurrences,
so that users can use Emacs compilation buffers to find
and fix all such places. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c5ab8dbd7fc..55414dfba2a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -96,17 +96,10 @@ int flag_signed_bitfields = 1;
int flag_no_ident = 0;
-/* Nonzero means handle things in ANSI, instead of GNU fashion. This
- flag should be tested for language behavior that's different between
- ANSI and GNU, but not so horrible as to merit a PEDANTIC label. */
+/* Nonzero means disable GNU extensions. */
int flag_ansi = 0;
-/* Nonzero means do argument matching for overloading according to the
- ANSI rules, rather than what g++ used to believe to be correct. */
-
-int flag_ansi_overloading = 1;
-
/* Nonzero means do emit exported implementations of functions even if
they can be inlined. */
@@ -359,7 +352,6 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"nonnull-objects", &flag_assume_nonnull_objects, 1},
{"implement-inlines", &flag_implement_inlines, 1},
{"external-templates", &flag_external_templates, 1},
- {"ansi-overloading", &flag_ansi_overloading, 1},
{"huge-objects", &flag_huge_objects, 1},
{"conserve-space", &flag_conserve_space, 1},
{"vtable-thunks", &flag_vtable_thunks, 1},
@@ -797,9 +789,11 @@ grokclassfn (ctype, cname, function, flags, quals)
we may wish to make it special. */
tree type = TREE_VALUE (arg_types);
- if (flags == DTOR_FLAG)
+ if ((flag_this_is_variable > 0)
+ && (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function)))
type = TYPE_MAIN_VARIANT (type);
- else if (DECL_CONSTRUCTOR_P (function))
+
+ if (DECL_CONSTRUCTOR_P (function))
{
if (TYPE_USES_VIRTUAL_BASECLASSES (ctype))
{
@@ -824,14 +818,7 @@ grokclassfn (ctype, cname, function, flags, quals)
/* We can make this a register, so long as we don't
accidentally complain if someone tries to take its address. */
DECL_REGISTER (parm) = 1;
-#if 0
- /* it is wrong to flag the object as readonly, when
- flag_this_is_variable is 0. */
- if (flags != DTOR_FLAG
- && (flag_this_is_variable <= 0 || TYPE_READONLY (type)))
-#else
- if (flags != DTOR_FLAG && TYPE_READONLY (type))
-#endif
+ if (TYPE_READONLY (type))
TREE_READONLY (parm) = 1;
TREE_CHAIN (parm) = last_function_parms;
last_function_parms = parm;
@@ -1044,7 +1031,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
case 2:
maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node, 1);
if (! flag_traditional)
- pedwarn ("ANSI C++ forbids array size in vector delete");
+ pedwarn ("anachronistic use of array size in vector delete");
/* Fall through. */
case 1:
elt_size = c_sizeof (type);
@@ -1800,7 +1787,7 @@ build_push_scope (cname, name)
void cplus_decl_attributes (decl, attributes)
tree decl, attributes;
{
- if (decl)
+ if (decl && decl != void_type_node)
decl_attributes (decl, attributes);
}
@@ -2952,3 +2939,43 @@ finish_decl_parsing (decl)
return NULL_TREE;
}
}
+
+tree
+check_cp_case_value (value)
+ tree value;
+{
+ if (value == NULL_TREE)
+ return value;
+
+ /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
+ Strip such NOP_EXPRs. */
+ if (TREE_CODE (value) == NOP_EXPR
+ && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
+ value = TREE_OPERAND (value, 0);
+
+ if (TREE_READONLY_DECL_P (value))
+ {
+ value = decl_constant_value (value);
+ /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
+ Strip such NOP_EXPRs. */
+ if (TREE_CODE (value) == NOP_EXPR
+ && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
+ value = TREE_OPERAND (value, 0);
+ }
+ value = fold (value);
+
+ if (TREE_CODE (value) != INTEGER_CST
+ && value != error_mark_node)
+ {
+ cp_error ("case label `%E' does not reduce to an integer constant",
+ value);
+ value = error_mark_node;
+ }
+ else
+ /* Promote char or short to int. */
+ value = default_conversion (value);
+
+ constant_expression_warning (value);
+
+ return value;
+}
diff --git a/gcc/cp/errfn.c b/gcc/cp/errfn.c
index 2cf2b87ff23..1b345fda9c2 100644
--- a/gcc/cp/errfn.c
+++ b/gcc/cp/errfn.c
@@ -120,7 +120,7 @@ cp_thing (errfn, atarg1, format, arglist)
if (arg >= NARGS) abort ();
- if (maybe_here && atarg)
+ if (maybe_here && atarg1)
atarg = args[arg];
/* Must use a temporary to avoid calling *function twice */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 629c70b92b1..6d2ec7fc8b8 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -198,6 +198,7 @@ dump_type (t, v)
/* fall through. */
case REAL_TYPE:
case VOID_TYPE:
+ case BOOLEAN_TYPE:
dump_readonly_or_volatile (t, after);
OB_PUTID (TYPE_IDENTIFIER (t));
break;
@@ -356,6 +357,10 @@ dump_type_prefix (t, v)
switch (TREE_CODE (sub))
{
+ case ARRAY_TYPE:
+ OB_PUTC2 (' ', '(');
+ break;
+
case POINTER_TYPE:
/* We don't want "char * &" */
if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
@@ -405,6 +410,7 @@ dump_type_prefix (t, v)
case ERROR_MARK:
case IDENTIFIER_NODE:
case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
case REAL_TYPE:
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
@@ -476,6 +482,7 @@ dump_type_suffix (t, v)
case ERROR_MARK:
case IDENTIFIER_NODE:
case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
case REAL_TYPE:
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf
index a3585341614..aa59484a305 100644
--- a/gcc/cp/gxx.gperf
+++ b/gcc/cp/gxx.gperf
@@ -28,6 +28,7 @@ __volatile__, TYPE_QUAL, RID_VOLATILE
__wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,
asm, ASM_KEYWORD, NORID,
auto, SCSPEC, RID_AUTO,
+bool, TYPESPEC, RID_BOOL,
break, BREAK, NORID,
case, CASE, NORID,
catch, CATCH, NORID,
@@ -45,6 +46,7 @@ dynamic_cast, DYNAMIC_CAST, NORID,
else, ELSE, NORID,
enum, ENUM, NORID,
extern, SCSPEC, RID_EXTERN,
+false, CXX_FALSE, NORID,
float, TYPESPEC, RID_FLOAT,
for, FOR, NORID,
friend, SCSPEC, RID_FRIEND,
@@ -76,6 +78,7 @@ switch, SWITCH, NORID,
this, THIS, NORID,
throw, THROW, NORID,
template, TEMPLATE, RID_TEMPLATE,
+true, CXX_TRUE, NORID,
try, TRY, NORID,
typedef, SCSPEC, RID_TYPEDEF,
typeof, TYPEOF, NORID,
diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h
index 0780d025d32..8453c4bec35 100644
--- a/gcc/cp/hash.h
+++ b/gcc/cp/hash.h
@@ -3,12 +3,12 @@
/* 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;};
-#define TOTAL_KEYWORDS 83
+#define TOTAL_KEYWORDS 86
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 16
#define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 170
-/* maximum key range = 167, duplicates = 0 */
+#define MAX_HASH_VALUE 171
+/* maximum key range = 168, duplicates = 0 */
#ifdef __GNUC__
inline
@@ -20,19 +20,19 @@ hash (str, len)
{
static unsigned char asso_values[] =
{
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 0, 171, 62, 5, 65,
- 27, 0, 18, 7, 10, 48, 171, 1, 30, 7,
- 79, 0, 33, 171, 18, 0, 4, 26, 13, 0,
- 1, 24, 171, 171, 171, 171, 171, 171,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 0, 172, 36, 1, 61,
+ 0, 0, 30, 44, 44, 35, 172, 7, 12, 53,
+ 40, 17, 6, 172, 28, 2, 4, 35, 31, 51,
+ 5, 7, 172, 172, 172, 172, 172, 172,
};
register int hval = len;
@@ -65,120 +65,120 @@ is_reserved_word (str, len)
{
{"",}, {"",}, {"",}, {"",},
{"else", ELSE, NORID,},
- {"",}, {"",},
+ {"",},
+ {"delete", DELETE, NORID,},
+ {"double", TYPESPEC, RID_DOUBLE,},
+ {"true", CXX_TRUE, NORID,},
{"__asm__", GCC_ASM_KEYWORD, NORID},
+ {"typeid", TYPEID, NORID,},
+ {"",},
{"this", THIS, NORID,},
- {"throw", THROW, NORID,},
+ {"",},
+ {"try", TRY, NORID,},
+ {"",}, {"",}, {"",}, {"",},
+ {"do", DO, NORID,},
+ {"",},
+ {"static_cast", STATIC_CAST, NORID,},
+ {"template", TEMPLATE, RID_TEMPLATE,},
+ {"protected", VISSPEC, RID_PROTECTED,},
+ {"",},
+ {"__classof__", CLASSOF, NORID},
+ {"",},
{"__headof__", HEADOF, NORID},
- {"goto", GOTO, NORID,},
- {"__asm", GCC_ASM_KEYWORD, NORID},
+ {"",},
+ {"bool", TYPESPEC, RID_BOOL,},
{"__const__", TYPE_QUAL, RID_CONST},
{"__volatile", TYPE_QUAL, RID_VOLATILE},
{"__const", TYPE_QUAL, RID_CONST},
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
- {"",},
- {"enum", ENUM, NORID,},
- {"static_cast", STATIC_CAST, NORID,},
- {"switch", SWITCH, NORID,},
- {"",}, {"",},
- {"sigof", SIGOF, NORID /* Extension */,},
+ {"__typeof__", TYPEOF, NORID},
+ {"void", TYPESPEC, RID_VOID,},
+ {"friend", SCSPEC, RID_FRIEND,},
+ {"false", CXX_FALSE, NORID,},
{"sizeof", SIZEOF, NORID,},
- {"",},
- {"__headof", HEADOF, NORID},
{"short", TYPESPEC, RID_SHORT,},
{"typeof", TYPEOF, NORID,},
- {"do", DO, NORID,},
- {"",},
- {"try", TRY, NORID,},
- {"",},
- {"delete", DELETE, NORID,},
- {"__typeof__", TYPEOF, NORID},
- {"while", WHILE, NORID,},
- {"struct", AGGR, RID_RECORD,},
- {"typeid", TYPEID, NORID,},
- {"double", TYPESPEC, RID_DOUBLE,},
- {"for", FOR, NORID,},
- {"",},
- {"__classof__", CLASSOF, NORID},
- {"",}, {"",},
- {"operator", OPERATOR, NORID,},
- {"",}, {"",},
- {"typedef", SCSPEC, RID_TYPEDEF,},
- {"long", TYPESPEC, RID_LONG,},
- {"template", TEMPLATE, RID_TEMPLATE,},
- {"__typeof", TYPEOF, NORID},
- {"friend", SCSPEC, RID_FRIEND,},
- {"",},
- {"private", VISSPEC, RID_PRIVATE,},
{"",},
{"int", TYPESPEC, RID_INT,},
- {"",},
- {"__classof", CLASSOF, NORID},
+ {"__signed", TYPESPEC, RID_SIGNED},
+ {"private", VISSPEC, RID_PRIVATE,},
{"__signed__", TYPESPEC, RID_SIGNED},
- {"",}, {"",},
- {"headof", HEADOF, NORID,},
- {"",},
+ {"extern", SCSPEC, RID_EXTERN,},
+ {"struct", AGGR, RID_RECORD,},
+ {"signed", TYPESPEC, RID_SIGNED,},
+ {"break", BREAK, NORID,},
{"__attribute", ATTRIBUTE, NORID},
- {"",},
+ {"default", DEFAULT, NORID,},
{"__attribute__", ATTRIBUTE, NORID},
- {"auto", SCSPEC, RID_AUTO,},
+ {"__classof", CLASSOF, NORID},
+ {"sigof", SIGOF, NORID /* Extension */,},
+ {"__headof", HEADOF, NORID},
+ {"switch", SWITCH, NORID,},
+ {"__label__", LABEL, NORID},
+ {"__extension__", EXTENSION, NORID},
+ {"",},
+ {"__asm", GCC_ASM_KEYWORD, NORID},
+ {"for", FOR, NORID,},
+ {"__typeof", TYPEOF, NORID},
+ {"__alignof__", ALIGNOF, NORID},
{"",},
- {"if", IF, NORID,},
{"case", CASE, NORID,},
+ {"virtual", SCSPEC, RID_VIRTUAL,},
+ {"if", IF, NORID,},
+ {"while", WHILE, NORID,},
+ {"",},
{"class", AGGR, RID_CLASS,},
- {"void", TYPESPEC, RID_VOID,},
- {"asm", ASM_KEYWORD, NORID,},
- {"break", BREAK, NORID,},
+ {"typedef", SCSPEC, RID_TYPEDEF,},
{"const", TYPE_QUAL, RID_CONST,},
{"static", SCSPEC, RID_STATIC,},
- {"mutable", SCSPEC, RID_MUTABLE,},
- {"protected", VISSPEC, RID_PROTECTED,},
- {"",}, {"",}, {"",}, {"",},
- {"new", NEW, NORID,},
- {"__signed", TYPESPEC, RID_SIGNED},
- {"virtual", SCSPEC, RID_VIRTUAL,},
- {"extern", SCSPEC, RID_EXTERN,},
- {"",}, {"",}, {"",},
+ {"auto", SCSPEC, RID_AUTO,},
{"float", TYPESPEC, RID_FLOAT,},
+ {"inline", SCSPEC, RID_INLINE,},
+ {"throw", THROW, NORID,},
+ {"unsigned", TYPESPEC, RID_UNSIGNED,},
+ {"",},
+ {"headof", HEADOF, NORID,},
+ {"",},
+ {"goto", GOTO, NORID,},
{"",}, {"",},
+ {"public", VISSPEC, RID_PUBLIC,},
+ {"signature", AGGR, RID_SIGNATURE /* Extension */,},
+ {"volatile", TYPE_QUAL, RID_VOLATILE,},
+ {"__inline", SCSPEC, RID_INLINE},
+ {"overload", OVERLOAD, NORID,},
+ {"__inline__", SCSPEC, RID_INLINE},
+ {"__alignof", ALIGNOF, NORID},
+ {"asm", ASM_KEYWORD, NORID,},
+ {"",},
+ {"new", NEW, NORID,},
+ {"",},
+ {"mutable", SCSPEC, RID_MUTABLE,},
+ {"union", AGGR, RID_UNION,},
+ {"operator", OPERATOR, NORID,},
{"register", SCSPEC, RID_REGISTER,},
- {"__extension__", EXTENSION, NORID},
{"",}, {"",},
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
- {"",}, {"",}, {"",}, {"",},
- {"__label__", LABEL, NORID},
- {"inline", SCSPEC, RID_INLINE,},
+ {"",},
+ {"long", TYPESPEC, RID_LONG,},
+ {"",}, {"",}, {"",},
{"continue", CONTINUE, NORID,},
- {"default", DEFAULT, NORID,},
- {"char", TYPESPEC, RID_CHAR,},
+ {"return", RETURN, NORID,},
+ {"enum", ENUM, NORID,},
{"",}, {"",},
- {"classof", CLASSOF, NORID,},
- {"unsigned", TYPESPEC, RID_UNSIGNED,},
- {"union", AGGR, RID_UNION,},
- {"",},
- {"signed", TYPESPEC, RID_SIGNED,},
- {"volatile", TYPE_QUAL, RID_VOLATILE,},
- {"signature", AGGR, RID_SIGNATURE /* Extension */,},
- {"overload", OVERLOAD, NORID,},
+ {"dynamic_cast", DYNAMIC_CAST, NORID,},
+ {"",}, {"",},
+ {"reinterpret_cast", REINTERPRET_CAST, NORID,},
{"",}, {"",}, {"",}, {"",},
- {"__alignof__", ALIGNOF, NORID},
+ {"char", TYPESPEC, RID_CHAR,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
- {"return", RETURN, NORID,},
- {"",}, {"",}, {"",}, {"",},
- {"public", VISSPEC, RID_PUBLIC,},
- {"reinterpret_cast", REINTERPRET_CAST, NORID,},
- {"__alignof", ALIGNOF, NORID},
+ {"classof", CLASSOF, NORID,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"const_cast", CONST_CAST, NORID,},
- {"catch", CATCH, NORID,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
- {"",}, {"",},
- {"__inline", SCSPEC, RID_INLINE},
- {"",},
- {"__inline__", SCSPEC, RID_INLINE},
- {"",},
- {"dynamic_cast", DYNAMIC_CAST, NORID,},
+ {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
+ {"",}, {"",}, {"",}, {"",}, {"",},
+ {"catch", CATCH, NORID,},
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 6ce92a3d0d4..186741421c2 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3566,7 +3566,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TREE_CODE (type) == POINTER_TYPE)
{
- type = TREE_TYPE (type);
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
if (TYPE_SIZE (type) == 0)
{
incomplete_type_error (0, type);
@@ -3582,6 +3582,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
}
if (TREE_SIDE_EFFECTS (addr))
addr = save_expr (addr);
+
+ /* throw away const and volatile on target type of addr */
+ addr = convert_force (build_pointer_type (type), addr);
ref = build_indirect_ref (addr, NULL_PTR);
ptr = 1;
}
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 22cf0a51cd8..595ba826667 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -577,6 +577,9 @@ init_lex ()
ridpointers[(int) RID_INT] = get_identifier ("int");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
+ ridpointers[(int) RID_BOOL] = get_identifier ("bool");
+ SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL],
+ build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL]));
ridpointers[(int) RID_CHAR] = get_identifier ("char");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
@@ -4442,9 +4445,9 @@ real_yylex ()
value = MIN_MAX;
nextchar = c1;
}
- if (pedantic)
- error ("use of `operator %s' is not standard C++",
- token_buffer);
+ if (flag_ansi)
+ pedwarn ("use of `operator %s' is not standard C++",
+ token_buffer);
goto done;
}
diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h
index f9bf3f1aea3..a9ea60efa0a 100644
--- a/gcc/cp/lex.h
+++ b/gcc/cp/lex.h
@@ -26,6 +26,7 @@ enum rid
{
RID_UNUSED,
RID_INT,
+ RID_BOOL,
RID_CHAR,
RID_WCHAR,
RID_FLOAT,
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d4ce558abb9..d0b847e8789 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -366,6 +366,11 @@ build_overload_value (type, value)
icat (TREE_INT_CST_LOW (value));
return;
}
+ case BOOLEAN_TYPE:
+ {
+ icat (TREE_INT_CST_LOW (value));
+ return;
+ }
#ifndef REAL_IS_NOT_DOUBLE
case REAL_TYPE:
{
@@ -587,10 +592,7 @@ build_overload_name (parmtypes, begin, end)
OB_PUTC ('A');
if (TYPE_DOMAIN (parmtype) == NULL_TREE)
- {
- error ("parameter type with unspecified array bounds invalid");
- icat (1);
- }
+ error ("pointer or reference to array of unknown bound in parm type");
else
{
length = array_type_nelts (parmtype);
@@ -701,6 +703,10 @@ build_overload_name (parmtypes, begin, end)
my_friendly_abort (73);
break;
+ case BOOLEAN_TYPE:
+ OB_PUTC ('b');
+ break;
+
case REAL_TYPE:
parmtype = TYPE_MAIN_VARIANT (parmtype);
if (parmtype == long_double_type_node)
@@ -1703,7 +1709,7 @@ emit_thunk (thunk_fndecl)
int delta = THUNK_DELTA (thunk_fndecl);
int tem;
int failure = 0;
- extern int current_call_is_indirect; /* Needed for (at least) HPPA. */
+ int current_call_is_indirect = 0; /* needed for HPPA FUNCTION_ARG */
/* Used to remember which regs we need to emit a USE rtx for. */
rtx need_use[FIRST_PSEUDO_REGISTER];
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index dd8a96ab5c6..30e076c6579 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -149,7 +149,7 @@ empty_parms ()
/* the reserved words... C++ extensions */
%token <ttype> AGGR
%token <itype> VISSPEC
-%token DELETE NEW OVERLOAD THIS OPERATOR
+%token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
%token LEFT_RIGHT TEMPLATE
%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
%token <itype> SCOPE
@@ -197,14 +197,15 @@ empty_parms ()
%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
%type <ttype> paren_expr_or_null nontrivial_exprlist
%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
-%type <ttype> typed_declspecs reserved_declspecs
+%type <ttype> typed_declspecs reserved_declspecs boolean.literal
%type <ttype> typed_typespecs reserved_typespecquals
%type <ttype> declmods typespec typespecqual_reserved
%type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
%type <itype> initdecls notype_initdecls initdcl /* C++ modification */
%type <ttype> init initlist maybeasm
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
-%type <ttype> maybe_attribute attribute_list attrib
+%type <ttype> maybe_attribute attributes attribute attribute_list attrib
+%type <ttype> any_word
%type <ttype> compstmt implicitly_scoped_stmt
@@ -284,7 +285,6 @@ static tree current_aggr;
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
extern void yyprint ();
extern tree combine_strings PROTO((tree));
-extern tree truthvalue_conversion PROTO((tree));
%}
%%
@@ -320,8 +320,7 @@ extdefs:
;
asm_keyword:
- ASM_KEYWORD { if (pedantic)
- pedwarn ("ANSI C++ forbids use of `asm' keyword"); }
+ ASM_KEYWORD
| GCC_ASM_KEYWORD
;
@@ -551,15 +550,6 @@ datadef:
else if (CLASSTYPE_USE_TEMPLATE (t) == 1)
error ("override declaration for already-expanded template");
}
- else if (TREE_CODE (t) == ENUMERAL_TYPE
- && !TYPE_SIZE (t))
- cp_error ("forward declaration of `%#T'", t);
- else if (TREE_CODE (t) == IDENTIFIER_NODE)
- {
- tree v = lookup_name (t, 1);
- cp_error ("abstract declarator `%T' used as declaration",
- v);
- }
}
note_list_got_semicolon ($<ttype>$);
}
@@ -1098,7 +1088,7 @@ new_initializer:
syntactically valid but semantically invalid. */
| '=' init
{
- if (pedantic || flag_ansi)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids initialization of new expression with `='");
$$ = $2;
}
@@ -1125,7 +1115,7 @@ cast_expr:
{
tree init = build_nt (CONSTRUCTOR, NULL_TREE,
nreverse ($3));
- if (pedantic)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids constructor-expressions");
/* Indicate that this was a GNU C constructor expression. */
TREE_HAS_CONSTRUCTOR (init) = 1;
@@ -1279,6 +1269,7 @@ primary:
$$ = do_identifier ($$);
}
| CONSTANT
+ | boolean.literal
| string
{ $$ = combine_strings ($$); }
| '(' expr ')'
@@ -1295,7 +1286,7 @@ primary:
$<ttype>$ = expand_start_stmt_expr (); }
compstmt ')'
{ tree rtl_exp;
- if (pedantic)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids braced-groups within expressions");
rtl_exp = expand_end_stmt_expr ($<ttype>2);
/* The statements have side effects, so the group does. */
@@ -1576,7 +1567,7 @@ primary_no_id:
}
$<ttype>$ = expand_start_stmt_expr (); }
compstmt ')'
- { if (pedantic)
+ { if (flag_ansi)
pedwarn ("ANSI C++ forbids braced-groups within expressions");
$$ = expand_end_stmt_expr ($<ttype>2); }
| primary_no_id '(' nonnull_exprlist ')'
@@ -1611,6 +1602,13 @@ delete: DELETE
{ got_scope = NULL_TREE; $$ = 1; }
;
+boolean.literal:
+ CXX_TRUE
+ { $$ = true_node; }
+ | CXX_FALSE
+ { $$ = false_node; }
+ ;
+
/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
string:
STRING
@@ -1802,11 +1800,11 @@ typespec: structsp
| complete_type_name
| TYPEOF '(' expr ')'
{ $$ = TREE_TYPE ($3);
- if (pedantic)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids `typeof'"); }
| TYPEOF '(' type_id ')'
{ $$ = groktypename ($3);
- if (pedantic)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids `typeof'"); }
| SIGOF '(' expr ')'
{ tree type = TREE_TYPE ($3);
@@ -1912,9 +1910,9 @@ initdcl:
/* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_decl ($<ttype>6, $7, $3, 0); }
| declarator maybe_raises maybeasm maybe_attribute
- { tree d = start_decl ($<ttype>1, current_declspecs, 0, $2);
+ { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2);
cplus_decl_attributes ($<ttype>$, $4);
- finish_decl (d, NULL_TREE, $3, 0); }
+ finish_decl ($<ttype>$, NULL_TREE, $3, 0); }
;
notype_initdcl0:
@@ -1958,64 +1956,53 @@ nomods_initdcl0:
/* the * rules are dummies to accept the Apollo extended syntax
so that the header files compile. */
maybe_attribute:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | attributes
+ { $$ = $1; }
+ ;
+
+attributes:
+ attribute
+ { $$ = $1; }
+ | attributes attribute
+ { $$ = chainon ($1, $2); }
+ ;
+
+attribute:
+ ATTRIBUTE '(' '(' attribute_list ')' ')'
+ { $$ = $4; }
+ ;
+
+attribute_list:
+ attrib
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | attribute_list ',' attrib
+ { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+attrib:
/* empty */
- { $$ = NULL_TREE; }
- | maybe_attribute ATTRIBUTE '(' '(' attribute_list ')' ')'
- { $$ = chainon ($5, $1); }
- ;
-
-attribute_list
- : attrib
- { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
- | attribute_list ',' attrib
- { $$ = tree_cons (NULL_TREE, $3, $1); }
- ;
-
-attrib
- : identifier
- { if (strcmp (IDENTIFIER_POINTER ($1), "packed")
- && strcmp (IDENTIFIER_POINTER ($1), "noreturn"))
- warning ("`%s' attribute directive ignored",
- IDENTIFIER_POINTER ($1));
- $$ = $1; }
- | TYPE_QUAL
- | identifier '(' expr_no_commas ')'
- { /* If not aligned(n), section(name), or mode(name),
- then issue warning */
- if (strcmp (IDENTIFIER_POINTER ($1), "section") == 0
- || strcmp (IDENTIFIER_POINTER ($1), "mode") == 0)
- {
- if (TREE_CODE ($3) != STRING_CST)
- {
- error ("invalid argument in `%s' attribute",
- IDENTIFIER_POINTER ($1));
- $$ = $1;
- }
- $$ = tree_cons ($1, $3, NULL_TREE);
- }
- else if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0)
- {
- warning ("`%s' attribute directive ignored",
- IDENTIFIER_POINTER ($1));
- $$ = $1;
- }
- else
- $$ = tree_cons ($1, $3, NULL_TREE); }
- | identifier '(' IDENTIFIER ',' expr_no_commas ',' expr_no_commas ')'
- { /* if not "format(...)", then issue warning */
- if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0)
- {
- warning ("`%s' attribute directive ignored",
- IDENTIFIER_POINTER ($1));
- $$ = $1;
- }
- else
- $$ = tree_cons ($1,
- tree_cons ($3,
- tree_cons ($5, $7, NULL_TREE),
- NULL_TREE),
- NULL_TREE); }
- ;
+ { $$ = NULL_TREE; }
+ | any_word
+ { $$ = $1; }
+ | any_word '(' IDENTIFIER ')'
+ { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); }
+ | any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
+ { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); }
+ | any_word '(' nonnull_exprlist ')'
+ { $$ = tree_cons ($1, NULL_TREE, $3); }
+ ;
+
+/* This still leaves out most reserved keywords,
+ shouldn't we include them? */
+
+any_word:
+ identifier
+ | SCSPEC
+ | TYPESPEC
+ | TYPE_QUAL
+ ;
/* A nonempty list of identifiers, including typenames. */
identifiers_or_typenames:
@@ -2663,7 +2650,7 @@ new_type_id:
non-constant dimension. */
| '(' type_id ')' '[' expr ']'
{
- if (pedantic || flag_ansi)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
$$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5);
$$ = build_decl_list (TREE_PURPOSE ($2), $$);
@@ -3003,7 +2990,7 @@ errstmt: error ';'
maybe_label_decls:
/* empty */
| label_decls
- { if (pedantic)
+ { if (flag_ansi)
pedwarn ("ANSI C++ forbids label declarations"); }
;
@@ -3040,6 +3027,10 @@ compstmt: '{' .pushlevel '}'
{ expand_end_bindings (getdecls (), kept_level_p(), 1);
$$ = poplevel (kept_level_p (), 1, 0);
pop_momentary (); }
+ | '{' .pushlevel maybe_label_decls stmts error '}'
+ { expand_end_bindings (getdecls (), kept_level_p(), 1);
+ $$ = poplevel (kept_level_p (), 0, 0);
+ pop_momentary (); }
| '{' .pushlevel maybe_label_decls error '}'
{ expand_end_bindings (getdecls (), kept_level_p(), 1);
$$ = poplevel (kept_level_p (), 0, 0);
@@ -3051,7 +3042,7 @@ simple_if:
{ cond_stmt_keyword = "if"; }
.pushlevel paren_cond_or_null
{ emit_line_note (input_filename, lineno);
- expand_start_cond (truthvalue_conversion ($4), 0); }
+ expand_start_cond (bool_truthvalue_conversion ($4), 0); }
implicitly_scoped_stmt
;
@@ -3059,7 +3050,7 @@ implicitly_scoped_stmt:
compstmt
{ finish_stmt (); }
| .pushlevel simple_stmt
- { expand_end_bindings (getdecls (), getdecls() != NULL_TREE, 1);
+ { expand_end_bindings (getdecls (), kept_level_p (), 1);
$$ = poplevel (kept_level_p (), 1, 0);
pop_momentary (); }
;
@@ -3106,7 +3097,7 @@ simple_stmt:
expand_start_loop (1);
cond_stmt_keyword = "while"; }
.pushlevel paren_cond_or_null
- { expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
+ { expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
already_scoped_stmt
{ expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0);
@@ -3122,7 +3113,7 @@ simple_stmt:
cond_stmt_keyword = "do"; }
paren_expr_or_null ';'
{ emit_line_note (input_filename, lineno);
- expand_exit_loop_if_false (0, truthvalue_conversion ($6));
+ expand_exit_loop_if_false (0, bool_truthvalue_conversion ($6));
expand_end_loop ();
clear_momentary ();
finish_stmt (); }
@@ -3133,7 +3124,7 @@ simple_stmt:
expand_start_loop_continue_elsewhere (1); }
.pushlevel xcond ';'
{ emit_line_note (input_filename, lineno);
- if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
+ if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
xexpr ')'
/* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */
@@ -3154,7 +3145,7 @@ simple_stmt:
expand_start_loop_continue_elsewhere (1); }
.pushlevel xcond ';'
{ emit_line_note (input_filename, lineno);
- if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
+ if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
xexpr ')'
/* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */
@@ -3185,36 +3176,10 @@ simple_stmt:
pop_momentary ();
finish_stmt (); }
| CASE expr_no_commas ':'
- { register tree value = $2;
+ { register tree value = check_cp_case_value ($2);
register tree label
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
- Strip such NOP_EXPRs. */
- if (TREE_CODE (value) == NOP_EXPR
- && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
- value = TREE_OPERAND (value, 0);
-
- if (TREE_READONLY_DECL_P (value))
- {
- value = decl_constant_value (value);
- /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
- Strip such NOP_EXPRs. */
- if (TREE_CODE (value) == NOP_EXPR
- && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
- value = TREE_OPERAND (value, 0);
- }
- value = fold (value);
-
- if (TREE_CODE (value) != INTEGER_CST
- && value != error_mark_node)
- {
- cp_error ("case label `%E' does not reduce to an integer constant", $2);
- value = error_mark_node;
- }
- else
- /* Promote char or short to int. */
- value = default_conversion (value);
if (value != error_mark_node)
{
tree duplicate;
@@ -3236,61 +3201,13 @@ simple_stmt:
}
stmt
| CASE expr_no_commas RANGE expr_no_commas ':'
- { register tree value1 = $2;
- register tree value2 = $4;
+ { register tree value1 = check_cp_case_value ($2);
+ register tree value2 = check_cp_case_value ($4);
register tree label
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- if (pedantic)
+ if (flag_ansi)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
-
- /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
- Strip such NOP_EXPRs. */
- if (TREE_CODE (value1) == NOP_EXPR
- && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
- value1 = TREE_OPERAND (value1, 0);
-
- if (TREE_READONLY_DECL_P (value1))
- {
- value1 = decl_constant_value (value1);
- /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
- Strip such NOP_EXPRs. */
- if (TREE_CODE (value1) == NOP_EXPR
- && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
- value1 = TREE_OPERAND (value1, 0);
- }
- value1 = fold (value1);
-
- /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
- Strip such NOP_EXPRs. */
- if (TREE_CODE (value2) == NOP_EXPR
- && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
- value2 = TREE_OPERAND (value2, 0);
-
- if (TREE_READONLY_DECL_P (value2))
- {
- value2 = decl_constant_value (value2);
- /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
- Strip such NOP_EXPRs. */
- if (TREE_CODE (value2) == NOP_EXPR
- && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
- value2 = TREE_OPERAND (value2, 0);
- }
- value2 = fold (value2);
-
-
- if (TREE_CODE (value1) != INTEGER_CST
- && value1 != error_mark_node)
- {
- error ("case label does not reduce to an integer constant");
- value1 = error_mark_node;
- }
- if (TREE_CODE (value2) != INTEGER_CST
- && value2 != error_mark_node)
- {
- error ("case label does not reduce to an integer constant");
- value2 = error_mark_node;
- }
if (value1 != error_mark_node
&& value2 != error_mark_node)
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 528bbdd34dc..997941c5a02 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -782,6 +782,7 @@ uses_template_parms (t)
case REAL_TYPE:
case VOID_TYPE:
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
return 0;
/* constants */
@@ -1142,6 +1143,7 @@ tsubst (t, args, nargs, in_decl)
case VOID_TYPE:
case REAL_TYPE:
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
@@ -1351,6 +1353,11 @@ tsubst (t, args, nargs, in_decl)
DECL_CONTEXT (t) != NULL_TREE);
r = build_lang_decl (FUNCTION_DECL, r, type);
}
+ else if (DECL_INLINE (r) && DECL_SAVED_INSNS (r))
+ {
+ /* This overrides the template version, use it. */
+ return r;
+ }
}
}
TREE_PUBLIC (r) = TREE_PUBLIC (t);
@@ -1638,8 +1645,10 @@ instantiate_template (tmpl, targ_ptr)
DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
}
+ /* If we have a preexisting version of this function, don't expand
+ the template version, use the other instead. */
t = DECL_TEMPLATE_INFO (tmpl);
- if (t->text)
+ if (t->text && !(DECL_INLINE (fndecl) && DECL_SAVED_INSNS (fndecl)))
{
p = (struct pending_inline *) permalloc (sizeof (struct pending_inline));
p->parm_vec = t->parm_vec;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index c81f1e1488d..ea7de8f9f6f 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2426,7 +2426,7 @@ dfs_init_vbase_pointers (binfo)
this_vbase_ptr = vbase_decl_ptr_intermediate;
- if (TYPE_POINTER_TO (type) != TREE_TYPE (this_vbase_ptr))
+ if (TYPE_POINTER_TO (type) != TYPE_MAIN_VARIANT (TREE_TYPE (this_vbase_ptr)))
my_friendly_abort (125);
while (fields && DECL_NAME (fields)
@@ -2525,9 +2525,30 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
if (use_computed_offsets)
addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
else
- addr = convert_pointer_to_real (vbases, vbase_decl_ptr);
- if (addr == error_mark_node)
- continue;
+ {
+ tree vbinfo = get_binfo (TREE_TYPE (vbases),
+ TREE_TYPE (vbase_decl),
+ 0);
+
+ /* See is we can get lucky. */
+ if (TREE_VIA_VIRTUAL (vbinfo))
+ addr = convert_pointer_to_real (vbinfo, vbase_decl_ptr);
+ else
+ {
+ /* We go through all these contortions to avoid this
+ call, as it will fail when the virtual base type
+ is ambiguous from here. We don't yet have a way
+ to search for and find just an instance of the
+ virtual base class. Searching for the binfo in
+ vbases won't work, as we don't have the vbase
+ pointer field, for all vbases in the main class,
+ only direct vbases. */
+ addr = convert_pointer_to_real (TREE_TYPE (vbases),
+ vbase_decl_ptr);
+ if (addr == error_mark_node)
+ continue;
+ }
+ }
/* Do all vtables from this virtual base. */
/* This assumes that virtual bases can never serve as parent
@@ -2877,12 +2898,16 @@ dfs_pushdecls (binfo)
{
/* Only complain if we shadow something we can access. */
if (old
+ && warn_shadow
&& ((DECL_LANG_SPECIFIC (old)
&& DECL_CLASS_CONTEXT (old) == current_class_type)
|| ! TREE_PRIVATE (old)))
/* Should figure out access control more accurately. */
- cp_warning ("shadowing member `%#D' with member function `%#D'",
- old, *methods);
+ {
+ cp_warning_at ("member `%#D' is shadowed", old);
+ cp_warning_at ("by member function `%#D'", *methods);
+ warning ("in this context");
+ }
tmp = build_tree_list (DECL_NAME (*methods), *methods);
}
pop_obstacks ();
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d8df8e48df8..b4712a6ac4d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -94,6 +94,9 @@ lvalue_p (ref)
return (lvalue_p (TREE_OPERAND (ref, 1))
&& lvalue_p (TREE_OPERAND (ref, 2)));
+ case MODIFY_EXPR:
+ return 1;
+
case COMPOUND_EXPR:
return lvalue_p (TREE_OPERAND (ref, 1));
}
@@ -111,7 +114,7 @@ lvalue_or_else (ref, string)
{
int win = lvalue_p (ref);
if (! win)
- error ("invalid lvalue in %s", string);
+ error ("non-lvalue in %s", string);
return win;
}
@@ -305,13 +308,7 @@ build_cplus_method_type (basetype, rettype, argtypes)
else
{
ptype = build_pointer_type (basetype);
-#if 0
- /* it is wrong to flag the object the pointer points to as readonly
- when flag_this_is_variable is 0. */
- ptype = build_type_variant (ptype, flag_this_is_variable <= 0, 0);
-#else
- ptype = build_type_variant (ptype, 0, 0);
-#endif
+ ptype = build_type_variant (ptype, 1, 0);
}
/* The actual arglist for this function includes a "hidden" argument
which is "this". Put it into the list of argument types. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 490d9988f07..f2b375bf40f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -47,7 +47,6 @@ static tree pointer_int_sum ();
static tree pointer_diff ();
static tree convert_sequence ();
/* static */ tree unary_complex_lvalue ();
-tree truthvalue_conversion ();
extern rtx original_result_rtx;
@@ -258,6 +257,7 @@ common_type (t1, t2)
{
register enum tree_code code1;
register enum tree_code code2;
+ tree attributes;
/* Save time if the two types are the same. */
@@ -269,6 +269,40 @@ common_type (t1, t2)
if (t2 == error_mark_node)
return t1;
+ /* Merge the attributes */
+
+ { register tree a1, a2;
+ a1 = TYPE_ATTRIBUTES (t1);
+ a2 = TYPE_ATTRIBUTES (t2);
+
+ /* Either one unset? Take the set one. */
+
+ if (!(attributes = a1))
+ attributes = a2;
+
+ /* One that completely contains the other? Take it. */
+
+ else if (a2 && !attribute_list_contained (a1, a2))
+ if (attribute_list_contained (a2, a1))
+ attributes = a2;
+ else
+ {
+ /* Pick the longest list, and hang on the other
+ list. */
+
+ if (list_length (a1) < list_length (a2))
+ attributes = a2, a2 = a1;
+
+ for (; a2; a2 = TREE_CHAIN (a2))
+ if (!value_member (attributes, a2))
+ {
+ a1 = copy_node (a2);
+ TREE_CHAIN (a1) = attributes;
+ attributes = a1;
+ }
+ }
+ }
+
/* Treat an enum type as the unsigned integer type of the same width. */
if (TREE_CODE (t1) == ENUMERAL_TYPE)
@@ -286,23 +320,24 @@ common_type (t1, t2)
/* If only one is real, use it as the result. */
if (code1 == REAL_TYPE && code2 != REAL_TYPE)
- return t1;
+ return build_type_attribute_variant (t1, attributes);
if (code2 == REAL_TYPE && code1 != REAL_TYPE)
- return t2;
+ return build_type_attribute_variant (t2, attributes);
/* Both real or both integers; use the one with greater precision. */
if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
- return t1;
+ return build_type_attribute_variant (t1, attributes);
else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
- return t2;
+ return build_type_attribute_variant (t2, attributes);
/* Same precision. Prefer longs to ints even when same size. */
-
+
if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
|| TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
- return long_unsigned_type_node;
+ return build_type_attribute_variant (long_unsigned_type_node,
+ attributes);
if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
|| TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
@@ -310,15 +345,18 @@ common_type (t1, t2)
/* But preserve unsignedness from the other type,
since long cannot hold all the values of an unsigned int. */
if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
- return long_unsigned_type_node;
- return long_integer_type_node;
+ t1 = long_unsigned_type_node;
+ else
+ t1 = long_integer_type_node;
+ return build_type_attribute_variant (t1, attributes);
}
/* Otherwise prefer the unsigned one. */
if (TREE_UNSIGNED (t1))
- return t1;
- else return t2;
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return build_type_attribute_variant (t2, attributes);
case POINTER_TYPE:
case REFERENCE_TYPE:
@@ -336,16 +374,19 @@ common_type (t1, t2)
= TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
target = build_type_variant (target, constp, volatilep);
if (code1 == POINTER_TYPE)
- return build_pointer_type (target);
+ t1 = build_pointer_type (target);
else
- return build_reference_type (target);
+ t1 = build_reference_type (target);
+ return build_type_attribute_variant (t1, attributes);
}
#if 0
case POINTER_TYPE:
- return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+ t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+ return build_type_attribute_variant (t1, attributes);
case REFERENCE_TYPE:
- return build_reference_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+ t1 = build_reference_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+ return build_type_attribute_variant (t1, attributes);
#endif
case ARRAY_TYPE:
@@ -353,11 +394,12 @@ common_type (t1, t2)
tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
/* Save space: see if the result is identical to one of the args. */
if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
- return t1;
+ return build_type_attribute_variant (t1, attributes);
if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
- return t2;
+ return build_type_attribute_variant (t2, attributes);
/* Merge the element types, and have a size if either arg has one. */
- return build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+ t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+ return build_type_attribute_variant (t1, attributes);
}
case FUNCTION_TYPE:
@@ -371,9 +413,9 @@ common_type (t1, t2)
/* Save space: see if the result is identical to one of the args. */
if (valtype == TREE_TYPE (t1) && ! p2)
- return t1;
+ return build_type_attribute_variant (t1, attributes);
if (valtype == TREE_TYPE (t2) && ! p1)
- return t2;
+ return build_type_attribute_variant (t2, attributes);
/* Simple way if one arg fails to specify argument types. */
if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
@@ -381,7 +423,7 @@ common_type (t1, t2)
rval = build_function_type (valtype, p2);
if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
rval = build_exception_variant (NULL_TREE, rval, raises);
- return rval;
+ return build_type_attribute_variant (rval, attributes);
}
raises = TYPE_RAISES_EXCEPTIONS (t1);
if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
@@ -389,11 +431,12 @@ common_type (t1, t2)
rval = build_function_type (valtype, p1);
if (raises)
rval = build_exception_variant (NULL_TREE, rval, raises);
- return rval;
+ return build_type_attribute_variant (rval, attributes);
}
rval = build_function_type (valtype, commonparms (p1, p2));
- return build_exception_variant (NULL_TREE, rval, raises);
+ rval = build_exception_variant (NULL_TREE, rval, raises);
+ return build_type_attribute_variant (rval, attributes);
}
case RECORD_TYPE:
@@ -401,10 +444,9 @@ common_type (t1, t2)
my_friendly_assert (TYPE_MAIN_VARIANT (t1) == t1
&& TYPE_MAIN_VARIANT (t2) == t2, 306);
- if (binfo_or_else (t1, t2))
- return t1;
- compiler_error ("common_type called with uncommon aggregate types");
- return t1;
+ if (! binfo_or_else (t1, t2))
+ compiler_error ("common_type called with uncommon aggregate types");
+ return build_type_attribute_variant (t1, attributes);
case METHOD_TYPE:
if (comptypes (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2), 1)
@@ -424,24 +466,28 @@ common_type (t1, t2)
t2 = build_function_type (TREE_TYPE (t2), TREE_CHAIN (TYPE_ARG_TYPES (t2)));
t3 = common_type (t1, t2);
t3 = build_cplus_method_type (basetype, TREE_TYPE (t3), TYPE_ARG_TYPES (t3));
- return build_exception_variant (basetype, t3, raises);
+ t1 = build_exception_variant (basetype, t3, raises);
}
- compiler_error ("common_type called with uncommon method types");
- return t1;
+ else
+ compiler_error ("common_type called with uncommon method types");
+
+ return build_type_attribute_variant (t1, attributes);
case OFFSET_TYPE:
if (TYPE_OFFSET_BASETYPE (t1) == TYPE_OFFSET_BASETYPE (t2)
&& TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
{
tree basetype = TYPE_OFFSET_BASETYPE (t1);
- return build_offset_type (basetype,
+ t1 = build_offset_type (basetype,
common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
}
- compiler_error ("common_type called with uncommon member types");
- return t1;
+ else
+ compiler_error ("common_type called with uncommon member types");
+
+ /* ... falls through ... */
default:
- return t1;
+ return build_type_attribute_variant (t1, attributes);
}
}
@@ -514,6 +560,7 @@ comptypes (type1, type2, strict)
{
register tree t1 = type1;
register tree t2 = type2;
+ int attrval, val;
/* Suppress errors caused by previously reported errors */
@@ -571,20 +618,30 @@ comptypes (type1, type2, strict)
if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return 1;
+#ifdef COMP_TYPE_ATTRIBUTES
+ if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))
+ return 0;
+#else
+ /* 1 if no need for warning yet, 2 if warning cause has been seen. */
+ attrval = 1;
+#endif
+
+ /* 1 if no need for warning yet, 2 if warning cause has been seen. */
+ val = 0;
+
switch (TREE_CODE (t1))
{
case RECORD_TYPE:
case UNION_TYPE:
- if (t1 == t2)
- return 1;
if (strict <= 0)
goto look_hard;
return 0;
case OFFSET_TYPE:
- return (comptypes (TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t1)),
+ val = (comptypes (TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t1)),
TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t2)), strict)
&& comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));
+ break;
case METHOD_TYPE:
if (! compexcepttypes (t1, t2, strict))
@@ -595,17 +652,22 @@ comptypes (type1, type2, strict)
to something expecting a derived member (or member function),
but not vice-versa! */
- return (comptypes (TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t2)),
+ val = (comptypes (TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t2)),
TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t1)), strict)
&& comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)
&& compparms (TREE_CHAIN (TYPE_ARG_TYPES (t1)),
TREE_CHAIN (TYPE_ARG_TYPES (t2)), strict));
+ break;
+
case POINTER_TYPE:
case REFERENCE_TYPE:
t1 = TREE_TYPE (t1);
t2 = TREE_TYPE (t2);
if (t1 == t2)
- return 1;
+ {
+ val = 1;
+ break;
+ }
if (strict <= 0)
{
if (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE)
@@ -615,26 +677,35 @@ comptypes (type1, type2, strict)
rval = t1 == t2 || UNIQUELY_DERIVED_FROM_P (t1, t2);
if (rval)
- return 1;
+ {
+ val = 1;
+ break;
+ }
if (strict < 0)
- return UNIQUELY_DERIVED_FROM_P (t2, t1);
+ {
+ val = UNIQUELY_DERIVED_FROM_P (t2, t1);
+ break;
+ }
}
return 0;
}
else
- return comptypes (t1, t2, strict);
+ val = comptypes (t1, t2, strict);
+ break;
case FUNCTION_TYPE:
if (! compexcepttypes (t1, t2, strict))
return 0;
- return ((TREE_TYPE (t1) == TREE_TYPE (t2)
- || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
- && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));
+ val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
+ || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
+ && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));
+ break;
case ARRAY_TYPE:
/* Target types must match incl. qualifiers. */
- return comp_array_types (comptypes, t1, t2, strict);
+ val = comp_array_types (comptypes, t1, t2, strict);
+ break;
case TEMPLATE_TYPE_PARM:
return 1;
@@ -642,7 +713,7 @@ comptypes (type1, type2, strict)
case UNINSTANTIATED_P_TYPE:
return UPT_TEMPLATE (t1) == UPT_TEMPLATE (t2);
}
- return 0;
+ return attrval == 2 && val == 1 ? 2 : val;
}
/* Return 1 if TTL and TTR are pointers to types that are equivalent,
@@ -683,7 +754,8 @@ comp_target_types (ttl, ttr, nptrs)
case 1:
return 1;
case 2:
- warning ("contravariance violation for method types ignored");
+ cp_pedwarn ("converting `%T' to `%T' is a contravariance violation",
+ ttr, ttl);
return 1;
default:
my_friendly_abort (112);
@@ -702,7 +774,8 @@ comp_target_types (ttl, ttr, nptrs)
else if (comptypes (TYPE_OFFSET_BASETYPE (ttl), TYPE_OFFSET_BASETYPE (ttr), 0)
&& comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs))
{
- warning ("contravariance violation for member types ignored");
+ cp_pedwarn ("converting `%T' to `%T' is a contravariance violation",
+ ttr, ttl);
return 1;
}
}
@@ -1224,7 +1297,7 @@ default_conversion (exp)
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */
- if (code == ENUMERAL_TYPE || code == INTEGER_TYPE)
+ if (INTEGRAL_CODE_P (code))
{
tree t = type_promotes_to (type);
if (t != TYPE_MAIN_VARIANT (type))
@@ -2656,14 +2729,21 @@ build_binary_op (code, arg1, arg2, convert_p)
tree types[2], try;
types[0] = type1; types[1] = type2;
- try = build_type_conversion (code, types[convert_index ^ 1],
- args[convert_index], 1);
-
- if (try == 0
- && args[1] == integer_zero_node
- && (code == NE_EXPR || code == EQ_EXPR))
- try = build_type_conversion (code, ptr_type_node,
+ if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
+ try = build_type_conversion (code, bool_type_node,
args[convert_index], 1);
+ else
+ {
+ try = build_type_conversion (code, types[convert_index ^ 1],
+ args[convert_index], 1);
+
+ if (try == 0
+ && args[1] == integer_zero_node
+ && (code == NE_EXPR || code == EQ_EXPR))
+ try = build_type_conversion (code, ptr_type_node,
+ args[convert_index], 1);
+ }
+
if (try == 0)
{
cp_error ("no match for `%O(%#T, %#T)'", code,
@@ -2875,17 +2955,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
- if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE || code0 == REAL_TYPE)
- && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE || code1 == REAL_TYPE))
- {
- /* Result of these operations is always an int,
- but that does not mean the operands should be
- converted to ints! */
- result_type = integer_type_node;
- op0 = truthvalue_conversion (op0);
- op1 = truthvalue_conversion (op1);
- converted = 1;
- }
+ result_type = bool_type_node;
+ op0 = bool_truthvalue_conversion (op0);
+ op1 = bool_truthvalue_conversion (op1);
+ converted = 1;
break;
/* Shift operations: result has same type as first operand;
@@ -2966,9 +3039,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
case EQ_EXPR:
case NE_EXPR:
- /* Result of comparison is always int,
- but don't convert the args to int! */
- result_type = integer_type_node;
+ result_type = bool_type_node;
converted = 1;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
@@ -2984,10 +3055,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
{
tree base = common_base_type (tt0, tt1);
if (base == NULL_TREE)
- warning ("comparison of distinct object pointer types");
+ cp_warning ("comparison of distinct object pointer types `%T' and `%T'", type0, type1);
else if (base == error_mark_node)
{
- message_2_types (error, "comparison of pointer types `%s*' and `%s*' requires conversion to ambiguous supertype", tt0, tt1);
+ cp_error ("comparison of pointer types `%T' and `%T' requires conversion to ambiguous supertype", type0, type1);
return error_mark_node;
}
else
@@ -3017,9 +3088,13 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
}
else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0))
- pedwarn ("comparison of complete and incomplete pointers");
+ cp_pedwarn ("comparison of %scomplete and %scomplete pointers `%T' and `%T'",
+ TYPE_SIZE (tt0) == 0 ? "in" : "",
+ TYPE_SIZE (tt1) == 0 ? "in" : "",
+ type0, type1);
else
- pedwarn ("comparison of distinct pointer types lacks a cast");
+ cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
+ type0, type1);
}
else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
&& integer_zerop (op1))
@@ -3137,10 +3212,14 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
if (! comp_target_types (type0, type1, 1))
- pedwarn ("comparison of distinct pointer types lacks a cast");
+ cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
+ type0, type1);
else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
!= (TYPE_SIZE (TREE_TYPE (type1)) != 0))
- pedwarn ("comparison of complete and incomplete pointers");
+ cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
+ TYPE_SIZE (TREE_TYPE (type0)) == 0 ? "in" : "",
+ TYPE_SIZE (TREE_TYPE (type1)) == 0 ? "in" : "",
+ type0, type1);
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
@@ -3158,19 +3237,21 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
if (! comp_target_types (type0, type1, 1))
- pedwarn ("comparison of distinct pointer types lacks a cast");
+ cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
+ type0, type1);
else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
!= (TYPE_SIZE (TREE_TYPE (type1)) != 0))
- pedwarn ("comparison of complete and incomplete pointers");
+ cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
+ TYPE_SIZE (TREE_TYPE (type0)) == 0 ? "in" : "",
+ TYPE_SIZE (TREE_TYPE (type1)) == 0 ? "in" : "",
+ type0, type1);
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
- result_type = integer_type_node;
}
else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
&& integer_zerop (op1))
{
- result_type = integer_type_node;
op1 = null_pointer_node;
if (pedantic)
pedwarn ("ordered comparison of pointer with integer zero");
@@ -3178,14 +3259,12 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
&& integer_zerop (op0))
{
- result_type = integer_type_node;
op0 = null_pointer_node;
if (pedantic)
pedwarn ("ANSI C++ forbids ordered comparison of pointer with integer zero");
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
- result_type = integer_type_node;
if (pedantic)
pedwarn ("ANSI C++ forbids comparison between pointer and integer");
else if (! flag_traditional)
@@ -3194,13 +3273,13 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
- result_type = integer_type_node;
if (pedantic)
pedwarn ("ANSI C++ forbids comparison between pointer and integer");
else if (! flag_traditional)
warning ("comparison between pointer and integer");
op0 = convert (TREE_TYPE (op1), op0);
}
+ result_type = bool_type_node;
converted = 1;
break;
}
@@ -3332,8 +3411,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
tree val
= shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
if (val != 0)
- return val;
- op0 = xop0, op1 = xop1, result_type = xresult_type;
+ return convert (bool_type_node, val);
+ op0 = xop0, op1 = xop1, result_type = bool_type_node;
resultcode = xresultcode;
}
@@ -3659,6 +3738,17 @@ build_x_unary_op (code, xarg)
return build_unary_op (code, xarg, 0);
}
+/* Just like truthvalue_conversion, but we want a BOOLEAN_TYPE */
+tree
+bool_truthvalue_conversion (expr)
+ tree expr;
+{
+ /* We really want to preform the optimizations in truthvalue_conversion
+ but, not this way. */
+ /* expr = truthvalue_conversion (expr); */
+ return convert (bool_type_node, expr);
+}
+
/* C++: Must handle pointers to members.
Perhaps type instantiation should be extended to handle conversion
@@ -3771,23 +3861,11 @@ build_unary_op (code, xarg, noconvert)
break;
case TRUTH_NOT_EXPR:
- if (isaggrtype)
- {
- arg = truthvalue_conversion (arg);
- typecode = TREE_CODE (TREE_TYPE (arg));
- }
-
- if (typecode != INTEGER_TYPE
- && typecode != REAL_TYPE && typecode != POINTER_TYPE
- /* These will convert to a pointer. */
- && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
- {
- errstring = "wrong type argument to unary exclamation mark";
- break;
- }
- arg = truthvalue_conversion (arg);
+ arg = bool_truthvalue_conversion (arg);
val = invert_truthvalue (arg);
- if (val) return val;
+ if (arg != error_mark_node)
+ return val;
+ errstring = "in argument to unary !";
break;
case NOP_EXPR:
@@ -4426,7 +4504,7 @@ build_conditional_expr (ifexp, op1, op2)
ifexp = op1 = save_expr (ifexp);
}
- ifexp = truthvalue_conversion (default_conversion (ifexp));
+ ifexp = bool_truthvalue_conversion (default_conversion (ifexp));
if (TREE_CODE (ifexp) == ERROR_MARK)
return error_mark_node;
@@ -4841,21 +4919,7 @@ build_c_cast (type, expr)
if (TREE_TYPE (value)
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
- {
- /* For C++, we must copy the constness of TYPE into VALUE. */
- if (TREE_READONLY (value) != TYPE_READONLY (type))
- {
- value = copy_node (value);
- TREE_READONLY (value) = TYPE_READONLY (type);
- }
- else if (pedantic)
- {
- if (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
- pedwarn ("ANSI C++ forbids casting nonscalar to the same type");
- }
- return value;
- }
+ return build1 (NOP_EXPR, type, value);
/* If there's only one function in the overloaded space,
just take it. */
@@ -5262,12 +5326,6 @@ build_modify_expr (lhs, modifycode, rhs)
if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
return error_mark_node;
- /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
- Strip such NOP_EXPRs, since RHS is being used in non-lvalue context. */
- if (TREE_CODE (rhs) == NOP_EXPR
- && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0)))
- rhs = TREE_OPERAND (rhs, 0);
-
/* Decide early if we are going to protect RHS from GC
before assigning it to LHS. */
if (type_needs_gc_entry (TREE_TYPE (rhs))
@@ -5432,6 +5490,7 @@ build_modify_expr (lhs, modifycode, rhs)
newrhs = build_binary_op (modifycode, lhs, rhs, 1);
}
+#if 0
/* Handle a cast used as an "lvalue".
We have already performed any binary operator using the value as cast.
Now convert the result to the cast type of the lhs,
@@ -5464,6 +5523,7 @@ build_modify_expr (lhs, modifycode, rhs)
return convert_force (TREE_TYPE (lhs), result);
}
}
+#endif
if (TREE_CODE (lhs) == OFFSET_REF)
{
@@ -5521,16 +5581,10 @@ build_modify_expr (lhs, modifycode, rhs)
/* check to see if there is an assignment to `this' */
if (lhs == current_class_decl)
{
- if (DECL_NAME (current_function_decl) != NULL_TREE)
- {
- /* ARM 18.3.3 and draft standard section C.11 say that assigning
- something to this is an anachronism. */
- if (pedantic)
- warning ("anachronistic assignment to `this' pointer");
- else if (flag_this_is_variable > 0
- && current_class_name != DECL_NAME (current_function_decl))
- warning ("assignment to `this' not in constructor or destructor");
- }
+ if (flag_this_is_variable > 0
+ && DECL_NAME (current_function_decl) != NULL_TREE
+ && current_class_name != DECL_NAME (current_function_decl))
+ warning ("assignment to `this' not in constructor or destructor");
current_function_just_assigned_this = 1;
}
@@ -6151,8 +6205,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
return error_mark_node;
}
/* Arithmetic types all interconvert. */
- if ((codel == INTEGER_TYPE || codel == REAL_TYPE)
- && (coder == INTEGER_TYPE || coder == REAL_TYPE))
+ if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE)
+ && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE))
{
/* But we should warn if assigning REAL_TYPE to INTEGER_TYPE. */
if (coder == REAL_TYPE && codel == INTEGER_TYPE)
@@ -6165,7 +6219,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
/* And we should warn if assigning a negative value to
an unsigned variable. */
- else if (TREE_UNSIGNED (type))
+ else if (TREE_UNSIGNED (type) && codel != BOOLEAN_TYPE)
{
if (TREE_CODE (rhs) == INTEGER_CST
&& TREE_NEGATED_INT (rhs))
@@ -6268,12 +6322,14 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (TYPE_MAIN_VARIANT (ttl) != void_type_node
&& TYPE_MAIN_VARIANT (ttr) == void_type_node
&& rhs != null_pointer_node)
- if (coder == RECORD_TYPE)
- pedwarn ("implicit conversion of signature pointer to type `%s'",
- type_as_string (type, 0));
- else
- pedwarn ("ANSI C++ forbids implicit conversion from `void *' in %s",
- errtype);
+ {
+ if (coder == RECORD_TYPE)
+ pedwarn ("implicit conversion of signature pointer to type `%s'",
+ type_as_string (type, 0));
+ else
+ pedwarn ("ANSI C++ forbids implicit conversion from `void *' in %s",
+ errtype);
+ }
/* Const and volatile mean something different for function types,
so the usual warnings are not appropriate. */
else if ((TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttr) != METHOD_TYPE)
@@ -6286,7 +6342,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
sorry ("%s between pointer to members converting across virtual baseclasses", errtype);
return error_mark_node;
}
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
+ else if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
{
if (fndecl)
cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
@@ -6295,7 +6351,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
cp_pedwarn ("%s to `%T' from `%T' discards const",
errtype, type, rhstype);
}
- if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+ else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{
if (fndecl)
cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
@@ -6304,6 +6360,16 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
cp_pedwarn ("%s to `%T' from `%T' discards volatile",
errtype, type, rhstype);
}
+ else if (TREE_CODE (ttl) == TREE_CODE (ttr)
+ && ! comp_target_types (type, rhstype, 1))
+ {
+ if (fndecl)
+ cp_pedwarn ("passing `%T' as argument %P of `%D' changes signedness",
+ rhstype, parmnum, fndecl);
+ else
+ cp_pedwarn ("%s to `%T' from `%T' changes signedness",
+ errtype, type, rhstype);
+ }
}
}
else if (TREE_CODE (ttr) == OFFSET_TYPE
@@ -6570,8 +6636,24 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
return here before checking if RHS is of complete type. */
if (codel == REFERENCE_TYPE)
- return convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
- exp ? exp : error_mark_node);
+ {
+ /* This should eventually happen in convert_arguments. */
+ extern int warningcount, errorcount;
+ int savew, savee;
+
+ if (fndecl)
+ savew = warningcount, savee = errorcount;
+ rhs = convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
+ exp ? exp : error_mark_node);
+ if (fndecl)
+ {
+ if (warningcount > savew)
+ cp_warning_at ("in passing argument %P of `%+D'", parmnum, fndecl);
+ else if (errorcount > savee)
+ cp_error_at ("in passing argument %P of `%+D'", parmnum, fndecl);
+ }
+ return rhs;
+ }
rhs = require_complete_type (rhs);
if (rhs == error_mark_node)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 858896a4f11..baf55a41b9f 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -766,6 +766,7 @@ digest_init (type, init, tail)
if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
|| code == ENUMERAL_TYPE || code == REFERENCE_TYPE
+ || code == BOOLEAN_TYPE
|| (code == RECORD_TYPE && ! raw_constructor
&& (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))))
{
@@ -951,13 +952,7 @@ process_init_constructor (type, init, elts)
continue;
}
- if (TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TYPE_DECL)
- continue;
-
- /* A static member isn't considered "part of the object", so
- it has no business even thinking about involving itself in
- what an initializer-list is trying to do. */
- if (TREE_CODE (field) == VAR_DECL && TREE_STATIC (field))
+ if (TREE_CODE (field) != FIELD_DECL)
continue;
if (TREE_VALUE (tail) != 0)
@@ -1462,16 +1457,18 @@ build_functional_cast (exp, parms)
}
{
- int flags = LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN;
+ int flags = LOOKUP_SPECULATIVELY|LOOKUP_NORMAL;
if (parms && TREE_CHAIN (parms) == NULL_TREE)
flags |= LOOKUP_NO_CONVERSION;
- try_again:
expr_as_ctor = build_method_call (NULL_TREE, name, parms,
NULL_TREE, flags);
- if (expr_as_ctor && expr_as_ctor != error_mark_node)
+ if (expr_as_ctor == error_mark_node)
+ return error_mark_node;
+
+ else if (expr_as_ctor)
{
if (expr_as_conversion && expr_as_conversion != error_mark_node)
{
@@ -1514,18 +1511,6 @@ build_functional_cast (exp, parms)
return expr_as_ctor;
}
- /* If it didn't work going through constructor, try type conversion. */
- if (! (flags & LOOKUP_COMPLAIN))
- {
- if (expr_as_conversion)
- return expr_as_conversion;
- if (flags & LOOKUP_NO_CONVERSION)
- {
- flags = LOOKUP_NORMAL;
- goto try_again;
- }
- }
-
if (expr_as_conversion)
return expr_as_conversion;
OpenPOWER on IntegriCloud