| /* Parser definitions for GDB. | 
 |  | 
 |    Copyright (C) 1986-2022 Free Software Foundation, Inc. | 
 |  | 
 |    Modified from expread.y by the Department of Computer Science at the | 
 |    State University of New York at Buffalo. | 
 |  | 
 |    This file is part of GDB. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #if !defined (PARSER_DEFS_H) | 
 | #define PARSER_DEFS_H 1 | 
 |  | 
 | #include "expression.h" | 
 | #include "symtab.h" | 
 | #include "expop.h" | 
 |  | 
 | struct block; | 
 | struct language_defn; | 
 | struct internalvar; | 
 | class innermost_block_tracker; | 
 |  | 
 | extern bool parser_debug; | 
 |  | 
 | /* A class that can be used to build a "struct expression".  */ | 
 |  | 
 | struct expr_builder | 
 | { | 
 |   /* Constructor.  LANG is the language used to parse the expression. | 
 |      And GDBARCH is the gdbarch to use during parsing.  */ | 
 |  | 
 |   expr_builder (const struct language_defn *lang, | 
 | 		struct gdbarch *gdbarch) | 
 |     : expout (new expression (lang, gdbarch)) | 
 |   { | 
 |   } | 
 |  | 
 |   DISABLE_COPY_AND_ASSIGN (expr_builder); | 
 |  | 
 |   /* Resize the allocated expression to the correct size, and return | 
 |      it as an expression_up -- passing ownership to the caller.  */ | 
 |   ATTRIBUTE_UNUSED_RESULT expression_up release () | 
 |   { | 
 |     return std::move (expout); | 
 |   } | 
 |  | 
 |   /* Return the gdbarch that was passed to the constructor.  */ | 
 |  | 
 |   struct gdbarch *gdbarch () | 
 |   { | 
 |     return expout->gdbarch; | 
 |   } | 
 |  | 
 |   /* Return the language that was passed to the constructor.  */ | 
 |  | 
 |   const struct language_defn *language () | 
 |   { | 
 |     return expout->language_defn; | 
 |   } | 
 |  | 
 |   /* Set the root operation of the expression that is currently being | 
 |      built.  */ | 
 |   void set_operation (expr::operation_up &&op) | 
 |   { | 
 |     expout->op = std::move (op); | 
 |   } | 
 |  | 
 |   /* The expression related to this parser state.  */ | 
 |  | 
 |   expression_up expout; | 
 | }; | 
 |  | 
 | /* Complete an expression that references a field, like "x->y".  */ | 
 |  | 
 | struct expr_complete_structop : public expr_completion_base | 
 | { | 
 |   explicit expr_complete_structop (expr::structop_base_operation *op) | 
 |     : m_op (op) | 
 |   { | 
 |   } | 
 |  | 
 |   bool complete (struct expression *exp, | 
 | 		 completion_tracker &tracker) override | 
 |   { | 
 |     return m_op->complete (exp, tracker); | 
 |   } | 
 |  | 
 | private: | 
 |  | 
 |   /* The last struct expression directly before a '.' or '->'.  This | 
 |      is set when parsing and is only used when completing a field | 
 |      name.  It is nullptr if no dereference operation was found.  */ | 
 |   expr::structop_base_operation *m_op = nullptr; | 
 | }; | 
 |  | 
 | /* Complete a tag name in an expression.  This is used for something | 
 |    like "enum abc<TAB>".  */ | 
 |  | 
 | struct expr_complete_tag : public expr_completion_base | 
 | { | 
 |   expr_complete_tag (enum type_code code, | 
 | 		     gdb::unique_xmalloc_ptr<char> name) | 
 |     : m_code (code), | 
 |       m_name (std::move (name)) | 
 |   { | 
 |     /* Parsers should enforce this statically.  */ | 
 |     gdb_assert (code == TYPE_CODE_ENUM | 
 | 		|| code == TYPE_CODE_UNION | 
 | 		|| code == TYPE_CODE_STRUCT); | 
 |   } | 
 |  | 
 |   bool complete (struct expression *exp, | 
 | 		 completion_tracker &tracker) override; | 
 |  | 
 | private: | 
 |  | 
 |   /* The kind of tag to complete.  */ | 
 |   enum type_code m_code; | 
 |  | 
 |   /* The token for tagged type name completion.  */ | 
 |   gdb::unique_xmalloc_ptr<char> m_name; | 
 | }; | 
 |  | 
 | /* An instance of this type is instantiated during expression parsing, | 
 |    and passed to the appropriate parser.  It holds both inputs to the | 
 |    parser, and result.  */ | 
 |  | 
 | struct parser_state : public expr_builder | 
 | { | 
 |   /* Constructor.  LANG is the language used to parse the expression. | 
 |      And GDBARCH is the gdbarch to use during parsing.  */ | 
 |  | 
 |   parser_state (const struct language_defn *lang, | 
 | 		struct gdbarch *gdbarch, | 
 | 		const struct block *context_block, | 
 | 		CORE_ADDR context_pc, | 
 | 		int comma, | 
 | 		const char *input, | 
 | 		bool completion, | 
 | 		innermost_block_tracker *tracker, | 
 | 		bool void_p) | 
 |     : expr_builder (lang, gdbarch), | 
 |       expression_context_block (context_block), | 
 |       expression_context_pc (context_pc), | 
 |       comma_terminates (comma), | 
 |       lexptr (input), | 
 |       parse_completion (completion), | 
 |       block_tracker (tracker), | 
 |       void_context_p (void_p) | 
 |   { | 
 |   } | 
 |  | 
 |   DISABLE_COPY_AND_ASSIGN (parser_state); | 
 |  | 
 |   /* Begin counting arguments for a function call, | 
 |      saving the data about any containing call.  */ | 
 |  | 
 |   void start_arglist () | 
 |   { | 
 |     m_funcall_chain.push_back (arglist_len); | 
 |     arglist_len = 0; | 
 |   } | 
 |  | 
 |   /* Return the number of arguments in a function call just terminated, | 
 |      and restore the data for the containing function call.  */ | 
 |  | 
 |   int end_arglist () | 
 |   { | 
 |     int val = arglist_len; | 
 |     arglist_len = m_funcall_chain.back (); | 
 |     m_funcall_chain.pop_back (); | 
 |     return val; | 
 |   } | 
 |  | 
 |   /* Mark the given operation as the starting location of a structure | 
 |      expression.  This is used when completing on field names.  */ | 
 |  | 
 |   void mark_struct_expression (expr::structop_base_operation *op); | 
 |  | 
 |   /* Indicate that the current parser invocation is completing a tag. | 
 |      TAG is the type code of the tag, and PTR and LENGTH represent the | 
 |      start of the tag name.  */ | 
 |  | 
 |   void mark_completion_tag (enum type_code tag, const char *ptr, int length); | 
 |  | 
 |   /* Mark for completion, using an arbitrary completer.  */ | 
 |  | 
 |   void mark_completion (std::unique_ptr<expr_completion_base> completer) | 
 |   { | 
 |     gdb_assert (m_completion_state == nullptr); | 
 |     m_completion_state = std::move (completer); | 
 |   } | 
 |  | 
 |   /* Push an operation on the stack.  */ | 
 |   void push (expr::operation_up &&op) | 
 |   { | 
 |     m_operations.push_back (std::move (op)); | 
 |   } | 
 |  | 
 |   /* Create a new operation and push it on the stack.  */ | 
 |   template<typename T, typename... Arg> | 
 |   void push_new (Arg... args) | 
 |   { | 
 |     m_operations.emplace_back (new T (std::forward<Arg> (args)...)); | 
 |   } | 
 |  | 
 |   /* Push a new C string operation.  */ | 
 |   void push_c_string (int, struct stoken_vector *vec); | 
 |  | 
 |   /* Push a symbol reference.  If SYM is nullptr, look for a minimal | 
 |      symbol.  */ | 
 |   void push_symbol (const char *name, block_symbol sym); | 
 |  | 
 |   /* Push a reference to $mumble.  This may result in a convenience | 
 |      variable, a history reference, or a register.  */ | 
 |   void push_dollar (struct stoken str); | 
 |  | 
 |   /* Pop an operation from the stack.  */ | 
 |   expr::operation_up pop () | 
 |   { | 
 |     expr::operation_up result = std::move (m_operations.back ()); | 
 |     m_operations.pop_back (); | 
 |     return result; | 
 |   } | 
 |  | 
 |   /* Pop N elements from the stack and return a vector.  */ | 
 |   std::vector<expr::operation_up> pop_vector (int n) | 
 |   { | 
 |     std::vector<expr::operation_up> result (n); | 
 |     for (int i = 1; i <= n; ++i) | 
 |       result[n - i] = pop (); | 
 |     return result; | 
 |   } | 
 |  | 
 |   /* A helper that pops an operation, wraps it in some other | 
 |      operation, and pushes it again.  */ | 
 |   template<typename T> | 
 |   void wrap () | 
 |   { | 
 |     using namespace expr; | 
 |     operation_up v = ::expr::make_operation<T> (pop ()); | 
 |     push (std::move (v)); | 
 |   } | 
 |  | 
 |   /* A helper that pops two operations, wraps them in some other | 
 |      operation, and pushes the result.  */ | 
 |   template<typename T> | 
 |   void wrap2 () | 
 |   { | 
 |     expr::operation_up rhs = pop (); | 
 |     expr::operation_up lhs = pop (); | 
 |     push (expr::make_operation<T> (std::move (lhs), std::move (rhs))); | 
 |   } | 
 |  | 
 |   /* If this is nonzero, this block is used as the lexical context for | 
 |      symbol names.  */ | 
 |  | 
 |   const struct block * const expression_context_block; | 
 |  | 
 |   /* If expression_context_block is non-zero, then this is the PC | 
 |      within the block that we want to evaluate expressions at.  When | 
 |      debugging C or C++ code, we use this to find the exact line we're | 
 |      at, and then look up the macro definitions active at that | 
 |      point.  */ | 
 |   const CORE_ADDR expression_context_pc; | 
 |  | 
 |   /* Nonzero means stop parsing on first comma (if not within parentheses).  */ | 
 |  | 
 |   int comma_terminates; | 
 |  | 
 |   /* During parsing of a C expression, the pointer to the next character | 
 |      is in this variable.  */ | 
 |  | 
 |   const char *lexptr; | 
 |  | 
 |   /* After a token has been recognized, this variable points to it. | 
 |      Currently used only for error reporting.  */ | 
 |   const char *prev_lexptr = nullptr; | 
 |  | 
 |   /* Number of arguments seen so far in innermost function call.  */ | 
 |  | 
 |   int arglist_len = 0; | 
 |  | 
 |   /* True if parsing an expression to attempt completion.  */ | 
 |   bool parse_completion; | 
 |  | 
 |   /* Completion state is updated here.  */ | 
 |   std::unique_ptr<expr_completion_base> m_completion_state; | 
 |  | 
 |   /* The innermost block tracker.  */ | 
 |   innermost_block_tracker *block_tracker; | 
 |  | 
 |   /* True if no value is expected from the expression.  */ | 
 |   bool void_context_p; | 
 |  | 
 | private: | 
 |  | 
 |   /* Data structure for saving values of arglist_len for function calls whose | 
 |      arguments contain other function calls.  */ | 
 |  | 
 |   std::vector<int> m_funcall_chain; | 
 |  | 
 |   /* Stack of operations.  */ | 
 |   std::vector<expr::operation_up> m_operations; | 
 | }; | 
 |  | 
 | /* When parsing expressions we track the innermost block that was | 
 |    referenced.  */ | 
 |  | 
 | class innermost_block_tracker | 
 | { | 
 | public: | 
 |   innermost_block_tracker (innermost_block_tracker_types types | 
 | 			   = INNERMOST_BLOCK_FOR_SYMBOLS) | 
 |     : m_types (types), | 
 |       m_innermost_block (NULL) | 
 |   { /* Nothing.  */ } | 
 |  | 
 |   /* Update the stored innermost block if the new block B is more inner | 
 |      than the currently stored block, or if no block is stored yet.  The | 
 |      type T tells us whether the block B was for a symbol or for a | 
 |      register.  The stored innermost block is only updated if the type T is | 
 |      a type we are interested in, the types we are interested in are held | 
 |      in M_TYPES and set during RESET.  */ | 
 |   void update (const struct block *b, innermost_block_tracker_types t); | 
 |  | 
 |   /* Overload of main UPDATE method which extracts the block from BS.  */ | 
 |   void update (const struct block_symbol &bs) | 
 |   { | 
 |     update (bs.block, INNERMOST_BLOCK_FOR_SYMBOLS); | 
 |   } | 
 |  | 
 |   /* Return the stored innermost block.  Can be nullptr if no symbols or | 
 |      registers were found during an expression parse, and so no innermost | 
 |      block was defined.  */ | 
 |   const struct block *block () const | 
 |   { | 
 |     return m_innermost_block; | 
 |   } | 
 |  | 
 | private: | 
 |   /* The type of innermost block being looked for.  */ | 
 |   innermost_block_tracker_types m_types; | 
 |  | 
 |   /* The currently stored innermost block found while parsing an | 
 |      expression.  */ | 
 |   const struct block *m_innermost_block; | 
 | }; | 
 |  | 
 | /* A string token, either a char-string or bit-string.  Char-strings are | 
 |    used, for example, for the names of symbols.  */ | 
 |  | 
 | struct stoken | 
 |   { | 
 |     /* Pointer to first byte of char-string or first bit of bit-string.  */ | 
 |     const char *ptr; | 
 |     /* Length of string in bytes for char-string or bits for bit-string.  */ | 
 |     int length; | 
 |   }; | 
 |  | 
 | struct typed_stoken | 
 |   { | 
 |     /* A language-specific type field.  */ | 
 |     int type; | 
 |     /* Pointer to first byte of char-string or first bit of bit-string.  */ | 
 |     char *ptr; | 
 |     /* Length of string in bytes for char-string or bits for bit-string.  */ | 
 |     int length; | 
 |   }; | 
 |  | 
 | struct stoken_vector | 
 |   { | 
 |     int len; | 
 |     struct typed_stoken *tokens; | 
 |   }; | 
 |  | 
 | struct ttype | 
 |   { | 
 |     struct stoken stoken; | 
 |     struct type *type; | 
 |   }; | 
 |  | 
 | struct symtoken | 
 |   { | 
 |     struct stoken stoken; | 
 |     struct block_symbol sym; | 
 |     int is_a_field_of_this; | 
 |   }; | 
 |  | 
 | struct objc_class_str | 
 |   { | 
 |     struct stoken stoken; | 
 |     struct type *type; | 
 |     int theclass; | 
 |   }; | 
 |  | 
 | extern const char *find_template_name_end (const char *); | 
 |  | 
 | extern std::string copy_name (struct stoken); | 
 |  | 
 | extern bool parse_float (const char *p, int len, | 
 | 			 const struct type *type, gdb_byte *data); | 
 |  | 
 |  | 
 | /* Function used to avoid direct calls to fprintf | 
 |    in the code generated by the bison parser.  */ | 
 |  | 
 | extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3); | 
 |  | 
 | extern bool exp_uses_objfile (struct expression *exp, struct objfile *objfile); | 
 |  | 
 | #endif /* PARSER_DEFS_H */ | 
 |  |