diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-07-09 08:48:08 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-07-09 08:48:08 +0000 |
commit | d17811fd1aad24d0f47d0b20679753b23803848b (patch) | |
tree | 1246373b84fbf4bb96eed29b458823d826bd18da /gcc/cp/decl2.c | |
parent | 844c00ed1626fba3304289f5f8c3531620b24d5f (diff) | |
download | gcc-d17811fd1aad24d0f47d0b20679753b23803848b.zip gcc-d17811fd1aad24d0f47d0b20679753b23803848b.tar.gz gcc-d17811fd1aad24d0f47d0b20679753b23803848b.tar.bz2 |
fold-const.c (make_range): Do not access operand 1 for a zero-operand operator.
* fold-const.c (make_range): Do not access operand 1 for a
zero-operand operator.
2003-07-08 Mark Mitchell <mark@codesourcery.com>
* cp-tree.def (NON_DEPENDENT_EXPR): New node.
* cp-tree.h (build_call_from_tree): Remove.
(build_member_call): Likewise.
(dependent_template_arg_p): Remove.
(any_dependent_template_arguments_p): New function.
(dependent_template_id_p): Likewise.
(any_type_dependent_arguments_p): Likewise.
(build_non_dependent_expr): Likewise.
(build_non_dependent_args): Likewise.
(build_x_compound_expr): Adjust prototype.
* call.c (build_new_method_call): Handle non-dependent expressions
correctly.
* decl2.c (grok_array_decl): Likewise.
(build_offset_ref_call_from_tree): Likewise.
(build_call_from_tree): Remove.
* error.c (dump_decl): Handle NON_DEPENDENT_EXPR.
(dump_expr): Likewise.
* init.c (build_member_call): Remove.
* mangle.c (write_expression): Update handling for template-ids.
* parser.c (cp_parser_primary_expression): Use
any_dependent_template_arguments_p. Update constant-expression
handling.
(cp_parser_postfix_expression): Use
any_type_dependent_arguments_p. Simplify call processing.
(cp_parser_unary_expression): Simplify.
(cp_parser_expression): Adjust for changes to
build_x_compound_expr.
(cp_parser_template_argument): Implement standard-conforming
parsing of non-type template arguments.
(cp_parser_direct_declarator): Use
cp_parser_fold_non_dependent_expr.
(cp_parser_fold_non_dependent_expr): New function.
(cp_parser_next_token_ends_template_argument_p): Likewise.
* pt.c (convert_template_argument): Do not call
maybe_fold_nontype_arg.
(tsubst_baselink): Likewise.
(tsubst_copy_and_build): Share common code. Make sizeof/alignof
processing work correctly for non-dependent expressions. Adjust
handling of COMPOUND_EXPR. Simplify call processing.
(value_dependent_expression_p): Deal with functional casts and
sizeof/alignof correctly.
(type_dependent_expression_p): Handle overloaded functions.
(any_type_dependent_arguments_p): New function.
(any_dependent_template_arguments_p): Likewise.
(dependent_template_p): Treat SCOPE_REFs as dependent.
(dependent_template_id_p): Simplify.
(build_non_dependent_expr): New function.
(build_non_dependent_args): Likewise.
* semantics.c (finish_stmt_expr): Don't make dependent
statement-expresions have void type.
(finish_call_expr): Handle non-dependent expressions
correctly.
* tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues.
* typeck.c (cxx_sizeof_or_alignof_type): Give the expression
type size_t, even in templates.
(expr_sizeof): Likewise.
(finish_class_member_access_expr): Handle non-dependent expressions
correctly.
(build_x_indirect_ref): Likewise.
(build_x_binary_op): Likewise.
(build_x_unary_op): Likewise.
(build_x_conditional_expr): Likewise.
(build_x_compound_expr): Likewise.
* typeck2.c (build_x_arrow): Likewise.
2003-07-08 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/mangle17.C: Make sure template expressions are
dependent.
* g++.dg/abi/mangle4.C: Mark erroneous casts.
* g++.dg/debug/debug7.C: Mark erronous new-declarator.
* g++.dg/opt/stack1.C: Remove erroneous code.
* g++.dg/parse/template7.C: New test.
* g++.dg/template/dependent-expr1.C: Mark erroneous code.
* g++.old-deja/g++.pt/crash4.C: Likewise.
2003-07-09 Mark Mitchell <mark@codesourcery.com>
* gcj/array.h (JvPrimClass): Don't parenthesize the output.
From-SVN: r69130
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 192 |
1 files changed, 89 insertions, 103 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7a2399a..c77e503 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -398,59 +398,77 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals) tree grok_array_decl (tree array_expr, tree index_exp) { - tree type = TREE_TYPE (array_expr); - tree p1, p2, i1, i2; + tree type; + tree expr; + tree orig_array_expr = array_expr; + tree orig_index_exp = index_exp; - if (type == error_mark_node || index_exp == error_mark_node) + if (error_operand_p (array_expr) || error_operand_p (index_exp)) return error_mark_node; + if (processing_template_decl) - return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE, - array_expr, index_exp); + { + if (type_dependent_expression_p (array_expr) + || type_dependent_expression_p (index_exp)) + return build_min_nt (ARRAY_REF, array_expr, index_exp); + array_expr = build_non_dependent_expr (array_expr); + index_exp = build_non_dependent_expr (index_exp); + } + type = TREE_TYPE (array_expr); my_friendly_assert (type, 20030626); - type = non_reference (type); /* If they have an `operator[]', use that. */ if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp))) - return build_new_op (ARRAY_REF, LOOKUP_NORMAL, + expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL, array_expr, index_exp, NULL_TREE); - - /* Otherwise, create an ARRAY_REF for a pointer or array type. It - is a little-known fact that, if `a' is an array and `i' is an - int, you can write `i[a]', which means the same thing as `a[i]'. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - p1 = array_expr; else - p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false); + { + tree p1, p2, i1, i2; + + /* Otherwise, create an ARRAY_REF for a pointer or array type. + It is a little-known fact that, if `a' is an array and `i' is + an int, you can write `i[a]', which means the same thing as + `a[i]'. */ + if (TREE_CODE (type) == ARRAY_TYPE) + p1 = array_expr; + else + p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false); - if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE) - p2 = index_exp; - else - p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false); + if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE) + p2 = index_exp; + else + p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false); - i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, false); - i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, false); + i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, + false); + i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, + false); - if ((p1 && i2) && (i1 && p2)) - error ("ambiguous conversion for array subscript"); + if ((p1 && i2) && (i1 && p2)) + error ("ambiguous conversion for array subscript"); - if (p1 && i2) - array_expr = p1, index_exp = i2; - else if (i1 && p2) - array_expr = p2, index_exp = i1; - else - { - error ("invalid types `%T[%T]' for array subscript", - type, TREE_TYPE (index_exp)); - return error_mark_node; - } + if (p1 && i2) + array_expr = p1, index_exp = i2; + else if (i1 && p2) + array_expr = p2, index_exp = i1; + else + { + error ("invalid types `%T[%T]' for array subscript", + type, TREE_TYPE (index_exp)); + return error_mark_node; + } - if (array_expr == error_mark_node || index_exp == error_mark_node) - error ("ambiguous conversion for array subscript"); + if (array_expr == error_mark_node || index_exp == error_mark_node) + error ("ambiguous conversion for array subscript"); - return build_array_ref (array_expr, index_exp); + expr = build_array_ref (array_expr, index_exp); + } + if (processing_template_decl && expr != error_mark_node) + return build_min (ARRAY_REF, TREE_TYPE (expr), orig_array_expr, + orig_index_exp); + return expr; } /* Given the cast expression EXP, checking out its validity. Either return @@ -2949,8 +2967,37 @@ tree build_offset_ref_call_from_tree (tree fn, tree args) { tree object_addr; + tree orig_fn; + tree orig_args; + tree expr; + + orig_fn = fn; + orig_args = args; - my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725); + if (processing_template_decl) + { + tree object; + tree object_type; + + my_friendly_assert (TREE_CODE (fn) == DOTSTAR_EXPR + || TREE_CODE (fn) == MEMBER_REF, + 20030708); + if (type_dependent_expression_p (fn) + || any_type_dependent_arguments_p (args)) + return build_min_nt (CALL_EXPR, fn, args); + + /* Transform the arguments and add the implicit "this" + parameter. That must be done before the FN is transformed + because we depend on the form of FN. */ + args = build_non_dependent_args (args); + object_type = TREE_TYPE (TREE_OPERAND (fn, 0)); + if (TREE_CODE (fn) == DOTSTAR_EXPR) + object_type = build_pointer_type (non_reference (object_type)); + object = build (NON_DEPENDENT_EXPR, object_type); + args = tree_cons (NULL_TREE, object, args); + /* Now that the arguments are done, transform FN. */ + fn = build_non_dependent_expr (fn); + } /* A qualified name corresponding to a bound pointer-to-member is represented as an OFFSET_REF: @@ -2958,79 +3005,18 @@ build_offset_ref_call_from_tree (tree fn, tree args) struct B { void g(); }; void (B::*p)(); void B::g() { (this->*p)(); } */ - if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL) - /* This case should now be handled elsewhere. */ - abort (); - else + if (TREE_CODE (fn) == OFFSET_REF) { object_addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (fn, 0), 0); fn = TREE_OPERAND (fn, 1); fn = get_member_function_from_ptrfunc (&object_addr, fn); args = tree_cons (NULL_TREE, object_addr, args); } - return build_function_call (fn, args); -} - -/* FN indicates the function to call. Name resolution has been - performed on FN. ARGS are the arguments to the function. They - have already been semantically analyzed. DISALLOW_VIRTUAL is true - if the function call should be determined at compile time, even if - FN is virtual. */ - -tree -build_call_from_tree (tree fn, tree args, bool disallow_virtual) -{ - tree template_args; - tree template_id; - tree f; - - /* Check to see that name lookup has already been performed. */ - my_friendly_assert (TREE_CODE (fn) != OFFSET_REF, 20020725); - my_friendly_assert (TREE_CODE (fn) != SCOPE_REF, 20020725); - - /* In the future all of this should be eliminated. Instead, - name-lookup for a member function should simply return a - baselink, instead of a FUNCTION_DECL, TEMPLATE_DECL, or - TEMPLATE_ID_EXPR. */ - - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - { - template_id = fn; - template_args = TREE_OPERAND (fn, 1); - fn = TREE_OPERAND (fn, 0); - } - else - { - template_id = NULL_TREE; - template_args = NULL_TREE; - } - - f = (TREE_CODE (fn) == OVERLOAD) ? get_first_fn (fn) : fn; - /* Make sure we have a baselink (rather than simply a - FUNCTION_DECL) for a member function. */ - if (current_class_type - && ((TREE_CODE (f) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (f)) - || (DECL_FUNCTION_TEMPLATE_P (f) - && DECL_FUNCTION_MEMBER_P (f)))) - { - f = lookup_member (current_class_type, DECL_NAME (f), - /*protect=*/1, /*want_type=*/false); - if (f) - fn = f; - } - - if (template_id) - { - if (BASELINK_P (fn)) - BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR, - BASELINK_FUNCTIONS (fn), - template_args); - else - fn = template_id; - } - return finish_call_expr (fn, args, disallow_virtual); + expr = build_function_call (fn, args); + if (processing_template_decl && expr != error_mark_node) + return build_min (CALL_EXPR, TREE_TYPE (expr), orig_fn, orig_args); + return expr; } /* Returns true if ROOT (a namespace, class, or function) encloses |