diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-10-16 19:38:57 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-10-16 19:38:57 +0000 |
commit | 02ed62dd463d55d9d9810b9c8829691e7814743d (patch) | |
tree | 76f4797c33c693120da1fa591e01740f0bef605d /gcc/cp/semantics.c | |
parent | c2b27658fe406ae890354dd825e4060d65df7e0a (diff) | |
download | gcc-02ed62dd463d55d9d9810b9c8829691e7814743d.zip gcc-02ed62dd463d55d9d9810b9c8829691e7814743d.tar.gz gcc-02ed62dd463d55d9d9810b9c8829691e7814743d.tar.bz2 |
re PR c++/22137 (Internal error: Segmentation fault (program cc1plus))
PR c++/22137
* cp-tree.h (QUALIFIED_NAME_IS_TEMPLATE): New macro.
(check_template_keyword): New function.
(finish_id_expression): Change prototoype.
(finish_qualified_id_expr): Change prototype.
(build_qualified_name): New function.
(finish_class_member_access_expr): Change prototype.
* init.c (build_offset_ref): Use build_qualified_name.
* mangle.c (write_expression): Likewise.
* parser.c (cp_parser_primary_expression): Remove qualifying_class
parameter. Add address_p and template_arg_p. Use
build_qualified_name.
(cp_parser_id_expression): Default *template_p to
template_keyword_p. Check for invalid uses of the template
keyword.
(cp_parser_postfix_expression): Eliminate special handling for
qualified names. Adjust call to cp_parser_primary_expression.
(cp_parser_postfix_dot_deref_expression): Adjust call to
cp_parser_id_expression and finish_class_member_access_expr.
(cp_parser_template_argument_list): Add comment.
(cp_parser_template_argument): Adjust use of
cp_parser_primary_expression. Remove call to
finish_qualified_id_expr.
(cp_parser_lookup_name): Use build_qualified_name.
* pt.c (tsubst): Use build_qualified_name.
(tsubst_qualified_id): Likewise. Adjust call to
finish_qualified_id_expr.
(tsubst_copy): Use build_qualified_name.
(tsubst_copy_and_build): Adjusts call to finish_id_expression and
finish_class_member_access_expr.
* semantics.c (finish_non_static_data_member): Use
build_qualified_name.
(finish_qualified_id_expr): Add template_p and template_arg_p
parameters.
(finish_id_expression): Remove qualifiying_class parameter. Add
template_p, done, address_p, and template_arg_p. Use
build_qualified_name. Adjust calls to
finish_class_member_acess_expr.
* tree.c (build_qualified_name): New function.
* typeck.c (check_template_keyword): New function.
(finish_class_member_access_expr): Add template_p argument. Check
for invalid uses of the template keyword.
PR c++/22137
* g++.dg/parse/template18.C: New test.
* g++.dg/template/nontype15.C: Likewise.
From-SVN: r105463
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r-- | gcc/cp/semantics.c | 91 |
1 files changed, 69 insertions, 22 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d870fda..5ccc7c7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1407,8 +1407,10 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) QUALIFYING_SCOPE is also non-null. Wrap this in a SCOPE_REF for now. */ if (processing_template_decl) - return build_min (SCOPE_REF, TREE_TYPE (decl), - qualifying_scope, DECL_NAME (decl)); + return build_qualified_name (TREE_TYPE (decl), + qualifying_scope, + DECL_NAME (decl), + /*template_p=*/false); perform_or_defer_access_check (TYPE_BINFO (access_type), decl); @@ -1494,15 +1496,24 @@ check_accessibility_of_qualified_id (tree decl, 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 '&'. */ + iff this expression is the operand of '&'. TEMPLATE_P is true iff + the qualified-id was of the form "A::template B". TEMPLATE_ARG_P + is true iff this qualified name appears as a template argument. */ tree -finish_qualified_id_expr (tree qualifying_class, tree expr, bool done, - bool address_p) +finish_qualified_id_expr (tree qualifying_class, + tree expr, + bool done, + bool address_p, + bool template_p, + bool template_arg_p) { if (error_operand_p (expr)) return error_mark_node; + if (template_p) + check_template_keyword (expr); + /* If EXPR occurs as the operand of '&', use special handling that permits a pointer-to-member. */ if (address_p && done) @@ -1514,7 +1525,13 @@ finish_qualified_id_expr (tree qualifying_class, tree expr, bool done, return expr; } - if (TREE_CODE (expr) == FIELD_DECL) + /* Within the scope of a class, turn references to non-static + members into expression of the form "this->...". */ + if (template_arg_p) + /* But, within a template argument, we do not want make the + transformation, as there is no "this" pointer. */ + ; + else if (TREE_CODE (expr) == FIELD_DECL) expr = finish_non_static_data_member (expr, current_class_ref, qualifying_class); else if (BASELINK_P (expr) && !processing_template_decl) @@ -2383,6 +2400,13 @@ qualified_name_lookup_error (tree scope, tree name, tree decl) constant-expression, but a non-constant expression is also permissible. + 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 '&'. + TEMPLATE_P is true iff the qualified-id was of the form + "A::template B". TEMPLATE_ARG_P is true iff this qualified name + appears as a template argument. + If an error occurs, and it is the kind of error that might cause the parser to abort a tentative parse, *ERROR_MSG is filled in. It is the caller's responsibility to issue the message. *ERROR_MSG @@ -2401,10 +2425,13 @@ finish_id_expression (tree id_expression, tree decl, tree scope, cp_id_kind *idk, - tree *qualifying_class, bool integral_constant_expression_p, bool allow_non_integral_constant_expression_p, bool *non_integral_constant_expression_p, + bool template_p, + bool done, + bool address_p, + bool template_arg_p, const char **error_msg) { /* Initialize the output parameters. */ @@ -2610,20 +2637,32 @@ finish_id_expression (tree id_expression, dependent. */ if (scope) { - if (TYPE_P (scope)) - *qualifying_class = scope; /* Since this name was dependent, the expression isn't constant -- yet. No error is issued because it might be constant when things are instantiated. */ if (integral_constant_expression_p) *non_integral_constant_expression_p = true; - if (TYPE_P (scope) && dependent_type_p (scope)) - return build_nt (SCOPE_REF, scope, id_expression); - else if (TYPE_P (scope) && DECL_P (decl)) - return convert_from_reference - (build2 (SCOPE_REF, TREE_TYPE (decl), scope, id_expression)); - else - return convert_from_reference (decl); + if (TYPE_P (scope)) + { + if (address_p && done) + decl = finish_qualified_id_expr (scope, decl, + done, address_p, + template_p, + template_arg_p); + else if (dependent_type_p (scope)) + decl = build_qualified_name (/*type=*/NULL_TREE, + scope, + id_expression, + template_p); + else if (DECL_P (decl)) + decl = build_qualified_name (TREE_TYPE (decl), + scope, + id_expression, + template_p); + } + if (TREE_TYPE (decl)) + decl = convert_from_reference (decl); + return decl; } /* A TEMPLATE_ID already contains all the information we need. */ @@ -2703,14 +2742,20 @@ finish_id_expression (tree id_expression, mark_used (decl); if (TREE_CODE (decl) == FIELD_DECL || BASELINK_P (decl)) - *qualifying_class = scope; + decl = finish_qualified_id_expr (scope, + decl, + done, + address_p, + template_p, + template_arg_p); else { tree r = convert_from_reference (decl); - if (processing_template_decl - && TYPE_P (scope)) - r = build2 (SCOPE_REF, TREE_TYPE (r), scope, decl); + if (processing_template_decl && TYPE_P (scope)) + r = build_qualified_name (TREE_TYPE (r), + scope, decl, + template_p); decl = r; } } @@ -2734,13 +2779,15 @@ finish_id_expression (tree id_expression, if (!really_overloaded_fn (decl)) mark_used (first_fn); - if (TREE_CODE (first_fn) == FUNCTION_DECL + if (!template_arg_p + && TREE_CODE (first_fn) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (first_fn) && !shared_member_p (decl)) { /* A set of member functions. */ decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0); - return finish_class_member_access_expr (decl, id_expression); + return finish_class_member_access_expr (decl, id_expression, + /*template_p=*/false); } } else |