]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cp-tree.h (build_scoped_method_call): Remove.
authorMark Mitchell <mark@codesourcery.com>
Tue, 8 Jul 2003 01:38:44 +0000 (01:38 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 8 Jul 2003 01:38:44 +0000 (01:38 +0000)
* cp-tree.h (build_scoped_method_call): Remove.
(lookup_qualified_name): Remove parameter.
(tsubst_copy_and_build): Declare.
(finish_qualified_object_call_expr): Remove.
(check_accessibility_of_qualified_id): New function.
(finish_qualified_id_expr): Likewise.
(non_reference): Likewise.
(build_expr_from-tree): Remove.
* call.c (non_reference): Remove.
(build_scoped_method_call): Likewise.
(build_method_call): Use error_operand_p.  Assert that we are not
processing a template.
(standard_conversion): Use non_reference.
* class.c (build_vtbl_entry_ref): Likewise.
(build_vtbl_ref_1): Likewise.
* cvt.c (build_expr_type_conversion): Use non_reference.
* decl.c (lookup_qualified_name): Remove flags parameter.
(grok_op_properties): Use non_reference.
* decl2.c (grok_array_decl): Likewise.
(build_expr_from_tree): Remove.
(build_offset_ref_call_from_tree): Update comment.
* error.c (parm_to_string): Call reinit_global_formatting_buffer.
* except.c (prepare_eh_types): Use non_reference.
(can_convert_eh): Likewise.
* init.c (build_dtor_call): Avoid using build_method_call.
* mangle.c (write_template_param): Remove misleading comment.
* method.c (locate_copy): Use non_reference.
* parser.c (cp_parser_scope_through_which_access_occurs): Remove.
(cp_parser_primary_expression): Do not create SCOPE_REFs is
non-dependent contexts.
(cp_parser_postfix_expression): Use finish_qualified_id_expr.
(cp_parser_direct_declarator): Use tsubst_copy_and_build, not
build_expr_from_tree.
(cp_parser_lookup_name): Adjust call to lookup_qualified_name.
Use check_accessibility_of_qualified_id.
* pt.c (maybe_fold_nontype_arg): Use tsubst_copy_and_build, not
build_expr_from_tree.
(tsubst_baselink): New function.
(tsubst_qualified_id): Likewise.
(tsubst_copy): Use them.  Remove support for METHOD_CALL_EXPR.
(tsubst_expr): Adjust call to lookup_qualified_name.
(tsubst_copy_and_build): Handle SCOPE_REFs specially.  Adjust
handling of CALL_EXPRs.
(value_dependent_expression_p): Use INTEGRAL_OR_ENUMERATION_TYPE_P.
* rtti.c (get_tinfo_decl_dynamic): Use non_reference.
* search.c (check_final_overrider): Likewise.
* semantics.c (check_accessibility_of_qualified_id): New function.
(finish_qualified_object_call_expr): Remove.
* typeck.c (target_type): Use non_reference.
(cxx_sizeof_or_alignof_type): Likewise.
(dubious_conversion_warnings): Likewise.
(convert_for_initialization): Likewise.
(non_reference): New function.

From-SVN: r69063

18 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/mangle.c
gcc/cp/method.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/cp/typeck.c

index d1de6c3bf6d7acd09809f70f957e85d5a5af931f..888f0310a7ebfb7c1cc9832aae50c56780bfd31b 100644 (file)
@@ -1,3 +1,59 @@
+2003-07-07  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (build_scoped_method_call): Remove.
+       (lookup_qualified_name): Remove parameter.
+       (tsubst_copy_and_build): Declare.
+       (finish_qualified_object_call_expr): Remove.
+       (check_accessibility_of_qualified_id): New function.
+       (finish_qualified_id_expr): Likewise.
+       (non_reference): Likewise.
+       (build_expr_from-tree): Remove.
+       * call.c (non_reference): Remove.
+       (build_scoped_method_call): Likewise.
+       (build_method_call): Use error_operand_p.  Assert that we are not
+       processing a template.
+       (standard_conversion): Use non_reference.
+       * class.c (build_vtbl_entry_ref): Likewise.
+       (build_vtbl_ref_1): Likewise.
+       * cvt.c (build_expr_type_conversion): Use non_reference.
+       * decl.c (lookup_qualified_name): Remove flags parameter.
+       (grok_op_properties): Use non_reference.
+       * decl2.c (grok_array_decl): Likewise.
+       (build_expr_from_tree): Remove.
+       (build_offset_ref_call_from_tree): Update comment.
+       * error.c (parm_to_string): Call reinit_global_formatting_buffer.
+       * except.c (prepare_eh_types): Use non_reference.
+       (can_convert_eh): Likewise.
+       * init.c (build_dtor_call): Avoid using build_method_call.
+       * mangle.c (write_template_param): Remove misleading comment.
+       * method.c (locate_copy): Use non_reference.
+       * parser.c (cp_parser_scope_through_which_access_occurs): Remove.
+       (cp_parser_primary_expression): Do not create SCOPE_REFs is
+       non-dependent contexts.
+       (cp_parser_postfix_expression): Use finish_qualified_id_expr.
+       (cp_parser_direct_declarator): Use tsubst_copy_and_build, not
+       build_expr_from_tree.
+       (cp_parser_lookup_name): Adjust call to lookup_qualified_name.
+       Use check_accessibility_of_qualified_id.
+       * pt.c (maybe_fold_nontype_arg): Use tsubst_copy_and_build, not
+       build_expr_from_tree.
+       (tsubst_baselink): New function.
+       (tsubst_qualified_id): Likewise.
+       (tsubst_copy): Use them.  Remove support for METHOD_CALL_EXPR.
+       (tsubst_expr): Adjust call to lookup_qualified_name.
+       (tsubst_copy_and_build): Handle SCOPE_REFs specially.  Adjust
+       handling of CALL_EXPRs.
+       (value_dependent_expression_p): Use INTEGRAL_OR_ENUMERATION_TYPE_P.
+       * rtti.c (get_tinfo_decl_dynamic): Use non_reference.
+       * search.c (check_final_overrider): Likewise.
+       * semantics.c (check_accessibility_of_qualified_id): New function.
+       (finish_qualified_object_call_expr): Remove.
+       * typeck.c (target_type): Use non_reference.
+       (cxx_sizeof_or_alignof_type): Likewise.
+       (dubious_conversion_warnings): Likewise.
+       (convert_for_initialization): Likewise.
+       (non_reference): New function.
+
 2003-07-07  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * decl.c (print_binding_level, print_other_binding_stack,
index 29c00de01eb8733a75977c78d994a55b33302a4e..fbf5c06a32fed257b6216d4190b783b4b5a87c4f 100644 (file)
@@ -87,7 +87,6 @@ static struct z_candidate *add_function_candidate
 static tree implicit_conversion (tree, tree, tree, int);
 static tree standard_conversion (tree, tree, tree);
 static tree reference_binding (tree, tree, tree, int);
-static tree non_reference (tree);
 static tree build_conv (enum tree_code, tree, tree);
 static bool is_subseq (tree, tree);
 static tree maybe_handle_ref_bind (tree *);
@@ -205,106 +204,6 @@ check_dtor_name (tree basetype, tree name)
   return false;
 }
 
-/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
-   This is how virtual function calls are avoided.  */
-
-tree
-build_scoped_method_call (tree exp, tree basetype, tree name, tree parms)
-{
-  /* Because this syntactic form does not allow
-     a pointer to a base class to be `stolen',
-     we need not protect the derived->base conversion
-     that happens here.
-     
-     @@ But we do have to check access privileges later.  */
-  tree binfo, decl;
-  tree type = TREE_TYPE (exp);
-
-  if (type == error_mark_node
-      || basetype == error_mark_node)
-    return error_mark_node;
-
-  if (processing_template_decl)
-    {
-      name = build_min_nt (SCOPE_REF, basetype, name);
-      return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE);
-    }
-
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
-
-  if (TREE_CODE (basetype) == TREE_VEC)
-    {
-      binfo = basetype;
-      basetype = BINFO_TYPE (binfo);
-    }
-  else
-    binfo = NULL_TREE;
-
-  /* Check the destructor call syntax.  */
-  if (TREE_CODE (name) == BIT_NOT_EXPR)
-    {
-      /* We can get here if someone writes their destructor call like
-        `obj.NS::~T()'; this isn't really a scoped method call, so hand
-        it off.  */
-      if (TREE_CODE (basetype) == NAMESPACE_DECL)
-       return build_method_call (exp, name, parms, NULL_TREE, LOOKUP_NORMAL);
-
-      if (! check_dtor_name (basetype, name))
-       error ("qualified type `%T' does not match destructor name `~%T'",
-                 basetype, TREE_OPERAND (name, 0));
-
-      /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
-        that explicit ~int is caught in the parser; this deals with typedefs
-        and template parms.  */
-      if (! IS_AGGR_TYPE (basetype))
-       {
-         if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
-           error ("type of `%E' does not match destructor type `%T' (type was `%T')",
-                     exp, basetype, type);
-
-         return convert_to_void (exp, /*implicit=*/NULL);
-       }
-    }
-
-  if (TREE_CODE (basetype) == NAMESPACE_DECL)
-    {
-      error ("`%D' is a namespace", basetype);
-      return error_mark_node;
-    }
-  if (! is_aggr_type (basetype, 1))
-    return error_mark_node;
-
-  if (! IS_AGGR_TYPE (type))
-    {
-      error ("base object `%E' of scoped method call is of non-aggregate type `%T'",
-               exp, type);
-      return error_mark_node;
-    }
-
-  decl = build_scoped_ref (exp, basetype, &binfo);
-
-  if (binfo)
-    {
-      /* Call to a destructor.  */
-      if (TREE_CODE (name) == BIT_NOT_EXPR)
-       {
-         if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
-           return convert_to_void (exp, /*implicit=*/NULL);
-         
-         return build_delete (TREE_TYPE (decl), decl, 
-                              sfk_complete_destructor,
-                              LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
-                              0);
-       }
-
-      /* Call to a method.  */
-      return build_method_call (decl, name, parms, binfo,
-                               LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
-    }
-  return error_mark_node;
-}
-
 /* We want the address of a function or method.  We avoid creating a
    pointer-to-member function.  */
 
@@ -460,14 +359,12 @@ build_method_call (tree instance, tree name, tree parms,
   n_build_method_call++;
 #endif
 
-  if (instance == error_mark_node
+  if (error_operand_p (instance)
       || name == error_mark_node
-      || parms == error_mark_node
-      || (instance && TREE_TYPE (instance) == error_mark_node))
+      || parms == error_mark_node)
     return error_mark_node;
 
-  if (processing_template_decl)
-    return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
+  my_friendly_assert (!processing_template_decl, 20030707);
 
   if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
     instance = convert_from_reference (instance);
@@ -518,7 +415,7 @@ build_method_call (tree instance, tree name, tree parms,
   else
     fn = lookup_member (object_type, name, /*protect=*/2, /*want_type=*/false);
   
-  if (fn && TREE_CODE (fn) == TREE_LIST && !BASELINK_P (fn))
+  if (fn && TREE_CODE (fn) == TREE_LIST)
     {
       error ("request for member `%D' is ambiguous", name);
       print_candidates (fn);
@@ -669,17 +566,6 @@ build_conv (enum tree_code code, tree type, tree from)
   return t;
 }
 
-/* If T is a REFERENCE_TYPE return the type to which T refers.
-   Otherwise, return T itself.  */
-
-static tree
-non_reference (tree t)
-{
-  if (TREE_CODE (t) == REFERENCE_TYPE)
-    t = TREE_TYPE (t);
-  return t;
-}
-
 tree
 strip_top_quals (tree t)
 {
@@ -699,8 +585,7 @@ standard_conversion (tree to, tree from, tree expr)
   tree conv;
   bool fromref = false;
 
-  if (TREE_CODE (to) == REFERENCE_TYPE)
-    to = TREE_TYPE (to);
+  to = non_reference (to);
   if (TREE_CODE (from) == REFERENCE_TYPE)
     {
       fromref = true;
index 00e66078984be365052934e53d0389963f86a6be..5c276a4a3d03feadc2678a08798296f9d7588af4 100644 (file)
@@ -401,9 +401,7 @@ build_vtable_entry_ref (tree array_ref, tree instance, tree idx)
 {
   tree i, i2, vtable, first_fn, basetype;
 
-  basetype = TREE_TYPE (instance);
-  if (TREE_CODE (basetype) == REFERENCE_TYPE)
-    basetype = TREE_TYPE (basetype);
+  basetype = non_reference (TREE_TYPE (instance));
 
   vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
   first_fn = TYPE_BINFO_VTABLE (basetype);
@@ -439,9 +437,7 @@ build_vtbl_ref_1 (tree instance, tree idx)
   int cdtorp = 0;
   tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
 
-  tree basetype = TREE_TYPE (instance);
-  if (TREE_CODE (basetype) == REFERENCE_TYPE)
-    basetype = TREE_TYPE (basetype);
+  tree basetype = non_reference (TREE_TYPE (instance));
 
   if (fixed_type && !cdtorp)
     {
index 85815a2c43d5b1009bfcce776c47746d7c88feeb..9d383cf24aef768d21906090d2e914bb658b5b0f 100644 (file)
@@ -3493,7 +3493,6 @@ extern GTY(()) operator_name_info_t assignment_operator_name_info
 extern bool check_dtor_name (tree, tree);
 
 extern tree build_vfield_ref                   (tree, tree);
-extern tree build_scoped_method_call (tree, tree, tree, tree);
 extern tree build_conditional_expr             (tree, tree, tree);
 extern tree build_addr_func (tree);
 extern tree build_call (tree, tree);
@@ -3660,7 +3659,7 @@ extern tree make_typename_type                    (tree, tree, tsubst_flags_t);
 extern tree make_unbound_class_template                (tree, tree, tsubst_flags_t);
 extern tree lookup_name_nonclass               (tree);
 extern tree lookup_function_nonclass            (tree, tree);
-extern tree lookup_qualified_name               (tree, tree, bool, int);
+extern tree lookup_qualified_name               (tree, tree, bool);
 extern tree lookup_name                                (tree, int);
 extern tree lookup_name_current_level          (tree);
 extern tree lookup_type_current_level          (tree);
@@ -3775,7 +3774,6 @@ extern void import_export_decl (tree);
 extern void import_export_tinfo        (tree, tree, bool);
 extern void finish_file                                (void);
 extern tree build_cleanup                      (tree);
-extern tree build_expr_from_tree               (tree);
 extern tree build_offset_ref_call_from_tree     (tree, tree);
 extern tree build_call_from_tree                (tree, tree, bool);
 extern void set_decl_namespace (tree, tree, bool);
@@ -3967,6 +3965,7 @@ extern tree most_specialized_instantiation      (tree);
 extern void print_candidates                    (tree);
 extern int instantiate_pending_templates        (void);
 extern tree tsubst_default_argument             (tree, tree, tree);
+extern tree tsubst_copy_and_build               (tree, tree, tsubst_flags_t, tree);
 extern tree most_general_template              (tree);
 extern tree get_mostly_instantiated_function_type (tree);
 extern int problematic_instantiation_changed    (void);
@@ -4114,7 +4113,6 @@ extern tree finish_call_expr                    (tree, tree, bool);
 extern tree finish_increment_expr               (tree, enum tree_code);
 extern tree finish_this_expr                    (void);
 extern tree finish_object_call_expr             (tree, tree, tree);
-extern tree finish_qualified_object_call_expr   (tree, tree, tree);
 extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
 extern tree finish_unary_op_expr                (enum tree_code, tree);
 extern tree finish_compound_literal             (tree, tree);
@@ -4149,6 +4147,8 @@ extern tree begin_global_stmt_expr              (void);
 extern tree finish_global_stmt_expr             (tree);
 extern tree check_template_template_default_arg (tree);
 extern void expand_or_defer_fn                 (tree);
+extern void check_accessibility_of_qualified_id (tree, tree, tree);
+extern tree finish_qualified_id_expr            (tree, tree, bool, bool);
 
 /* in tree.c */
 extern void lang_check_failed                  (const char *, int,
@@ -4299,6 +4299,7 @@ extern tree check_return_expr                   (tree);
 extern tree build_ptrmemfunc_access_expr       (tree, tree);
 extern tree build_address                       (tree);
 extern tree build_nop                           (tree, tree);
+extern tree non_reference                       (tree);
 
 /* in typeck2.c */
 extern void require_complete_eh_spec_types     (tree, tree);
index 081d3b8caca9dd6f53915df7751d8701cfc311d6..bc9b309fa25e1f95bee9a2c54a4324eea9254968 100644 (file)
@@ -1077,9 +1077,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
       if (winner && winner == cand)
        continue;
 
-      candidate = TREE_TYPE (TREE_TYPE (cand));
-      if (TREE_CODE (candidate) == REFERENCE_TYPE)
-       candidate = TREE_TYPE (candidate);
+      candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
 
       switch (TREE_CODE (candidate))
        {
@@ -1117,9 +1115,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
 
   if (winner)
     {
-      tree type = TREE_TYPE (TREE_TYPE (winner));
-      if (TREE_CODE (type) == REFERENCE_TYPE)
-       type = TREE_TYPE (type);
+      tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
       return build_user_type_conversion (type, expr, LOOKUP_NORMAL);
     }
 
index 54c2336be117d31980667c7d61994ec23e075855..f0aef38513f283243aa46336f3a61945434751c0 100644 (file)
@@ -5770,8 +5770,10 @@ qualify_lookup (tree val, int flags)
    declaration found.  */
 
 tree
-lookup_qualified_name (tree scope, tree name, bool is_type_p, int flags)
+lookup_qualified_name (tree scope, tree name, bool is_type_p)
 {
+  int flags = 0;
+
   if (TREE_CODE (scope) == NAMESPACE_DECL)
     {
       cxx_binding binding;
@@ -5780,12 +5782,15 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, int flags)
       flags |= LOOKUP_COMPLAIN;
       if (is_type_p)
        flags |= LOOKUP_PREFER_TYPES;
-      if (!qualified_lookup_using_namespace (name, scope, &binding, flags))
+      if (!qualified_lookup_using_namespace (name, scope, &binding, 
+                                            flags))
        return NULL_TREE;
       return select_decl (&binding, flags);
     }
-  else
+  else if (is_aggr_type (scope, /*or_else=*/1))
     return lookup_member (scope, name, 0, is_type_p);
+  else
+    return error_mark_node;
 }
 
 /* Check to see whether or not DECL is a variable that would have been
@@ -12320,9 +12325,7 @@ grok_op_properties (tree decl, int friendp)
              if (p)
                for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
                  {
-                   tree arg = TREE_VALUE (p);
-                   if (TREE_CODE (arg) == REFERENCE_TYPE)
-                     arg = TREE_TYPE (arg);
+                   tree arg = non_reference (TREE_VALUE (p));
 
                    /* This lets bad template code slip through.  */
                    if (IS_AGGR_TYPE (arg)
index 39f6ca5536917e0fba46e94b63a729862feac36d..7158f1021471f192a64f5bce96457b4d06c1f637 100644 (file)
@@ -409,8 +409,7 @@ grok_array_decl (tree array_expr, tree index_exp)
 
   my_friendly_assert (type, 20030626);
 
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+  type = non_reference (type);
 
   /* If they have an `operator[]', use that.  */
   if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
@@ -2938,415 +2937,6 @@ finish_file ()
   input_location = locus;
 }
 
-/* T is the parse tree for an expression.  Return the expression after
-   performing semantic analysis.  */
-
-tree
-build_expr_from_tree (tree t)
-{
-  if (t == NULL_TREE || t == error_mark_node)
-    return t;
-
-  switch (TREE_CODE (t))
-    {
-    case IDENTIFIER_NODE:
-      return do_identifier (t, NULL_TREE);
-
-    case LOOKUP_EXPR:
-      if (LOOKUP_EXPR_GLOBAL (t))
-       {
-         tree token = TREE_OPERAND (t, 0);
-         return do_scoped_id (token, IDENTIFIER_GLOBAL_VALUE (token));
-       }
-      else
-       {
-         t = do_identifier (TREE_OPERAND (t, 0), NULL_TREE);
-         if (TREE_CODE (t) == ALIAS_DECL)
-           t = DECL_INITIAL (t);
-         return t;
-       }
-
-    case TEMPLATE_ID_EXPR:
-      {
-       tree template;
-       tree args;
-       tree object;
-
-       template = build_expr_from_tree (TREE_OPERAND (t, 0));
-       args = build_expr_from_tree (TREE_OPERAND (t, 1));
-       
-       if (TREE_CODE (template) == COMPONENT_REF)
-         {
-           object = TREE_OPERAND (template, 0);
-           template = TREE_OPERAND (template, 1);
-         }
-       else
-         object = NULL_TREE;
-
-       template = lookup_template_function (template, args);
-       if (object)
-         return build (COMPONENT_REF, TREE_TYPE (template), 
-                       object, template);
-       else
-         return template;
-      }
-
-    case INDIRECT_REF:
-      return build_x_indirect_ref
-       (build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *");
-
-    case CAST_EXPR:
-      return build_functional_cast
-       (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case REINTERPRET_CAST_EXPR:
-      return build_reinterpret_cast
-       (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case CONST_CAST_EXPR:
-      return build_const_cast
-       (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case DYNAMIC_CAST_EXPR:
-      return build_dynamic_cast
-       (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case STATIC_CAST_EXPR:
-      return build_static_cast
-       (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case PREDECREMENT_EXPR:
-    case PREINCREMENT_EXPR:
-    case POSTDECREMENT_EXPR:
-    case POSTINCREMENT_EXPR:
-    case NEGATE_EXPR:
-    case BIT_NOT_EXPR:
-    case ABS_EXPR:
-    case TRUTH_NOT_EXPR:
-    case ADDR_EXPR:
-    case CONVERT_EXPR:      /* Unary + */
-    case REALPART_EXPR:
-    case IMAGPART_EXPR:
-      if (TREE_TYPE (t))
-       return t;
-      return build_x_unary_op (TREE_CODE (t),
-                              build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-    case MULT_EXPR:
-    case TRUNC_DIV_EXPR:
-    case CEIL_DIV_EXPR:
-    case FLOOR_DIV_EXPR:
-    case ROUND_DIV_EXPR:
-    case EXACT_DIV_EXPR:
-    case BIT_AND_EXPR:
-    case BIT_ANDTC_EXPR:
-    case BIT_IOR_EXPR:
-    case BIT_XOR_EXPR:
-    case TRUNC_MOD_EXPR:
-    case FLOOR_MOD_EXPR:
-    case TRUTH_ANDIF_EXPR:
-    case TRUTH_ORIF_EXPR:
-    case TRUTH_AND_EXPR:
-    case TRUTH_OR_EXPR:
-    case RSHIFT_EXPR:
-    case LSHIFT_EXPR:
-    case RROTATE_EXPR:
-    case LROTATE_EXPR:
-    case EQ_EXPR:
-    case NE_EXPR:
-    case MAX_EXPR:
-    case MIN_EXPR:
-    case LE_EXPR:
-    case GE_EXPR:
-    case LT_EXPR:
-    case GT_EXPR:
-    case MEMBER_REF:
-      return build_x_binary_op
-       (TREE_CODE (t), 
-        build_expr_from_tree (TREE_OPERAND (t, 0)),
-        build_expr_from_tree (TREE_OPERAND (t, 1)));
-
-    case DOTSTAR_EXPR:
-      return build_m_component_ref
-       (build_expr_from_tree (TREE_OPERAND (t, 0)),
-        build_expr_from_tree (TREE_OPERAND (t, 1)));
-
-    case SCOPE_REF:
-      return build_offset_ref (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
-
-    case ARRAY_REF:
-      if (TREE_OPERAND (t, 0) == NULL_TREE)
-       /* new-type-id */
-       return build_nt (ARRAY_REF, NULL_TREE,
-                        build_expr_from_tree (TREE_OPERAND (t, 1)));
-      return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)),
-                             build_expr_from_tree (TREE_OPERAND (t, 1)));
-
-    case SIZEOF_EXPR:
-    case ALIGNOF_EXPR:
-      {
-       tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
-       if (!TYPE_P (r))
-         return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
-       else
-         return cxx_sizeof_or_alignof_type (r, TREE_CODE (t), true);
-      }
-
-    case MODOP_EXPR:
-      return build_x_modify_expr
-       (build_expr_from_tree (TREE_OPERAND (t, 0)),
-        TREE_CODE (TREE_OPERAND (t, 1)),
-        build_expr_from_tree (TREE_OPERAND (t, 2)));
-
-    case ARROW_EXPR:
-      return build_x_arrow
-       (build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case NEW_EXPR:
-      return build_new
-       (build_expr_from_tree (TREE_OPERAND (t, 0)),
-        build_expr_from_tree (TREE_OPERAND (t, 1)),
-        build_expr_from_tree (TREE_OPERAND (t, 2)),
-        NEW_EXPR_USE_GLOBAL (t));
-
-    case DELETE_EXPR:
-      return delete_sanity
-       (build_expr_from_tree (TREE_OPERAND (t, 0)),
-        build_expr_from_tree (TREE_OPERAND (t, 1)),
-        DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t));
-
-    case COMPOUND_EXPR:
-      if (TREE_OPERAND (t, 1) == NULL_TREE)
-       return build_x_compound_expr
-         (build_expr_from_tree (TREE_OPERAND (t, 0)));
-      else
-       abort ();
-
-    case METHOD_CALL_EXPR:
-      if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
-       {
-         tree ref = TREE_OPERAND (t, 0);
-         tree name = TREE_OPERAND (ref, 1);
-         
-         if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-           name = build_nt (TEMPLATE_ID_EXPR,
-                            TREE_OPERAND (name, 0),
-                            build_expr_from_tree (TREE_OPERAND (name, 1)));
-           
-         return build_scoped_method_call
-           (build_expr_from_tree (TREE_OPERAND (t, 1)),
-            build_expr_from_tree (TREE_OPERAND (ref, 0)),
-            name,
-            build_expr_from_tree (TREE_OPERAND (t, 2)));
-       }
-      else 
-       {
-         tree fn = TREE_OPERAND (t, 0);
-
-         /* We can get a TEMPLATE_ID_EXPR here on code like:
-
-              x->f<2>();
-             
-            so we must resolve that.  However, we can also get things
-            like a BIT_NOT_EXPR here, when referring to a destructor,
-            and things like that are not correctly resolved by
-            build_expr_from_tree.  So, just use build_expr_from_tree
-            when we really need it.  */
-         if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
-           fn = lookup_template_function
-             (TREE_OPERAND (fn, 0),
-              build_expr_from_tree (TREE_OPERAND (fn, 1)));
-
-         return build_method_call
-           (build_expr_from_tree (TREE_OPERAND (t, 1)),
-            fn,
-            build_expr_from_tree (TREE_OPERAND (t, 2)),
-            NULL_TREE, LOOKUP_NORMAL);
-       }
-
-    case CALL_EXPR:
-      if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
-       {
-         tree ref = TREE_OPERAND (t, 0);
-         tree name = TREE_OPERAND (ref, 1);
-         tree fn, scope, args;
-         
-         if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-           name = build_nt (TEMPLATE_ID_EXPR,
-                            TREE_OPERAND (name, 0),
-                            build_expr_from_tree (TREE_OPERAND (name, 1)));
-
-         scope = build_expr_from_tree (TREE_OPERAND (ref, 0));
-         args = build_expr_from_tree (TREE_OPERAND (t, 1));
-         fn = resolve_scoped_fn_name (scope, name);
-         
-         return build_call_from_tree (fn, args, 1);
-       }
-      else
-       {
-         tree name = TREE_OPERAND (t, 0);
-          tree id;
-          tree args = build_expr_from_tree (TREE_OPERAND (t, 1));
-          if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR
-              && !LOOKUP_EXPR_GLOBAL (name)
-              && TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE
-              && (!current_class_type
-                  || !lookup_member (current_class_type, id, 0, false)))
-            {
-              /* Do Koenig lookup if there are no class members.  */
-              name = do_identifier (id, args);
-            }
-          else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
-                  || ! really_overloaded_fn (name))
-           name = build_expr_from_tree (name);
-
-         if (TREE_CODE (name) == OFFSET_REF)
-           return build_offset_ref_call_from_tree (name, args);
-         if (TREE_CODE (name) == COMPONENT_REF)
-           return finish_object_call_expr (TREE_OPERAND (name, 1),
-                                           TREE_OPERAND (name, 0),
-                                           args);
-         name = convert_from_reference (name);
-         return build_call_from_tree (name, args, 
-                                      /*disallow_virtual=*/false);
-       }
-
-    case COND_EXPR:
-      return build_x_conditional_expr
-       (build_expr_from_tree (TREE_OPERAND (t, 0)),
-        build_expr_from_tree (TREE_OPERAND (t, 1)),
-        build_expr_from_tree (TREE_OPERAND (t, 2)));
-
-    case PSEUDO_DTOR_EXPR:
-      return (finish_pseudo_destructor_expr 
-             (build_expr_from_tree (TREE_OPERAND (t, 0)),
-              build_expr_from_tree (TREE_OPERAND (t, 1)),
-              build_expr_from_tree (TREE_OPERAND (t, 2))));
-
-    case TREE_LIST:
-      {
-       tree purpose, value, chain;
-
-       if (t == void_list_node)
-         return t;
-
-       purpose = TREE_PURPOSE (t);
-       if (purpose)
-         purpose = build_expr_from_tree (purpose);
-       value = TREE_VALUE (t);
-       if (value)
-         value = build_expr_from_tree (value);
-       chain = TREE_CHAIN (t);
-       if (chain && chain != void_type_node)
-         chain = build_expr_from_tree (chain);
-       return tree_cons (purpose, value, chain);
-      }
-
-    case COMPONENT_REF:
-      {
-       tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
-       tree member = TREE_OPERAND (t, 1);
-
-       if (!CLASS_TYPE_P (TREE_TYPE (object)))
-         {
-           if (TREE_CODE (member) == BIT_NOT_EXPR)
-             return finish_pseudo_destructor_expr (object, 
-                                                   NULL_TREE,
-                                                   TREE_TYPE (object));
-           else if (TREE_CODE (member) == SCOPE_REF
-                    && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
-             return finish_pseudo_destructor_expr (object, 
-                                                   TREE_OPERAND (t, 0),
-                                                   TREE_TYPE (object));
-         }
-       else if (TREE_CODE (member) == SCOPE_REF
-                && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
-         {
-           tree tmpl;
-           tree args;
-       
-           /* Lookup the template functions now that we know what the
-              scope is.  */
-           tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
-           args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
-           member = lookup_qualified_name (TREE_OPERAND (member, 0),
-                                           tmpl, 
-                                           /*is_type=*/0,
-                                           /*flags=*/0);
-           if (BASELINK_P (member))
-             BASELINK_FUNCTIONS (member) 
-               = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
-                           args);
-           else
-             {
-               error ("`%D' is not a member of `%T'",
-                      tmpl, TREE_TYPE (object));
-               return error_mark_node;
-             }
-         }
-
-
-       return finish_class_member_access_expr (object, member);
-      }
-
-    case THROW_EXPR:
-      return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case CONSTRUCTOR:
-      {
-       tree r;
-       tree elts;
-       tree type = TREE_TYPE (t);
-       bool purpose_p;
-
-       /* digest_init will do the wrong thing if we let it.  */
-       if (type && TYPE_PTRMEMFUNC_P (type))
-         return t;
-
-       r = NULL_TREE;
-       /* We do not want to process the purpose of aggregate
-          initializers as they are identifier nodes which will be
-          looked up by digest_init.  */
-       purpose_p = !(type && IS_AGGR_TYPE (type));
-       for (elts = CONSTRUCTOR_ELTS (t); elts; elts = TREE_CHAIN (elts))
-         {
-           tree purpose = TREE_PURPOSE (elts);
-           tree value = TREE_VALUE (elts);
-           
-           if (purpose && purpose_p)
-             purpose = build_expr_from_tree (purpose);
-           value = build_expr_from_tree (value);
-           r = tree_cons (purpose, value, r);
-         }
-       
-       r = build_constructor (NULL_TREE, nreverse (r));
-       TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
-
-       if (type)
-         return digest_init (type, r, 0);
-       return r;
-      }
-
-    case TYPEID_EXPR:
-      if (TYPE_P (TREE_OPERAND (t, 0)))
-       return get_typeid (TREE_OPERAND (t, 0));
-      return build_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
-
-    case PARM_DECL:
-    case VAR_DECL:
-      return convert_from_reference (t);
-
-    case VA_ARG_EXPR:
-      return build_va_arg (build_expr_from_tree (TREE_OPERAND (t, 0)),
-                          TREE_TYPE (t));
-
-    default:
-      return t;
-    }
-}
-
 /* FN is an OFFSET_REF indicating the function to call in parse-tree
    form; it has not yet been semantically analyzed.  ARGS are the
    arguments to the function.  They have already been semantically
@@ -3359,22 +2949,12 @@ build_offset_ref_call_from_tree (tree fn, tree args)
 
   my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725);
 
-  /* A qualified name corresponding to a non-static member
-     function or a pointer-to-member is represented as an 
-     OFFSET_REF.  
-
-     For both of these function calls, FN will be an OFFSET_REF.
-
-       struct A { void f(); };
-       void A::f() { (A::f) (); } 
+  /* A qualified name corresponding to a bound pointer-to-member is
+     represented as an OFFSET_REF:
 
        struct B { void g(); };
        void (B::*p)();
        void B::g() { (this->*p)(); }  */
-
-  /* This code is not really correct (for example, it does not
-     handle the case that `A::f' is overloaded), but it is
-     historically how we have handled this situation.  */
   if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL)
     /* This case should now be handled elsewhere.  */
     abort ();
index 17dc1185cdbe34157f629d0f438ff93a261bde9b..a9f5b15834accd3ee7c1733971213c9af0519f8e 100644 (file)
@@ -2230,6 +2230,8 @@ language_to_string (enum languages c)
 static const char *
 parm_to_string (int p)
 {
+  reinit_global_formatting_buffer ();
+
   if (p < 0)
     output_add_string (scratch_buffer, "'this'");
   else
index 70c446d7c5968482a1ecd8da9630faaefb0b9fe8..390f12c45514919198ae30a7088be6ddeb662530 100644 (file)
@@ -107,8 +107,7 @@ prepare_eh_type (tree type)
     return error_mark_node;
 
   /* peel back references, so they match.  */
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+  type = non_reference (type);
 
   /* Peel off cv qualifiers.  */
   type = TYPE_MAIN_VARIANT (type);
@@ -872,10 +871,8 @@ nothrow_libfn_p (tree fn)
 static int
 can_convert_eh (tree to, tree from)
 {
-  if (TREE_CODE (to) == REFERENCE_TYPE)
-    to = TREE_TYPE (to);
-  if (TREE_CODE (from) == REFERENCE_TYPE)
-    from = TREE_TYPE (from);
+  to = non_reference (to);
+  from = non_reference (from);
 
   if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
     {
index 18a4dcf988ea80586dbffa2f3b2bb3a3b82a512c..f89b4248e65fa37b71c5359532212afda3b462ad 100644 (file)
@@ -2915,7 +2915,7 @@ static tree
 build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
 {
   tree name;
-
+  tree fn;
   switch (dtor_kind)
     {
     case sfk_complete_destructor:
@@ -2933,8 +2933,13 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
     default:
       abort ();
     }
-  return build_method_call (exp, name, NULL_TREE, 
-                           TYPE_BINFO (TREE_TYPE (exp)), flags);
+
+  exp = convert_from_reference (exp);
+  fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
+  return build_new_method_call (exp, fn, 
+                               /*args=*/NULL_TREE,
+                               /*conversion_path=*/NULL_TREE,
+                               flags);
 }
 
 /* Generate a call to a destructor. TYPE is the type to cast ADDR to.
index 49a956886a71c63dc53efa9e782cdfbb2c18ac0d..63c58baf059e2ed638731804f2e58098cc54886b 100644 (file)
@@ -2197,14 +2197,7 @@ write_pointer_to_member_type (const tree type)
    TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
    TEMPLATE_PARM_INDEX.
 
-     <template-param> ::= T </parameter/ number> _
-
-   If we are internally mangling then we distinguish level and, for
-   non-type parms, type too. The mangling appends
-   
-     </level/ number> _ </non-type type/ type> _
-
-   This is used by mangle_conv_op_name_for_type.  */
+     <template-param> ::= T </parameter/ number> _  */
 
 static void
 write_template_param (const tree parm)
index a0d8b63c97216469502798e07abf44d96233c229..e1ffaad3769ae53aef72a6d4cc65689e8e4155cd 100644 (file)
@@ -1000,9 +1000,7 @@ locate_copy (tree type, void *client_)
       parms = TREE_CHAIN (parms);
       if (!parms)
         continue;
-      src_type = TREE_VALUE (parms);
-      if (TREE_CODE (src_type) == REFERENCE_TYPE)
-        src_type = TREE_TYPE (src_type);
+      src_type = non_reference (TREE_VALUE (parms));
       if (!same_type_ignoring_top_level_qualifiers_p (src_type, type))
         continue;
       if (!sufficient_parms_p (TREE_CHAIN (parms)))
index 1fd2ead6ab9a48f579644d7442ec3c64008e0857..27e73cb967fa7af638170a79585e72e66920065d 100644 (file)
@@ -1717,8 +1717,6 @@ static bool cp_parser_is_string_literal
   (cp_token *);
 static bool cp_parser_is_keyword 
   (cp_token *, enum rid);
-static tree cp_parser_scope_through_which_access_occurs
-  (tree, tree, tree);
 
 /* Returns nonzero if we are parsing tentatively.  */
 
@@ -1744,62 +1742,6 @@ cp_parser_is_keyword (cp_token* token, enum rid keyword)
   return token->keyword == keyword;
 }
 
-/* Returns the scope through which DECL is being accessed, or
-   NULL_TREE if DECL is not a member.  If OBJECT_TYPE is non-NULL, we
-   have just seen `x->' or `x.' and OBJECT_TYPE is the type of `*x',
-   or `x', respectively.  If the DECL was named as `A::B' then
-   NESTED_NAME_SPECIFIER is `A'.  */
-
-static tree
-cp_parser_scope_through_which_access_occurs (tree decl, 
-                                            tree object_type,
-                                            tree nested_name_specifier)
-{
-  tree scope;
-  tree qualifying_type = NULL_TREE;
-  
-  /* Determine the SCOPE of DECL.  */
-  scope = context_for_name_lookup (decl);
-  /* If the SCOPE is not a type, then DECL is not a member.  */
-  if (!TYPE_P (scope))
-    return NULL_TREE;
-  /* Figure out the type through which DECL is being accessed.  */
-  if (object_type 
-      /* OBJECT_TYPE might not be a class type; consider:
-
-          class A { typedef int I; };
-          I *p;
-          p->A::I::~I();
-
-         In this case, we will have "A::I" as the DECL, but "I" as the
-        OBJECT_TYPE.  */
-      && CLASS_TYPE_P (object_type)
-      && DERIVED_FROM_P (scope, object_type))
-    /* If we are processing a `->' or `.' expression, use the type of the
-       left-hand side.  */
-    qualifying_type = object_type;
-  else if (nested_name_specifier)
-    {
-      /* If the reference is to a non-static member of the
-        current class, treat it as if it were referenced through
-        `this'.  */
-      if (DECL_NONSTATIC_MEMBER_P (decl)
-         && current_class_ptr
-         && DERIVED_FROM_P (scope, current_class_type))
-       qualifying_type = current_class_type;
-      /* Otherwise, use the type indicated by the
-        nested-name-specifier.  */
-      else
-       qualifying_type = nested_name_specifier;
-    }
-  else
-    /* Otherwise, the name must be from the current class or one of
-       its bases.  */
-    qualifying_type = currently_open_derived_class (scope);
-
-  return qualifying_type;
-}
-
 /* Issue the indicated error MESSAGE.  */
 
 static void
@@ -2600,7 +2542,7 @@ cp_parser_primary_expression (cp_parser *parser,
        else
          {
            bool dependent_p;
-           
+
            /* If the declaration was explicitly qualified indicate
               that.  The semantics of `A::f(3)' are different than
               `f(3)' if `f' is virtual.  */
@@ -2710,7 +2652,8 @@ cp_parser_primary_expression (cp_parser *parser,
               we will resolve the name at instantiation time.  */
            if (dependent_p)
              {
-               /* Create a SCOPE_REF for qualified names.  */
+               /* Create a SCOPE_REF for qualified names, if the
+                  scope is dependent.  */
                if (parser->scope)
                  {
                    if (TYPE_P (parser->scope))
@@ -2720,9 +2663,13 @@ cp_parser_primary_expression (cp_parser *parser,
                       might be constant when things are instantiated.  */
                    if (parser->constant_expression_p)
                      parser->non_constant_expression_p = true;
-                   return build_nt (SCOPE_REF, 
-                                    parser->scope, 
-                                    id_expression);
+                   if (TYPE_P (parser->scope)
+                       && dependent_type_p (parser->scope))
+                     return build_nt (SCOPE_REF, 
+                                      parser->scope, 
+                                      id_expression);
+                   else
+                     return decl;
                  }
                /* A TEMPLATE_ID already contains all the information
                   we need.  */
@@ -3523,7 +3470,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
      form a pointer-to-member.  In that case, QUALIFYING_CLASS is the
      class used to qualify the member.  */
   tree qualifying_class = NULL_TREE;
-  bool done;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -3752,68 +3698,28 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
       break;
     }
 
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-  done = (token->type != CPP_OPEN_SQUARE
-         && token->type != CPP_OPEN_PAREN
-         && token->type != CPP_DOT
-         && token->type != CPP_DEREF
-         && token->type != CPP_PLUS_PLUS
-         && token->type != CPP_MINUS_MINUS);
-
-  /* If the postfix expression is complete, finish up.  */
-  if (address_p && qualifying_class && done)
-    {
-      if (TREE_CODE (postfix_expression) == SCOPE_REF)
-       postfix_expression = TREE_OPERAND (postfix_expression, 1);
-      postfix_expression 
-       = build_offset_ref (qualifying_class, postfix_expression);
-      return postfix_expression;
-    }
-
-  /* Otherwise, if we were avoiding committing until we knew
-     whether or not we had a pointer-to-member, we now know that
-     the expression is an ordinary reference to a qualified name.  */
+  /* If we were avoiding committing to the processing of a
+     qualified-id until we knew whether or not we had a
+     pointer-to-member, we now know.  */
   if (qualifying_class)
     {
-      if (TREE_CODE (postfix_expression) == FIELD_DECL)
-       postfix_expression 
-         = finish_non_static_data_member (postfix_expression,
-                                          qualifying_class);
-      else if (BASELINK_P (postfix_expression) 
-              && !processing_template_decl)
-       {
-         tree fn;
-         tree fns;
+      bool done;
 
-         /* See if any of the functions are non-static members.  */
-         fns = BASELINK_FUNCTIONS (postfix_expression);
-         if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
-           fns = TREE_OPERAND (fns, 0);
-         for (fn = fns; fn; fn = OVL_NEXT (fn))
-           if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
-             break;
-         /* If so, the expression may be relative to the current
-            class.  */
-         if (fn && current_class_type 
-             && DERIVED_FROM_P (qualifying_class, current_class_type))
-           postfix_expression 
-             = (build_class_member_access_expr 
-                (maybe_dummy_object (qualifying_class, NULL),
-                 postfix_expression,
-                 BASELINK_ACCESS_BINFO (postfix_expression),
-                 /*preserve_reference=*/false));
-         else if (done)
-           {
-             /* The expression is a qualified name whose address is not
-                being taken.  */
-             postfix_expression = build_offset_ref (qualifying_class,
-                                                    postfix_expression);
-             if (TREE_CODE (postfix_expression) == OFFSET_REF)
-               postfix_expression = resolve_offset_ref (postfix_expression);
-             return postfix_expression;
-           }
-       }
+      /* Peek at the next token.  */
+      token = cp_lexer_peek_token (parser->lexer);
+      done = (token->type != CPP_OPEN_SQUARE
+             && token->type != CPP_OPEN_PAREN
+             && token->type != CPP_DOT
+             && token->type != CPP_DEREF
+             && token->type != CPP_PLUS_PLUS
+             && token->type != CPP_MINUS_MINUS);
+
+      postfix_expression = finish_qualified_id_expr (qualifying_class,
+                                                    postfix_expression,
+                                                    done,
+                                                    address_p);
+      if (done)
+       return postfix_expression;
     }
 
   /* Remember that there was a reference to this entity.  */
@@ -3915,7 +3821,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
                if (!arg)
                  {
                    postfix_expression 
-                     = lookup_arg_dependent(identifier, functions, args);
+                     = lookup_arg_dependent (identifier, functions, args);
                    if (!postfix_expression)
                      {
                        /* The unqualified name could not be resolved.  */
@@ -4014,8 +3920,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
                   may have reference type even when the standard says
                   it does not.  Therefore, we have to manually obtain
                   the underlying type here.  */
-               if (TREE_CODE (scope) == REFERENCE_TYPE)
-                 scope = TREE_TYPE (scope);
+               scope = non_reference (scope);
                /* If the SCOPE is an OFFSET_TYPE, then we grab the
                   type of the field.  We get an OFFSET_TYPE for
                   something like:
@@ -10031,7 +9936,10 @@ cp_parser_direct_declarator (cp_parser* parser,
 
                  saved_processing_template_decl = processing_template_decl;
                  processing_template_decl = 0;
-                 bounds = build_expr_from_tree (bounds);
+                 bounds = tsubst_copy_and_build (bounds, 
+                                                 /*args=*/NULL_TREE,
+                                                 tf_error,
+                                                 /*in_decl=*/NULL_TREE);
                  processing_template_decl = saved_processing_template_decl;
                }
            }
@@ -13209,8 +13117,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
             may be instantiated during name lookup.  In that case,
             errors may be issued.  Even if we rollback the current
             tentative parse, those errors are valid.  */
-         decl = lookup_qualified_name (parser->scope, name, is_type,
-                                       /*flags=*/0);
+         decl = lookup_qualified_name (parser->scope, name, is_type);
          if (dependent_p)
            pop_scope (parser->scope);
        }
@@ -13282,18 +13189,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
      During an explicit instantiation, access is not checked at all,
      as per [temp.explicit].  */
   if (DECL_P (decl))
-    {
-      tree qualifying_type;
-      
-      /* Figure out the type through which DECL is being
-        accessed.  */
-      qualifying_type 
-       = cp_parser_scope_through_which_access_occurs (decl,
-                                                      object_type,
-                                                      parser->scope);
-      if (qualifying_type)
-       perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
-    }
+    check_accessibility_of_qualified_id (decl, object_type, parser->scope);
 
   return decl;
 }
index af3b55602962dd2c04362dd172520c12ffb1a7bb..60383ef914ab410881e739db2ed5767f9cb4856a 100644 (file)
@@ -171,7 +171,6 @@ static bool dependent_template_id_p (tree, tree);
 static tree tsubst (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_expr        (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_copy        (tree, tree, tsubst_flags_t, tree);
-static tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -5527,9 +5526,8 @@ maybe_fold_nontype_arg (tree arg)
         template constant parameter, like N - 1.  Now that we've
         tsubst'd, we might have something like 2 - 1.  This will
         confuse lookup_template_class, so we do constant folding
-        here.  We have to unset processing_template_decl, to
-        fool build_expr_from_tree() into building an actual
-        tree.  */
+        here.  We have to unset processing_template_decl, to fool
+        tsubst_copy_and_build() into building an actual tree.  */
 
       /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
         as simple as it's going to get, and trying to reprocess
@@ -5538,7 +5536,10 @@ maybe_fold_nontype_arg (tree arg)
        {
          int saved_processing_template_decl = processing_template_decl; 
          processing_template_decl = 0;
-         arg = build_expr_from_tree (arg);
+         arg = tsubst_copy_and_build (arg,
+                                      /*args=*/NULL_TREE,
+                                      tf_error,
+                                      /*in_decl=*/NULL_TREE);
          processing_template_decl = saved_processing_template_decl; 
        }
 
@@ -7076,6 +7077,118 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     }
 }
 
+/* Like tsubst_expr for a BASELINK.  OBJECT_TYPE, if non-NULL, is the
+   type of the expression on the left-hand side of the "." or "->"
+   operator.  */
+
+static tree
+tsubst_baselink (tree baselink, tree object_type,
+                tree args, tsubst_flags_t complain, tree in_decl)
+{
+    tree name;
+    tree qualifying_scope;
+    tree fns;
+    tree template_args = 0;
+    bool template_id_p = false;
+
+    /* A baselink indicates a function from a base class.  The
+       BASELINK_ACCESS_BINFO and BASELINK_BINFO are going to have
+       non-dependent types; otherwise, the lookup could not have
+       succeeded.  However, they may indicate bases of the template
+       class, rather than the instantiated class.  
+
+       In addition, lookups that were not ambiguous before may be
+       ambiguous now.  Therefore, we perform the lookup again. */
+    qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
+    fns = BASELINK_FUNCTIONS (baselink);
+    if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+      {
+       template_id_p = true;
+       template_args = TREE_OPERAND (fns, 1);
+       fns = TREE_OPERAND (fns, 0);
+       template_args = tsubst_copy (template_args, args,
+                                    complain, in_decl);
+       maybe_fold_nontype_args (template_args);
+      }
+    name = DECL_NAME (get_first_fn (fns));
+    baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
+    if (BASELINK_P (baselink) && template_id_p)
+      BASELINK_FUNCTIONS (baselink) 
+       = build_nt (TEMPLATE_ID_EXPR,
+                   BASELINK_FUNCTIONS (baselink),
+                   template_args);
+    if (!object_type)
+      object_type = current_class_type;
+    return adjust_result_of_qualified_name_lookup (baselink, 
+                                                  qualifying_scope,
+                                                  object_type);
+}
+
+/* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID.  DONE is
+   true if the qualified-id will be a postfix-expression in-and-of
+   itself; false if more of the postfix-expression follows the
+   QUALIFIED_ID.  ADDRESS_P is true if the qualified-id is the operand
+   of "&".  */
+
+static tree
+tsubst_qualified_id (tree qualified_id, tree args, 
+                    tsubst_flags_t complain, tree in_decl,
+                    bool done, bool address_p)
+{
+  tree expr;
+  tree scope;
+  tree name;
+  bool is_template;
+  tree template_args;
+
+  my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706);
+
+  /* Look up the qualified name.  */
+  scope = TREE_OPERAND (qualified_id, 0);
+  scope = tsubst (scope, args, complain, in_decl);
+
+  /* Figure out what name to look up.  */
+  name = TREE_OPERAND (qualified_id, 1);
+  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+    {
+      is_template = true;
+      template_args = tsubst_copy_and_build (TREE_OPERAND (name, 1), 
+                                            args, complain, in_decl);
+      name = TREE_OPERAND (name, 0);
+    }
+  else
+    {
+      is_template = false;
+      template_args = NULL_TREE;
+    }
+
+  expr = tsubst_copy (name, args, complain, in_decl);
+  if (!BASELINK_P (name))
+    {
+      expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0);
+      if (DECL_P (expr))
+       check_accessibility_of_qualified_id (expr, 
+                                            /*object_type=*/NULL_TREE,
+                                            scope);
+    }
+
+  /* Remember that there was a reference to this entity.  */
+  if (DECL_P (expr))
+    mark_used (expr);
+
+  if (is_template)
+    lookup_template_function (expr, template_args);
+
+  if (TYPE_P (scope))
+    {
+      expr = (adjust_result_of_qualified_name_lookup 
+             (expr, scope, current_class_type));
+      expr = finish_qualified_id_expr (scope, expr, done, address_p);
+    }
+
+  return expr;
+}
+
 /* Like tsubst, but deals with expressions.  This function just replaces
    template parms; to finish processing the resultant expression, use
    tsubst_expr.  */
@@ -7157,43 +7270,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       return t;
 
     case BASELINK:
-      {
-       tree name;
-       tree qualifying_scope;
-       tree fns;
-       tree template_args = 0;
-       bool template_id_p = false;
-
-       /* A baselink indicates a function from a base class.  The
-          BASELINK_ACCESS_BINFO and BASELINK_BINFO are going to have
-          non-dependent types; otherwise, the lookup could not have
-          succeeded.  However, they may indicate bases of the template
-          class, rather than the instantiated class.  
-          
-          In addition, lookups that were not ambiguous before may be
-          ambiguous now.  Therefore, we perform the lookup again.  */
-       qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (t));
-       fns = BASELINK_FUNCTIONS (t);
-       if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
-         {
-           template_id_p = true;
-           template_args = TREE_OPERAND (fns, 1);
-           fns = TREE_OPERAND (fns, 0);
-           template_args = tsubst_copy (template_args, args,
-                                        complain, in_decl);
-           maybe_fold_nontype_args (template_args);
-         }
-       name = DECL_NAME (get_first_fn (fns));
-       t = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
-       if (BASELINK_P (t) && template_id_p)
-         BASELINK_FUNCTIONS (t) 
-           = build_nt (TEMPLATE_ID_EXPR,
-                       BASELINK_FUNCTIONS (t),
-                       template_args);
-       return adjust_result_of_qualified_name_lookup (t, 
-                                                      qualifying_scope,
-                                                      current_class_type);
-      }
+      return tsubst_baselink (t, current_class_type, args, complain, in_decl);
 
     case TEMPLATE_DECL:
       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
@@ -7296,8 +7373,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
            name = build_nt (SCOPE_REF, base, name);
          }
+       else if (TREE_CODE (name) == BASELINK)
+         name = tsubst_baselink (name, 
+                                 non_reference (TREE_TYPE (object)), 
+                                 args, complain, 
+                                 in_decl);
        else
-         name = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+         name = tsubst_copy (name, args, complain, in_decl);
        return build_nt (COMPONENT_REF, object, name);
       }
 
@@ -7352,14 +7434,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                    in_decl),
                       NULL_TREE);
 
-    case METHOD_CALL_EXPR:
-      return build_nt
-       (code, 
-        tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl),
-        NULL_TREE);
-
     case STMT_EXPR:
       /* This processing should really occur in tsubst_expr.  However,
         tsubst_expr does not recurse into expressions, since it
@@ -7547,8 +7621,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            scope = tsubst_expr (scope, args, complain, in_decl);
            do_local_using_decl (lookup_qualified_name (scope,
                                                        name, 
-                                                       /*is_type_p=*/0,
-                                                       /*flags=*/0));
+                                                       /*is_type_p=*/0));
          }
        else
          {
@@ -7814,12 +7887,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 /* Like tsubst but deals with expressions and performs semantic
    analysis.  */
 
-static tree
+tree
 tsubst_copy_and_build (tree t, 
                        tree args, 
                        tsubst_flags_t complain, 
                        tree in_decl)
 {
+  tree op1;
+
   if (t == NULL_TREE || t == error_mark_node)
     return t;
 
@@ -7859,9 +7934,11 @@ tsubst_copy_and_build (tree t,
       {
        tree object;
        tree template
-         = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+         = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, 
+                                  in_decl);
        tree targs
-         = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+         = tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, 
+                                  in_decl);
        
        if (TREE_CODE (template) == COMPONENT_REF)
          {
@@ -7870,7 +7947,6 @@ tsubst_copy_and_build (tree t,
          }
        else
          object = NULL_TREE;
-       maybe_fold_nontype_args (targs);
        template = lookup_template_function (template, targs);
        
        if (object)
@@ -7910,10 +7986,21 @@ tsubst_copy_and_build (tree t,
        (tsubst (TREE_TYPE (t), args, complain, in_decl),
         tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
 
-    case PREDECREMENT_EXPR:
-    case PREINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
     case POSTINCREMENT_EXPR:
+      op1 = TREE_OPERAND (t, 0);
+      if (TREE_CODE (op1) == SCOPE_REF)
+       op1 = tsubst_qualified_id (TREE_OPERAND (t, 0),
+                                  args, complain, 
+                                  in_decl,
+                                  /*done=*/false,
+                                  /*address_p=*/false);
+      else
+       op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+      return build_x_unary_op (TREE_CODE (t), op1);
+
+    case PREDECREMENT_EXPR:
+    case PREINCREMENT_EXPR:
       if (TREE_TYPE (t))
        return tsubst_copy (t, args, complain, in_decl);
       else
@@ -7939,8 +8026,16 @@ tsubst_copy_and_build (tree t,
        (TREE_CODE (t),
         tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
 
-    case TRUTH_NOT_EXPR:
     case ADDR_EXPR:
+      op1 = TREE_OPERAND (t, 0);
+      if (TREE_CODE (op1) == SCOPE_REF)
+       op1 = tsubst_qualified_id (op1, args, complain, in_decl, 
+                                  /*done=*/true, /*address_p=*/true);
+      else
+       op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+      return build_x_unary_op (ADDR_EXPR, op1);
+
+    case TRUTH_NOT_EXPR:
     case CONVERT_EXPR:  /* Unary + */
     case REALPART_EXPR:
     case IMAGPART_EXPR:
@@ -7994,26 +8089,31 @@ tsubst_copy_and_build (tree t,
         tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl));
 
     case SCOPE_REF:
-      return build_offset_ref
-       (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
+      return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
+                                 /*address_p=*/false);
 
     case ARRAY_REF:
-      {
-       if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl)
-           == NULL_TREE)
-         /* new-type-id */
-         return build_nt
-           (ARRAY_REF, NULL_TREE,
-            tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain,
-                                   in_decl));
-       
-       return grok_array_decl
-         (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain,
-                                 in_decl),
+      if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl)
+         == NULL_TREE)
+       /* new-type-id */
+       return build_nt
+         (ARRAY_REF, NULL_TREE,
           tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain,
                                  in_decl));
-      }
+
+      op1 = TREE_OPERAND (t, 0);
+      if (TREE_CODE (op1) == SCOPE_REF)
+       op1 = tsubst_qualified_id (op1, args, complain, in_decl,
+                                  /*done=*/false, /*address_p=*/false);
+      else
+       op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+      /* Remember that there was a reference to this entity.  */
+      if (DECL_P (op1))
+       mark_used (op1);
+      return grok_array_decl (op1, 
+                             tsubst_copy_and_build (TREE_OPERAND (t, 1), 
+                                                    args, complain,
+                                                    in_decl));
 
     case SIZEOF_EXPR:
     case ALIGNOF_EXPR:
@@ -8034,8 +8134,16 @@ tsubst_copy_and_build (tree t,
         tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl));
 
     case ARROW_EXPR:
