/* DIE indexing 

   Copyright (C) 2022-2024 Free Software Foundation, Inc.

   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/>.  */

#ifndef GDB_DWARF2_COOKED_INDEX_H
#define GDB_DWARF2_COOKED_INDEX_H

#include "dwarf2.h"
#include "dwarf2/types.h"
#include "symtab.h"
#include "hashtab.h"
#include "quick-symbol.h"
#include "gdbsupport/gdb_obstack.h"
#include "addrmap.h"
#include "gdbsupport/iterator-range.h"
#include "dwarf2/mapped-index.h"
#include "dwarf2/read.h"
#include "dwarf2/abbrev-table-cache.h"
#include "dwarf2/parent-map.h"
#include "gdbsupport/range-chain.h"
#include "complaints.h"

#if CXX_STD_THREAD
#include <mutex>
#include <condition_variable>
#endif /* CXX_STD_THREAD */

struct dwarf2_per_cu_data;
struct dwarf2_per_bfd;
struct index_cache_store_context;
struct cooked_index_entry;

/* Flags that describe an entry in the index.  */
enum cooked_index_flag_enum : unsigned char
{
  /* True if this entry is the program's "main".  */
  IS_MAIN = 1,
  /* True if this entry represents a "static" object.  */
  IS_STATIC = 2,
  /* True if this entry uses the linkage name.  */
  IS_LINKAGE = 4,
  /* True if this entry is just for the declaration of a type, not the
     definition.  */
  IS_TYPE_DECLARATION = 8,
  /* True is parent_entry.deferred has a value rather than parent_entry
     .resolved.  */
  IS_PARENT_DEFERRED = 16,
};
DEF_ENUM_FLAGS_TYPE (enum cooked_index_flag_enum, cooked_index_flag);

/* Type representing either a resolved or deferred cooked_index_entry.  */

union cooked_index_entry_ref
{
  cooked_index_entry_ref (parent_map::addr_type deferred_)
  {
    deferred = deferred_;
  }

  cooked_index_entry_ref (const cooked_index_entry *resolved_)
  {
    resolved = resolved_;
  }

  const cooked_index_entry *resolved;
  parent_map::addr_type deferred;
};

/* Return a string representation of FLAGS.  */

std::string to_string (cooked_index_flag flags);

/* Return true if LANG requires canonicalization.  This is used
   primarily to work around an issue computing the name of "main".
   This function must be kept in sync with
   cooked_index_shard::finalize.  */

extern bool language_requires_canonicalization (enum language lang);

/* A cooked_index_entry represents a single item in the index.  Note
   that two entries can be created for the same DIE -- one using the
   name, and another one using the linkage name, if any.

   This is an "open" class and the members are all directly
   accessible.  It is read-only after the index has been fully read
   and processed.  */
struct cooked_index_entry : public allocate_on_obstack<cooked_index_entry>
{
  cooked_index_entry (sect_offset die_offset_, enum dwarf_tag tag_,
		      cooked_index_flag flags_,
		      enum language lang_, const char *name_,
		      cooked_index_entry_ref parent_entry_,
		      dwarf2_per_cu_data *per_cu_)
    : name (name_),
      tag (tag_),
      flags (flags_),
      lang (lang_),
      die_offset (die_offset_),
      per_cu (per_cu_),
      m_parent_entry (parent_entry_)
  {
  }

  /* Return true if this entry matches SEARCH_FLAGS.  */
  bool matches (block_search_flags search_flags) const
  {
    /* Just reject type declarations.  */
    if ((flags & IS_TYPE_DECLARATION) != 0)
      return false;

    if ((search_flags & SEARCH_STATIC_BLOCK) != 0
	&& (flags & IS_STATIC) != 0)
      return true;
    if ((search_flags & SEARCH_GLOBAL_BLOCK) != 0
	&& (flags & IS_STATIC) == 0)
      return true;
    return false;
  }

  /* Return true if this entry matches KIND.  */
  bool matches (domain_search_flags kind) const;

  /* Construct the fully-qualified name of this entry and return a
     pointer to it.  If allocation is needed, it will be done on
     STORAGE.  FOR_MAIN is true if we are computing the name of the
     "main" entry -- one marked DW_AT_main_subprogram.  This matters
     for avoiding name canonicalization and also a related race (if
     "main" computation is done during finalization).  If the language
     doesn't prescribe a separator, one can be specified using
     DEFAULT_SEP.  */
  const char *full_name (struct obstack *storage, bool for_main = false,
			 const char *default_sep = nullptr) const;

