* dbxread.c (set_namestring): Remove cast to unsigned. Check N_STRX
[deliverable/binutils-gdb.git] / gdb / c-exp.y
index d8b39752591afbf810c69e34c426f2861a43405c..8ee323e4b78c0810bb66491de4cd51ba80ebc0bc 100644 (file)
@@ -157,6 +157,7 @@ void yyerror (char *);
 %{
 /* YYSTYPE gets defined by %union */
 static int parse_number (char *, int, int, YYSTYPE *);
+static struct stoken operator_stoken (const char *);
 %}
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
@@ -199,9 +200,12 @@ static int parse_number (char *, int, int, YYSTYPE *);
 
 %token <ssym> NAME_OR_INT 
 
+%token OPERATOR
 %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
 %token TEMPLATE
 %token ERROR
+%token NEW DELETE
+%type <sval> operator
 
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
@@ -232,7 +236,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
 %left '+' '-'
 %left '*' '/' '%'
 %right UNARY INCREMENT DECREMENT
-%right ARROW '.' '[' '('
+%right ARROW ARROW_STAR '.' DOT_STAR '[' '('
 %token <ssym> BLOCKNAME 
 %token <bval> FILENAME
 %type <bval> block
@@ -333,7 +337,7 @@ exp :       exp ARROW qualified_name
                          write_exp_elt_opcode (STRUCTOP_MPTR); }
        ;
 
-exp    :       exp ARROW '*' exp
+exp    :       exp ARROW_STAR exp
                        { write_exp_elt_opcode (STRUCTOP_MPTR); }
        ;
 
@@ -368,7 +372,7 @@ exp :       exp '.' qualified_name
                          write_exp_elt_opcode (STRUCTOP_MEMBER); }
        ;
 
-exp    :       exp '.' '*' exp
+exp    :       exp DOT_STAR exp
                        { write_exp_elt_opcode (STRUCTOP_MEMBER); }
        ;
 
@@ -401,6 +405,18 @@ arglist    :       arglist ',' exp   %prec ABOVE_COMMA
                        { arglist_len++; }
        ;
 
+exp     :       exp '(' nonempty_typelist ')' const_or_volatile
+                       { int i;
+                         write_exp_elt_opcode (TYPE_INSTANCE);
+                         write_exp_elt_longcst ((LONGEST) $<ivec>3[0]);
+                         for (i = 0; i < $<ivec>3[0]; ++i)
+                           write_exp_elt_type ($<tvec>3[i + 1]);
+                         write_exp_elt_longcst((LONGEST) $<ivec>3[0]);
+                         write_exp_elt_opcode (TYPE_INSTANCE);
+                         free ($3);
+                       }
+       ;
+
 rcurly :       '}'
                        { $$ = end_arglist () - 1; }
        ;
