]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: Make the parser recognize the [[N]] syntax for variables
authorGuinevere Larsen <guinevere@redhat.com>
Thu, 27 Mar 2025 14:43:58 +0000 (11:43 -0300)
committerGuinevere Larsen <guinevere@redhat.com>
Mon, 28 Apr 2025 12:37:51 +0000 (09:37 -0300)
This commit adds a couple new rules to the YACC parser, that will allow
GDB to recognize expressions like [[N]]::var. Notably, a block
equivalent has not been added yet, so an expression like [[N]]::foo::var
will not work yet.

This is accomplished by introducing a new function,
lookup_symbol_in_linker_namespace, that will only perform the symbol
lookup in the objfiles that belong to the requested namespace.

This function should probably also be used in the generic lookup_symbol
function, as if "var" exists in several namespaces, it is probably more
natural to the user to get the var in the current namespace, if it
exists.  This will be done in a future patch.

gdb/c-exp.y
gdb/solib.c
gdb/symtab.c
gdb/symtab.h

index f53a1383b72be5a079a2df7e35da736c70558568..ea94dad54a504d505443e75af0a62c538d32b204 100644 (file)
@@ -145,6 +145,11 @@ using namespace expr;
     struct symtoken ssym;
     int voidval;
     const struct block *bval;
+    struct scope_val_type_i_guess {
+      bool has_namespace;
+      const struct block *bval;
+      LONGEST namespace_val;
+    } scope_val;
     enum exp_opcode opcode;
 
     struct stoken_vector svec;
@@ -265,7 +270,8 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
 %right ARROW ARROW_STAR '.' DOT_STAR '[' OBJC_LBRAC '('
 %token <ssym> BLOCKNAME
 %token <bval> FILENAME
-%type <bval> block
+%type <typed_val_int> namespace
+%type <scope_val> block
 %left COLONCOLON
 
 %token DOTDOTDOT
@@ -1067,17 +1073,22 @@ exp     :       FALSEKEYWORD
 
 /* end of C++.  */
 
+namespace:     '[' '[' INT ']' ']'
+                       {
+                           $$ = $3;
+                       }
+       ;
+
 block  :       BLOCKNAME
                        {
-                         if ($1.sym.symbol)
-                           $$ = $1.sym.symbol->value_block ();
-                         else
+                         if (!$1.sym.symbol)
                            error (_("No file or function \"%s\"."),
                                   copy_name ($1.stoken).c_str ());
+                         $$.bval = $1.sym.symbol->value_block ();
                        }
        |       FILENAME
                        {
-                         $$ = $1;
+                         $$.bval = $1;
                        }
        ;
 
@@ -1085,14 +1096,17 @@ block   :       block COLONCOLON name
                        {
                          std::string copy = copy_name ($3);
                          struct symbol *tem
-                           = lookup_symbol (copy.c_str (), $1,
+                           = lookup_symbol (copy.c_str (), $1.bval,
                                             SEARCH_FUNCTION_DOMAIN,
                                             nullptr).symbol;
 
                          if (tem == nullptr)
                            error (_("No function \"%s\" in specified context."),
                                   copy.c_str ());
-                         $$ = tem->value_block (); }
+                         $$.bval = tem->value_block ();
+                         $$.has_namespace = $1.has_namespace;
+                         $$.namespace_val = $1.namespace_val;
+                       }
        ;
 
 variable:      name_not_typename ENTRY
@@ -1112,7 +1126,7 @@ variable: block COLONCOLON name
                        {
                          std::string copy = copy_name ($3);
                          struct block_symbol sym
-                           = lookup_symbol (copy.c_str (), $1,
+                           = lookup_symbol (copy.c_str (), $1.bval,
                                             SEARCH_VFT, NULL);
 
                          if (sym.symbol == 0)
@@ -1123,6 +1137,24 @@ variable:        block COLONCOLON name
 
                          pstate->push_new<var_value_operation> (sym);
                        }
+       |       namespace COLONCOLON name
+                       {
+                           std::string sym_name = copy_name ($3);
+
+                           struct block_symbol bsym
+                               = lookup_symbol_in_linker_namespace
+                                   (sym_name.c_str (), $1.val, SEARCH_VFT);
+
+                           if (bsym.symbol == NULL)
+                               error (_("Symbol %s not found in"
+                                        " namespace [[%ld]]"),
+                                        sym_name.c_str (), $1.val);
+
+                           if (symbol_read_needs_frame (bsym.symbol))
+                               pstate->block_tracker->update (bsym);
+
+                           pstate->push_new<var_value_operation> (bsym);
+                       }
        ;
 
 qualified_name:        TYPENAME COLONCOLON name
index 85ec6bb2f1ede061774e4f52ba83c0392e59801b..4e2cc3d1aa57608d76e84c62a2aa63e7be4ed4b5 100644 (file)
@@ -48,6 +48,7 @@
 #include "gdbsupport/scoped_fd.h"
 #include "source.h"
 #include "cli/cli-style.h"
+#include "block.h"
 
 /* See solib.h.  */
 
index 5147aee55d5ef0397017c37e16b72c2afdfe2708..939751613a92468fdf689f58192d2bfc7f2324f7 100644 (file)
@@ -2691,6 +2691,44 @@ lookup_static_symbol (const char *name, const domain_search_flags domain)
 
 /* See symtab.h.  */
 
+struct block_symbol
+lookup_symbol_in_linker_namespace (const char *name, int nsid,
+                                  const domain_search_flags domain)
+{
+  struct gdbarch *gdbarch = current_inferior ()->arch ();
+  const solib_ops *ops = gdbarch_so_ops (gdbarch);
+
+  if (ops->get_solibs_in_ns == nullptr)
+    error (_("Namespaces are not supported by the inferior."));
+
+  std::vector<const solib *> sos_in_namespace = ops->get_solibs_in_ns (nsid);
+  if (sos_in_namespace.size() == 0)
+    error (_("Namespace [[%d]] is inactive"), nsid);
+
+  symbol_lookup_debug_printf ("lookup_symbol_in_linker_namespace (%d, %s, %s)",
+                             nsid, name, domain_name (domain).c_str ());
+
+  /* We look for both global and static symbols in here.  There is no reason
+     to pick one over the other to my knowledge, so we go alphabetical.  */
+  for (const solib *so : sos_in_namespace)
+    {
+      struct block_symbol bsym
+       = lookup_global_symbol_from_objfile (so->objfile, GLOBAL_BLOCK,
+                                            name, domain);
+      if (bsym.symbol != nullptr)
+       return bsym;
+
+      bsym = lookup_global_symbol_from_objfile (so->objfile, STATIC_BLOCK,
+                                               name, domain);
+      if (bsym.symbol != nullptr)
+       return bsym;
+    }
+
+  return {};
+}
+
+/* See symtab.h.  */
+
 struct block_symbol
 lookup_global_symbol (const char *name,
                      const struct block *block,
index e547d109f356fbb41c98b8488611681d0cf1b0eb..d06c00929fe4c90f6f0582f05e40e2c75791fa56 100644 (file)
@@ -2750,6 +2750,14 @@ extern struct block_symbol
                                     const char *name,
                                     const domain_search_flags domain);
 
+/* Lookup symbol NAME from DOMAIN in the linker namespace NSID.
+   This generates a list of all objfiles in NSID, then searches
+   those objfiles for the given symbol.  Searches for both global or
+   static symbols.  */
+extern struct block_symbol
+  lookup_symbol_in_linker_namespace (const char *name, int nsid,
+                                    const domain_search_flags domain);
+
 extern unsigned int symtab_create_debug;
 
 /* Print a "symtab-create" debug statement.  */