  /* Comparison modes for the 'compare' function.  See the function
     for a description.  */
  enum comparison_mode
  {
    MATCH,
    SORT,
    COMPLETE,
  };

  /* Compare two strings, case-insensitively.  Return -1 if STRA is
     less than STRB, 0 if they are equal, and 1 if STRA is greater.

     When comparing, '<' is considered to be less than all other
     printable characters.  This ensures that "t<x>" sorts before
     "t1", which is necessary when looking up "t".  This '<' handling
     is to ensure that certain C++ lookups work correctly.  It is
     inexact, and applied regardless of the search language, but this
     is ok because callers of this code do more precise filtering
     according to their needs.  This is also why using a
     case-insensitive comparison works even for languages that are
     case sensitive.

     MODE controls how the comparison proceeds.

     MODE==SORT is used when sorting and the only special '<' handling
     that it does is to ensure that '<' sorts before all other
     printable characters.  This ensures that the resulting ordering
     will be binary-searchable.

     MODE==MATCH is used when searching for a symbol.  In this case,
     STRB must always be the search name, and STRA must be the name in
     the index that is under consideration.  In compare mode, early
     termination of STRB may match STRA -- for example, "t<int>" and
     "t" will be considered to be equal.  (However, if A=="t" and
     B=="t<int>", then this will not consider them as equal.)

     MODE==COMPLETE is used when searching for a symbol for
     completion.  In this case, STRB must always be the search name,
     and STRA must be the name in the index that is under
     consideration.  In completion mode, early termination of STRB
     always results in a match.  */
  static int compare (const char *stra, const char *strb,
		      comparison_mode mode);

  /* Compare two entries by canonical name.  */
  bool operator< (const cooked_index_entry &other) const
  {
    return compare (canonical, other.canonical, SORT) < 0;
  }

  /* Set parent entry to PARENT.  */
  void set_parent (const cooked_index_entry *parent)
  {
    gdb_assert ((flags & IS_PARENT_DEFERRED) == 0);
    m_parent_entry.resolved = parent;
  }

  /* Resolve deferred parent entry to PARENT.  */
  void resolve_parent (const cooked_index_entry *parent)
  {
    gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
    flags = flags & ~IS_PARENT_DEFERRED;
    m_parent_entry.resolved = parent;
  }

  /* Return parent entry.  */
  const cooked_index_entry *get_parent () const
  {
    gdb_assert ((flags & IS_PARENT_DEFERRED) == 0);
    return m_parent_entry.resolved;
  }

  /* Return deferred parent entry.  */
  parent_map::addr_type get_deferred_parent () const
  {
    gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
    return m_parent_entry.deferred;
  }

  /* The name as it appears in DWARF.  This always points into one of
     the mapped DWARF sections.  Note that this may be the name or the
     linkage name -- two entries are created for DIEs which have both
     attributes.  */
  const char *name;
  /* The canonical name.  This may be equal to NAME.  */
  const char *canonical = nullptr;
  /* The DWARF tag.  */
  enum dwarf_tag tag;
  /* Any flags attached to this entry.  */
  cooked_index_flag flags;
  /* The language of this symbol.  */
  ENUM_BITFIELD (language) lang : LANGUAGE_BITS;
  /* The offset of this DIE.  */
  sect_offset die_offset;
  /* The CU from which this entry originates.  */
  dwarf2_per_cu_data *per_cu;

private:

  /* A helper method for full_name.  Emits the full scope of this
     object, followed by the separator, to STORAGE.  If this entry has
     a parent, its write_scope method is called first.  FOR_MAIN is
     true when computing the name of 'main'; see full_name.  */
  void write_scope (struct obstack *storage, const char *sep,
		    bool for_main) const;

  /* The parent entry.  This is NULL for top-level entries.
     Otherwise, it points to the parent entry, such as a namespace or
     class.  */
  cooked_index_entry_ref m_parent_entry;
};

class cooked_index;

/* An index of interesting DIEs.  This is "cooked", in contrast to a
   mapped .debug_names or .gdb_index, which are "raw".  An entry in
   the index is of type cooked_index_entry.

   Operations on the index are described below.  They are chosen to
   make it relatively simple to implement the symtab "quick"
   methods.  */
class cooked_index_shard
{
public:
  cooked_index_shard () = default;
  DISABLE_COPY_AND_ASSIGN (cooked_index_shard);

