diff options
author | Simon Marchi <simon.marchi@polymtl.ca> | 2019-11-21 00:10:18 -0500 |
---|---|---|
committer | Simon Marchi <simon.marchi@polymtl.ca> | 2019-11-21 00:27:37 -0500 |
commit | 90c3c3ef0b5d0861a2f16137c55c9791e21714fc (patch) | |
tree | 8b99751d1d64d5d00fe89df0f3b797e8719a3dbd | |
parent | 379876d22a8950594835b6861d5f4dadd2bf66f3 (diff) | |
download | gdb-users/simark/mi-symbols-output.zip gdb-users/simark/mi-symbols-output.tar.gz gdb-users/simark/mi-symbols-output.tar.bz2 |
Hi Andrewusers/simark/mi-symbols-output
Change-Id: I695d9860d6f7dae86f966dfc0524b934660478da
-rw-r--r-- | gdb/mi/mi-symbol-cmds.c | 214 |
1 files changed, 61 insertions, 153 deletions
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c index 46086bf..a2e0138 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++; + } } } |