+2000-10-21 Jason Merrill <jason@redhat.com>
+
+ * parse.y (operator): Set got_object from got_scope.
+ Set looking_for_typename.
+ * decl.c (lookup_name_real): Clear val after setting from_obj.
+ Reorganize diagnostic.
+
2000-10-20 Jason Merrill <jason@redhat.com>
* tree.c (walk_tree): Don't walk into default args.
(cp_parse_init): Adjust.
(do_id): If lastiddecl is NULL, do do_identifier.
(operator): Save scope information.
- (unoperator): new reduction. Restore scope information.
+ (unoperator): New reduction. Restore scope information.
(operator_name): Append unoperator. Call frob_opname.
* spew.c (frob_opname): Define.
if (got_scope)
goto done;
else if (got_object && val)
- from_obj = val;
+ {
+ from_obj = val;
+ val = NULL_TREE;
+ }
}
else
{
{
if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
&& TREE_CODE (val) == TYPE_DECL
- && TREE_TYPE (from_obj) != TREE_TYPE (val))
- {
- cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
- name, got_object, TREE_TYPE (from_obj));
- cp_pedwarn (" does not match lookup in the current scope (`%#T')",
- TREE_TYPE (val));
- }
+ && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
+ cp_pedwarn ("\
+lookup of `%D' in the scope of `%#T' (`%#T') \
+does not match lookup in the current scope (`%#T')",
+ name, got_object, TREE_TYPE (from_obj),
+ TREE_TYPE (val));
/* We don't change val to from_obj if got_object depends on
template parms because that breaks implicit typename for
operator:
OPERATOR
- { saved_scopes = tree_cons (got_scope, got_object, saved_scopes);
- got_scope = NULL_TREE; got_object = NULL_TREE; }
+ {
+ saved_scopes = tree_cons (got_scope, got_object, saved_scopes);
+ /* We look for conversion-type-id's in both the class and current
+ scopes, just as for ID in 'ptr->ID::'. */
+ looking_for_typename = 1; got_object = got_scope;
+ got_scope = NULL_TREE;
+ }
;
+
unoperator:
{ got_scope = TREE_PURPOSE (saved_scopes);
got_object = TREE_VALUE (saved_scopes);
{ $$ = frob_opname (ansi_opname (VEC_NEW_EXPR)); }
| operator DELETE '[' ']' unoperator
{ $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); }
- /* Names here should be looked up in class scope ALSO. */
| operator type_specifier_seq conversion_declarator unoperator
{ $$ = frob_opname (grokoptypename ($2.t, $3)); }
| operator error unoperator
--- /dev/null
+// Test for proper handling of type lookup for conversion operator names.
+// Build don't link:
+
+// Test 1: Only at file scope
+typedef int B;
+struct A
+{
+ int B;
+ operator B *();
+};
+
+A::operator B * ()
+{
+ return 0;
+}
+
+// Test 2: Only at class scope
+struct C
+{
+ typedef int D;
+ operator D *();
+};
+
+int D;
+C::operator D * ()
+{
+ return 0;
+}
+
+// Test 3: Matching
+struct E
+{
+ typedef int F;
+ operator F *();
+};
+
+typedef int F;
+E::operator F * ()
+{
+ return 0;
+}
+
+// Test 4: Conflicting
+struct G
+{
+ typedef int H;
+ operator H *();
+};
+
+typedef double H;
+G::operator H * () // ERROR - mismatch
+{
+ return 0;
+}