On Jun 6, 2011, at 1:28 PM, Jason Merrill wrote: > On 06/02/2011 03:25 PM, David Krauss wrote: >> Optimally the re-opened context would be the preceding operator-> function itself, to create the illusion of nested calls. However, the result of build_new_op may be a target_expr or a call_expr. I'm not sure of the best way to recover the function declaration from this ambiguous tree, nor whether it would a performance issue (i.e., too much work for the reward). > > For a CALL_EXPR you can use get_callee_fndecl. I wouldn't object to teaching it to handle TARGET_EXPR and AGGR_INIT_EXPR as well. I had played around with this a bit in the meantime. It still gets stumped if operator-> is virtual. I don't know how to recover a virtual fn declaration from the tree of a virtual dispatch, but it seems to require recovery of and indirection through the vtable. A completely different alternative is to change the overloaded_p argument of build_new_op from a bool* to a tree*. Instead of returning *whether* an overload was used, it should return *which* was used if any. This seems to be much lower impact and returns some side benefit. Perhaps the argument should be changed to a z_candidate** instead? Patch attached. 90% of it is just stripping the "_p" from the name of the variable which is no longer a predicate. The change propagates to a few other functions, but the changes are mostly unsubstantial. I did eliminate one dead variable in cp_parser_omp_for_cond. > As for the duplicate error message, that happens because we complain when doing push_tinst_level first in instantiate_decl and then again in build_x_arrow. To avoid this we would need to hit each new depth first in build_x_arrow, either by pushing and then popping again before the call the build_new_op, or adding something like suspend/resume_tinst_level to pt.c. The complaints happen inside build_new_op, not from my added push_tinst_level. Looks like I'm creating a novel condition where the return type has not been instantiated before it is used in the function call. One message results from the function body and another results from the function return type. Perhaps the multiple messages should be regarded as a separate low-priority bug. A reference return type results in three messages, all from the class template, for what it's worth. This passes check-g++ applied to recent trunk code. - D