  /* Create a new cooked_index_entry and register it with this object.
     Entries are owned by this object.  The new item is returned.  */
  cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
			   cooked_index_flag flags, enum language lang,
			   const char *name,
			   cooked_index_entry_ref parent_entry,
			   dwarf2_per_cu_data *per_cu);

  /* Install a new fixed addrmap from the given mutable addrmap.  */
  void install_addrmap (addrmap_mutable *map)
  {
    gdb_assert (m_addrmap == nullptr);
    m_addrmap = new (&m_storage) addrmap_fixed (&m_storage, map);
  }

  friend class cooked_index;

  /* A simple range over part of m_entries.  */
  typedef iterator_range<std::vector<cooked_index_entry *>::const_iterator>
       range;

  /* Return a range of all the entries.  */
  range all_entries () const
  {
    return { m_entries.cbegin (), m_entries.cend () };
  }

  /* Look up an entry by name.  Returns a range of all matching
     results.  If COMPLETING is true, then a larger range, suitable
     for completion, will be returned.  */
  range find (const std::string &name, bool completing) const;

private:

  /* Return the entry that is believed to represent the program's
     "main".  This will return NULL if no such entry is available.  */
  const cooked_index_entry *get_main () const
  {
    return m_main;
  }

  /* Look up ADDR in the address map, and return either the
     corresponding CU, or nullptr if the address could not be
     found.  */
  dwarf2_per_cu_data *lookup (unrelocated_addr addr)
  {
    return (static_cast<dwarf2_per_cu_data *>
	    (m_addrmap->find ((CORE_ADDR) addr)));
  }

  /* Create a new cooked_index_entry and register it with this object.
     Entries are owned by this object.  The new item is returned.  */
  cooked_index_entry *create (sect_offset die_offset,
			      enum dwarf_tag tag,
			      cooked_index_flag flags,
			      enum language lang,
			      const char *name,
			      cooked_index_entry_ref parent_entry,
			      dwarf2_per_cu_data *per_cu)
  {
    return new (&m_storage) cooked_index_entry (die_offset, tag, flags,
						lang, name, parent_entry,
						per_cu);
  }

  /* GNAT only emits mangled ("encoded") names in the DWARF, and does
     not emit the module structure.  However, we need this structure
     to do lookups.  This function recreates that structure for an
     existing entry, modifying ENTRY as appropriate.  */
  void handle_gnat_encoded_entry
       (cooked_index_entry *entry, htab_t gnat_entries);

  /* Finalize the index.  This should be called a single time, when
     the index has been fully populated.  It enters all the entries
     into the internal table and fixes up all missing parent links.
     This may be invoked in a worker thread.  */
  void finalize (const parent_map_map *parent_maps);

  /* Storage for the entries.  */
  auto_obstack m_storage;
  /* List of all entries.  */
  std::vector<cooked_index_entry *> m_entries;
  /* If we found an entry with 'is_main' set, store it here.  */
  cooked_index_entry *m_main = nullptr;
  /* The addrmap.  This maps address ranges to dwarf2_per_cu_data
     objects.  */
  addrmap_fixed *m_addrmap = nullptr;
  /* Storage for canonical names.  */
  std::vector<gdb::unique_xmalloc_ptr<char>> m_names;
};

class cutu_reader;

/* An instance of this is created when scanning DWARF to create a
   cooked index.  */

class cooked_index_storage
{
public:

  cooked_index_storage ();
  DISABLE_COPY_AND_ASSIGN (cooked_index_storage);

  /* Return the current abbrev table_cache.  */
  const abbrev_table_cache &get_abbrev_table_cache () const
  { return m_abbrev_table_cache; }

  /* Return the DIE reader corresponding to PER_CU.  If no such reader
     has been registered, return NULL.  */
  cutu_reader *get_reader (dwarf2_per_cu_data *per_cu);

  /* Preserve READER by storing it in the local hash table.  */
  cutu_reader *preserve (std::unique_ptr<cutu_reader> reader);

