aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1998-10-28 01:53:50 +0000
committerJason Merrill <jason@gcc.gnu.org>1998-10-27 20:53:50 -0500
commitaa45967f76ad4641556288a415eaceaf2269c9d5 (patch)
tree7eef74f4242089b2072e082e3cc77e5aef19ad5d
parentb58c9a790af44c27c4bdc15106d4685f8d38f831 (diff)
downloadgcc-aa45967f76ad4641556288a415eaceaf2269c9d5.zip
gcc-aa45967f76ad4641556288a415eaceaf2269c9d5.tar.gz
gcc-aa45967f76ad4641556288a415eaceaf2269c9d5.tar.bz2
call.c (add_function_candidate): Treat conversion functions as coming from the argument's class.
* call.c (add_function_candidate): Treat conversion functions as coming from the argument's class. * cp-tree.h (DECL_CONV_FN_P): New fn. (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE. * class.c (add_method): Use DECL_CONV_FN_P. * decl2.c (check_classfn): Likewise. * error.c (dump_function_name): Likewise. (dump_function_decl): Likewise. * pt.c (fn_type_unification): Likewise. * search.c (add_conversions): Likewise. From-SVN: r23387
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/call.c24
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/error.c13
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/search.c3
8 files changed, 55 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 328039a..b47514b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+1998-10-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_function_candidate): Treat conversion functions
+ as coming from the argument's class.
+ * cp-tree.h (DECL_CONV_FN_P): New fn.
+ (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE.
+ * class.c (add_method): Use DECL_CONV_FN_P.
+ * decl2.c (check_classfn): Likewise.
+ * error.c (dump_function_name): Likewise.
+ (dump_function_decl): Likewise.
+ * pt.c (fn_type_unification): Likewise.
+ * search.c (add_conversions): Likewise.
+
1998-10-27 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (do_identifier): Also generate LOOKUP_EXPR for RESULT_DECL.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8e074b6..3784784 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1150,8 +1150,28 @@ add_function_candidate (candidates, fn, arglist, flags)
if (parmnode == void_list_node)
break;
- else if (parmnode)
- t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags);
+
+ if (parmnode)
+ {
+ tree parmtype = TREE_VALUE (parmnode);
+
+ /* [over.match.funcs] For conversion functions, the function is
+ considered to be a member of the class of the implicit object
+ argument for the purpose of defining the type of the implicit
+ object parameter.
+
+ Since build_over_call ignores the ICS for the `this' parameter,
+ we can just change the parm type. */
+ if (DECL_CONV_FN_P (fn) && i == 0)
+ {
+ parmtype
+ = build_qualified_type (TREE_TYPE (argtype),
+ TYPE_QUALS (TREE_TYPE (parmtype)));
+ parmtype = build_pointer_type (parmtype);
+ }
+
+ t = implicit_conversion (parmtype, argtype, arg, flags);
+ }
else
{
t = build1 (IDENTITY_CONV, argtype, arg);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c5d67e5..9180e64 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1229,7 +1229,7 @@ add_method (type, fields, method)
}
}
- if (IDENTIFIER_TYPENAME_P (DECL_NAME (method)))
+ if (DECL_CONV_FN_P (method))
{
/* Type conversion operators have to come before
ordinary methods; add_conversions depends on this to
@@ -1240,15 +1240,13 @@ add_method (type, fields, method)
for (i = 2; i < len; ++i)
{
tree fn = TREE_VEC_ELT (method_vec, i);
- tree name;
if (!fn)
/* There are no more entries in the vector, so we
can insert the new conversion operator here. */
break;
- name = DECL_NAME (OVL_CURRENT (fn));
- if (!IDENTIFIER_TYPENAME_P (name))
+ if (! DECL_CONV_FN_P (OVL_CURRENT (fn)))
/* We can insert the new function right at the Ith
position. */
break;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b96246a..61593d5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1128,7 +1128,15 @@ struct lang_decl
/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */
#define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr)
-#define DECL_DESTRUCTOR_P(NODE) (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME(NODE)))
+
+/* There ought to be a better way to find out whether or not something is
+ a destructor. */
+#define DECL_DESTRUCTOR_P(NODE) \
+ (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE)) \
+ && DECL_LANGUAGE (NODE) == lang_cplusplus)
+
+#define DECL_CONV_FN_P(NODE) \
+ (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE)))
/* For FUNCTION_DECLs: nonzero means that this function is a constructor
for an object with virtual baseclasses. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 6ef3099..b16eb04 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1426,8 +1426,8 @@ check_classfn (ctype, function)
break; /* loser */
}
else if (TREE_CODE (fndecl) == TEMPLATE_DECL
- && IDENTIFIER_TYPENAME_P (DECL_NAME (fndecl))
- && IDENTIFIER_TYPENAME_P (fn_name))
+ && DECL_CONV_FN_P (fndecl)
+ && DECL_CONV_FN_P (function))
/* The method in the class is a member template
conversion operator. We are declaring another
conversion operator. It is possible that even though
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index bd7d178..13469c0 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -978,9 +978,9 @@ dump_function_decl (t, v)
if (DECL_STATIC_FUNCTION_P (t))
OB_PUTS ("static ");
- if (! IDENTIFIER_TYPENAME_P (name)
+ if (! DECL_CONV_FN_P (t)
&& ! DECL_CONSTRUCTOR_P (t)
- && ! DESTRUCTOR_NAME_P (name))
+ && ! DECL_DESTRUCTOR_P (t))
{
dump_type_prefix (TREE_TYPE (fntype), 1, 0);
OB_PUTC (' ');
@@ -1012,7 +1012,7 @@ dump_function_decl (t, v)
OB_PUTC (')');
- if (v && ! IDENTIFIER_TYPENAME_P (name))
+ if (v && ! DECL_CONV_FN_P (t))
dump_type_suffix (TREE_TYPE (fntype), 1, 0);
if (TREE_CODE (fntype) == METHOD_TYPE)
@@ -1036,15 +1036,12 @@ dump_function_name (t)
{
tree name = DECL_NAME (t);
- /* There ought to be a better way to find out whether or not something is
- a destructor. */
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))
- && DECL_LANGUAGE (t) == lang_cplusplus)
+ if (DECL_DESTRUCTOR_P (t))
{
OB_PUTC ('~');
dump_decl (name, 0);
}
- else if (IDENTIFIER_TYPENAME_P (name))
+ else if (DECL_CONV_FN_P (t))
{
/* This cannot use the hack that the operator's return
type is stashed off of its name because it may be
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1efbd19..c0726b7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6565,7 +6565,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
- if (IDENTIFIER_TYPENAME_P (DECL_NAME (fn)))
+ if (DECL_CONV_FN_P (fn))
{
/* This is a template conversion operator. Use the return types
as well as the argument types. */
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index c49fd22..26599f1 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -3295,8 +3295,7 @@ add_conversions (binfo)
{
tree tmp = TREE_VEC_ELT (method_vec, i);
- if (!tmp
- || !IDENTIFIER_TYPENAME_P (DECL_NAME (OVL_CURRENT (tmp))))
+ if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
break;
conversions = scratch_tree_cons (binfo, tmp, conversions);
}