OSDN Git Service

PR c++/43648
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 5c8dbcb..8a1bb9f 100644 (file)
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
+#include "intl.h"
 #include "c-pragma.h"
 #include "decl.h"
 #include "flags.h"
@@ -889,6 +890,7 @@ make_declarator (cp_declarator_kind kind)
   declarator->attributes = NULL_TREE;
   declarator->declarator = NULL;
   declarator->parameter_pack_p = false;
+  declarator->id_loc = UNKNOWN_LOCATION;
 
   return declarator;
 }
@@ -3895,13 +3897,15 @@ cp_parser_unqualified_id (cp_parser* parser,
          }
        gcc_assert (!scope || TYPE_P (scope));
 
-       /* If the name is of the form "X::~X" it's OK.  */
+       /* If the name is of the form "X::~X" it's OK even if X is a
+          typedef.  */
        token = cp_lexer_peek_token (parser->lexer);
        if (scope
            && token->type == CPP_NAME
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
                != CPP_LESS)
-           && constructor_name_p (token->u.value, scope))
+           && (token->u.value == TYPE_IDENTIFIER (scope)
+               || constructor_name_p (token->u.value, scope)))
          {
            cp_lexer_consume_token (parser->lexer);
            return build_nt (BIT_NOT_EXPR, scope);
@@ -4439,6 +4443,16 @@ cp_parser_qualifying_entity (cp_parser *parser,
      
       /* Parse a typedef-name or enum-name.  */
       scope = cp_parser_nonclass_name (parser);
+
+      /* "If the name found does not designate a namespace or a class,
+        enumeration, or dependent type, the program is ill-formed."
+
+         We cover classes and dependent types above and namespaces below,
+         so this code is only looking for enums.  */
+      if (!scope || TREE_CODE (scope) != TYPE_DECL
+         || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE)
+       cp_parser_simulate_error (parser);
+
       successful_parse_p = cp_parser_parse_definitely (parser);
     }
   /* If that didn't work, try for a namespace-name.  */
@@ -4537,7 +4551,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* New types cannot be defined in the cast.  */
        saved_message = parser->type_definition_forbidden_message;
        parser->type_definition_forbidden_message
-         = "types may not be defined in casts";
+         = G_("types may not be defined in casts");
 
        /* Look for the opening `<'.  */
        cp_parser_require (parser, CPP_LESS, "%<<%>");
@@ -4600,7 +4614,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* Types cannot be defined in a `typeid' expression.  */
        saved_message = parser->type_definition_forbidden_message;
        parser->type_definition_forbidden_message
-         = "types may not be defined in a %<typeid%> expression";
+         = G_("types may not be defined in a %<typeid%> expression");
        /* We can't be sure yet whether we're looking at a type-id or an
           expression.  */
        cp_parser_parse_tentatively (parser);
@@ -5628,7 +5642,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
        {
        case INDIRECT_REF:
          non_constant_p = "%<*%>";
-         expression = build_x_indirect_ref (cast_expression, "unary *",
+         expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR,
                                              tf_warning_or_error);
          break;
 
@@ -5837,7 +5851,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
      complete.)  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in a new-type-id";
+    = G_("types may not be defined in a new-type-id");
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
                                /*is_trailing_return=*/false,
@@ -6150,7 +6164,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
       /* Types may not be defined in a cast.  */
       saved_message = parser->type_definition_forbidden_message;
       parser->type_definition_forbidden_message
-       = "types may not be defined in casts";
+       = G_("types may not be defined in casts");
       /* Consume the `('.  */
       cp_lexer_consume_token (parser->lexer);
       /* A very tricky bit is that `(struct S) { 3 }' is a
@@ -7071,6 +7085,8 @@ cp_parser_lambda_expression (cp_parser* parser)
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
 
+  cp_parser_lambda_introducer (parser, lambda_expr);
+
   type = begin_lambda_type (lambda_expr);
 
   record_lambda_scope (lambda_expr);
@@ -7078,6 +7094,10 @@ cp_parser_lambda_expression (cp_parser* parser)
   /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
   determine_visibility (TYPE_NAME (type));
 
+  /* Now that we've started the type, add the capture fields for any
+     explicit captures.  */
+  register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
+
   {
     /* Inside the class, surrounding template-parameter-lists do not apply.  */
     unsigned int saved_num_template_parameter_lists
@@ -7085,8 +7105,6 @@ cp_parser_lambda_expression (cp_parser* parser)
 
     parser->num_template_parameter_lists = 0;
 
-    cp_parser_lambda_introducer (parser, lambda_expr);
-
     /* By virtue of defining a local class, a lambda expression has access to
        the private variables of enclosing classes.  */
 
@@ -7385,21 +7403,12 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
                                     sfk_none);
 
-    quals = TYPE_UNQUALIFIED;
-    if (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) == NULL_TREE
-       && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
-      {
-       /* A lambda with no captures has a static op() and a conversion op
-          to function type.  */
-       if (LAMBDA_EXPR_MUTABLE_P (lambda_expr))
-         error ("lambda expression with no captures declared mutable");
-       return_type_specs.storage_class = sc_static;
-      }
-    else if (!LAMBDA_EXPR_MUTABLE_P (lambda_expr))
-      quals = TYPE_QUAL_CONST;
+    quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
+            ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
     declarator = make_call_declarator (declarator, param_list, quals,
                                       exception_spec,
                                        /*late_return_type=*/NULL_TREE);
+    declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
 
     fco = grokmethod (&return_type_specs,
                      declarator,
@@ -8103,7 +8112,7 @@ cp_parser_condition (cp_parser* parser)
      condition.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in conditions";
+    = G_("types may not be defined in conditions");
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_declaration==*/true,
                                /*is_trailing_return=*/false,
@@ -8347,7 +8356,7 @@ cp_parser_for_init_statement (cp_parser* parser)
        return;
     }
 
-  cp_parser_expression_statement (parser, false);
+  cp_parser_expression_statement (parser, NULL_TREE);
 }
 
 /* Parse a jump-statement.
@@ -9513,7 +9522,7 @@ cp_parser_decltype (cp_parser *parser)
 
   /* And create the new one.  */
   parser->type_definition_forbidden_message
-    = "types may not be defined in %<decltype%> expressions";
+    = G_("types may not be defined in %<decltype%> expressions");
 
   /* The restrictions on constant-expressions do not apply inside
      decltype expressions.  */
@@ -10649,14 +10658,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
 
     case RID_TEMPLATE:
       {
-       tree parameter_list;
        tree identifier;
        tree default_argument;
 
        /* Look for the `<'.  */
        cp_parser_require (parser, CPP_LESS, "%<<%>");
        /* Parse the template-parameter-list.  */
-       parameter_list = cp_parser_template_parameter_list (parser);
+       cp_parser_template_parameter_list (parser);
        /* Look for the `>'.  */
        cp_parser_require (parser, CPP_GREATER, "%<>%>");
        /* Look for the `class' keyword.  */
@@ -10790,7 +10798,7 @@ cp_parser_template_id (cp_parser *parser,
   cp_token_position start_of_id = 0;
   deferred_access_check *chk;
   VEC (deferred_access_check,gc) *access_check;
-  cp_token *next_token = NULL, *next_token_2 = NULL, *token = NULL;
+  cp_token *next_token = NULL, *next_token_2 = NULL;
   bool is_identifier;
 
   /* If the next token corresponds to a template-id, there is no need
@@ -10838,7 +10846,6 @@ cp_parser_template_id (cp_parser *parser,
 
   /* Parse the template-name.  */
   is_identifier = false;
-  token = cp_lexer_peek_token (parser->lexer);
   templ = cp_parser_template_name (parser, template_keyword_p,
                                   check_dependency_p,
                                   is_declaration,
@@ -11248,6 +11255,9 @@ cp_parser_template_argument_list (cp_parser* parser)
   parser->non_integral_constant_expression_p = saved_non_ice_p;
   parser->integral_constant_expression_p = saved_ice_p;
   parser->in_template_argument_list_p = saved_in_template_argument_list_p;
+#ifdef ENABLE_CHECKING
+  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+#endif
   return vec;
 }
 
@@ -11515,7 +11525,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
   int declares_class_or_enum;
   cp_decl_specifier_seq decl_specifiers;
   tree extension_specifier = NULL_TREE;
-  cp_token *token;
 
   /* Look for an (optional) storage-class-specifier or
      function-specifier.  */
@@ -11538,7 +11547,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
      control while processing explicit instantiation directives.  */
   push_deferring_access_checks (dk_no_check);
   /* Parse a decl-specifier-seq.  */
-  token = cp_lexer_peek_token (parser->lexer);
   cp_parser_decl_specifier_seq (parser,
                                CP_PARSER_FLAGS_OPTIONAL,
                                &decl_specifiers,
@@ -11995,8 +12003,6 @@ cp_parser_simple_type_specifier (cp_parser* parser,
   /* If the type-specifier was for a built-in type, we're done.  */
   if (type)
     {
-      tree id;
-
       /* Record the type.  */
       if (decl_specs
          && (token->keyword != RID_SIGNED
@@ -12011,7 +12017,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        decl_specs->any_specifiers_p = true;
 
       /* Consume the token.  */
-      id = cp_lexer_consume_token (parser->lexer)->u.value;
+      cp_lexer_consume_token (parser->lexer);
 
       /* There is no valid C++ program where a non-template type is
         followed by a "<".  That usually indicates that the user thought
@@ -13475,6 +13481,11 @@ cp_parser_init_declarator (cp_parser* parser,
      we compute it now.  */
   scope = get_scope_of_declarator (declarator);
 
+  /* Perform any lookups in the declared type which were thought to be
+     dependent, but are not in the scope of the declarator.  */
+  decl_specifiers->type
+    = maybe_update_decl_type (decl_specifiers->type, scope);
+
   /* If we're allowing GNU extensions, look for an asm-specification
      and attributes.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
@@ -13799,7 +13810,6 @@ cp_parser_declarator (cp_parser* parser,
                      bool* parenthesized_p,
                      bool member_p)
 {
-  cp_token *token;
   cp_declarator *declarator;
   enum tree_code code;
   cp_cv_quals cv_quals;
@@ -13814,9 +13824,6 @@ cp_parser_declarator (cp_parser* parser,
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
 
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-
   /* Check for the ptr-operator production.  */
   cp_parser_parse_tentatively (parser);
   /* Parse the ptr-operator.  */
@@ -14101,11 +14108,13 @@ cp_parser_direct_declarator (cp_parser* parser,
                bounds = fold_non_dependent_expr (bounds);
              /* Normally, the array bound must be an integral constant
                 expression.  However, as an extension, we allow VLAs
-                in function scopes.  */
-             else if (!parser->in_function_body)
+                in function scopes as long as they aren't part of a
+                parameter declaration.  */
+             else if (!parser->in_function_body
+                      || current_binding_level->kind == sk_function_parms)
                {
-                 error_at (token->location,
-                           "array bound is not an integer constant");
+                 cp_parser_error (parser,
+                                  "array bound is not an integer constant");
                  bounds = error_mark_node;
                }
              else if (processing_template_decl && !error_operand_p (bounds))
@@ -15011,7 +15020,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
                                 bool *parenthesized_p)
 {
   int declares_class_or_enum;
-  bool greater_than_is_operator_p;
   cp_decl_specifier_seq decl_specifiers;
   cp_declarator *declarator;
   tree default_argument;
@@ -15026,12 +15034,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
      template-parameter, the first non-nested `>' is taken as the end
      of the template parameter-list rather than a greater-than
      operator.  */
-  greater_than_is_operator_p = !template_parm_p;
 
   /* Type definitions may not appear in parameter types.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in parameter types";
+    = G_("types may not be defined in parameter types");
 
   /* Parse the declaration-specifiers.  */
   cp_parser_decl_specifier_seq (parser,
@@ -17221,7 +17228,7 @@ cp_parser_exception_specification_opt (cp_parser* parser)
       /* Types may not be defined in an exception-specification.  */
       saved_message = parser->type_definition_forbidden_message;
       parser->type_definition_forbidden_message
-       = "types may not be defined in an exception-specification";
+       = G_("types may not be defined in an exception-specification");
       /* Parse the type-id-list.  */
       type_id_list = cp_parser_type_id_list (parser);
       /* Restore the saved message.  */
@@ -17402,7 +17409,7 @@ cp_parser_exception_declaration (cp_parser* parser)
   /* Types may not be defined in exception-declarations.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in exception-declarations";
+    = G_("types may not be defined in exception-declarations");
 
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
@@ -18214,10 +18221,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
       if (declarator->u.id.qualifying_scope)
        {
          tree scope;
-         tree member;
 
          scope = declarator->u.id.qualifying_scope;
-         member = declarator->u.id.unqualified_name;
 
          while (scope && CLASS_TYPE_P (scope))
            {
@@ -23116,7 +23121,6 @@ pragma_lex (tree *value)
 void
 c_parse_file (void)
 {
-  bool error_occurred;
   static bool already_called = false;
 
   if (already_called)
@@ -23129,7 +23133,7 @@ c_parse_file (void)
   the_parser = cp_parser_new ();
   push_deferring_access_checks (flag_access_control
                                ? dk_no_deferred : dk_no_check);
-  error_occurred = cp_parser_translation_unit (the_parser);
+  cp_parser_translation_unit (the_parser);
   the_parser = NULL;
 }