  /* Add an entry to the index.  The arguments describe the entry; see
     cooked-index.h.  The new entry is returned.  */
  cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
			   cooked_index_flag flags,
			   const char *name,
			   cooked_index_entry_ref parent_entry,
			   dwarf2_per_cu_data *per_cu)
  {
    return m_index->add (die_offset, tag, flags, per_cu->lang (),
			 name, parent_entry, per_cu);
  }

  /* Install the current addrmap into the shard being constructed,
     then transfer ownership of the index to the caller.  */
  std::unique_ptr<cooked_index_shard> release ()
  {
    m_index->install_addrmap (&m_addrmap);
    return std::move (m_index);
  }

  /* Return the mutable addrmap that is currently being created.  */
  addrmap_mutable *get_addrmap ()
  {
    return &m_addrmap;
  }

  /* Return the parent_map that is currently being created.  */
  parent_map *get_parent_map ()
  {
    return &m_parent_map;
  }

  /* Return the parent_map that is currently being created.  Ownership
     is passed to the caller.  */
  parent_map release_parent_map ()
  {
    return std::move (m_parent_map);
  }

private:

  /* Hash function for a cutu_reader.  */
  static hashval_t hash_cutu_reader (const void *a);

  /* Equality function for cutu_reader.  */
  static int eq_cutu_reader (const void *a, const void *b);

  /* The abbrev table cache used by this indexer.  */
  abbrev_table_cache m_abbrev_table_cache;

  /* A hash table of cutu_reader objects.  */
  htab_up m_reader_hash;
  /* The index shard that is being constructed.  */
  std::unique_ptr<cooked_index_shard> m_index;

  /* Parent map for each CU that is read.  */
  parent_map m_parent_map;

  /* A writeable addrmap being constructed by this scanner.  */
  addrmap_mutable m_addrmap;
};

/* The possible states of the index.  See the explanatory comment
   before cooked_index for more details.  */
enum class cooked_state
{
  /* The default state.  This is not a valid argument to 'wait'.  */
  INITIAL,
  /* The initial scan has completed.  The name of "main" is now
     available (if known).  The addrmaps are usable now.
     Finalization has started but is not complete.  */
  MAIN_AVAILABLE,
  /* Finalization has completed.  This means the index is fully
     available for queries.  */
  FINALIZED,
  /* Writing to the index cache has finished.  */
  CACHE_DONE,
};

/* An object of this type controls the scanning of the DWARF.  It
   schedules the worker tasks and tracks the current state.  Once
   scanning is done, this object is discarded.
   
   This is an abstract base class that defines the basic behavior of
   scanners.  Separate concrete implementations exist for scanning
   .debug_names and .debug_info.  */

class cooked_index_worker
{
public:

  explicit cooked_index_worker (dwarf2_per_objfile *per_objfile)
    : m_per_objfile (per_objfile),
      m_cache_store (global_index_cache, per_objfile->per_bfd)
  { }
  virtual ~cooked_index_worker ()
  { }
  DISABLE_COPY_AND_ASSIGN (cooked_index_worker);

  /* Start reading.  */
  void start ();

  /* Wait for a particular state to be achieved.  If ALLOW_QUIT is
     true, then the loop will check the QUIT flag.  Normally this
     method may only be called from the main thread; however, it can
     be called from a worker thread provided that the desired state
     has already been attained.  (This oddity is used by the index
     cache writer.)  */
  bool wait (cooked_state desired_state, bool allow_quit);

protected:

  /* Let cooked_index call the 'set' and 'write_to_cache' methods.  */
  friend class cooked_index;

  /* Set the current state.  */
  void set (cooked_state desired_state);

  /* Write to the index cache.  */
  void write_to_cache (const cooked_index *idx,
		       deferred_warnings *warn) const;

  /* Helper function that does the work of reading.  This must be able
     to be run in a worker thread without problems.  */
  virtual void do_reading () = 0;

  /* A callback that can print stats, if needed.  This is called when
     transitioning to the 'MAIN_AVAILABLE' state.  */
  virtual void print_stats ()
  { }

  /* Each thread returns a tuple holding a cooked index, any collected
     complaints, a vector of errors that should be printed, and a
     vector of parent maps.

     The errors are retained because GDB's I/O system is not
     thread-safe.  run_on_main_thread could be used, but that would
     mean the messages are printed after the prompt, which looks
     weird.  */
  using result_type = std::tuple<std::unique_ptr<cooked_index_shard>,
				 complaint_collection,
				 std::vector<gdb_exception>,
				 parent_map>;

  /* The per-objfile object.  */
  dwarf2_per_objfile *m_per_objfile;
  /* Result of each worker task.  */
  std::vector<result_type> m_results;
  /* Any warnings emitted.  This is not in 'result_type' because (for
     the time being at least), it's only needed in do_reading, not in
     every worker.  Note that deferred_warnings uses gdb_stderr in its
     constructor, and this should only be done from the main thread.
     This is enforced in the cooked_index_worker constructor.  */
  deferred_warnings m_warnings;