-      return build_x_arrow
-       (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+      op1 = TREE_OPERAND (t, 0);
+      if (TREE_CODE (op1) == SCOPE_REF)
+       op1 = tsubst_qualified_id (op1, args, complain, in_decl,
+                                  /*done=*/false, /*address_p=*/false);
+      else
+       op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+      /* Remember that there was a reference to this entity.  */
+      if (DECL_P (op1))
+       mark_used (op1);
+      return build_x_arrow (op1);
 
     case NEW_EXPR:
       return build_new
@@ -8062,104 +8170,62 @@ tsubst_copy_and_build (tree t,
          abort ();
       }
 
-    case METHOD_CALL_EXPR:
+    case CALL_EXPR:
       {
-       tree method
-         = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
-       
-       if (TREE_CODE (method) == SCOPE_REF)
+       tree function;
+       tree call_args;
+       tree koenig_name;
+       bool qualified_p;
+
+       function = TREE_OPERAND (t, 0);
+       if (TREE_CODE (function) == LOOKUP_EXPR
+           && !LOOKUP_EXPR_GLOBAL (function))
+         koenig_name = TREE_OPERAND (function, 0);
+       else
+         koenig_name = NULL_TREE;
+       if (TREE_CODE (function) == SCOPE_REF)
          {
-           tree name = TREE_OPERAND (method, 1);
-         
-           if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-             name = build_nt (TEMPLATE_ID_EXPR,
-                              TREE_OPERAND (name, 0),
-                              TREE_OPERAND (name, 1));
-           
-           return build_scoped_method_call
-             (tsubst_copy_and_build
-              (TREE_OPERAND (t, 1), args, complain, in_decl),
-              TREE_OPERAND (method, 0),
-              name,
-              tsubst_copy_and_build
-              (TREE_OPERAND (t, 2), args, complain, in_decl));
+           qualified_p = true;
+           function = tsubst_qualified_id (function, args, complain, in_decl,
+                                           /*done=*/false, 
+                                           /*address_p=*/false);
          }
-       else 
+       else
          {
-           /* We can get a TEMPLATE_ID_EXPR here on code like:
-
-           x->f<2>();
-             
-           so we must resolve that.  However, we can also get things
-           like a BIT_NOT_EXPR here, when referring to a destructor,
-           and things like that are not correctly resolved by this
-           function so just use it when we really need it.  */
-           if (TREE_CODE (method) == TEMPLATE_ID_EXPR)
-             method = lookup_template_function
-               (TREE_OPERAND (method, 0),
-                TREE_OPERAND (method, 1));
-
-           return build_method_call
-             (tsubst_copy_and_build
-              (TREE_OPERAND (t, 1), args, complain, in_decl),
-              method,
-              tsubst_copy_and_build
-              (TREE_OPERAND (t, 2), args, complain, in_decl),
-              NULL_TREE, LOOKUP_NORMAL);
+           qualified_p = (TREE_CODE (function) == COMPONENT_REF
+                          && (TREE_CODE (TREE_OPERAND (function, 1))
+                              == SCOPE_REF));
+           function = tsubst_copy_and_build (function, args, complain, 
+                                             in_decl);
+           function = convert_from_reference (function);
          }
-      }
 
-    case CALL_EXPR:
-      {
-       tree function, copy_args;
+       /* Remember that there was a reference to this entity.  */
+       if (DECL_P (function))
+         mark_used (function);
 
-       function = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
-       copy_args = tsubst_copy_and_build (TREE_OPERAND (t, 1), args,
+       call_args = tsubst_copy_and_build (TREE_OPERAND (t, 1), args,
                                           complain, in_decl);
          
        if (BASELINK_P (function))
-         return build_call_from_tree (function, copy_args, 1);
-       else if (TREE_CODE (function) == SCOPE_REF)
-         {
-           tree name = TREE_OPERAND (function, 1);
-           if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-             name = build_nt (TEMPLATE_ID_EXPR,
-                              TREE_OPERAND (name, 0),
-                              build_expr_from_tree (TREE_OPERAND (name, 1)));
-           
-           function = resolve_scoped_fn_name (TREE_OPERAND (function, 0),
-                                              name);
-           
-           return build_call_from_tree (function, copy_args, 1);
-         }
+         return build_call_from_tree (function, call_args, 1);
        else
          {
-           tree name = function;
-           tree id;
-           
-           if (copy_args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR
-               && !LOOKUP_EXPR_GLOBAL (name)
-               && (TREE_CODE ((id = TREE_OPERAND (name, 0)))
-                   == IDENTIFIER_NODE)
-               && (!current_class_type
-                   || !lookup_member (current_class_type, id, 0, false)))
-             {
-               /* Do Koenig lookup if there are no class members.  */
-               name = do_identifier (id, copy_args);
-             }
-           else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
-                    || ! really_overloaded_fn (name))
-             name = build_expr_from_tree (name);
-
-           if (TREE_CODE (name) == OFFSET_REF)
-             return build_offset_ref_call_from_tree (name, copy_args);
-           if (TREE_CODE (name) == COMPONENT_REF)
-             return finish_object_call_expr (TREE_OPERAND (name, 1),
-                                             TREE_OPERAND (name, 0),
-                                             copy_args);
-           name = convert_from_reference (name);
-           return build_call_from_tree (name, copy_args, 
-                                        /*disallow_virtual=*/false);
+           if (call_args != NULL_TREE && koenig_name)
+             function = lookup_arg_dependent (koenig_name,
+                                              function, 
+                                              call_args);
+
+           if (TREE_CODE (function) == OFFSET_REF)
+             return build_offset_ref_call_from_tree (function, call_args);
+           if (TREE_CODE (function) == COMPONENT_REF)
+             return (build_new_method_call 
+                     (TREE_OPERAND (function, 0),
+                      TREE_OPERAND (function, 1),
+                      call_args, NULL_TREE, 
+                      qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL));
+           return finish_call_expr (function, call_args, 
+                                    /*disallow_virtual=*/qualified_p);
          }
       }
 
@@ -8200,10 +8266,27 @@ tsubst_copy_and_build (tree t,
 
     case COMPONENT_REF:
       {
-       tree object =
-         tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl);
-       tree member =
-         tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       tree object;
+       tree member;
+
+       object = TREE_OPERAND (t, 0);
+       if (TREE_CODE (object) == SCOPE_REF)
+         object = tsubst_qualified_id (object, args, complain, in_decl,
+                                       /*done=*/false, /*address_p=*/false);
+       else
+         object = tsubst_copy_and_build (object, args, complain, in_decl);
+
+       /* Remember that there was a reference to this entity.  */
+       if (DECL_P (object))
+         mark_used (object);
+
+       member = TREE_OPERAND (t, 1);
+       if (BASELINK_P (member))
+         member = tsubst_baselink (member, 
+                                   non_reference (TREE_TYPE (object)),
+                                   args, complain, in_decl);
+       else
+         member = tsubst_copy (member, args, complain, in_decl);
 
        if (!CLASS_TYPE_P (TREE_TYPE (object)))
          {
@@ -8229,8 +8312,7 @@ tsubst_copy_and_build (tree t,
            args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
            member = lookup_qualified_name (TREE_OPERAND (member, 0),
                                            tmpl, 
-                                           /*is_type=*/0,
-                                           /*flags=*/0);
+                                           /*is_type=*/0);
            if (BASELINK_P (member))
              BASELINK_FUNCTIONS (member) 
                = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
@@ -8303,7 +8385,9 @@ tsubst_copy_and_build (tree t,
       return convert_from_reference (tsubst_copy (t, args, complain, in_decl));
 
     case VAR_DECL:
-      return convert_from_reference (tsubst_copy (t, args, complain, in_decl));
+      if (args)
+       t = tsubst_copy (t, args, complain, in_decl);
+      return convert_from_reference (t);
 
     case VA_ARG_EXPR:
        return build_x_va_arg
@@ -11405,8 +11489,7 @@ value_dependent_expression_p (tree expression)
      with an expression that is value-dependent.  */
   if (TREE_CODE (expression) == VAR_DECL
       && DECL_INITIAL (expression)
-      && (CP_INTEGRAL_TYPE_P (TREE_TYPE (expression))
-         || TREE_CODE (TREE_TYPE (expression)) == ENUMERAL_TYPE)
+      && INTEGRAL_OR_ENUMERATION_TYPE_P (expression)
       && value_dependent_expression_p (DECL_INITIAL (expression)))
     return true;
   /* These expressions are value-dependent if the type to which the
index 33745e573242d85a61efa5aa6f0e1e3797d14ba8..b28fea6212a5e35509914a7913c4825c63f6288e 100644 (file)
@@ -213,11 +213,8 @@ get_tinfo_decl_dynamic (tree exp)
   if (exp == error_mark_node)
     return error_mark_node;
 
-  type = TREE_TYPE (exp);
-
   /* peel back references, so they match.  */
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+  type = non_reference (TREE_TYPE (exp));
 
   /* Peel off cv qualifiers.  */
   type = TYPE_MAIN_VARIANT (type);
@@ -408,8 +405,7 @@ get_typeid (tree type)
   /* If the type of the type-id is a reference type, the result of the
      typeid expression refers to a type_info object representing the
      referenced type.  */
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+  type = non_reference (type);
 
   /* The top-level cv-qualifiers of the lvalue expression or the type-id
      that is the operand of typeid are always ignored.  */
index cee35ff2d525d5245d715bc8c52d63079289f95c..64e5707e1f0f484550764995d0d1d9e98f85e2e1 100644 (file)
@@ -1712,9 +1712,7 @@ check_final_overrider (tree overrider, tree basefn)
        {
          /* can_convert will permit user defined conversion from a
             (reference to) class type. We must reject them.  */
-         over_return = TREE_TYPE (over_type);
-         if (TREE_CODE (over_return) == REFERENCE_TYPE)
-           over_return = TREE_TYPE (over_return);
+         over_return = non_reference (TREE_TYPE (over_type));
          if (CLASS_TYPE_P (over_return))
            fail = 2;
        }
index 9301e6595361c9adf820be4edc1285a656f861a0..cc1e2ea3e9c314285694b29e63856064e94766b7 100644 (file)
@@ -1276,6 +1276,119 @@ finish_non_static_data_member (tree decl, tree qualifying_scope)
     }
 }
 
+/* DECL was the declaration to which a qualified-id resolved.  Issue
+   an error message if it is not accessible.  If OBJECT_TYPE is
+   non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
+   type of `*x', or `x', respectively.  If the DECL was named as
+   `A::B' then NESTED_NAME_SPECIFIER is `A'.  */
+
+void
+check_accessibility_of_qualified_id (tree decl, 
+                                    tree object_type, 
+                                    tree nested_name_specifier)
+{
+  tree scope;
+  tree qualifying_type = NULL_TREE;
+  
+  /* Determine the SCOPE of DECL.  */
+  scope = context_for_name_lookup (decl);
+  /* If the SCOPE is not a type, then DECL is not a member.  */
+  if (!TYPE_P (scope))
+    return;
+  /* Compute the scope through which DECL is being accessed.  */
+  if (object_type 
+      /* OBJECT_TYPE might not be a class type; consider:
+
+          class A { typedef int I; };
+          I *p;
+          p->A::I::~I();
+
+         In this case, we will have "A::I" as the DECL, but "I" as the
+        OBJECT_TYPE.  */
+      && CLASS_TYPE_P (object_type)
+      && DERIVED_FROM_P (scope, object_type))
+    /* If we are processing a `->' or `.' expression, use the type of the
+       left-hand side.  */
+    qualifying_type = object_type;
+  else if (nested_name_specifier)
+    {
+      /* If the reference is to a non-static member of the
+        current class, treat it as if it were referenced through
+        `this'.  */
+      if (DECL_NONSTATIC_MEMBER_P (decl)
+         && current_class_ptr
+         && DERIVED_FROM_P (scope, current_class_type))
+       qualifying_type = current_class_type;
+      /* Otherwise, use the type indicated by the
+        nested-name-specifier.  */
+      else
+       qualifying_type = nested_name_specifier;
+    }
+  else
+    /* Otherwise, the name must be from the current class or one of
+       its bases.  */
+    qualifying_type = currently_open_derived_class (scope);
+
+  if (qualifying_type)
+    perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
+}
+
+/* EXPR is the result of a qualified-id.  The QUALIFYING_CLASS was the
+   class named to the left of the "::" operator.  DONE is true if this
+   expression is a complete postfix-expression; it is false if this
+   expression is followed by '->', '[', '(', etc.  ADDRESS_P is true
+   iff this expression is the operand of '&'.  */
+
+tree
+finish_qualified_id_expr (tree qualifying_class, tree expr, bool done,
+                         bool address_p)
+{
+  /* If EXPR occurs as the operand of '&', use special handling that
+     permits a pointer-to-member.  */
+  if (address_p && done)
+    {
+      if (TREE_CODE (expr) == SCOPE_REF)
+       expr = TREE_OPERAND (expr, 1);
+      expr = build_offset_ref (qualifying_class, expr);
+      return expr;
+    }
+
+  if (TREE_CODE (expr) == FIELD_DECL)
+    expr = finish_non_static_data_member (expr, qualifying_class);
+  else if (BASELINK_P (expr) && !processing_template_decl)
+    {
+      tree fn;
+      tree fns;
+
+      /* See if any of the functions are non-static members.  */
+      fns = BASELINK_FUNCTIONS (expr);
+      if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+       fns = TREE_OPERAND (fns, 0);
+      for (fn = fns; fn; fn = OVL_NEXT (fn))
+       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+         break;
+      /* If so, the expression may be relative to the current
+        class.  */
+      if (fn && current_class_type 
+         && DERIVED_FROM_P (qualifying_class, current_class_type))
+       expr = (build_class_member_access_expr 
+               (maybe_dummy_object (qualifying_class, NULL),
+                expr,
+                BASELINK_ACCESS_BINFO (expr),
+                /*preserve_reference=*/false));
+      else if (done)
+       {
+         /* The expression is a qualified name whose address is not
+            being taken.  */
+         expr = build_offset_ref (qualifying_class, expr);
+         if (TREE_CODE (expr) == OFFSET_REF)
+           expr = resolve_offset_ref (expr);
+       }
+    }
+
+  return expr;
+}
+
 /* Begin a statement-expression.  The value returned must be passed to
    finish_stmt_expr.  */
 
@@ -1548,16 +1661,6 @@ finish_object_call_expr (tree fn, tree object, tree args)
     return build_new_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
 }
 
-/* Finish a qualified member function call using OBJECT and ARGS as
-   arguments to FN.  Returns an expression for the call.  */
-
-tree 
-finish_qualified_object_call_expr (tree fn, tree object, tree args)
-{
-  return build_scoped_method_call (object, TREE_OPERAND (fn, 0),
-                                  TREE_OPERAND (fn, 1), args);
-}
-
 /* Finish a pseudo-destructor expression.  If SCOPE is NULL, the
    expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
    the TYPE for the type given.  If SCOPE is non-NULL, the expression
index 5be6aa88602919c1ffc5298686d4de82ef973c78..e6abb3df57f28e2bed9544737956c08a4293212c 100644 (file)
@@ -72,8 +72,7 @@ static tree lookup_destructor (tree, tree, tree);
 tree
 target_type (tree type)
 {
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+  type = non_reference (type);
   while (TREE_CODE (type) == POINTER_TYPE
         || TREE_CODE (type) == ARRAY_TYPE
         || TREE_CODE (type) == FUNCTION_TYPE
@@ -1421,9 +1420,8 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, int complain)
     return build_min_nt (op, type);
   
   op_name = operator_name_info[(int) op].name;
-  
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+
+  type = non_reference (type);
   type_code = TREE_CODE (type);
 
   if (type_code == METHOD_TYPE)
@@ -5888,8 +5886,7 @@ tree
 dubious_conversion_warnings (tree type, tree expr,
                             const char *errtype, tree fndecl, int parmnum)
 {
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
+  type = non_reference (type);
   
   /* Issue warnings about peculiar, but valid, uses of NULL.  */
   if (ARITHMETIC_TYPE_P (type) && expr == null_node)
@@ -6102,8 +6099,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
   if (exp == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (rhstype) == REFERENCE_TYPE)
-    rhstype = TREE_TYPE (rhstype);
+  rhstype = non_reference (rhstype);
 
   type = complete_type (type);
 
@@ -6708,3 +6704,14 @@ strip_all_pointer_quals (tree type)
   else
     return TYPE_MAIN_VARIANT (type);
 }
+
+/* If T is a REFERENCE_TYPE return the type to which T refers.
+   Otherwise, return T itself.  */
+
+tree
+non_reference (tree t)
+{
+  if (TREE_CODE (t) == REFERENCE_TYPE)
+    t = TREE_TYPE (t);
+  return t;
+}