summaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-02 08:16:14 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-02 08:16:14 +0000
commit766ea20013c206911829dcc3f01705578656d0f8 (patch)
treebde0a90afafe80c675b78627a527471633716094 /gcc/cp/parser.c
parent50ebd62c4be721e1ff9751b6029e04050bad6746 (diff)
downloadgcc-766ea20013c206911829dcc3f01705578656d0f8.tar.gz
2012-07-02 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 189108 using svnmerge [gcc/] 2012-07-02 Basile Starynkevitch <basile@starynkevitch.net> * Makefile.in (MELT_REVISION_STR): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@189109 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c91
1 files changed, 54 insertions, 37 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6bc6877c325..027a7b9d07a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2062,9 +2062,9 @@ static tree cp_parser_template_parameter
static tree cp_parser_type_parameter
(cp_parser *, bool *);
static tree cp_parser_template_id
- (cp_parser *, bool, bool, bool);
+ (cp_parser *, bool, bool, enum tag_types, bool);
static tree cp_parser_template_name
- (cp_parser *, bool, bool, bool, bool *);
+ (cp_parser *, bool, bool, bool, enum tag_types, bool *);
static tree cp_parser_template_argument_list
(cp_parser *);
static tree cp_parser_template_argument
@@ -2278,7 +2278,7 @@ static bool cp_parser_check_type_definition
static void cp_parser_check_for_definition_in_return_type
(cp_declarator *, tree, location_t type_location);
static void cp_parser_check_for_invalid_template_id
- (cp_parser *, tree, location_t location);
+ (cp_parser *, tree, enum tag_types, location_t location);
static bool cp_parser_non_integral_constant_expression
(cp_parser *, non_integral_constant);
static void cp_parser_diagnose_invalid_type_name
@@ -2551,7 +2551,9 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
static void
cp_parser_check_for_invalid_template_id (cp_parser* parser,
- tree type, location_t location)
+ tree type,
+ enum tag_types tag_type,
+ location_t location)
{
cp_token_position start = 0;
@@ -2560,7 +2562,12 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
if (TYPE_P (type))
error_at (location, "%qT is not a template", type);
else if (TREE_CODE (type) == IDENTIFIER_NODE)
- error_at (location, "%qE is not a template", type);
+ {
+ if (tag_type != none_type)
+ error_at (location, "%qE is not a class template", type);
+ else
+ error_at (location, "%qE is not a template", type);
+ }
else
error_at (location, "invalid template-id");
/* Remember the location of the invalid "<". */
@@ -4466,6 +4473,7 @@ cp_parser_id_expression (cp_parser *parser,
id = cp_parser_template_id (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
+ none_type,
declarator_p);
/* If that worked, we're done. */
if (cp_parser_parse_definitely (parser))
@@ -4543,6 +4551,7 @@ cp_parser_unqualified_id (cp_parser* parser,
/* Try a template-id. */
id = cp_parser_template_id (parser, template_keyword_p,
check_dependency_p,
+ none_type,
declarator_p);
/* If it worked, we're done. */
if (cp_parser_parse_definitely (parser))
@@ -4554,6 +4563,7 @@ cp_parser_unqualified_id (cp_parser* parser,
case CPP_TEMPLATE_ID:
return cp_parser_template_id (parser, template_keyword_p,
check_dependency_p,
+ none_type,
declarator_p);
case CPP_COMPL:
@@ -4769,6 +4779,7 @@ cp_parser_unqualified_id (cp_parser* parser,
/* Try a template-id. */
id = cp_parser_template_id (parser, template_keyword_p,
/*check_dependency_p=*/true,
+ none_type,
declarator_p);
/* If that worked, we're done. */
if (cp_parser_parse_definitely (parser))
@@ -6280,6 +6291,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
cp_parser_template_id (parser,
/*template_keyword_p=*/true,
/*check_dependency_p=*/false,
+ class_type,
/*is_declaration=*/true);
/* Look for the `::' token. */
cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
@@ -6883,41 +6895,34 @@ cp_parser_direct_new_declarator (cp_parser* parser)
while (true)
{
tree expression;
+ cp_token *token;
/* Look for the opening `['. */
cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
- /* The first expression is not required to be constant. */
- if (!declarator)
+
+ token = cp_lexer_peek_token (parser->lexer);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ /* The standard requires that the expression have integral
+ type. DR 74 adds enumeration types. We believe that the
+ real intent is that these expressions be handled like the
+ expression in a `switch' condition, which also allows
+ classes with a single conversion to integral or
+ enumeration type. */
+ if (!processing_template_decl)
{
- cp_token *token = cp_lexer_peek_token (parser->lexer);
- expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
- /* The standard requires that the expression have integral
- type. DR 74 adds enumeration types. We believe that the
- real intent is that these expressions be handled like the
- expression in a `switch' condition, which also allows
- classes with a single conversion to integral or
- enumeration type. */
- if (!processing_template_decl)
+ expression
+ = build_expr_type_conversion (WANT_INT | WANT_ENUM,
+ expression,
+ /*complain=*/true);
+ if (!expression)
{
- expression
- = build_expr_type_conversion (WANT_INT | WANT_ENUM,
- expression,
- /*complain=*/true);
- if (!expression)
- {
- error_at (token->location,
- "expression in new-declarator must have integral "
- "or enumeration type");
- expression = error_mark_node;
- }
+ error_at (token->location,
+ "expression in new-declarator must have integral "
+ "or enumeration type");
+ expression = error_mark_node;
}
}
- /* But all the other expressions must be. */
- else
- expression
- = cp_parser_constant_expression (parser,
- /*allow_non_constant=*/false,
- NULL);
+
/* Look for the closing `]'. */
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
@@ -12383,6 +12388,7 @@ static tree
cp_parser_template_id (cp_parser *parser,
bool template_keyword_p,
bool check_dependency_p,
+ enum tag_types tag_type,
bool is_declaration)
{
int i;
@@ -12439,6 +12445,7 @@ cp_parser_template_id (cp_parser *parser,
templ = cp_parser_template_name (parser, template_keyword_p,
check_dependency_p,
is_declaration,
+ tag_type,
&is_identifier);
if (templ == error_mark_node || is_identifier)
{
@@ -12611,6 +12618,7 @@ cp_parser_template_name (cp_parser* parser,
bool template_keyword_p,
bool check_dependency_p,
bool is_declaration,
+ enum tag_types tag_type,
bool *is_identifier)
{
tree identifier;
@@ -12717,7 +12725,7 @@ cp_parser_template_name (cp_parser* parser,
/* Look up the name. */
decl = cp_parser_lookup_name (parser, identifier,
- none_type,
+ tag_type,
/*is_template=*/true,
/*is_namespace=*/false,
check_dependency_p,
@@ -13667,7 +13675,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user thought
that the type was a template. */
- cp_parser_check_for_invalid_template_id (parser, type, token->location);
+ cp_parser_check_for_invalid_template_id (parser, type, none_type,
+ token->location);
return TYPE_NAME (type);
}
@@ -13706,6 +13715,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
type = cp_parser_template_id (parser,
/*template_keyword_p=*/true,
/*check_dependency_p=*/true,
+ none_type,
/*is_declaration=*/false);
/* If the template-id did not name a type, we are out of
luck. */
@@ -13768,6 +13778,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
followed by a "<". That usually indicates that the user
thought that the type was a template. */
cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
+ none_type,
token->location);
}
@@ -13818,6 +13829,7 @@ cp_parser_type_name (cp_parser* parser)
type_decl = cp_parser_template_id (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/false,
+ none_type,
/*is_declaration=*/false);
/* Note that this must be an instantiation of an alias template
because [temp.names]/6 says:
@@ -14042,6 +14054,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
token = cp_lexer_peek_token (parser->lexer);
decl = cp_parser_template_id (parser, template_p,
/*check_dependency_p=*/true,
+ tag_type,
is_declaration);
/* If we didn't find a template-id, look for an ordinary
identifier. */
@@ -14269,7 +14282,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/* A "<" cannot follow an elaborated type specifier. If that
happens, the user was probably trying to form a template-id. */
- cp_parser_check_for_invalid_template_id (parser, type, token->location);
+ cp_parser_check_for_invalid_template_id (parser, type, tag_type,
+ token->location);
return type;
}
@@ -17872,6 +17886,7 @@ cp_parser_class_name (cp_parser *parser,
/* Try a template-id. */
decl = cp_parser_template_id (parser, template_keyword_p,
check_dependency_p,
+ tag_type,
is_declaration);
if (decl == error_mark_node)
return error_mark_node;
@@ -18324,7 +18339,7 @@ cp_parser_class_head (cp_parser* parser,
= cp_parser_nested_name_specifier_opt (parser,
/*typename_keyword_p=*/false,
/*check_dependency_p=*/false,
- /*type_p=*/false,
+ /*type_p=*/true,
/*is_declaration=*/false);
/* If there was a nested-name-specifier, then there *must* be an
identifier. */
@@ -18399,6 +18414,7 @@ cp_parser_class_head (cp_parser* parser,
id = cp_parser_template_id (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
+ class_key,
/*is_declaration=*/true);
/* If that didn't work, it could still be an identifier. */
if (!cp_parser_parse_definitely (parser))
@@ -18423,6 +18439,7 @@ cp_parser_class_head (cp_parser* parser,
if (id)
{
cp_parser_check_for_invalid_template_id (parser, id,
+ class_key,
type_start_token->location);
}
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);