This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: prepare for type inference fix
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 08 Nov 2005 16:33:39 -0700
- Subject: [gcjx] Patch: FYI: prepare for type inference fix
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
When doing type inference, there is a case where we must add a
constraint for the method's return type, but only if the method's
result will be subject to assignment conversion.
This patch adds the necessary infrastructure for this, by adding a new
method to model_expression and changing callers of
assignment_conversion to call this method first.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* model/invoke.cc (method_conversion_p): Pass assign_type to
method.
* model/method.hh (model_method::method_conversion_p): Updated.
* model/method.cc (method_conversion_p): Added 'assign_type'
argument.
* model/invoke.hh (model_invocation_base::assign_type): New
field.
(model_invocation_base): Initialize it.
(model_invocation_base::use_assignment_conversion): New method.
* model/assign.cc (handle_resolve): Removed.
(resolve): Merged in code from handle_resolve. Call
use_assignment_conversion.
* model/variable.cc (resolve): Call use_assignment_conversion.
* model/return.cc (resolve): Call use_assignment_conversion.
* model/assign.hh (model_assignment::handle_resolve): Removed.
* model/arrayinit.cc (resolve): Call use_assignment_conversion.
* model/expr.hh (model_expression::use_assignment_conversion):
Declare.
Index: model/arrayinit.cc
===================================================================
--- model/arrayinit.cc (revision 105944)
+++ model/arrayinit.cc (working copy)
@@ -1,6 +1,6 @@
// Array initializers.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -30,6 +30,7 @@
i != initializers.end ();
++i)
{
+ (*i)->use_assignment_conversion (ct);
(*i)->resolve (scope);
if (assignment_conversion (ct, *i) == NULL)
std::cerr << (*i)->error ("expression in array initializer of "
Index: model/return.cc
===================================================================
--- model/return.cc (revision 105944)
+++ model/return.cc (working copy)
@@ -1,6 +1,6 @@
// return statement.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -43,6 +43,8 @@
}
else
{
+ if (method_type != primitive_void_type)
+ expression->use_assignment_conversion (method_type);
expression->resolve (scope);
fold (expression);
if (method_type == primitive_void_type)
Index: model/assign.hh
===================================================================
--- model/assign.hh (revision 105944)
+++ model/assign.hh (working copy)
@@ -1,6 +1,6 @@
// Represent an assignment operator.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -36,10 +36,6 @@
// A helper method to check that the LHS has a valid form.
void check_lhs (const char *);
- // This is just a helper method to let us reuse a little code both
- // here and in the clinit subclass.
- void handle_resolve (resolution_scope *);
-
public:
model_assignment (const location &w)
Index: model/method.hh
===================================================================
--- model/method.hh (revision 106607)
+++ model/method.hh (working copy)
@@ -286,6 +286,7 @@
/// are considered. The returned method might differ from 'this' if
/// a generic instance is created.
model_method *method_conversion_p (const std::list<model_type *> &,
+ model_type *assign_type,
method_phase);
/// Like the above, but handles method conversion in the case where
Index: model/variable.cc
===================================================================
--- model/variable.cc (revision 106607)
+++ model/variable.cc (working copy)
@@ -35,6 +35,7 @@
decltype->resolve (scope); // fixme redundant for fields...
if (initializer)
{
+ initializer->use_assignment_conversion (decltype->type ());
initializer->resolve (scope);
if (! assignment_conversion (decltype->type (), initializer))
// FIXME error message!
Index: model/invoke.hh
===================================================================
--- model/invoke.hh (revision 105944)
+++ model/invoke.hh (working copy)
@@ -50,6 +50,11 @@
// True if this is an unqualified method invocation.
bool unqualified;
+ /// If the invocation occurs in a context where assignment
+ /// conversion is used, this will be non-NULL and will be the type
+ /// to which the return result of the method is assigned.
+ model_type *assign_type;
+
void try_method_conversion (const std::set<model_method *> &,
const std::list<model_type *> &,
std::set<model_method *> &);
@@ -90,7 +95,8 @@
: model_expression (w),
method (NULL),
search (NULL),
- unqualified (false)
+ unqualified (false),
+ assign_type (NULL)
{
}
@@ -124,6 +130,12 @@
model_class *get_qualifying_class () const;
+ void use_assignment_conversion (model_type *t)
+ {
+ assert (assign_type == NULL);
+ assign_type = t;
+ }
+
void resolve (resolution_scope *);
};
Index: model/forenhanced.cc
===================================================================
--- model/forenhanced.cc (revision 105944)
+++ model/forenhanced.cc (working copy)
@@ -59,6 +59,7 @@
resolution_scope::push_iscope var_holder (scope, &vscope);
variable->resolve (scope);
+ // FIXME: perhaps we should call use_assignment_conversion here?
expression->resolve (scope);
fold (expression);
if (expression->type ()->array_p ())
Index: model/assign.cc
===================================================================
--- model/assign.cc (revision 105944)
+++ model/assign.cc (working copy)
@@ -1,6 +1,6 @@
// Assignments.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -72,8 +72,14 @@
}
void
-model_assignment::handle_resolve (resolution_scope *scope)
+model_assignment::resolve (resolution_scope *scope)
{
+ lhs->set_left_hand_side (false);
+ lhs->resolve (scope);
+
+ rhs->use_assignment_conversion (lhs->type ());
+ rhs->resolve (scope);
+
check_lhs ("");
model_type *result = assignment_conversion (lhs->type (), rhs);
@@ -101,15 +107,6 @@
}
void
-model_assignment::resolve (resolution_scope *scope)
-{
- lhs->set_left_hand_side (false);
- lhs->resolve (scope);
- rhs->resolve (scope);
- handle_resolve (scope);
-}
-
-void
model_assignment::visit (visitor *v)
{
v->visit_assignment (this, lhs, rhs);
Index: model/method.cc
===================================================================
--- model/method.cc (revision 106607)
+++ model/method.cc (working copy)
@@ -302,14 +302,17 @@
model_method *
model_method::method_conversion_p (const std::list<model_type *> &args,
+ model_type *assign_type,
method_phase phase)
{
if (! type_parameters.empty ())
{
model_type_map typeargs;
- // FIXME: return result..? error detection?
+ // FIXME: error detection?
// FIXME: pass in argument for varargs handling.
- unify (args, this, NULL /* FIXME */, typeargs);
+ // FIXME: this dynamic_cast is probably wrong, we should
+ // fix the type inferencer.
+ unify (args, this, dynamic_cast<model_class *> (assign_type), typeargs);
return do_method_conversion_p (typeargs, args, phase);
}
return do_method_conversion_p (args, phase);
Index: model/expr.hh
===================================================================
--- model/expr.hh (revision 105944)
+++ model/expr.hh (working copy)
@@ -110,6 +110,15 @@
// Don't abort here -- at the point when this is called, we won't
// have had a chance to emit an error message.
}
+
+ /// This is called before resolution on an expression which will
+ /// undergo assignment conversion. The argument is the type of the
+ /// left hand side of the assignment. (This hook exists for type
+ /// inference of method calls to work correctly.)
+ virtual void use_assignment_conversion (model_type *)
+ {
+ // Do nothing by default.
+ }
};
const format &operator% (const format &, const model_expression *);
Index: model/invoke.cc
===================================================================
--- model/invoke.cc (revision 105944)
+++ model/invoke.cc (working copy)
@@ -33,7 +33,7 @@
const std::list<model_type *> &actual_types,
method_phase phase)
{
- return meth->method_conversion_p (actual_types, phase);
+ return meth->method_conversion_p (actual_types, assign_type, phase);
}
void