diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-12-27 09:05:17 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-12-27 09:05:17 +0000 |
commit | d85d3d578a5c2abcf2b071ef42a558a4ed18b55c (patch) | |
tree | 54ef59d674eb69b32d822563e62bc42a55204106 /gcc/cp | |
parent | dec2f8810bf2a30c8fa8d0714074df10dc04bc5c (diff) | |
download | gcc-d85d3d578a5c2abcf2b071ef42a558a4ed18b55c.zip gcc-d85d3d578a5c2abcf2b071ef42a558a4ed18b55c.tar.gz gcc-d85d3d578a5c2abcf2b071ef42a558a4ed18b55c.tar.bz2 |
re PR c++/25439 ("template<> int A<0>" accepted)
PR c++/25439
* decl.c (grokdeclarator): Remove dead code.
* ptree.c (cxx_print_xnode): Handle BASELINK.
* parser.c (make_id_declarator): Add sfk parameter.
(cp_parser_direct_declarator): Do not pass TYPE_DECLs to
make_id_declarator.
(cp_parser_declarator_id): Simplify BASELINKs here.
(cp_parser_member_declaration): Adjust calls to
make_id_declarator.
PR c++/25439
* g++.dg/parse/crash17.C: Adjust error markers.
* g++.dg/template/error20.C: New test.
From-SVN: r109079
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/decl.c | 16 | ||||
-rw-r--r-- | gcc/cp/parser.c | 106 | ||||
-rw-r--r-- | gcc/cp/ptree.c | 6 |
4 files changed, 88 insertions, 52 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8f27064..ae0fcf5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,17 @@ 2005-12-26 Mark Mitchell <mark@codesourcery.com> + PR c++/25439 + * decl.c (grokdeclarator): Remove dead code. + * ptree.c (cxx_print_xnode): Handle BASELINK. + * parser.c (make_id_declarator): Add sfk parameter. + (cp_parser_direct_declarator): Do not pass TYPE_DECLs to + make_id_declarator. + (cp_parser_declarator_id): Simplify BASELINKs here. + (cp_parser_member_declaration): Adjust calls to + make_id_declarator. + +2005-12-26 Mark Mitchell <mark@codesourcery.com> + PR c++/23171, c++/23172, c++/25417. * typeck.c (build_unary_op): Create temporary variables for compound literals whose addresses are taken. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7517214..d6074d7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6725,10 +6725,6 @@ grokdeclarator (const cp_declarator *declarator, else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL) in_namespace = qualifying_scope; } - if (TREE_CODE (decl) == BASELINK) - decl = BASELINK_FUNCTIONS (decl); - if (decl == error_mark_node) - return error_mark_node; switch (TREE_CODE (decl)) { case BIT_NOT_EXPR: @@ -6792,11 +6788,6 @@ grokdeclarator (const cp_declarator *declarator, } break; - case TYPE_DECL: - dname = constructor_name (TREE_TYPE (decl)); - name = IDENTIFIER_POINTER (dname); - break; - default: gcc_unreachable (); } @@ -7262,8 +7253,6 @@ grokdeclarator (const cp_declarator *declarator, else { unqualified_id = id_declarator->u.id.unqualified_name; - if (TREE_CODE (unqualified_id) == BASELINK) - unqualified_id = BASELINK_FUNCTIONS (unqualified_id); switch (TREE_CODE (unqualified_id)) { case BIT_NOT_EXPR: @@ -7271,11 +7260,6 @@ grokdeclarator (const cp_declarator *declarator, = constructor_name (TREE_OPERAND (unqualified_id, 0)); break; - case TYPE_DECL: - unqualified_id - = constructor_name (TREE_TYPE (unqualified_id)); - break; - case IDENTIFIER_NODE: case TEMPLATE_ID_EXPR: break; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ca56176..86d7edbc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -833,12 +833,15 @@ make_declarator (cp_declarator_kind kind) return declarator; } -/* Make a declarator for a generalized identifier. If non-NULL, the - identifier is QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is - just UNQUALIFIED_NAME. */ +/* Make a declarator for a generalized identifier. If + QUALIFYING_SCOPE is non-NULL, the identifier is + QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just + UNQUALIFIED_NAME. SFK indicates the kind of special function this + is, if any. */ static cp_declarator * -make_id_declarator (tree qualifying_scope, tree unqualified_name) +make_id_declarator (tree qualifying_scope, tree unqualified_name, + special_function_kind sfk) { cp_declarator *declarator; @@ -855,10 +858,14 @@ make_id_declarator (tree qualifying_scope, tree unqualified_name) if (qualifying_scope && TYPE_P (qualifying_scope)) qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope); + gcc_assert (TREE_CODE (unqualified_name) == IDENTIFIER_NODE + || TREE_CODE (unqualified_name) == BIT_NOT_EXPR + || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR); + declarator = make_declarator (cdk_id); declarator->u.id.qualifying_scope = qualifying_scope; declarator->u.id.unqualified_name = unqualified_name; - declarator->u.id.sfk = sfk_none; + declarator->u.id.sfk = sfk; return declarator; } @@ -11354,6 +11361,7 @@ cp_parser_direct_declarator (cp_parser* parser, { tree qualifying_scope; tree unqualified_name; + special_function_kind sfk; /* Parse a declarator-id */ if (dcl_kind == CP_PARSER_DECLARATOR_EITHER) @@ -11411,9 +11419,7 @@ cp_parser_direct_declarator (cp_parser* parser, qualifying_scope = type; } - declarator = make_id_declarator (qualifying_scope, - unqualified_name); - declarator->id_loc = token->location; + sfk = sfk_none; if (unqualified_name) { tree class_type; @@ -11424,28 +11430,9 @@ cp_parser_direct_declarator (cp_parser* parser, else class_type = current_class_type; - if (class_type) + if (TREE_CODE (unqualified_name) == TYPE_DECL) { - if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) - declarator->u.id.sfk = sfk_destructor; - else if (IDENTIFIER_TYPENAME_P (unqualified_name)) - declarator->u.id.sfk = sfk_conversion; - else if (/* There's no way to declare a constructor - for an anonymous type, even if the type - got a name for linkage purposes. */ - !TYPE_WAS_ANONYMOUS (class_type) - && (constructor_name_p (unqualified_name, - class_type) - || (TREE_CODE (unqualified_name) == TYPE_DECL - && (same_type_p - (TREE_TYPE (unqualified_name), - class_type))))) - declarator->u.id.sfk = sfk_constructor; - - if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none) - *ctor_dtor_or_conv_p = -1; - if (qualifying_scope - && TREE_CODE (unqualified_name) == TYPE_DECL + if (qualifying_scope && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name))) { error ("invalid use of constructor as a template"); @@ -11454,9 +11441,50 @@ cp_parser_direct_declarator (cp_parser* parser, class_type, DECL_NAME (TYPE_TI_TEMPLATE (class_type)), class_type, class_type); + declarator = cp_error_declarator; + break; + } + else if (class_type + && same_type_p (TREE_TYPE (unqualified_name), + class_type)) + unqualified_name = constructor_name (class_type); + else + { + /* We do not attempt to print the declarator + here because we do not have enough + information about its original syntactic + form. */ + error ("invalid declarator"); + declarator = cp_error_declarator; + break; } } + + if (class_type) + { + if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) + sfk = sfk_destructor; + else if (IDENTIFIER_TYPENAME_P (unqualified_name)) + sfk = sfk_conversion; + else if (/* There's no way to declare a constructor + for an anonymous type, even if the type + got a name for linkage purposes. */ + !TYPE_WAS_ANONYMOUS (class_type) + && constructor_name_p (unqualified_name, + class_type)) + { + unqualified_name = constructor_name (class_type); + sfk = sfk_constructor; + } + + if (ctor_dtor_or_conv_p && sfk != sfk_none) + *ctor_dtor_or_conv_p = -1; + } } + declarator = make_id_declarator (qualifying_scope, + unqualified_name, + sfk); + declarator->id_loc = token->location; handle_declarator:; scope = get_scope_of_declarator (declarator); @@ -11666,6 +11694,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) static tree cp_parser_declarator_id (cp_parser* parser) { + tree id; /* The expression must be an id-expression. Assume that qualified names are the names of types so that: @@ -11680,11 +11709,14 @@ cp_parser_declarator_id (cp_parser* parser) int S<T>::R<T>::i = 3; will work, too. */ - return cp_parser_id_expression (parser, - /*template_keyword_p=*/false, - /*check_dependency_p=*/false, - /*template_p=*/NULL, - /*declarator_p=*/true); + id = cp_parser_id_expression (parser, + /*template_keyword_p=*/false, + /*check_dependency_p=*/false, + /*template_p=*/NULL, + /*declarator_p=*/true); + if (BASELINK_P (id)) + id = BASELINK_FUNCTIONS (id); + return id; } /* Parse a type-id. @@ -13464,7 +13496,8 @@ cp_parser_member_declaration (cp_parser* parser) /* Create the bitfield declaration. */ decl = grokbitfield (identifier ? make_id_declarator (NULL_TREE, - identifier) + identifier, + sfk_none) : NULL, &decl_specifiers, width); @@ -17095,7 +17128,8 @@ cp_parser_objc_class_ivars (cp_parser* parser) { /* Get the name of the bitfield. */ declarator = make_id_declarator (NULL_TREE, - cp_parser_identifier (parser)); + cp_parser_identifier (parser), + sfk_none); eat_colon: cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index 5d6651c..c222bdc 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -169,6 +169,12 @@ cxx_print_xnode (FILE *file, tree node, int indent) { switch (TREE_CODE (node)) { + case BASELINK: + print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4); + print_node (file, "binfo", BASELINK_BINFO (node), indent + 4); + print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node), + indent + 4); + break; case OVERLOAD: print_node (file, "function", OVL_FUNCTION (node), indent+4); print_node (file, "chain", TREE_CHAIN (node), indent+4); |