+ /* Storage for canonical names. */
+ std::vector<gdb::unique_xmalloc_ptr<char>> m_names;
+ /* A future that tracks when the 'finalize' method is done. Note
+ that the 'get' method is never called on this future, only
+ 'wait'. */
+ gdb::future<void> m_future;
+};
+
+/* The main index of DIEs. The parallel DIE indexers create
+ cooked_index objects. Then, these are all handled to a
+ cooked_index_vector for storage and final indexing. The index is
+ made by iterating over the entries previously created. */
+
+class cooked_index_vector : public dwarf_scanner_base
+{
+public:
+
+ /* A convenience typedef for the vector that is contained in this
+ object. */
+ typedef std::vector<std::unique_ptr<cooked_index>> vec_type;
+
+ explicit cooked_index_vector (vec_type &&vec);
+ DISABLE_COPY_AND_ASSIGN (cooked_index_vector);
+
+ /* Wait until the finalization of the entire cooked_index_vector is
+ done. */
+ void wait ()
+ {
+ for (auto &item : m_vector)
+ item->wait ();
+ }
+
+ ~cooked_index_vector ()
+ {
+ /* The 'finalize' methods may be run in a different thread. If
+ this object is destroyed before these complete, then one will
+ end up writing to freed memory. Waiting for finalization to
+ complete avoids this problem; and the cost seems ignorable
+ because creating and immediately destroying the debug info is a
+ relatively rare thing to do. */
+ wait ();
+ }
+
+ /* A range over a vector of subranges. */
+ typedef range_chain<cooked_index::range> 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 (gdb::string_view name, bool completing);
+
+ /* Return a range of all the entries. */
+ range all_entries ()
+ {
+ std::vector<cooked_index::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 (CORE_ADDR addr);
+
+ /* Return a new vector of all the addrmaps used by all the indexes
+ held by this object. */
+ std::vector<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;
+
+ cooked_index_vector *index_for_writing () override
+ {
+ return this;
+ }
+
+ quick_symbol_functions_up make_quick_functions () const override;
+
+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;