OSDN Git Service

PR c++/15946
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 44dceb2..47f5f13 100644 (file)
@@ -402,7 +402,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
    /* Get a new token from the preprocessor.  */
   token->type
     = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
-                       lexer == NULL ? 0 : C_LEX_RAW_STRINGS);
+                       lexer == NULL ? 0 : C_LEX_STRING_NO_JOIN);
   token->keyword = RID_MAX;
   token->pragma_kind = PRAGMA_NONE;
 
@@ -792,6 +792,7 @@ cp_lexer_print_token (FILE * stream, cp_token *token)
     case CPP_STRING16:
     case CPP_STRING32:
     case CPP_WSTRING:
+    case CPP_UTF8STRING:
       fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
       break;
 
@@ -1194,8 +1195,12 @@ enum
   /* The construct is optional.  If it is not present, then no error
      should be issued.  */
   CP_PARSER_FLAGS_OPTIONAL = 0x1,
-  /* When parsing a type-specifier, do not allow user-defined types.  */
-  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2
+  /* When parsing a type-specifier, treat user-defined type-names
+     as non-type identifiers.  */
+  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2,
+  /* When parsing a type-specifier, do not try to parse a class-specifier
+     or enum-specifier.  */
+  CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4
 };
 
 /* This type is used for parameters and variables which hold
@@ -1741,10 +1746,11 @@ static tree cp_parser_type_id
   (cp_parser *);
 static tree cp_parser_template_type_arg
   (cp_parser *);
+static tree cp_parser_trailing_type_id (cp_parser *);
 static tree cp_parser_type_id_1
-  (cp_parser *, bool);
+  (cp_parser *, bool, bool);
 static void cp_parser_type_specifier_seq
-  (cp_parser *, bool, cp_decl_specifier_seq *);
+  (cp_parser *, bool, bool, cp_decl_specifier_seq *);
 static tree cp_parser_parameter_declaration_clause
   (cp_parser *);
 static tree cp_parser_parameter_declaration_list
@@ -2060,7 +2066,8 @@ cp_parser_is_string_literal (cp_token* token)
   return (token->type == CPP_STRING ||
          token->type == CPP_STRING16 ||
          token->type == CPP_STRING32 ||
-         token->type == CPP_WSTRING);
+         token->type == CPP_WSTRING ||
+         token->type == CPP_UTF8STRING);
 }
 
 /* Returns nonzero if TOKEN is the indicated KEYWORD.  */
@@ -2393,6 +2400,11 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
       if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
        error_at (location, "%qE in namespace %qE does not name a type",
                  id, parser->scope);
+      else if (TYPE_P (parser->scope)
+              && dependent_scope_p (parser->scope))
+       error_at (location, "need %<typename%> before %<%T::%E%> to name "
+                 "a type in dependent scope %qT",
+                 parser->scope, id, parser->scope);
       else if (TYPE_P (parser->scope))
        error_at (location, "%qE in class %qT does not name a type",
                  id, parser->scope);
@@ -2426,11 +2438,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
                                /*declarator_p=*/true,
                                /*optional_p=*/false);
   /* After the id-expression, there should be a plain identifier,
-     otherwise this is not a simple variable declaration. Also, if
-     the scope is dependent, we cannot do much.  */
+     otherwise this is not a simple variable declaration.  */
   if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME)
-      || (parser->scope && TYPE_P (parser->scope)
-         && dependent_type_p (parser->scope))
       || TREE_CODE (id) == TYPE_DECL)
     {
       cp_parser_abort_tentative_parse (parser);
@@ -2999,6 +3008,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
        {
        default:
        case CPP_STRING:
+       case CPP_UTF8STRING:
          TREE_TYPE (value) = char_array_type_node;
          break;
        case CPP_STRING16:
@@ -3228,6 +3238,7 @@ cp_parser_primary_expression (cp_parser *parser,
     case CPP_STRING16:
     case CPP_STRING32:
     case CPP_WSTRING:
+    case CPP_UTF8STRING:
       /* ??? Should wide strings be allowed when parser->translate_strings_p
         is false (i.e. in attributes)?  If not, we can kill the third
         argument to cp_parser_string_literal.  */
@@ -5794,7 +5805,8 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
   parser->type_definition_forbidden_message
     = "types may not be defined in a new-type-id";
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                               /*is_trailing_return=*/false,
                                &type_specifier_seq);
   /* Restore the old message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -7080,6 +7092,8 @@ cp_parser_lambda_expression (cp_parser* parser)
       LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
     }
 
+    maybe_add_lambda_conv_op (type);
+
     type = finish_struct (type, /*attributes=*/NULL_TREE);
 
     parser->num_template_parameter_lists = saved_num_template_parameter_lists;
@@ -7337,15 +7351,25 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
                                     sfk_none);
 
