OSDN Git Service

PR middle-end/42344
[pf3gnuchains/gcc-fork.git] / gcc / c-parser.c
index 3f6e949..bf66a58 100644 (file)
@@ -72,6 +72,10 @@ c_parse_init (void)
   tree id;
   int mask = 0;
 
+  /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
+     the c_token structure.  */
+  gcc_assert (RID_MAX <= 255);
+
   mask |= D_CXXONLY;
   if (!flag_isoc99)
     mask |= D_C99;
@@ -132,6 +136,8 @@ typedef enum c_id_kind {
   C_ID_TYPENAME,
   /* An identifier declared as an Objective-C class name.  */
   C_ID_CLASSNAME,
+  /* An address space identifier.  */
+  C_ID_ADDRSPACE,
   /* Not an identifier.  */
   C_ID_NONE
 } c_id_kind;
@@ -226,6 +232,13 @@ c_lex_one_token (c_parser *parser, c_token *token)
                            "identifier %qE conflicts with C++ keyword",
                            token->value);
              }
+           else if (rid_code >= RID_FIRST_ADDR_SPACE
+                    && rid_code <= RID_LAST_ADDR_SPACE)
+             {
+               token->id_kind = C_ID_ADDRSPACE;
+               token->keyword = rid_code;
+               break;
+             }
            else if (c_dialect_objc ())
              {
                if (!objc_is_reserved_word (token->value)
@@ -352,6 +365,8 @@ c_token_starts_typename (c_token *token)
        {
        case C_ID_ID:
          return false;
+       case C_ID_ADDRSPACE:
+         return true;
        case C_ID_TYPENAME:
          return true;
        case C_ID_CLASSNAME:
@@ -422,6 +437,8 @@ c_token_starts_declspecs (c_token *token)
        {
        case C_ID_ID:
          return false;
+       case C_ID_ADDRSPACE:
+         return true;
        case C_ID_TYPENAME:
          return true;
        case C_ID_CLASSNAME:
@@ -975,7 +992,7 @@ c_parser_translation_unit (c_parser *parser)
 {
   if (c_parser_next_token_is (parser, CPP_EOF))
     {
-      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
               "ISO C forbids an empty translation unit");
     }
   else
@@ -1061,7 +1078,7 @@ c_parser_external_declaration (c_parser *parser)
        }
       break;
     case CPP_SEMICOLON:
-      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
               "ISO C does not allow extra %<;%> outside of a function");
       c_parser_consume_token (parser);
       break;
@@ -1141,9 +1158,9 @@ c_parser_external_declaration (c_parser *parser)
    C we also allow but diagnose declarations without declaration
    specifiers, but only at top level (elsewhere they conflict with
    other syntax).
-   
+
    OpenMP:
-   
+
    declaration:
      threadprivate-directive  */
 
@@ -1411,6 +1428,7 @@ c_parser_asm_definition (c_parser *parser)
      const
      restrict
      volatile
+     address-space-qualifier
 
    (restrict is new in C99.)
 
@@ -1419,6 +1437,12 @@ c_parser_asm_definition (c_parser *parser)
    declaration-specifiers:
      attributes declaration-specifiers[opt]
 
+   type-qualifier:
+     address-space
+
+   address-space:
+     identifier recognized by the target
+
    storage-class-specifier:
      __thread
 
@@ -1459,6 +1483,17 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
        {
          tree value = c_parser_peek_token (parser)->value;
          c_id_kind kind = c_parser_peek_token (parser)->id_kind;
+
+         if (kind == C_ID_ADDRSPACE)
+           {
+             addr_space_t as
+               = c_parser_peek_token (parser)->keyword - RID_FIRST_ADDR_SPACE;
+             declspecs_add_addrspace (specs, as);
+             c_parser_consume_token (parser);
+             attrs_ok = true;
+             continue;
+           }
+
          /* This finishes the specifiers unless a type name is OK, it
             is declared as a type name and a type name hasn't yet
             been seen.  */
@@ -1873,7 +1908,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
          /* Parse any stray semicolon.  */
          if (c_parser_next_token_is (parser, CPP_SEMICOLON))
            {
-             pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+             pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
                       "extra semicolon in struct or union specified");
              c_parser_consume_token (parser);
              continue;
@@ -1902,7 +1937,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
          else
            {
              if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
-               pedwarn (c_parser_peek_token (parser)->location, 0, 
+               pedwarn (c_parser_peek_token (parser)->location, 0,
                         "no semicolon at end of struct or union");
              else
                {
@@ -1998,7 +2033,7 @@ c_parser_struct_declaration (c_parser *parser)
       tree ret;
       if (!specs->type_seen_p)
        {
-         pedwarn (decl_loc, OPT_pedantic, 
+         pedwarn (decl_loc, OPT_pedantic,
                   "ISO C forbids member declarations with no members");
          shadow_tag_warned (specs, pedantic);
          ret = NULL_TREE;
@@ -2379,7 +2414,7 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
   /* Parse a sequence of array declarators and parameter lists.  */
   if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
     {
-      location_t brace_loc = c_parser_peek_token (parser)->location; 
+      location_t brace_loc = c_parser_peek_token (parser)->location;
       struct c_declarator *declarator;
       struct c_declspecs *quals_attrs = build_null_declspecs ();
       bool static_seen;
@@ -3108,7 +3143,7 @@ c_parser_initelt (c_parser *parser)
       /* Old-style structure member designator.  */
       set_init_label (c_parser_peek_token (parser)->value);
       /* Use the colon as the error location.  */
-      pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic, 
+      pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic,
               "obsolete use of designated initializer with %<:%>");
       c_parser_consume_token (parser);
       c_parser_consume_token (parser);
@@ -3243,7 +3278,7 @@ c_parser_initelt (c_parser *parser)
                  c_parser_consume_token (parser);
                  set_init_index (first, second);
                  if (second)
-                   pedwarn (ellipsis_loc, OPT_pedantic, 
+                   pedwarn (ellipsis_loc, OPT_pedantic,
                             "ISO C forbids specifying range of elements to initialize");
                }
              else
@@ -3256,14 +3291,14 @@ c_parser_initelt (c_parser *parser)
          if (c_parser_next_token_is (parser, CPP_EQ))
            {
              if (!flag_isoc99)
-               pedwarn (des_loc, OPT_pedantic, 
+               pedwarn (des_loc, OPT_pedantic,
                         "ISO C90 forbids specifying subobject to initialize");
              c_parser_consume_token (parser);
            }
          else
            {
              if (des_seen == 1)
-               pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+               pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
                         "obsolete use of designated initializer without %<=%>");
              else
                {
@@ -3350,9 +3385,9 @@ c_parser_initval (c_parser *parser, struct c_expr *after)
    old parser in requiring something after label declarations.
    Although they are erroneous if the labels declared aren't defined,
    is it useful for the syntax to be this way?
-   
+
    OpenMP:
-   
+
    block-item:
      openmp-directive
 
@@ -3461,7 +3496,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
          mark_valid_location_for_stdc_pragma (false);
          c_parser_declaration_or_fndef (parser, true, true, true, true);
          if (last_stmt)
-           pedwarn_c90 (loc, 
+           pedwarn_c90 (loc,
                         (pedantic && !flag_isoc99)
                         ? OPT_pedantic
                         : OPT_Wdeclaration_after_statement,
@@ -3518,13 +3553,13 @@ c_parser_compound_statement_nostart (c_parser *parser)
        }
       else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
         {
-          if (parser->in_if_block) 
+          if (parser->in_if_block)
             {
              mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
               error_at (loc, """expected %<}%> before %<else%>");
               return;
             }
-          else 
+          else
             {
               error_at (loc, "%<else%> without a previous %<if%>");
               c_parser_consume_token (parser);
@@ -3623,7 +3658,7 @@ c_parser_label (c_parser *parser)
          error_at (c_parser_peek_token (parser)->location,
                    "a label can only be part of a statement and "
                    "a declaration is not a statement");
-         c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, 
+         c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
                                         /*nested*/ true, /*empty_ok*/ false,
                                         /*start_attr_ok*/ true);
        }
@@ -3979,7 +4014,7 @@ c_parser_else_body (c_parser *parser)
       add_stmt (build_empty_stmt (loc));
       c_parser_consume_token (parser);
     }
-  else 
+  else
     c_parser_statement_after_labels (parser);
   return c_end_compound_stmt (else_loc, block, flag_isoc99);
 }
@@ -4466,7 +4501,7 @@ c_parser_asm_clobbers (c_parser *parser)
 }
 
 /* Parse asm goto labels, a GNU extension.
+
    asm-goto-operands:
      identifier
      asm-goto-operands , identifier
@@ -4617,7 +4652,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
       tree eptype = NULL_TREE;
-      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
               "ISO C forbids omitting the middle term of a ?: expression");
       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
        {
@@ -5067,7 +5102,7 @@ c_parser_unary_expression (c_parser *parser)
       exp_loc = c_parser_peek_token (parser)->location;
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (exp_loc, op);
-      ret.value = build_indirect_ref (op_loc, op.value, "unary *");
+      ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
       return ret;
     case CPP_PLUS:
       if (!c_dialect_objc () && !in_system_header)
@@ -5349,6 +5384,7 @@ c_parser_postfix_expression (c_parser *parser)
     case CPP_STRING16:
     case CPP_STRING32:
     case CPP_WSTRING:
+    case CPP_UTF8STRING:
       expr.value = c_parser_peek_token (parser)->value;
       expr.original_code = STRING_CST;
       c_parser_consume_token (parser);
@@ -5400,7 +5436,7 @@ c_parser_postfix_expression (c_parser *parser)
          c_parser_compound_statement_nostart (parser);
          c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
                                     "expected %<)%>");
-         pedwarn (loc, OPT_pedantic, 
+         pedwarn (loc, OPT_pedantic,
                   "ISO C forbids braced-groups within expressions");
          expr.value = c_finish_stmt_expr (brace_loc, stmt);
        }
@@ -5774,6 +5810,14 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
   finish_init ();
   maybe_warn_string_init (type, init);
 
+  if (type != error_mark_node
+      && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
+      && current_function_decl)
+    {
+      error ("compound literal qualified by address-space qualifier");
+      type = error_mark_node;
+    }
+
   if (!flag_isoc99)
     pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals");
   non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
@@ -5903,7 +5947,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
          expr.value = build_component_ref (op_loc,
                                            build_indirect_ref (op_loc,
                                                                expr.value,
-                                                               "->"),
+                                                               RO_ARROW),
                                            ident);
          expr.original_code = ERROR_MARK;
          if (TREE_CODE (expr.value) != COMPONENT_REF)
@@ -6172,7 +6216,7 @@ c_parser_objc_class_instance_variables (c_parser *parser)
       /* Parse any stray semicolon.  */
       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
        {
-         pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+         pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
                   "extra semicolon in struct or union specified");
          c_parser_consume_token (parser);
          continue;
@@ -6389,7 +6433,7 @@ c_parser_objc_method_definition (c_parser *parser)
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
       c_parser_consume_token (parser);
-      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
               "extra semicolon in method definition specified");
     }
   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
@@ -6426,7 +6470,7 @@ c_parser_objc_methodprotolist (c_parser *parser)
       switch (c_parser_peek_token (parser)->type)
        {
        case CPP_SEMICOLON:
-         pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, 
+         pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
                   "ISO C does not allow extra %<;%> outside of a function");
          c_parser_consume_token (parser);
          break;
@@ -7002,7 +7046,7 @@ c_parser_pragma (c_parser *parser, enum pragma_context context)
   c_parser_consume_pragma (parser);
   c_invoke_pragma_handler (id);
 
-  /* Skip to EOL, but suppress any error message.  Those will have been 
+  /* Skip to EOL, but suppress any error message.  Those will have been
      generated by the handler routine through calling error, as opposed
      to calling c_parser_error.  */
   parser->error = true;
@@ -7766,7 +7810,7 @@ c_parser_omp_structured_block (c_parser *parser)
    binop:
      +, *, -, /, &, ^, |, <<, >>
 
-  where x is an lvalue expression with scalar type.  
+  where x is an lvalue expression with scalar type.
 
   LOC is the location of the #pragma token.  */
 
@@ -8276,7 +8320,7 @@ c_parser_omp_ordered (location_t loc, c_parser *parser)
 
    section-sequence:
      section-directive[opt] structured-block
-     section-sequence section-directive structured-block  
+     section-sequence section-directive structured-block
 
     SECTIONS_LOC is the location of the #pragma omp sections.  */