* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / gdb / c-exp.y
index 981634a0eb1388fbb93797a2b6f2b9699e012f51..1ab991c14c205ba060400c68bc82fc8e8117ffa0 100644 (file)
@@ -102,7 +102,6 @@ yyerror PARAMS ((char *));
 %union
   {
     LONGEST lval;
-    unsigned LONGEST ulval;
     struct {
       LONGEST val;
       struct type *type;
@@ -547,7 +546,8 @@ block       :       BLOCKNAME
 block  :       block COLONCOLON name
                        { struct symbol *tem
                            = lookup_symbol (copy_name ($3), $1,
-                                            VAR_NAMESPACE, 0, NULL);
+                                            VAR_NAMESPACE, (int *) NULL,
+                                            (struct symtab **) NULL);
                          if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
                            error ("No function \"%s\" in specified context.",
                                   copy_name ($3));
@@ -557,12 +557,15 @@ block     :       block COLONCOLON name
 variable:      block COLONCOLON name
                        { struct symbol *sym;
                          sym = lookup_symbol (copy_name ($3), $1,
-                                              VAR_NAMESPACE, 0, NULL);
+                                              VAR_NAMESPACE, (int *) NULL,
+                                              (struct symtab **) NULL);
                          if (sym == 0)
                            error ("No symbol \"%s\" in specified context.",
                                   copy_name ($3));
 
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         /* block_found is set by lookup_symbol.  */
+                         write_exp_elt_block (block_found);
                          write_exp_elt_sym (sym);
                          write_exp_elt_opcode (OP_VAR_VALUE); }
        ;
@@ -613,10 +616,13 @@ variable: qualified_name
                          struct minimal_symbol *msymbol;
 
                          sym =
-                           lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
+                           lookup_symbol (name, (const struct block *) NULL,
+                                          VAR_NAMESPACE, (int *) NULL,
+                                          (struct symtab **) NULL);
                          if (sym)
                            {
                              write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_block (NULL);
                              write_exp_elt_sym (sym);
                              write_exp_elt_opcode (OP_VAR_VALUE);
                              break;
@@ -627,7 +633,7 @@ variable:   qualified_name
                          if (msymbol != NULL)
                            {
                              write_exp_elt_opcode (OP_LONG);
-                             write_exp_elt_type (builtin_type_int);
+                             write_exp_elt_type (builtin_type_long);
                              write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
                              write_exp_elt_opcode (OP_LONG);
                              write_exp_elt_opcode (UNOP_MEMVAL);
@@ -659,8 +665,11 @@ variable:  name_not_typename
                                case LOC_ARG:
                                case LOC_REF_ARG:
                                case LOC_REGPARM:
+                               case LOC_REGPARM_ADDR:
                                case LOC_LOCAL:
                                case LOC_LOCAL_ARG:
+                               case LOC_BASEREG:
+                               case LOC_BASEREG_ARG:
                                  if (innermost_block == 0 ||
                                      contained_in (block_found, 
                                                    innermost_block))
@@ -672,6 +681,7 @@ variable:   name_not_typename
                                case LOC_LABEL:
                                case LOC_BLOCK:
                                case LOC_CONST_BYTES:
+                               case LOC_OPTIMIZED_OUT:
 
                                  /* In this case the expression can
                                     be evaluated regardless of what
@@ -685,6 +695,10 @@ variable:  name_not_typename
                                  break;
                                }
                              write_exp_elt_opcode (OP_VAR_VALUE);
+                             /* We want to use the selected frame, not
+                                another more inner frame which happens to
+                                be in the same block.  */
+                             write_exp_elt_block (NULL);
                              write_exp_elt_sym (sym);
                              write_exp_elt_opcode (OP_VAR_VALUE);
                            }
@@ -712,7 +726,7 @@ variable:   name_not_typename
                              if (msymbol != NULL)
                                {
                                  write_exp_elt_opcode (OP_LONG);
-                                 write_exp_elt_type (builtin_type_int);
+                                 write_exp_elt_type (builtin_type_long);
                                  write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
                                  write_exp_elt_opcode (OP_LONG);
                                  write_exp_elt_opcode (UNOP_MEMVAL);
@@ -957,12 +971,12 @@ parse_number (p, len, parsed_float, putithere)
 {
   register LONGEST n = 0;
   register LONGEST prevn = 0;
-  register int i;
+  register int i = 0;
   register int c;
   register int base = input_radix;
   int unsigned_p = 0;
   int long_p = 0;
-  LONGEST high_bit;
+  unsigned LONGEST high_bit;
   struct type *signed_type;
   struct type *unsigned_type;
 
@@ -1043,17 +1057,26 @@ parse_number (p, len, parsed_float, putithere)
      /* If the number is too big to be an int, or it's got an l suffix
        then it's a long.  Work out if this has to be a long by
        shifting right and and seeing if anything remains, and the
-       target int size is different to the target long size. */
-
-    if ((TARGET_INT_BIT != TARGET_LONG_BIT && (n >> TARGET_INT_BIT)) || long_p)
+       target int size is different to the target long size.
+
+       In the expression below, we could have tested
+               (n >> TARGET_INT_BIT)
+       to see if it was zero,
+       but too many compilers warn about that, when ints and longs
+       are the same size.  So we shift it twice, with fewer bits
+       each time, for the same result.  */
+
+    if (   (TARGET_INT_BIT != TARGET_LONG_BIT 
+            && ((n >> 2) >> (TARGET_INT_BIT-2)))   /* Avoid shift warning */
+        || long_p)
       {
-         high_bit = ((LONGEST)1) << (TARGET_LONG_BIT-1);
+         high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
         unsigned_type = builtin_type_unsigned_long;
         signed_type = builtin_type_long;
       }
     else 
       {
-        high_bit = ((LONGEST)1) << (TARGET_INT_BIT-1);
+        high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
         unsigned_type = builtin_type_unsigned_int;
         signed_type = builtin_type_int;
       }    
@@ -1177,6 +1200,8 @@ yylex ()
          if (namelen > 2)
            {
              lexptr = tokstart + namelen;
+             if (lexptr[-1] != '\'')
+               error ("Unmatched single quote.");
              namelen -= 2;
              tokstart++;
              goto tryname;
@@ -1238,9 +1263,14 @@ yylex ()
 
        for (;; ++p)
          {
+           /* This test includes !hex because 'e' is a valid hex digit
+              and thus does not indicate a floating point number when
+              the radix is hex.  */
            if (!hex && !got_e && (*p == 'e' || *p == 'E'))
              got_dot = got_e = 1;
-           else if (!hex && !got_dot && *p == '.')
+           /* This test does not include !hex, because a '.' always indicates
+              a decimal floating point number regardless of the radix.  */
+           else if (!got_dot && *p == '.')
              got_dot = 1;
            else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
                     && (*p == '-' || *p == '+'))
@@ -1462,7 +1492,8 @@ yylex ()
                                 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
 
          if (lookup_symbol (this_name, expression_context_block,
-                            VAR_NAMESPACE, 0, NULL))
+                            VAR_NAMESPACE, (int *) NULL,
+                            (struct symtab **) NULL))
            return THIS;
        }
       break;
@@ -1499,8 +1530,8 @@ yylex ()
     sym = lookup_symbol (tmp, expression_context_block,
                         VAR_NAMESPACE,
                         current_language->la_language == language_cplus
-                        ? &is_a_field_of_this : NULL,
-                        NULL);
+                        ? &is_a_field_of_this : (int *) NULL,
+                        (struct symtab **) NULL);
     if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
         lookup_partial_symtab (tmp))
       {
@@ -1510,7 +1541,73 @@ yylex ()
       }
     if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
         {
-         yylval.tsym.type = SYMBOL_TYPE (sym);
+         char *p;
+         char *namestart;
+         struct symbol *best_sym;
+
+         /* Look ahead to detect nested types.  This probably should be
+            done in the grammar, but trying seemed to introduce a lot
+            of shift/reduce and reduce/reduce conflicts.  It's possible
+            that it could be done, though.  Or perhaps a non-grammar, but
+            less ad hoc, approach would work well.  */
+
+         /* Since we do not currently have any way of distinguishing
+            a nested type from a non-nested one (the stabs don't tell
+            us whether a type is nested), we just ignore the
+            containing type.  */
+
+         p = lexptr;
+         best_sym = sym;
+         while (1)
+           {
+             /* Skip whitespace.  */
+             while (*p == ' ' || *p == '\t' || *p == '\n')
+               ++p;
+             if (*p == ':' && p[1] == ':')
+               {
+                 /* Skip the `::'.  */
+                 p += 2;
+                 /* Skip whitespace.  */
+                 while (*p == ' ' || *p == '\t' || *p == '\n')
+                   ++p;
+                 namestart = p;
+                 while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
+                        || (*p >= 'a' && *p <= 'z')
+                        || (*p >= 'A' && *p <= 'Z'))
+                   ++p;
+                 if (p != namestart)
+                   {
+                     struct symbol *cur_sym;
+                     /* As big as the whole rest of the expression, which is
+                        at least big enough.  */
+                     char *tmp = alloca (strlen (namestart));
+
+                     memcpy (tmp, namestart, p - namestart);
+                     tmp[p - namestart] = '\0';
+                     cur_sym = lookup_symbol (tmp, expression_context_block,
+                                              VAR_NAMESPACE, (int *) NULL,
+                                              (struct symtab **) NULL);
+                     if (cur_sym)
+                       {
+                         if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
+                           {
+                             best_sym = cur_sym;
+                             lexptr = p;
+                           }
+                         else
+                           break;
+                       }
+                     else
+                       break;
+                   }
+                 else
+                   break;
+               }
+             else
+               break;
+           }
+
+         yylval.tsym.type = SYMBOL_TYPE (best_sym);
          return TYPENAME;
         }
     if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
This page took 0.026272 seconds and 4 git commands to generate.