aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-12-27 09:05:17 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-12-27 09:05:17 +0000
commitd85d3d578a5c2abcf2b071ef42a558a4ed18b55c (patch)
tree54ef59d674eb69b32d822563e62bc42a55204106 /gcc/cp/parser.c
parentdec2f8810bf2a30c8fa8d0714074df10dc04bc5c (diff)
downloadgcc-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/parser.c')
-rw-r--r--gcc/cp/parser.c106
1 files changed, 70 insertions, 36 deletions
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 ':'. */