OSDN Git Service

PR c++/43509
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index d27d122..05b5b66 100644 (file)
@@ -24,7 +24,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "dyn-string.h"
-#include "varray.h"
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
@@ -890,6 +889,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;
 }
@@ -1595,7 +1595,9 @@ static tree cp_parser_postfix_open_square_expression
 static tree cp_parser_postfix_dot_deref_expression
   (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
 static VEC(tree,gc) *cp_parser_parenthesized_expression_list
-  (cp_parser *, bool, bool, bool, bool *);
+  (cp_parser *, int, bool, bool, bool *);
+/* Values for the second parameter of cp_parser_parenthesized_expression_list.  */
+enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree *, tree *);
 static tree cp_parser_unary_expression
@@ -3366,6 +3368,11 @@ cp_parser_primary_expression (cp_parser *parser,
          cp_lexer_consume_token (parser->lexer);
          return null_node;
 
+         /* The `nullptr' literal.  */
+       case RID_NULLPTR:
+         cp_lexer_consume_token (parser->lexer);
+         return nullptr_node;
+
          /* Recognize the `this' keyword.  */
        case RID_THIS:
          cp_lexer_consume_token (parser->lexer);
@@ -3896,13 +3903,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);
@@ -4440,6 +4449,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.  */
@@ -4793,7 +4812,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                parser->integral_constant_expression_p = false;
              }
            args = (cp_parser_parenthesized_expression_list
-                   (parser, /*is_attribute_list=*/false,
+                   (parser, non_attr,
                     /*cast_p=*/false, /*allow_expansion_p=*/true,
                     /*non_constant_p=*/NULL));
            if (is_builtin_constant_p)
@@ -5231,20 +5250,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
    Returns a vector of trees.  Each element is a representation of an
    assignment-expression.  NULL is returned if the ( and or ) are
    missing.  An empty, but allocated, vector is returned on no
-   expressions.  The parentheses are eaten.  IS_ATTRIBUTE_LIST is true
-   if this is really an attribute list being parsed.  If
+   expressions.  The parentheses are eaten.  IS_ATTRIBUTE_LIST is id_attr
+   if we are parsing an attribute list for an attribute that wants a
+   plain identifier argument, normal_attr for an attribute that wants
+   an expression, or non_attr if we aren't parsing an attribute list.  If
    NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
    not all of the expressions in the list were constant.  */
 
 static VEC(tree,gc) *
 cp_parser_parenthesized_expression_list (cp_parser* parser,
-                                        bool is_attribute_list,
+                                        int is_attribute_list,
                                         bool cast_p,
                                          bool allow_expansion_p,
                                         bool *non_constant_p)
 {
   VEC(tree,gc) *expression_list;
-  bool fold_expr_p = is_attribute_list;
+  bool fold_expr_p = is_attribute_list != non_attr;
   tree identifier = NULL_TREE;
   bool saved_greater_than_is_operator_p;
 
@@ -5271,7 +5292,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
 
        /* At the beginning of attribute lists, check to see if the
           next token is an identifier.  */
-       if (is_attribute_list
+       if (is_attribute_list == id_attr
            && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
          {
            cp_token *token;
@@ -5332,7 +5353,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
 
        /* After the first item, attribute lists look the same as
           expression lists.  */
-       is_attribute_list = false;
+       is_attribute_list = non_attr;
 
       get_comma:;
        /* If the next token isn't a `,', then we are done.  */
@@ -5807,7 +5828,8 @@ cp_parser_new_placement (cp_parser* parser)
 
   /* Parse the expression-list.  */
   expression_list = (cp_parser_parenthesized_expression_list
-                    (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+                    (parser, non_attr, /*cast_p=*/false,
+                     /*allow_expansion_p=*/true,
                      /*non_constant_p=*/NULL));
 
   return expression_list;
@@ -6013,7 +6035,8 @@ cp_parser_new_initializer (cp_parser* parser)
     }
   else
     expression_list = (cp_parser_parenthesized_expression_list
-                      (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+                      (parser, non_attr, /*cast_p=*/false,
+                       /*allow_expansion_p=*/true,
                        /*non_constant_p=*/NULL));
 
   return expression_list;
@@ -7068,6 +7091,10 @@ cp_parser_lambda_expression (cp_parser* parser)
   LAMBDA_EXPR_LOCATION (lambda_expr)
     = cp_lexer_peek_token (parser->lexer)->location;
 
+  if (cp_unevaluated_operand)
+    error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
+             "lambda-expression in unevaluated context");
+
   /* We may be in the middle of deferred access check.  Disable
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
@@ -7390,21 +7417,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,
@@ -9959,7 +9977,7 @@ cp_parser_mem_initializer (cp_parser* parser)
   else
     {
       VEC(tree,gc)* vec;
-      vec = cp_parser_parenthesized_expression_list (parser, false,
+      vec = cp_parser_parenthesized_expression_list (parser, non_attr,
                                                     /*cast_p=*/false,
                                                     /*allow_expansion_p=*/true,
                                                     /*non_constant_p=*/NULL);
@@ -14104,11 +14122,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))
@@ -15443,7 +15463,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
   else if (token->type == CPP_OPEN_PAREN)
     {
       VEC(tree,gc) *vec;
-      vec = cp_parser_parenthesized_expression_list (parser, false,
+      vec = cp_parser_parenthesized_expression_list (parser, non_attr,
                                                     /*cast_p=*/false,
                                                     /*allow_expansion_p=*/true,
                                                     non_constant_p);
@@ -16389,6 +16409,9 @@ cp_parser_class_head (cp_parser* parser,
       end_specialization ();
       --parser->num_template_parameter_lists;
     }
+
+  if (type)
+    DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
   *attributes_p = attributes;
   return type;
 }
@@ -17755,8 +17778,10 @@ cp_parser_attribute_list (cp_parser* parser)
          if (token->type == CPP_OPEN_PAREN)
            {
              VEC(tree,gc) *vec;
+             int attr_flag = (attribute_takes_identifier_p (identifier)
+                              ? id_attr : normal_attr);
              vec = cp_parser_parenthesized_expression_list
-                   (parser, true, /*cast_p=*/false,
+                   (parser, attr_flag, /*cast_p=*/false,
                     /*allow_expansion_p=*/false,
                     /*non_constant_p=*/NULL);
              if (vec == NULL)
@@ -18958,7 +18983,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
     }
 
 
-  vec = cp_parser_parenthesized_expression_list (parser, false,
+  vec = cp_parser_parenthesized_expression_list (parser, non_attr,
                                                 /*cast_p=*/true,
                                                 /*allow_expansion_p=*/true,
                                                 /*non_constant_p=*/NULL);