summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2019-11-21 00:10:18 -0500
committerSimon Marchi <simon.marchi@polymtl.ca>2019-11-21 00:27:37 -0500
commit90c3c3ef0b5d0861a2f16137c55c9791e21714fc (patch)
tree8b99751d1d64d5d00fe89df0f3b797e8719a3dbd
parent379876d22a8950594835b6861d5f4dadd2bf66f3 (diff)
downloadbinutils-gdb-users/simark/mi-symbols-output.tar.gz
Change-Id: I695d9860d6f7dae86f966dfc0524b934660478da
-rw-r--r--gdb/mi/mi-symbol-cmds.c214
1 files changed, 61 insertions, 153 deletions
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c
index 46086bf6c6f..a2e0138f119 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -69,14 +69,14 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc)
results. */
static void
-mi_info_one_symbol_details (enum search_domain kind,
- struct symbol *sym, int block)
+output_debug_symbol (ui_out *uiout, enum search_domain kind,
+ struct symbol *sym, int block)
{
- struct ui_out *uiout = current_uiout;
-
ui_out_emit_tuple tuple_emitter (uiout, NULL);
+
if (SYMBOL_LINE (sym) != 0)
uiout->field_unsigned ("line", SYMBOL_LINE (sym));
+
uiout->field_string ("name", SYMBOL_PRINT_NAME (sym));
if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN)
@@ -90,153 +90,18 @@ mi_info_one_symbol_details (enum search_domain kind,
}
}
-/* This class is used to produce the nested structure of tuples and lists
- required to present the results of the MI_SYMBOL_INFO function. */
-class mi_symbol_info_emitter
+/* Actually output one nondebug symbol, puts a tuple emitter in place
+ and then outputs the fields for this msymbol. */
+static void
+output_nondebug_symbol (ui_out *uiout,
+ const struct bound_minimal_symbol &msymbol)
{
- /* When printing debug symbols we need to track the last symtab so we can
- spot when we have entered a new one. */
- const symtab *m_last_symtab;
-
- /* The ui_out to which output will be sent. */
- struct ui_out *m_uiout;
-
- /* The outer container for all the matched symbols. */
- ui_out_emit_tuple m_outer_symbols;
-
- /* The order of these optional emitters is critical as they will be
- deleted in reverse order, which is important as these are popped from
- the uiout stack as they are destroyed. */
- gdb::optional<ui_out_emit_list> m_debug_emitter;
- gdb::optional<ui_out_emit_tuple> m_symtab_emitter;
- gdb::optional<ui_out_emit_list> m_symbols_emitter;
- gdb::optional<ui_out_emit_list> m_nondebug_emitter;
-
- /* Called when we might want to print our first nondebug symbol in order
- to shutdown any debug symbol printing that might be in progress. */
- void maybe_finish_debug_output ()
- {
- /* If the debug emitter is in use. */
- if (m_debug_emitter.has_value ())
- {
- /* Then we should have a symbols list inside a symtab tuple also
- currently in use. */
- gdb_assert (m_symbols_emitter.has_value ());
- gdb_assert (m_symtab_emitter.has_value ());
-
- /* Shut down the symbols list, symtab tuple, and debug list
- emitters (in that order). We are now back to the level of the
- outer_symbols tuple ready to (possibly) start a nondebug list,
- though that is not done here. */
- m_symbols_emitter.reset ();
- m_symtab_emitter.reset ();
- m_debug_emitter.reset ();
- }
- }
-
- /* Return true if the nondebug emitter has been put in place. */
- bool have_started_nondebug_symbol_output () const
- {
- return m_nondebug_emitter.has_value ();
- }
-
- /* Called before we print every nondebug symbol. If this is the first
- nondebug symbol to be printed then it will setup the emitters required
- to print nondebug symbols. */
- void maybe_start_nondebug_symbol_output ()
- {
- if (!have_started_nondebug_symbol_output ())
- m_nondebug_emitter.emplace (m_uiout, "nondebug");
- }
+ struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
- /* Actually output one nondebug symbol, puts a tuple emitter in place
- and then outputs the fields for this msymbol. */
- void output_nondebug_symbol (const struct bound_minimal_symbol &msymbol)
- {
- struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile);
- ui_out_emit_tuple tuple_emitter (m_uiout, NULL);
- m_uiout->field_core_addr ("address", gdbarch,
- BMSYMBOL_VALUE_ADDRESS (msymbol));
- m_uiout->field_string ("name", MSYMBOL_PRINT_NAME (msymbol.minsym));
- }
-
- /* Called before we print every debug symbol. If this is the first debug
- symbol to be printed then it will setup the top level of emitters
- required to print debug symbols. */
- void maybe_start_debug_symbol_output ()
- {
- if (!m_debug_emitter.has_value ())
- m_debug_emitter.emplace (m_uiout, "debug");
- }
-
- /* Called before we print every debug symbol, S is the symtab for the
- symbol to be printed. If S is different to the last symtab we printed
- for then we close down the emitters for the last symtab, and create
- new emitters for this new symtab. */
- void setup_emitters_for_symtab (symtab *s)
- {
- if (s != m_last_symtab)
- {
- /* Reset a possible previous symbol list within a symtab. */
- m_symbols_emitter.reset ();
- m_symtab_emitter.reset ();
-
- /* Start a new symtab and symbol list within the symtab. */
- m_symtab_emitter.emplace (m_uiout, nullptr);
- m_uiout->field_string ("filename",
- symtab_to_filename_for_display (s));
- m_uiout->field_string ("fullname", symtab_to_fullname (s));
- m_symbols_emitter.emplace (m_uiout, "symbols");
-
- /* Record the current symtab. */
- m_last_symtab = s;
- }
- }
-
-public:
- /* Constructor. */
- mi_symbol_info_emitter (struct ui_out *uiout)
- : m_last_symtab (nullptr),
- m_uiout (uiout),
- m_outer_symbols (uiout, "symbols")
- { /* Nothing. */ }
-
- /* Output P a symbol found by searching for symbols of type KIND. */
- void output (const symbol_search &p, enum search_domain kind)
- {
- if (p.msymbol.minsym != NULL)
- {
- /* If this is the first nondebug symbol, and we have previous
- outputted a debug symbol then we need to close down all of the
- emitters related to printing debug symbols. */
- maybe_finish_debug_output ();
-
- /* If this is the first nondebug symbol then we need to create the
- emitters related to printing nondebug symbols. */
- maybe_start_nondebug_symbol_output ();
-
- /* We are no safe to emit the nondebug symbol. */
- output_nondebug_symbol (p.msymbol);
- }
- else
- {
- /* All debug symbols should appear in the list before all
- non-debug symbols. */
- gdb_assert (!have_started_nondebug_symbol_output ());
-
- /* If this is the first debug symbol then we need to create the
- outer level of emitters related to printing debug symbols. */
- maybe_start_debug_symbol_output ();
-
- /* Ensure the correct emitters are in place to emit this debug
- symbol. */
- setup_emitters_for_symtab (symbol_symtab (p.symbol));
-
- /* Emit information for this debug symbol. */
- mi_info_one_symbol_details (kind, p.symbol, p.block);
- }
- }
-};
+ uiout->field_core_addr ("address", gdbarch, BMSYMBOL_VALUE_ADDRESS (msymbol));
+ uiout->field_string ("name", MSYMBOL_PRINT_NAME (msymbol.minsym));
+}
/* This is the guts of the commands '-symbol-info-functions',
'-symbol-info-variables', and '-symbol-info-types'. It calls
@@ -253,12 +118,55 @@ mi_symbol_info (enum search_domain kind, const char *regexp,
/* Must make sure that if we're interrupted, symbols gets freed. */
global_symbol_searcher sym_search (kind, regexp, t_regexp, exclude_minsyms);
std::vector<symbol_search> symbols = sym_search.search ();
+ ui_out *uiout = current_uiout;
+ int i = 0;
+
+ ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols");
- mi_symbol_info_emitter emitter (current_uiout);
- for (const symbol_search &p : symbols)
+ /* Debug symbols are placed first. */
+ if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
{
- QUIT;
- emitter.output (p, kind);
+ ui_out_emit_list debug_symbols_list_emitter (uiout, "debug");
+
+ /* As long as we have debug symbols... */
+ while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
+ {
+ symtab *symtab = symbol_symtab (symbols[i].symbol);
+ ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr);
+
+ uiout->field_string ("filename", symtab_to_filename_for_display (symtab));
+ uiout->field_string ("fullname", symtab_to_fullname (symtab));
+
+ ui_out_emit_list symbols_list_emitter (uiout, "symbols");
+
+ /* As long as we have debug symbols from this symtab... */
+ while (i < symbols.size ()
+ && symbols[i].msymbol.minsym == nullptr
+ && symbol_symtab (symbols[i].symbol) == symtab)
+ {
+ symbol_search &s = symbols[i];
+
+ output_debug_symbol(uiout, kind, s.symbol, s.block);
+
+ i++;
+ }
+ }
+ }
+
+ /* Non-debug symbols are placed after. */
+ if (i < symbols.size ())
+ {
+ ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug");
+
+ /* As long as we have nondebug symbols... */
+ while (i < symbols.size ())
+ {
+ gdb_assert (symbols[i].msymbol.minsym != nullptr);
+
+ output_nondebug_symbol(uiout, symbols[i].msymbol);
+
+ i++;
+ }
}
}