diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-07-08 01:38:44 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-07-08 01:38:44 +0000 |
commit | ee76b9314ba2aa2dc1f59c4efa32ac42dd84147d (patch) | |
tree | fd553211eb12fd2f9ce0b66abea29db6c18cd0f0 /gcc | |
parent | 923c4cf299afcff993b1ae8f510e997d3aca94f5 (diff) | |
download | gcc-ee76b9314ba2aa2dc1f59c4efa32ac42dd84147d.tar.gz |
cp-tree.h (build_scoped_method_call): Remove.
* 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 56 | ||||
-rw-r--r-- | gcc/cp/call.c | 125 | ||||
-rw-r--r-- | gcc/cp/class.c | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 9 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 15 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 426 | ||||
-rw-r--r-- | gcc/cp/error.c | 2 | ||||
-rw-r--r-- | gcc/cp/except.c | 9 | ||||
-rw-r--r-- | gcc/cp/init.c | 11 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 9 | ||||
-rw-r--r-- | gcc/cp/method.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 178 | ||||
-rw-r--r-- | gcc/cp/pt.c | 429 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 8 | ||||
-rw-r--r-- | gcc/cp/search.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 123 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 25 |
18 files changed, 522 insertions, 927 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d1de6c3bf6d..888f0310a7e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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, diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 29c00de01eb..fbf5c06a32f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 00e66078984..5c276a4a3d0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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) { diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 85815a2c43d..9d383cf24ae 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 081d3b8caca..bc9b309fa25 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 54c2336be11..f0aef38513f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 39f6ca55369..7158f102147 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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 (); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 17dc1185cdb..a9f5b15834a 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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 diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 70c446d7c59..390f12c4551 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -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) { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 18a4dcf988e..f89b4248e65 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 49a956886a7..63c58baf059 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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) diff --git a/gcc/cp/method.c b/gcc/cp/method.c index a0d8b63c972..e1ffaad3769 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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))) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1fd2ead6ab9..27e73cb967f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index af3b5560296..60383ef914a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 33745e57324..b28fea6212a 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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. */ diff --git a/gcc/cp/search.c b/gcc/cp/search.c index cee35ff2d52..64e5707e1f0 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9301e659536..cc1e2ea3e9c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5be6aa88602..e6abb3df57f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; +} |