OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Jul 2003 17:19:41 +0000 (17:19 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Jul 2003 17:19:41 +0000 (17:19 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69564 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/non-dependent2.C [new file with mode: 0644]

index a9323cc..6f677a5 100644 (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)
index 1728b37..4f2a143 100644 (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);
index e1ffaad..fdc026b 100644 (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))
index bbce47e..9d66c3c 100644 (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);
       }
index 3d704eb..812ef6d 100644 (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));
-  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;
index 60a68bb..4a3fcb9 100644 (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 
diff --git a/gcc/testsuite/g++.dg/parse/non-dependent2.C b/gcc/testsuite/g++.dg/parse/non-dependent2.C
new file mode 100644 (file)
index 0000000..46335c5
--- /dev/null
@@ -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;
+}