  /* A map of all parent maps.  Used during finalization to fix up
     parent relationships.  */
  parent_map_map m_all_parents_map;

#if CXX_STD_THREAD
  /* Current state of this object.  */
  cooked_state m_state = cooked_state::INITIAL;
  /* Mutex and condition variable used to synchronize.  */
  std::mutex m_mutex;
  std::condition_variable m_cond;
#endif /* CXX_STD_THREAD */
  /* This flag indicates whether any complaints or exceptions that
     arose during scanning have been reported by 'wait'.  This may
     only be modified on the main thread.  */
  bool m_reported = false;
  /* If set, an exception occurred during reading; in this case the
     scanning is stopped and this exception will later be reported by
     the 'wait' method.  */
  std::optional<gdb_exception> m_failed;
  /* An object used to write to the index cache.  */
  index_cache_store_context m_cache_store;
};

/* The main index of DIEs.

   The index is created by multiple threads.  The overall process is
   somewhat complicated, so here's a diagram to help sort it out.

   The basic idea behind this design is (1) to do as much work as
   possible in worker threads, and (2) to start the work as early as
   possible.  This combination should help hide the effort from the
   user to the maximum possible degree.

   . Main Thread                |       Worker Threads
   ============================================================
   . dwarf2_initialize_objfile
   . 	      |
   .          v
   .     cooked index ------------> cooked_index_worker::start
   .          |                           / | \
   .          v                          /  |  \
   .       install                      /   |	\
   .  cooked_index_functions        scan CUs in workers
   .          |               create cooked_index_shard objects
   .          |                           \ | /
   .          v                            \|/
   .    return to caller                    v
   .                                 initial scan is done
   .                                state = MAIN_AVAILABLE
   .                              "main" name now available
   .                                        |
   .                                        |
   .   if main thread calls...              v
   .   compute_main_name         cooked_index::set_contents
   .          |                           / | \
   .          v                          /  |  \
   .   wait (MAIN_AVAILABLE)          finalization
   .          |                          \  |  /
   .          v                           \ | /        
   .        done                      state = FINALIZED
   .                                        |
   .                                        v
   .                              maybe write to index cache
   .                                  state = CACHE_DONE
   .
   .
   .   if main thread calls...
   .   any other "quick" API
   .          |
   .          v
   .   wait (FINALIZED)
   .          |
   .          v
   .    use the index
*/

class cooked_index : public dwarf_scanner_base
{
public:

  /* A convenience typedef for the vector that is contained in this
     object.  */
  using vec_type = std::vector<std::unique_ptr<cooked_index_shard>>;

  cooked_index (dwarf2_per_objfile *per_objfile,
		std::unique_ptr<cooked_index_worker> &&worker);
  ~cooked_index () override;

  DISABLE_COPY_AND_ASSIGN (cooked_index);

  /* Start reading the DWARF.  */
  void start_reading ();

  /* Called by cooked_index_worker to set the contents of this index
     and transition to the MAIN_AVAILABLE state.  WARN is used to
     collect any warnings that may arise when writing to the cache.
     PARENT_MAPS is used when resolving pending parent links.
     PARENT_MAPS may be NULL if there are no IS_PARENT_DEFERRED
     entries in VEC.  */
  void set_contents (vec_type &&vec, deferred_warnings *warn,
		     const parent_map_map *parent_maps);

  /* A range over a vector of subranges.  */
  using range = range_chain<cooked_index_shard::range>;

  /* Look up an entry by name.  Returns a range of all matching
     results.  If COMPLETING is true, then a larger range, suitable
     for completion, will be returned.  */
  range find (const std::string &name, bool completing);

  /* Return a range of all the entries.  */
  range all_entries ()
  {
    wait (cooked_state::FINALIZED, true);
    std::vector<cooked_index_shard::range> result_range;
    result_range.reserve (m_vector.size ());
    for (auto &entry : m_vector)
      result_range.push_back (entry->all_entries ());
    return range (std::move (result_range));
  }

  /* Look up ADDR in the address map, and return either the
     corresponding CU, or nullptr if the address could not be
     found.  */
  dwarf2_per_cu_data *lookup (unrelocated_addr addr) override;