-    quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
-            ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
+    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;
     declarator = make_call_declarator (declarator, param_list, quals,
                                       exception_spec,
                                        /*late_return_type=*/NULL_TREE);
 
     fco = grokmethod (&return_type_specs,
-                        declarator,
-                        attributes);
+                     declarator,
+                     attributes);
     DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
     DECL_ARTIFICIAL (fco) = 1;
 
@@ -7738,12 +7762,21 @@ static tree
 cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
 {
   tree statement = NULL_TREE;
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
 
   /* If the next token is a ';', then there is no expression
      statement.  */
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
 
+  /* Give a helpful message for "A<T>::type t;"  */
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
+      && !cp_parser_uncommitted_to_tentative_parse_p (parser)
+      && TREE_CODE (statement) == SCOPE_REF)
+    error_at (token->location, "need %<typename%> before %qE to name "
+             "a type in dependent scope %qT",
+             statement, TREE_OPERAND (statement, 0));
+
   /* Consume the final `;'.  */
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 
@@ -8027,7 +8060,8 @@ cp_parser_condition (cp_parser* parser)
   parser->type_definition_forbidden_message
     = "types may not be defined in conditions";
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition==*/true,
+  cp_parser_type_specifier_seq (parser, /*is_declaration==*/true,
+                               /*is_trailing_return=*/false,
                                &type_specifiers);
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -9541,12 +9575,25 @@ cp_parser_decltype (cp_parser *parser)
     cp_parser_parse_definitely (parser);
   else
     {
+      bool saved_greater_than_is_operator_p;
+
       /* Abort our attempt to parse an id-expression or member access
          expression.  */
       cp_parser_abort_tentative_parse (parser);
 
+      /* Within a parenthesized expression, a `>' token is always
+        the greater-than operator.  */
+      saved_greater_than_is_operator_p
+       = parser->greater_than_is_operator_p;
+      parser->greater_than_is_operator_p = true;
+
       /* Parse a full expression.  */
       expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+
+      /* The `>' token might be the end of a template-id or
+        template-parameter-list now.  */
+      parser->greater_than_is_operator_p
+       = saved_greater_than_is_operator_p;
     }
 
   /* Go back to evaluating expressions.  */
@@ -9655,7 +9702,8 @@ cp_parser_conversion_type_id (cp_parser* parser)
   /* Parse the attributes.  */
   attributes = cp_parser_attributes_opt (parser);
   /* Parse the type-specifiers.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                               /*is_trailing_return=*/false,
                                &type_specifiers);
   /* If that didn't work, stop.  */
   if (type_specifiers.type == error_mark_node)
@@ -11631,6 +11679,9 @@ cp_parser_type_specifier (cp_parser* parser,
   switch (keyword)
     {
     case RID_ENUM:
+      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+       goto elaborated_type_specifier;
+
       /* Look for the enum-specifier.  */
       type_spec = cp_parser_enum_specifier (parser);
       /* If that worked, we're done.  */
@@ -11653,6 +11704,9 @@ cp_parser_type_specifier (cp_parser* parser,
     case RID_CLASS:
     case RID_STRUCT:
     case RID_UNION:
+      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+       goto elaborated_type_specifier;
+
       /* Parse tentatively so that we can back up if we don't find a
         class-specifier.  */
       cp_parser_parse_tentatively (parser);
@@ -12518,7 +12572,8 @@ cp_parser_enum_specifier (cp_parser* parser)
       cp_lexer_consume_token (parser->lexer);
 
       /* Parse the type-specifier-seq.  */
-      cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+      cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                                   /*is_trailing_return=*/false,
                                     &type_specifiers);
 
       /* At this point this is surely not elaborated type specifier.  */
@@ -12802,7 +12857,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
 #ifdef HANDLE_PRAGMA_VISIBILITY
   if (has_visibility)
-    pop_visibility ();
+    pop_visibility (1);
 #endif
 
   /* Finish the namespace.  */
@@ -14409,7 +14464,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
 /* Parse a late-specified return type, if any.  This is not a separate
    non-terminal, but part of a function declarator, which looks like
 
-   -> type-id
+   -> trailing-type-specifier-seq abstract-declarator(opt)
 
    Returns the type indicated by the type-id.  */
 
@@ -14427,7 +14482,7 @@ cp_parser_late_return_type_opt (cp_parser* parser)
   /* Consume the ->.  */
   cp_lexer_consume_token (parser->lexer);
 
-  return cp_parser_type_id (parser);
+  return cp_parser_trailing_type_id (parser);
 }
 
 /* Parse a declarator-id.
@@ -14480,13 +14535,15 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p)
    Returns the TYPE specified.  */
 
 static tree
-cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
+cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
+                    bool is_trailing_return)
 {
   cp_decl_specifier_seq type_specifier_seq;
   cp_declarator *abstract_declarator;
 
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                               is_trailing_return,
                                &type_specifier_seq);
   if (type_specifier_seq.type == error_mark_node)
     return error_mark_node;
