aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2003-07-18 17:19:41 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2003-07-18 17:19:41 +0000
commita3f10e50d72e939d3d413d0c84a92af34b53c3b6 (patch)
tree739c2d965b5f14c53b06da69cb304426d2ea001d
parentc26052b06be808348a5bf78f9bf3d4a29cb80843 (diff)
downloadgcc-a3f10e50d72e939d3d413d0c84a92af34b53c3b6.zip
gcc-a3f10e50d72e939d3d413d0c84a92af34b53c3b6.tar.gz
gcc-a3f10e50d72e939d3d413d0c84a92af34b53c3b6.tar.bz2
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
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/semantics.c50
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/parse/non-dependent2.C37
7 files changed, 79 insertions, 20 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index a9323cc..6f677a5 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1728b37..4f2a143 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index e1ffaad..fdc026b 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bbce47e..9d66c3c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3d704eb..812ef6d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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));
- else
{
- tree access_type = current_class_type;
- tree object = current_class_ref;
+ tree type = TREE_TYPE (decl);
- while (access_type
- && !DERIVED_FROM_P (context_for_name_lookup (decl), access_type))
+ 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 = 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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 60a68bb..4a3fcb9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/parse/non-dependent2.C b/gcc/testsuite/g++.dg/parse/non-dependent2.C
new file mode 100644
index 0000000..46335c5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/non-dependent2.C
@@ -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;
+}