aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-07-08 01:38:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-07-08 01:38:44 +0000
commitee76b9314ba2aa2dc1f59c4efa32ac42dd84147d (patch)
treefd553211eb12fd2f9ce0b66abea29db6c18cd0f0 /gcc/cp
parent923c4cf299afcff993b1ae8f510e997d3aca94f5 (diff)
downloadgcc-ee76b9314ba2aa2dc1f59c4efa32ac42dd84147d.zip
gcc-ee76b9314ba2aa2dc1f59c4efa32ac42dd84147d.tar.gz
gcc-ee76b9314ba2aa2dc1f59c4efa32ac42dd84147d.tar.bz2
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/cp')
-rw-r--r--gcc/cp/ChangeLog56
-rw-r--r--gcc/cp/call.c125
-rw-r--r--gcc/cp/class.c8
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/cvt.c8
-rw-r--r--gcc/cp/decl.c15
-rw-r--r--gcc/cp/decl2.c426
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/except.c9
-rw-r--r--gcc/cp/init.c11
-rw-r--r--gcc/cp/mangle.c9
-rw-r--r--gcc/cp/method.c4
-rw-r--r--gcc/cp/parser.c178
-rw-r--r--gcc/cp/pt.c429
-rw-r--r--gcc/cp/rtti.c8
-rw-r--r--gcc/cp/search.c4
-rw-r--r--gcc/cp/semantics.c123
-rw-r--r--gcc/cp/typeck.c25
18 files changed, 522 insertions, 927 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d1de6c3..888f031 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 29c00de..fbf5c06 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 00e6607..5c276a4 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 85815a2..9d383cf 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 081d3b8..bc9b309 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 54c2336..f0aef38 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 39f6ca5..7158f10 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 17dc118..a9f5b15 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 70c446d..390f12c 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 18a4dcf..f89b424 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 49a9568..63c58ba 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 a0d8b63..e1ffaad 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 1fd2ead..27e73cb 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 af3b556..60383ef 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 33745e5..b28fea6 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 cee35ff..64e5707 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 9301e65..cc1e2ea 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 5be6aa8..e6abb3d 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;
+}