@@ -14524,12 +14581,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
 
 static tree cp_parser_type_id (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, false);
+  return cp_parser_type_id_1 (parser, false, false);
 }
 
 static tree cp_parser_template_type_arg (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, true);
+  return cp_parser_type_id_1 (parser, true, false);
+}
+
+static tree cp_parser_trailing_type_id (cp_parser *parser)
+{
+  return cp_parser_type_id_1 (parser, false, true);
 }
 
 /* Parse a type-specifier-seq.
@@ -14542,14 +14604,18 @@ static tree cp_parser_template_type_arg (cp_parser *parser)
    type-specifier-seq:
      attributes type-specifier-seq [opt]
 
-   If IS_CONDITION is true, we are at the start of a "condition",
-   e.g., we've just seen "if (".
+   If IS_DECLARATION is true, we are at the start of a "condition" or
+   exception-declaration, so we might be followed by a declarator-id.
+
+   If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
+   i.e. we've just seen "->".
 
    Sets *TYPE_SPECIFIER_SEQ to represent the sequence.  */
 
 static void
 cp_parser_type_specifier_seq (cp_parser* parser,
-                             bool is_condition,
+                             bool is_declaration,
+                             bool is_trailing_return,
                              cp_decl_specifier_seq *type_specifier_seq)
 {
   bool seen_type_specifier = false;
@@ -14559,6 +14625,12 @@ cp_parser_type_specifier_seq (cp_parser* parser,
   /* Clear the TYPE_SPECIFIER_SEQ.  */
   clear_decl_specs (type_specifier_seq);
 
+  /* In the context of a trailing return type, enum E { } is an
+     elaborated-type-specifier followed by a function-body, not an
+     enum-specifier.  */
+  if (is_trailing_return)
+    flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
+
   /* Parse the type-specifiers and attributes.  */
   while (true)
     {
@@ -14618,7 +14690,7 @@ cp_parser_type_specifier_seq (cp_parser* parser,
         would be clearer just to allow a decl-specifier-seq here, and
         then add a semantic restriction that if any decl-specifiers
         that are not type-specifiers appear, the program is invalid.  */
-      if (is_condition && !is_cv_qualifier)
+      if (is_declaration && !is_cv_qualifier)
        flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
     }
 
@@ -17269,7 +17341,8 @@ cp_parser_exception_declaration (cp_parser* parser)
     = "types may not be defined in exception-declarations";
 
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+                               /*is_trailing_return=*/false,
                                &type_specifiers);
   /* If it's a `)', then there is no declarator.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
@@ -18135,11 +18208,15 @@ cp_parser_check_template_parameters (cp_parser* parser,
        template <class T> void S<T>::R<T>::f ();  */
   if (parser->num_template_parameter_lists < num_templates)
     {
-      if (declarator)
+      if (declarator && !current_function_decl)
        error_at (location, "specializing member %<%T::%E%> "
                  "requires %<template<>%> syntax", 
                  declarator->u.id.qualifying_scope,
                  declarator->u.id.unqualified_name);
+      else if (declarator)
+       error_at (location, "invalid declaration of %<%T::%E%>",
+                 declarator->u.id.qualifying_scope,
+                 declarator->u.id.unqualified_name);
       else 
        error_at (location, "too few template-parameter-lists");
       return false;
@@ -22042,7 +22119,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
             cp_parser_condition, from whence the bulk of this is copied.  */
 
          cp_parser_parse_tentatively (parser);
-         cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+         cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+                                       /*is_trailing_return=*/false,
                                        &type_specifiers);
          if (cp_parser_parse_definitely (parser))
            {
@@ -22361,7 +22439,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
            }
          collapse_err = true;
          cp_parser_statement_seq_opt (parser, NULL);
-         cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+         if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+           break;
        }
     }