[08/11] Add PARSER_LEAVE_BLOCK_ALONE flag

Message ID 20230504-frameless-v1-8-4191201740b0@adacore.com
State New
Headers
Series Fix frame-less expression evaluation in DAP |

Commit Message

Tom Tromey May 4, 2023, 2:21 p.m. UTC
  This adds a PARSER_LEAVE_BLOCK_ALONE flag, and changes the parse API
to respect it.  This flag lets callers avoid any change to the
passed-in block and expression PC, letting them specify the context
exactly.  In particular, now nullptr can be used to indicate that the
parse should not examine any local variables.
---
 gdb/expression.h |  6 ++++++
 gdb/parse.c      | 37 +++++++++++++++++++++----------------
 2 files changed, 27 insertions(+), 16 deletions(-)
  

Patch

diff --git a/gdb/expression.h b/gdb/expression.h
index c485b159ef8..d1858776e8e 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -301,6 +301,12 @@  enum parser_flag
      it parses.  For yacc-based parsers, this translates to setting
      yydebug.  */
   PARSER_DEBUG = (1 << 2),
+
+  /* Normally the expression-parsing functions like parse_exp_1 will
+     attempt to find a context block if one is not passed in.  If set,
+     this flag suppresses this search and uses a null context for the
+     parse.  */
+  PARSER_LEAVE_BLOCK_ALONE = (1 << 3),
 };
 DEF_ENUM_FLAGS_TYPE (enum parser_flag, parser_flags);
 
diff --git a/gdb/parse.c b/gdb/parse.c
index bbe5cf12d37..221733a3f90 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -344,26 +344,31 @@  parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
   if (tracker == nullptr)
     tracker = &local_tracker;
 
-  /* If no context specified, try using the current frame, if any.  */
-  if (!expression_context_block)
-    expression_context_block = get_selected_block (&expression_context_pc);
-  else if (pc == 0)
-    expression_context_pc = expression_context_block->entry_pc ();
-  else
-    expression_context_pc = pc;
+  if ((flags & PARSER_LEAVE_BLOCK_ALONE) == 0)
+    {
+      /* If no context specified, try using the current frame, if any.  */
+      if (!expression_context_block)
+	expression_context_block
+	  = get_selected_block (&expression_context_pc);
+      else if (pc == 0)
+	expression_context_pc = expression_context_block->entry_pc ();
+      else
+	expression_context_pc = pc;
 
-  /* Fall back to using the current source static context, if any.  */
+      /* Fall back to using the current source static context, if any.  */
 
-  if (!expression_context_block)
-    {
-      struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+      if (!expression_context_block)
+	{
+	  struct symtab_and_line cursal
+	    = get_current_source_symtab_and_line ();
 
-      if (cursal.symtab)
-	expression_context_block
-	  = cursal.symtab->compunit ()->blockvector ()->static_block ();
+	  if (cursal.symtab)
+	    expression_context_block
+	      = cursal.symtab->compunit ()->blockvector ()->static_block ();
 
-      if (expression_context_block)
-	expression_context_pc = expression_context_block->entry_pc ();
+	  if (expression_context_block)
+	    expression_context_pc = expression_context_block->entry_pc ();
+	}
     }
 
   if (language_mode == language_mode_auto && block != NULL)