aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
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
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')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/decl.c16
-rw-r--r--gcc/cp/parser.c106
-rw-r--r--gcc/cp/ptree.c6
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);