aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2005-11-08 22:39:39 +0000
committerTom Tromey <tromey@redhat.com>2005-11-08 22:39:39 +0000
commit11b2e7aa42ad9f5d4f7a5ff5c2743b502b07642c (patch)
treeab84a2f4728ec8a8e1c60583823777cf632b35fa
parent53400fa516c71d5f43a7d66748c4028341d4656f (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcjx-branch@106661 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcjx/ChangeLog21
-rw-r--r--gcjx/model/arrayinit.cc3
-rw-r--r--gcjx/model/assign.cc19
-rw-r--r--gcjx/model/assign.hh6
-rw-r--r--gcjx/model/expr.hh9
-rw-r--r--gcjx/model/forenhanced.cc1
-rw-r--r--gcjx/model/invoke.cc2
-rw-r--r--gcjx/model/invoke.hh14
-rw-r--r--gcjx/model/method.cc7
-rw-r--r--gcjx/model/method.hh1
-rw-r--r--gcjx/model/return.cc4
-rw-r--r--gcjx/model/variable.cc1
12 files changed, 66 insertions, 22 deletions
diff --git a/gcjx/ChangeLog b/gcjx/ChangeLog
index 2ad84668502..98c3f447397 100644
--- a/gcjx/ChangeLog
+++ b/gcjx/ChangeLog
@@ -1,3 +1,24 @@
+2005-11-08 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.
+
2005-11-07 Tom Tromey <tromey@redhat.com>
* conversions.cc (widen_instantiation): Directly use contains_p
diff --git a/gcjx/model/arrayinit.cc b/gcjx/model/arrayinit.cc
index 27c188b06a6..eed6ab06d30 100644
--- a/gcjx/model/arrayinit.cc
+++ b/gcjx/model/arrayinit.cc
@@ -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 @@ model_array_initializer::resolve (resolution_scope *scope)
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 "
diff --git a/gcjx/model/assign.cc b/gcjx/model/assign.cc
index 1e947201695..8136af1e428 100644
--- a/gcjx/model/assign.cc
+++ b/gcjx/model/assign.cc
@@ -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 @@ model_assignment::check_lhs (const char *name)
}
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 @@ model_assignment::handle_resolve (resolution_scope *scope)
}
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);
diff --git a/gcjx/model/assign.hh b/gcjx/model/assign.hh
index 7cfb6a1204d..21f8f2ac673 100644
--- a/gcjx/model/assign.hh
+++ b/gcjx/model/assign.hh
@@ -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 @@ protected:
// 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)
diff --git a/gcjx/model/expr.hh b/gcjx/model/expr.hh
index 0ca7d9de416..cc335e145b4 100644
--- a/gcjx/model/expr.hh
+++ b/gcjx/model/expr.hh
@@ -110,6 +110,15 @@ public:
// 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 *);
diff --git a/gcjx/model/forenhanced.cc b/gcjx/model/forenhanced.cc
index 70163b48e95..92e372aa873 100644
--- a/gcjx/model/forenhanced.cc
+++ b/gcjx/model/forenhanced.cc
@@ -59,6 +59,7 @@ model_for_enhanced::resolve (resolution_scope *scope)
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 ())
diff --git a/gcjx/model/invoke.cc b/gcjx/model/invoke.cc
index 99c80a793f8..011c0ecb37e 100644
--- a/gcjx/model/invoke.cc
+++ b/gcjx/model/invoke.cc
@@ -33,7 +33,7 @@ model_invocation_base::method_conversion_p (model_method *meth,
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
diff --git a/gcjx/model/invoke.hh b/gcjx/model/invoke.hh
index 89610fad0f2..041304e3b00 100644
--- a/gcjx/model/invoke.hh
+++ b/gcjx/model/invoke.hh
@@ -50,6 +50,11 @@ protected:
// 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 @@ protected:
: model_expression (w),
method (NULL),
search (NULL),
- unqualified (false)
+ unqualified (false),
+ assign_type (NULL)
{
}
@@ -124,6 +130,12 @@ public:
model_class *get_qualifying_class () const;
+ void use_assignment_conversion (model_type *t)
+ {
+ assert (assign_type == NULL);
+ assign_type = t;
+ }
+
void resolve (resolution_scope *);
};
diff --git a/gcjx/model/method.cc b/gcjx/model/method.cc
index c1f12661ac4..1babc9a42fa 100644
--- a/gcjx/model/method.cc
+++ b/gcjx/model/method.cc
@@ -302,14 +302,17 @@ model_method::do_method_conversion_p (const model_type_map &typeargs,
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);
diff --git a/gcjx/model/method.hh b/gcjx/model/method.hh
index caefd803053..b3d96f9a273 100644
--- a/gcjx/model/method.hh
+++ b/gcjx/model/method.hh
@@ -286,6 +286,7 @@ public:
/// 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
diff --git a/gcjx/model/return.cc b/gcjx/model/return.cc
index 54f49d82838..5941ac4d4da 100644
--- a/gcjx/model/return.cc
+++ b/gcjx/model/return.cc
@@ -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 @@ model_return::resolve (resolution_scope *scope)
}
else
{
+ if (method_type != primitive_void_type)
+ expression->use_assignment_conversion (method_type);
expression->resolve (scope);
fold (expression);
if (method_type == primitive_void_type)
diff --git a/gcjx/model/variable.cc b/gcjx/model/variable.cc
index 37ba52a0c2e..c31a0ae9039 100644
--- a/gcjx/model/variable.cc
+++ b/gcjx/model/variable.cc
@@ -35,6 +35,7 @@ model_variable_decl::resolve (resolution_scope *scope)
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!