  /* Return a new vector of all the addrmaps used by all the indexes
     held by this object.  */
  std::vector<const addrmap *> get_addrmaps ();

  /* Return the entry that is believed to represent the program's
     "main".  This will return NULL if no such entry is available.  */
  const cooked_index_entry *get_main () const;

  const char *get_main_name (struct obstack *obstack, enum language *lang)
    const;

  cooked_index *index_for_writing () override
  {
    wait (cooked_state::FINALIZED, true);
    return this;
  }

  quick_symbol_functions_up make_quick_functions () const override;

  /* Dump a human-readable form of the contents of the index.  */
  void dump (gdbarch *arch);

  /* Wait until this object reaches the desired state.  Note that
     DESIRED_STATE may not be INITIAL -- it does not make sense to
     wait for this.  If ALLOW_QUIT is true, timed waits will be done
     and the quit flag will be checked in a loop.  This may normally
     only be called from the main thread; however, it is ok to call
     from a worker as long as the desired state has already been
     attained.  (This property is needed by the index cache
     writer.)  */
  void wait (cooked_state desired_state, bool allow_quit = false);

  void wait_completely () override
  { wait (cooked_state::CACHE_DONE); }

private:

  /* The vector of cooked_index objects.  This is stored because the
     entries are stored on the obstacks in those objects.  */
  vec_type m_vector;

  /* This tracks the current state.  When this is nullptr, it means
     that the state is CACHE_DONE -- it's important to note that only
     the main thread may change the value of this pointer.  */
  std::unique_ptr<cooked_index_worker> m_state;

  dwarf2_per_bfd *m_per_bfd;
};

/* An implementation of quick_symbol_functions for the cooked DWARF
   index.  */

struct cooked_index_functions : public dwarf2_base_index_functions
{
  cooked_index *wait (struct objfile *objfile, bool allow_quit)
  {
    dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
    cooked_index *table
      = (gdb::checked_static_cast<cooked_index *>
	 (per_objfile->per_bfd->index_table.get ()));
    table->wait (cooked_state::MAIN_AVAILABLE, allow_quit);
    return table;
  }

  struct compunit_symtab *find_compunit_symtab_by_address
    (struct objfile *objfile, CORE_ADDR address) override;

  bool has_unexpanded_symtabs (struct objfile *objfile) override
  {
    wait (objfile, true);
    return dwarf2_base_index_functions::has_unexpanded_symtabs (objfile);
  }

  struct symtab *find_last_source_symtab (struct objfile *objfile) override
  {
    wait (objfile, true);
    return dwarf2_base_index_functions::find_last_source_symtab (objfile);
  }

  void forget_cached_source_info (struct objfile *objfile) override
  {
    wait (objfile, true);
    dwarf2_base_index_functions::forget_cached_source_info (objfile);
  }

  void print_stats (struct objfile *objfile, bool print_bcache) override
  {
    wait (objfile, true);
    dwarf2_base_index_functions::print_stats (objfile, print_bcache);
  }

  void dump (struct objfile *objfile) override
  {
    cooked_index *index = wait (objfile, true);
    gdb_printf ("Cooked index in use:\n");
    gdb_printf ("\n");
    index->dump (objfile->arch ());
  }

  void expand_all_symtabs (struct objfile *objfile) override
  {
    wait (objfile, true);
    dwarf2_base_index_functions::expand_all_symtabs (objfile);
  }

  bool expand_symtabs_matching
    (struct objfile *objfile,
     gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
     const lookup_name_info *lookup_name,
     gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
     gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
     block_search_flags search_flags,
     domain_search_flags domain,
     gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
       override;

  struct compunit_symtab *find_pc_sect_compunit_symtab
    (struct objfile *objfile, bound_minimal_symbol msymbol,
     CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override
  {
    wait (objfile, true);
    return (dwarf2_base_index_functions::find_pc_sect_compunit_symtab
	    (objfile, msymbol, pc, section, warn_if_readin));
  }

  void map_symbol_filenames
       (struct objfile *objfile,
	gdb::function_view<symbol_filename_ftype> fun,
	bool need_fullname) override
  {
    wait (objfile, true);
    return (dwarf2_base_index_functions::map_symbol_filenames
	    (objfile, fun, need_fullname));
  }

  void compute_main_name (struct objfile *objfile) override
  {
    wait (objfile, false);
  }
};

#endif /* GDB_DWARF2_COOKED_INDEX_H */
