This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gcjx] Patch: FYI: prepare for type inference fix


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]