diff options
author | Tom Tromey <tromey@redhat.com> | 2005-11-08 22:39:39 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2005-11-08 22:39:39 +0000 |
commit | 11b2e7aa42ad9f5d4f7a5ff5c2743b502b07642c (patch) | |
tree | ab84a2f4728ec8a8e1c60583823777cf632b35fa | |
parent | 53400fa516c71d5f43a7d66748c4028341d4656f (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/ChangeLog | 21 | ||||
-rw-r--r-- | gcjx/model/arrayinit.cc | 3 | ||||
-rw-r--r-- | gcjx/model/assign.cc | 19 | ||||
-rw-r--r-- | gcjx/model/assign.hh | 6 | ||||
-rw-r--r-- | gcjx/model/expr.hh | 9 | ||||
-rw-r--r-- | gcjx/model/forenhanced.cc | 1 | ||||
-rw-r--r-- | gcjx/model/invoke.cc | 2 | ||||
-rw-r--r-- | gcjx/model/invoke.hh | 14 | ||||
-rw-r--r-- | gcjx/model/method.cc | 7 | ||||
-rw-r--r-- | gcjx/model/method.hh | 1 | ||||
-rw-r--r-- | gcjx/model/return.cc | 4 | ||||
-rw-r--r-- | gcjx/model/variable.cc | 1 |
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! |