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
This commit is contained in:
Nathan Sidwell 2003-07-18 17:19:41 +00:00 committed by Nathan Sidwell
parent c26052b06b
commit a3f10e50d7
7 changed files with 79 additions and 20 deletions

View file

@ -2651,7 +2651,7 @@ resolve_scoped_fn_name (tree scope, tree name)
/* It might be the name of a function pointer member. */
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)

View file

@ -4129,7 +4129,7 @@ extern tree finish_label_stmt (tree);
extern void finish_label_decl (tree);
extern void finish_subobject (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 finish_stmt_expr (tree);
extern tree perform_koenig_lookup (tree, tree);

View file

@ -117,7 +117,7 @@ hack_identifier (tree value, tree name)
type = TREE_TYPE (value);
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);
else if ((TREE_CODE (value) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (value))

View file

@ -8273,6 +8273,8 @@ tsubst_copy_and_build (tree t,
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);
}

View file

@ -1218,11 +1218,11 @@ finish_parenthesized_expr (tree expr)
preceded by `.' or `->'. */
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);
if (current_class_ptr == NULL_TREE)
if (!object)
{
if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl))
@ -1236,27 +1236,42 @@ finish_non_static_data_member (tree decl, tree qualifying_scope)
}
TREE_USED (current_class_ptr) = 1;
if (processing_template_decl)
return build_min (COMPONENT_REF, TREE_TYPE (decl),
current_class_ref, DECL_NAME (decl));
{
tree type = TREE_TYPE (decl);
if (TREE_CODE (type) == REFERENCE_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 = current_class_type;
tree object = current_class_ref;
while (access_type
&& !DERIVED_FROM_P (context_for_name_lookup (decl), access_type))
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);
while (access_type && DECL_P (access_type))
access_type = DECL_CONTEXT (access_type);
}
if (!access_type)
{
cp_error_at ("object missing in reference to `%D'",
decl);
error ("from this location");
return error_mark_node;
if (!access_type)
{
cp_error_at ("object missing in reference to `%D'", decl);
error ("from this location");
return error_mark_node;
}
}
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,
}
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)
{
tree fn;

View file

@ -1,3 +1,7 @@
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>
* g++.dg/init/init-ref4.C: xfail on targets without

View file

@ -0,0 +1,37 @@
// { 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;
}