@@ -703,6 +719,7 @@ variable:   block COLONCOLON name
 qualified_name:        typebase COLONCOLON name
                        {
                          struct type *type = $1;
+                         CHECK_TYPEDEF (type);
                          if (TYPE_CODE (type) != TYPE_CODE_STRUCT
                              && TYPE_CODE (type) != TYPE_CODE_UNION
                              && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
@@ -718,6 +735,7 @@ qualified_name:     typebase COLONCOLON name
                        {
                          struct type *type = $1;
                          struct stoken tmp_token;
+                         CHECK_TYPEDEF (type);
                          if (TYPE_CODE (type) != TYPE_CODE_STRUCT
                              && TYPE_CODE (type) != TYPE_CODE_UNION
                              && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
@@ -775,9 +793,9 @@ variable:   name_not_typename
                            {
                              if (symbol_read_needs_frame (sym))
                                {
-                                 if (innermost_block == 0 ||
-                                     contained_in (block_found, 
-                                                   innermost_block))
+                                 if (innermost_block == 0
+                                     || contained_in (block_found, 
+                                                      innermost_block))
                                    innermost_block = block_found;
                                }
 
@@ -794,8 +812,9 @@ variable:   name_not_typename
                              /* C++: it hangs off of `this'.  Must
                                 not inadvertently convert from a method call
                                 to data ref.  */
-                             if (innermost_block == 0 || 
-                                 contained_in (block_found, innermost_block))
+                             if (innermost_block == 0
+                                 || contained_in (block_found,
+                                                  innermost_block))
                                innermost_block = block_found;
                              write_exp_elt_opcode (OP_THIS);
                              write_exp_elt_opcode (OP_THIS);
@@ -969,11 +988,15 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
                        { $$ = lookup_enum (copy_name ($2),
                                            expression_context_block); }
        |       UNSIGNED typename
-                       { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
+                       { $$ = lookup_unsigned_typename (parse_language,
+                                                        parse_gdbarch,
+                                                        TYPE_NAME($2.type)); }
        |       UNSIGNED
                        { $$ = parse_type->builtin_unsigned_int; }
        |       SIGNED_KEYWORD typename
-                       { $$ = lookup_signed_typename (TYPE_NAME($2.type)); }
+                       { $$ = lookup_signed_typename (parse_language,
+                                                      parse_gdbarch,
+                                                      TYPE_NAME($2.type)); }
        |       SIGNED_KEYWORD
                        { $$ = parse_type->builtin_int; }
                 /* It appears that this rule for templates is never
@@ -1113,10 +1136,130 @@ const_or_volatile_noopt:       const_and_volatile
                        { push_type (tp_volatile); }
        ;
 
+operator:      OPERATOR NEW
+                       { $$ = operator_stoken (" new"); }
+       |       OPERATOR DELETE
+                       { $$ = operator_stoken (" delete"); }
+       |       OPERATOR NEW '[' ']'
+                       { $$ = operator_stoken (" new[]"); }
+       |       OPERATOR DELETE '[' ']'
+                       { $$ = operator_stoken (" delete[]"); }
+       |       OPERATOR '+'
+                       { $$ = operator_stoken ("+"); }
+       |       OPERATOR '-'
+                       { $$ = operator_stoken ("-"); }
+       |       OPERATOR '*'
+                       { $$ = operator_stoken ("*"); }
+       |       OPERATOR '/'
+                       { $$ = operator_stoken ("/"); }
+       |       OPERATOR '%'
+                       { $$ = operator_stoken ("%"); }
+       |       OPERATOR '^'
+                       { $$ = operator_stoken ("^"); }
+       |       OPERATOR '&'
+                       { $$ = operator_stoken ("&"); }
+       |       OPERATOR '|'
+                       { $$ = operator_stoken ("|"); }
+       |       OPERATOR '~'
+                       { $$ = operator_stoken ("~"); }
+       |       OPERATOR '!'
+                       { $$ = operator_stoken ("!"); }
+       |       OPERATOR '='
+                       { $$ = operator_stoken ("="); }
+       |       OPERATOR '<'
+                       { $$ = operator_stoken ("<"); }
+       |       OPERATOR '>'
+                       { $$ = operator_stoken (">"); }
+       |       OPERATOR ASSIGN_MODIFY
+                       { const char *op = "unknown";
+                         switch ($2)
+                           {
+                           case BINOP_RSH:
+                             op = ">>=";
+                             break;
+                           case BINOP_LSH:
+                             op = "<<=";
+                             break;
+                           case BINOP_ADD:
+                             op = "+=";
+                             break;
+                           case BINOP_SUB:
+                             op = "-=";
+                             break;
+                           case BINOP_MUL:
+                             op = "*=";
+                             break;
+                           case BINOP_DIV:
+                             op = "/=";
+                             break;
+                           case BINOP_REM:
+                             op = "%=";
+                             break;
+                           case BINOP_BITWISE_IOR:
+                             op = "|=";
+                             break;
+                           case BINOP_BITWISE_AND:
+                             op = "&=";
+                             break;
+                           case BINOP_BITWISE_XOR:
+                             op = "^=";
+                             break;
+                           default:
+                             break;
+                           }
+
+                         $$ = operator_stoken (op);
+                       }
+       |       OPERATOR LSH
+                       { $$ = operator_stoken ("<<"); }
+       |       OPERATOR RSH
+                       { $$ = operator_stoken (">>"); }
+       |       OPERATOR EQUAL
+                       { $$ = operator_stoken ("=="); }
+       |       OPERATOR NOTEQUAL
+                       { $$ = operator_stoken ("!="); }
+       |       OPERATOR LEQ
+                       { $$ = operator_stoken ("<="); }
+       |       OPERATOR GEQ
+                       { $$ = operator_stoken (">="); }
+       |       OPERATOR ANDAND
+                       { $$ = operator_stoken ("&&"); }
+       |       OPERATOR OROR
+                       { $$ = operator_stoken ("||"); }
+       |       OPERATOR INCREMENT
+                       { $$ = operator_stoken ("++"); }
+       |       OPERATOR DECREMENT
+                       { $$ = operator_stoken ("--"); }
+       |       OPERATOR ','
+                       { $$ = operator_stoken (","); }
+       |       OPERATOR ARROW_STAR
+                       { $$ = operator_stoken ("->*"); }
+       |       OPERATOR ARROW
+                       { $$ = operator_stoken ("->"); }
+       |       OPERATOR '(' ')'
+                       { $$ = operator_stoken ("()"); }
+       |       OPERATOR '[' ']'
+                       { $$ = operator_stoken ("[]"); }
+       |       OPERATOR ptype
+                       { char *name;
+                         long length;
+                         struct ui_file *buf = mem_fileopen ();
+
+                         c_print_type ($2, NULL, buf, -1, 0);
+                         name = ui_file_xstrdup (buf, &length);
+                         ui_file_delete (buf);
+                         $$ = operator_stoken (name);
+                         free (name);
+                       }
+       ;
+
+
+
 name   :       NAME { $$ = $1.stoken; }
        |       BLOCKNAME { $$ = $1.stoken; }
        |       TYPENAME { $$ = $1.stoken; }
        |       NAME_OR_INT  { $$ = $1.stoken; }
+       |       operator { $$ = $1; }
        ;
 
 name_not_typename :    NAME
@@ -1132,6 +1275,23 @@ name_not_typename :      NAME
 
 %%
 
+/* Returns a stoken of the operator name given by OP (which does not
+   include the string "operator").  */ 
+static struct stoken
+operator_stoken (const char *op)
+{
+  static const char *operator_string = "operator";
+  struct stoken st = { NULL, 0 };
+  st.length = strlen (operator_string) + strlen (op);
+  st.ptr = malloc (st.length + 1);
+  strcpy (st.ptr, operator_string);
+  strcat (st.ptr, op);
+
+  /* The toplevel (c_parse) will free the memory allocated here.  */
+  make_cleanup (free, st.ptr);
+  return st;
+};
+
 /* Take care of parsing a number (anything that starts with a digit).
    Set yylval and return the token type; update lexptr.
    LEN is the number of characters in it.  */
@@ -1177,7 +1337,8 @@ parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
          p[len - 2] = '\0';
          putithere->typed_val_decfloat.type
            = parse_type->builtin_decfloat;
-         decimal_from_string (putithere->typed_val_decfloat.val, 4, p);
+         decimal_from_string (putithere->typed_val_decfloat.val, 4,
+                              gdbarch_byte_order (parse_gdbarch), p);
          p[len - 2] = 'd';
          return DECFLOAT;
        }
@@ -1187,7 +1348,8 @@ parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
          p[len - 2] = '\0';
          putithere->typed_val_decfloat.type
            = parse_type->builtin_decdouble;
-         decimal_from_string (putithere->typed_val_decfloat.val, 8, p);
+         decimal_from_string (putithere->typed_val_decfloat.val, 8,
+                              gdbarch_byte_order (parse_gdbarch), p);
          p[len - 2] = 'd';
          return DECFLOAT;
        }
@@ -1197,7 +1359,8 @@ parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
          p[len - 2] = '\0';
          putithere->typed_val_decfloat.type
            = parse_type->builtin_declong;
-         decimal_from_string (putithere->typed_val_decfloat.val, 16, p);
+         decimal_from_string (putithere->typed_val_decfloat.val, 16,
+                              gdbarch_byte_order (parse_gdbarch), p);
          p[len - 2] = 'd';
          return DECFLOAT;
        }
@@ -1433,14 +1596,19 @@ c_parse_escape (char **ptr, struct obstack *output)
     case '5':
     case '6':
     case '7':
-      if (output)
-       obstack_grow_str (output, "\\");
-      while (isdigit (*tokptr) && *tokptr != '8' && *tokptr != '9')
-       {
-         if (output)
-           obstack_1grow (output, *tokptr);
-         ++tokptr;
-       }
+      {
+       int i;
+       if (output)
+         obstack_grow_str (output, "\\");
+       for (i = 0;
+            i < 3 && isdigit (*tokptr) && *tokptr != '8' && *tokptr != '9';
+            ++i)
+         {
+           if (output)
+             obstack_1grow (output, *tokptr);
+           ++tokptr;
+         }
+      }
       break;
 
       /* We handle UCNs later.  We could handle them here, but that
@@ -1652,7 +1820,8 @@ struct token
 static const struct token tokentab3[] =
   {
     {">>=", ASSIGN_MODIFY, BINOP_RSH, 0},
-    {"<<=", ASSIGN_MODIFY, BINOP_LSH, 0}
+    {"<<=", ASSIGN_MODIFY, BINOP_LSH, 0},
+    {"->*", ARROW_STAR, BINOP_END, 1}
   };
 
 static const struct token tokentab2[] =
@@ -1670,13 +1839,16 @@ static const struct token tokentab2[] =
     {"->", ARROW, BINOP_END, 0},
     {"&&", ANDAND, BINOP_END, 0},
     {"||", OROR, BINOP_END, 0},
+    /* "::" is *not* only C++: gdb overrides its meaning in several
+       different ways, e.g., 'filename'::func, function::variable.  */
     {"::", COLONCOLON, BINOP_END, 0},
     {"<<", LSH, BINOP_END, 0},
     {">>", RSH, BINOP_END, 0},
     {"==", EQUAL, BINOP_END, 0},
     {"!=", NOTEQUAL, BINOP_END, 0},
     {"<=", LEQ, BINOP_END, 0},
-    {">=", GEQ, BINOP_END, 0}
+    {">=", GEQ, BINOP_END, 0},
+    {".*", DOT_STAR, BINOP_END, 1}
   };
 
 /* Identifier-like tokens.  */
@@ -1698,6 +1870,9 @@ static const struct token ident_tokens[] =
     {"long", LONG, OP_NULL, 0},
     {"true", TRUEKEYWORD, OP_NULL, 1},
     {"int", INT_KEYWORD, OP_NULL, 0},
+    {"new", NEW, OP_NULL, 1},
+    {"delete", DELETE, OP_NULL, 1},
+    {"operator", OPERATOR, OP_NULL, 1},
 
     {"and", ANDAND, BINOP_END, 1},
     {"and_eq", ASSIGN_MODIFY, BINOP_BITWISE_AND, 1},
@@ -1835,6 +2010,10 @@ yylex (void)
   for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
     if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
       {
+       if (tokentab3[i].cxx_only
+           && parse_language->la_language != language_cplus)
+         break;
+
        lexptr += 3;
        yylval.opcode = tokentab3[i].opcode;
        return tokentab3[i].token;
@@ -1844,6 +2023,10 @@ yylex (void)
   for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
     if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
       {
+       if (tokentab2[i].cxx_only
+           && parse_language->la_language != language_cplus)
+         break;
+
        lexptr += 2;
        yylval.opcode = tokentab2[i].opcode;
        if (in_parse_field && tokentab2[i].token == ARROW)
@@ -2148,9 +2331,9 @@ yylex (void)
     /* Input names that aren't symbols but ARE valid hex numbers,
        when the input radix permits them, can be names or numbers
        depending on the parse.  Note we support radixes > 16 here.  */
-    if (!sym && 
-        ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
-         (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+    if (!sym 
+        && ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10)
+           || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
       {
        YYSTYPE newlval;        /* Its value is ignored.  */
        hextype = parse_number (tokstart, namelen, 0, &newlval);
This page took 0.067742 seconds and 4 git commands to generate.