Commit a3f10e50 by Nathan Sidwell Committed by Nathan Sidwell

cp-tree.h (finish_non_static_data_member): Add object param.

cp:
	* cp-tree.h (finish_non_static_data_member): Add object param.
	* method.c (hack_identifier): Adjust.
	* pt.c (tsubst_copy_and_build) <COMPONENT_REF case>: Don't search
	again for a FIELD_DECL.
	* semantics.c (finish_non_static_data_member): Add object
	parameter. Always save the DECL in the COMPONENT_REF.
	* call.c (resolve_scoped_fn_name): Adjust.
testsuite:
	* g++.dg/parse/non-dependent2.C: New test.

From-SVN: r69564
parent c26052b0
...@@ -2651,7 +2651,7 @@ resolve_scoped_fn_name (tree scope, tree name) ...@@ -2651,7 +2651,7 @@ resolve_scoped_fn_name (tree scope, tree name)
/* It might be the name of a function pointer member. */ /* It might be the name of a function pointer member. */
if (fn && TREE_CODE (fn) == FIELD_DECL) if (fn && TREE_CODE (fn) == FIELD_DECL)
fn = finish_non_static_data_member (fn, scope); fn = finish_non_static_data_member (fn, current_class_ref, scope);
} }
if (!fn) if (!fn)
......
...@@ -4129,7 +4129,7 @@ extern tree finish_label_stmt (tree); ...@@ -4129,7 +4129,7 @@ extern tree finish_label_stmt (tree);
extern void finish_label_decl (tree); extern void finish_label_decl (tree);
extern void finish_subobject (tree); extern void finish_subobject (tree);
extern tree finish_parenthesized_expr (tree); extern tree finish_parenthesized_expr (tree);
extern tree finish_non_static_data_member (tree, tree); extern tree finish_non_static_data_member (tree, tree, tree);
extern tree begin_stmt_expr (void); extern tree begin_stmt_expr (void);
extern tree finish_stmt_expr (tree); extern tree finish_stmt_expr (tree);
extern tree perform_koenig_lookup (tree, tree); extern tree perform_koenig_lookup (tree, tree);
......
...@@ -117,7 +117,7 @@ hack_identifier (tree value, tree name) ...@@ -117,7 +117,7 @@ hack_identifier (tree value, tree name)
type = TREE_TYPE (value); type = TREE_TYPE (value);
if (TREE_CODE (value) == FIELD_DECL) if (TREE_CODE (value) == FIELD_DECL)
value = finish_non_static_data_member (value, value = finish_non_static_data_member (value, current_class_ref,
/*qualifying_scope=*/NULL_TREE); /*qualifying_scope=*/NULL_TREE);
else if ((TREE_CODE (value) == FUNCTION_DECL else if ((TREE_CODE (value) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (value)) && DECL_FUNCTION_MEMBER_P (value))
......
...@@ -8273,6 +8273,8 @@ tsubst_copy_and_build (tree t, ...@@ -8273,6 +8273,8 @@ tsubst_copy_and_build (tree t,
return error_mark_node; return error_mark_node;
} }
} }
else if (TREE_CODE (member) == FIELD_DECL)
return finish_non_static_data_member (member, object, NULL_TREE);
return finish_class_member_access_expr (object, member); return finish_class_member_access_expr (object, member);
} }
......
...@@ -1218,11 +1218,11 @@ finish_parenthesized_expr (tree expr) ...@@ -1218,11 +1218,11 @@ finish_parenthesized_expr (tree expr)
preceded by `.' or `->'. */ preceded by `.' or `->'. */
tree tree
finish_non_static_data_member (tree decl, tree qualifying_scope) finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
{ {
my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909); my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
if (current_class_ptr == NULL_TREE) if (!object)
{ {
if (current_function_decl if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl)) && DECL_STATIC_FUNCTION_P (current_function_decl))
...@@ -1236,27 +1236,42 @@ finish_non_static_data_member (tree decl, tree qualifying_scope) ...@@ -1236,27 +1236,42 @@ finish_non_static_data_member (tree decl, tree qualifying_scope)
} }
TREE_USED (current_class_ptr) = 1; TREE_USED (current_class_ptr) = 1;
if (processing_template_decl) if (processing_template_decl)
return build_min (COMPONENT_REF, TREE_TYPE (decl),
current_class_ref, DECL_NAME (decl));
else
{ {
tree access_type = current_class_type; tree type = TREE_TYPE (decl);
tree object = current_class_ref;
while (access_type if (TREE_CODE (type) == REFERENCE_TYPE)
&& !DERIVED_FROM_P (context_for_name_lookup (decl), access_type)) type = TREE_TYPE (type);
else
{
/* Set the cv qualifiers */
int quals = cp_type_quals (TREE_TYPE (current_class_ref));
if (DECL_MUTABLE_P (decl))
quals &= ~TYPE_QUAL_CONST;
quals |= cp_type_quals (TREE_TYPE (decl));
type = cp_build_qualified_type (type, quals);
}
return build_min (COMPONENT_REF, type, object, decl);
}
else
{
tree access_type = TREE_TYPE (object);
tree lookup_context = context_for_name_lookup (decl);
while (!DERIVED_FROM_P (lookup_context, access_type))
{ {
access_type = TYPE_CONTEXT (access_type); access_type = TYPE_CONTEXT (access_type);
while (access_type && DECL_P (access_type)) while (access_type && DECL_P (access_type))
access_type = DECL_CONTEXT (access_type); access_type = DECL_CONTEXT (access_type);
}
if (!access_type) if (!access_type)
{ {
cp_error_at ("object missing in reference to `%D'", cp_error_at ("object missing in reference to `%D'", decl);
decl); error ("from this location");
error ("from this location"); return error_mark_node;
return error_mark_node; }
} }
perform_or_defer_access_check (TYPE_BINFO (access_type), decl); perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
...@@ -1357,7 +1372,8 @@ finish_qualified_id_expr (tree qualifying_class, tree expr, bool done, ...@@ -1357,7 +1372,8 @@ finish_qualified_id_expr (tree qualifying_class, tree expr, bool done,
} }
if (TREE_CODE (expr) == FIELD_DECL) if (TREE_CODE (expr) == FIELD_DECL)
expr = finish_non_static_data_member (expr, qualifying_class); expr = finish_non_static_data_member (expr, current_class_ref,
qualifying_class);
else if (BASELINK_P (expr) && !processing_template_decl) else if (BASELINK_P (expr) && !processing_template_decl)
{ {
tree fn; tree fn;
......
2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/parse/non-dependent2.C: New test.
2003-07-18 Andrew Pinski <pinskia@physics.uc.edu> 2003-07-18 Andrew Pinski <pinskia@physics.uc.edu>
* g++.dg/init/init-ref4.C: xfail on targets without * g++.dg/init/init-ref4.C: xfail on targets without
......
// { dg-do compile }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 16 Jul 2003 <nathan@codesourcery.com>
// A non-dependent field_decl can bind at parse time.
template <class T>
struct Foo {
int j; // we never see this one.
int k; // { dg-error "" "" }
};
struct Baz
{
int j;
int k; // { dg-error "" "" }
};
template <class T>
struct Bar : public Foo<T>, Baz {
int baz () { return j; } // binds to Baz::j
int foo () { return this->k; } // { dg-error "request for member" "" }
};
int main()
{
Bar<int> bar;
bar.baz ();
bar.foo ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment