Add target_ops argument to to_info_record
[deliverable/binutils-gdb.git] / gdb / c-exp.y
index 77713dd35f1ed407524eb2c7f8021d208c142987..4704845e203efc45917df0d7e33a1751dda12806 100644 (file)
@@ -1,5 +1,5 @@
 /* YACC parser for C expressions, for GDB.
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -36,7 +36,7 @@
 %{
 
 #include "defs.h"
-#include "gdb_string.h"
+#include <string.h>
 #include <ctype.h>
 #include "expression.h"
 #include "value.h"
@@ -169,8 +169,10 @@ static struct stoken operator_stoken (const char *);
 static void check_parameter_typelist (VEC (type_ptr) *);
 static void write_destructor_name (struct stoken);
 
+#ifdef YYBISON
 static void c_print_token (FILE *file, int type, YYSTYPE value);
 #define YYPRINT(FILE, TYPE, VALUE) c_print_token (FILE, TYPE, VALUE)
+#endif
 %}
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
@@ -2415,7 +2417,7 @@ static int last_was_structop;
 /* Read one token, getting characters through lexptr.  */
 
 static int
-lex_one_token (void)
+lex_one_token (int *is_quoted_name)
 {
   int c;
   int namelen;
@@ -2425,6 +2427,7 @@ lex_one_token (void)
   char *copy;
 
   last_was_structop = 0;
+  *is_quoted_name = 0;
 
  retry:
 
@@ -2669,6 +2672,8 @@ lex_one_token (void)
              {
                ++tokstart;
                namelen = lexptr - tokstart - 1;
+               *is_quoted_name = 1;
+
                goto tryname;
              }
            else if (host_len > 1)
@@ -2813,10 +2818,11 @@ static struct obstack name_obstack;
 
 /* Classify a NAME token.  The contents of the token are in `yylval'.
    Updates yylval and returns the new token type.  BLOCK is the block
-   in which lookups start; this can be NULL to mean the global
-   scope.  */
+   in which lookups start; this can be NULL to mean the global scope.
+   IS_QUOTED_NAME is non-zero if the name token was originally quoted
+   in single quotes.  */
 static int
-classify_name (const struct block *block)
+classify_name (const struct block *block, int is_quoted_name)
 {
   struct symbol *sym;
   char *copy;
@@ -2840,16 +2846,6 @@ classify_name (const struct block *block)
     }
   else if (!sym)
     {
-      /* See if it's a file name. */
-      struct symtab *symtab;
-
-      symtab = lookup_symtab (copy);
-      if (symtab)
-       {
-         yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
-         return FILENAME;
-       }
-
       /* If we found a field of 'this', we might have erroneously
         found a constructor where we wanted a type name.  Handle this
         case by noticing that we found a constructor and then look up
@@ -2869,6 +2865,24 @@ classify_name (const struct block *block)
              return TYPENAME;
            }
        }
+
+      /* If we found a field, then we want to prefer it over a
+        filename.  However, if the name was quoted, then it is better
+        to check for a filename or a block, since this is the only
+        way the user has of requiring the extension to be used.  */
+      if (is_a_field_of_this.type == NULL || is_quoted_name)
+       {
+         /* See if it's a file name. */
+         struct symtab *symtab;
+
+         symtab = lookup_symtab (copy);
+         if (symtab)
+           {
+             yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
+                                              STATIC_BLOCK);
+             return FILENAME;
+           }
+       }
     }
 
   if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
@@ -2938,7 +2952,7 @@ classify_inner_name (const struct block *block, struct type *context)
   char *copy;
 
   if (context == NULL)
-    return classify_name (block);
+    return classify_name (block, 0);
 
   type = check_typedef (context);
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT
@@ -2948,13 +2962,39 @@ classify_inner_name (const struct block *block, struct type *context)
 
   copy = copy_name (yylval.ssym.stoken);
   yylval.ssym.sym = cp_lookup_nested_symbol (type, copy, block);
+
+  /* If no symbol was found, search for a matching base class named
+     COPY.  This will allow users to enter qualified names of class members
+     relative to the `this' pointer.  */
   if (yylval.ssym.sym == NULL)
-    return ERROR;
+    {
+      struct type *base_type = find_type_baseclass_by_name (type, copy);
+
+      if (base_type != NULL)
+       {
+         yylval.tsym.type = base_type;
+         return TYPENAME;
+       }
+
+      return ERROR;
+    }
 
   switch (SYMBOL_CLASS (yylval.ssym.sym))
     {
     case LOC_BLOCK:
     case LOC_LABEL:
+      /* cp_lookup_nested_symbol might have accidentally found a constructor
+        named COPY when we really wanted a base class of the same name.
+        Double-check this case by looking for a base class.  */
+      {
+       struct type *base_type = find_type_baseclass_by_name (type, copy);
+
+       if (base_type != NULL)
+         {
+           yylval.tsym.type = base_type;
+           return TYPENAME;
+         }
+      }
       return ERROR;
 
     case LOC_TYPEDEF:
@@ -2986,6 +3026,7 @@ yylex (void)
   struct type *context_type = NULL;
   int last_to_examine, next_to_examine, checkpoint;
   const struct block *search_block;
+  int is_quoted_name;
 
   if (popping && !VEC_empty (token_and_value, token_fifo))
     goto do_pop;
@@ -2994,9 +3035,9 @@ yylex (void)
   /* Read the first token and decide what to do.  Most of the
      subsequent code is C++-only; but also depends on seeing a "::" or
      name-like token.  */
-  current.token = lex_one_token ();
+  current.token = lex_one_token (&is_quoted_name);
   if (current.token == NAME)
-    current.token = classify_name (expression_context_block);
+    current.token = classify_name (expression_context_block, is_quoted_name);
   if (parse_language->la_language != language_cplus
       || (current.token != TYPENAME && current.token != COLONCOLON
          && current.token != FILENAME))
@@ -3009,7 +3050,11 @@ yylex (void)
   last_was_coloncolon = current.token == COLONCOLON;
   while (1)
     {
-      current.token = lex_one_token ();
+      int ignore;
+
+      /* We ignore quoted names other than the very first one.
+        Subsequent ones do not have any special meaning.  */
+      current.token = lex_one_token (&ignore);
       current.value = yylval;
       VEC_safe_push (token_and_value, token_fifo, &current);
 
@@ -3158,6 +3203,8 @@ c_parse (void)
   return result;
 }
 
+#ifdef YYBISON
+
 /* This is called via the YYPRINT macro when parser debugging is
    enabled.  It prints a token's value.  */
 
@@ -3212,6 +3259,8 @@ c_print_token (FILE *file, int type, YYSTYPE value)
     }
 }
 
+#endif
+
 void
 yyerror (char *msg)
 {
This page took 0.026942 seconds and 4 git commands to generate.