diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 153 |
1 files changed, 119 insertions, 34 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4a50b556f46..e8f10a4d000 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "cp-tree.h" #include "intl.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" #include "decl.h" #include "flags.h" #include "diagnostic-core.h" @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "target.h" #include "cgraph.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "plugin.h" @@ -393,7 +393,7 @@ cp_lexer_new_main (void) c_common_no_more_pch (); /* Allocate the memory. */ - lexer = GGC_CNEW (cp_lexer); + lexer = ggc_alloc_cleared_cp_lexer (); #ifdef ENABLE_CHECKING /* Initially we are not debugging. */ @@ -404,7 +404,7 @@ cp_lexer_new_main (void) /* Create the buffer. */ alloc = CP_LEXER_BUFFER_SIZE; - buffer = GGC_NEWVEC (cp_token, alloc); + buffer = ggc_alloc_vec_cp_token (alloc); /* Put the first token in the buffer. */ space = alloc; @@ -445,7 +445,7 @@ cp_lexer_new_from_tokens (cp_token_cache *cache) { cp_token *first = cache->first; cp_token *last = cache->last; - cp_lexer *lexer = GGC_CNEW (cp_lexer); + cp_lexer *lexer = ggc_alloc_cleared_cp_lexer (); /* We do not own the buffer. */ lexer->buffer = NULL; @@ -946,7 +946,7 @@ cp_lexer_stop_debugging (cp_lexer* lexer) static cp_token_cache * cp_token_cache_new (cp_token *first, cp_token *last) { - cp_token_cache *cache = GGC_NEW (cp_token_cache); + cp_token_cache *cache = ggc_alloc_cp_token_cache (); cache->first = first; cache->last = last; return cache; @@ -1496,7 +1496,7 @@ cp_parser_context_new (cp_parser_context* next) memset (context, 0, sizeof (*context)); } else - context = GGC_CNEW (cp_parser_context); + context = ggc_alloc_cleared_cp_parser_context (); /* No errors have occurred yet in this context. */ context->status = CP_PARSER_STATUS_KIND_NO_ERROR; @@ -3093,7 +3093,7 @@ cp_parser_new (void) cp_lexer *lexer; unsigned i; - /* cp_lexer_new_main is called before calling ggc_alloc because + /* cp_lexer_new_main is called before doing GC allocation because cp_lexer_new_main might load a PCH file. */ lexer = cp_lexer_new_main (); @@ -3102,7 +3102,7 @@ cp_parser_new (void) for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++) binops_by_token[binops[i].token_type] = binops[i]; - parser = GGC_CNEW (cp_parser); + parser = ggc_alloc_cleared_cp_parser (); parser->lexer = lexer; parser->context = cp_parser_context_new (NULL); @@ -4605,7 +4605,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, token->type = CPP_NESTED_NAME_SPECIFIER; /* Retrieve any deferred checks. Do not pop this access checks yet so the memory will not be reclaimed during token replacing below. */ - token->u.tree_check_value = GGC_CNEW (struct tree_check); + token->u.tree_check_value = ggc_alloc_cleared_tree_check (); token->u.tree_check_value->value = parser->scope; token->u.tree_check_value->checks = get_deferred_access_checks (); token->u.tree_check_value->qualifying_scope = @@ -5841,6 +5841,51 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, } break; + case RID_NOEXCEPT: + { + tree expr; + const char *saved_message; + bool saved_integral_constant_expression_p; + bool saved_non_integral_constant_expression_p; + bool saved_greater_than_is_operator_p; + + cp_lexer_consume_token (parser->lexer); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + + saved_message = parser->type_definition_forbidden_message; + parser->type_definition_forbidden_message + = G_("types may not be defined in %<noexcept%> expressions"); + + saved_integral_constant_expression_p + = parser->integral_constant_expression_p; + saved_non_integral_constant_expression_p + = parser->non_integral_constant_expression_p; + parser->integral_constant_expression_p = false; + + saved_greater_than_is_operator_p + = parser->greater_than_is_operator_p; + parser->greater_than_is_operator_p = true; + + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; + expr = cp_parser_expression (parser, false, NULL); + --c_inhibit_evaluation_warnings; + --cp_unevaluated_operand; + + parser->greater_than_is_operator_p + = saved_greater_than_is_operator_p; + + parser->integral_constant_expression_p + = saved_integral_constant_expression_p; + parser->non_integral_constant_expression_p + = saved_non_integral_constant_expression_p; + + parser->type_definition_forbidden_message = saved_message; + + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + return finish_noexcept_expr (expr, tf_warning_or_error); + } + default: break; } @@ -6770,15 +6815,20 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) { tree expr; tree assignment_expr; + struct cp_token *token; /* Consume the `?' token. */ cp_lexer_consume_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); if (cp_parser_allow_gnu_extensions_p (parser) - && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + && token->type == CPP_COLON) { + pedwarn (token->location, OPT_pedantic, + "ISO C++ does not allow ?: with omitted middle operand"); /* Implicit true clause. */ expr = NULL_TREE; c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node; + warn_for_omitted_condop (token->location, logical_or_expr); } else { @@ -10136,7 +10186,7 @@ cp_parser_mem_initializer_list (cp_parser* parser) mem-initializer-list. */ if (!DECL_CONSTRUCTOR_P (current_function_decl)) error_at (token->location, - "only constructors take base initializers"); + "only constructors take member initializers"); /* Loop through the list. */ while (true) @@ -11230,7 +11280,7 @@ cp_parser_template_id (cp_parser *parser, token->type = CPP_TEMPLATE_ID; /* Retrieve any deferred checks. Do not pop this access checks yet so the memory will not be reclaimed during token replacing below. */ - token->u.tree_check_value = GGC_CNEW (struct tree_check); + token->u.tree_check_value = ggc_alloc_cleared_tree_check (); token->u.tree_check_value->value = template_id; token->u.tree_check_value->checks = get_deferred_access_checks (); token->keyword = RID_MAX; @@ -17489,13 +17539,50 @@ cp_parser_exception_specification_opt (cp_parser* parser) { cp_token *token; tree type_id_list; + const char *saved_message; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); + + /* Is it a noexcept-specification? */ + if (cp_parser_is_keyword (token, RID_NOEXCEPT)) + { + tree expr; + cp_lexer_consume_token (parser->lexer); + + if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN) + { + cp_lexer_consume_token (parser->lexer); + + /* Types may not be defined in an exception-specification. */ + saved_message = parser->type_definition_forbidden_message; + parser->type_definition_forbidden_message + = G_("types may not be defined in an exception-specification"); + + expr = cp_parser_constant_expression (parser, false, NULL); + + /* Restore the saved message. */ + parser->type_definition_forbidden_message = saved_message; + + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + } + else + expr = boolean_true_node; + + return build_noexcept_spec (expr, tf_warning_or_error); + } + /* If it's not `throw', then there's no exception-specification. */ if (!cp_parser_is_keyword (token, RID_THROW)) return NULL_TREE; +#if 0 + /* Enable this once a lot of code has transitioned to noexcept? */ + if (cxx_dialect == cxx0x && !in_system_header) + warning (OPT_Wdeprecated, "dynamic exception specifications are " + "deprecated in C++0x; use %<noexcept%> instead."); +#endif + /* Consume the `throw'. */ cp_lexer_consume_token (parser->lexer); @@ -17507,8 +17594,6 @@ cp_parser_exception_specification_opt (cp_parser* parser) /* If it's not a `)', then there is a type-id-list. */ if (token->type != CPP_CLOSE_PAREN) { - const char *saved_message; - /* Types may not be defined in an exception-specification. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message @@ -18285,6 +18370,14 @@ cp_parser_lookup_name (cp_parser *parser, tree name, if (dependent_p) pushed_scope = push_scope (parser->scope); + /* If the PARSER->SCOPE is a template specialization, it + may be instantiated during name lookup. In that case, + errors may be issued. Even if we rollback the current + tentative parse, those errors are valid. */ + decl = lookup_qualified_name (parser->scope, name, + tag_type != none_type, + /*complain=*/true); + /* 3.4.3.1: In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C: * if the name specified after the nested-name-specifier, when @@ -18300,17 +18393,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name, shall be used only in the declarator-id of a declaration that names a constructor or in a using-declaration. */ if (tag_type == none_type - && CLASS_TYPE_P (parser->scope) - && constructor_name_p (name, parser->scope)) - name = ctor_identifier; - - /* If the PARSER->SCOPE is a template specialization, it - may be instantiated during name lookup. In that case, - errors may be issued. Even if we rollback the current - tentative parse, those errors are valid. */ - decl = lookup_qualified_name (parser->scope, name, - tag_type != none_type, - /*complain=*/true); + && DECL_SELF_REFERENCE_P (decl) + && same_type_p (DECL_CONTEXT (decl), parser->scope)) + decl = lookup_qualified_name (parser->scope, ctor_identifier, + tag_type != none_type, + /*complain=*/true); /* If we have a single function from a using decl, pull it out. */ if (TREE_CODE (decl) == OVERLOAD @@ -22618,11 +22705,12 @@ static tree cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) { tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret; - tree for_block = NULL_TREE, real_decl, initv, condv, incrv, declv; + tree real_decl, initv, condv, incrv, declv; tree this_pre_body, cl; location_t loc_first; bool collapse_err = false; int i, collapse = 1, nbraces = 0; + VEC(tree,gc) *for_block = make_tree_vector (); for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) @@ -22741,8 +22829,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) LOOKUP_ONLYCONVERTING); if (CLASS_TYPE_P (TREE_TYPE (decl))) { - for_block - = tree_cons (NULL, this_pre_body, for_block); + VEC_safe_push (tree, gc, for_block, this_pre_body); init = NULL_TREE; } else @@ -22996,11 +23083,9 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) } } - while (for_block) - { - add_stmt (pop_stmt_list (TREE_VALUE (for_block))); - for_block = TREE_CHAIN (for_block); - } + while (!VEC_empty (tree, for_block)) + add_stmt (pop_stmt_list (VEC_pop (tree, for_block))); + release_tree_vector (for_block); return ret; } |