public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: Tom Tromey <tom@tromey.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 5/5] [gdb/symtab] Fix data race on per_cu->lang
Date: Tue, 5 Jul 2022 17:19:49 +0200	[thread overview]
Message-ID: <35591557-02e9-d87c-e07b-49919282666e@suse.de> (raw)
In-Reply-To: <877d4svih2.fsf@tromey.com>

[-- Attachment #1: Type: text/plain, Size: 595 bytes --]

On 7/4/22 20:30, Tom Tromey wrote:
>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
> Tom> Fix this by guarding the write with a lock.
> 
> I would rather we avoid locks.  Ideally the existing exclusion mechanism
> should be made to work, but if that fails, perhaps we can use another
> atomic.

I gave a different approach a try: eliminating the field.

That seems to work reasonably well, apart from one specific usage that I 
disabled (mentioned in commit message).

I'm not sure this is a good idea though, but I thought I could at least 
post it.  Currently testing.

Thanks,
- Tom


[-- Attachment #2: 0002-gdb-symtab-Eliminate-per_cu-lang.patch --]
[-- Type: text/x-patch, Size: 44427 bytes --]

[gdb/symtab] Eliminate per_cu->lang

[ Note: written on top of this (
https://sourceware.org/pipermail/gdb-patches/2022-July/190476.html ) patch. ]

Eliminate the field dwarf2_per_cu_data::lang.

Fix most uses by replacing cu->per_cu->lang () with cu->lang ().

The remaining uses are in the cooked index code.  Fix those by some sort of
side-table approach, where we define a new struct:
...
struct per_cu_lang
{
  dwarf2_per_cu_data *per_cu;
  enum language lang;
};
...
and replace dwarf2_per_cu_data handling with per_cu_lang handling in the code.

In order not to allocate identical per_cu_lang objects, we enter new entries
in a map.  Making the map thread_local fixes the data races we set out to fix
in the first place.

The only casualty is this code in process_imported_unit_die:
...
      /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
	 into another compilation unit, at root level.  Regard this as a hint,
	 and ignore it.  */
      if (die->parent && die->parent->parent == NULL
	  && per_cu->unit_type () == DW_UT_compile
	  && per_cu->lang () == language_cplus)
	return;
...
which is disabled because dwarf2_find_containing_comp_unit returns a
dwarf2_per_cu_data and it's not clear how to get at the language from
there.

---
 gdb/dwarf2/cooked-index.c |  20 +++--
 gdb/dwarf2/cooked-index.h |  39 ++++++--
 gdb/dwarf2/cu.c           |   2 +-
 gdb/dwarf2/cu.h           |   7 ++
 gdb/dwarf2/index-write.c  |   8 +-
 gdb/dwarf2/read.c         | 223 +++++++++++++++++++++++-----------------------
 gdb/dwarf2/read.h         |  21 -----
 7 files changed, 168 insertions(+), 152 deletions(-)

diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index adb0046609e..7f98b301c8f 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -54,7 +54,7 @@ cooked_index_entry::full_name (struct obstack *storage) const
     return canonical;
 
   const char *sep = nullptr;
-  switch (per_cu->lang ())
+  switch (m_per_cu_lang->lang)
     {
     case language_cplus:
     case language_rust:
@@ -94,17 +94,18 @@ const cooked_index_entry *
 cooked_index::add (sect_offset die_offset, enum dwarf_tag tag,
 		   cooked_index_flag flags, const char *name,
 		   const cooked_index_entry *parent_entry,
-		   dwarf2_per_cu_data *per_cu)
+		   dwarf2_per_cu_data *per_cu,
+		   enum language lang)
 {
   cooked_index_entry *result = create (die_offset, tag, flags, name,
-				       parent_entry, per_cu);
+				       parent_entry, per_cu, lang);
   m_entries.push_back (result);
 
   /* An explicitly-tagged main program should always override the
      implicit "main" discovery.  */
   if ((flags & IS_MAIN) != 0)
     m_main = result;
-  else if (per_cu->lang () != language_ada
+  else if (lang != language_ada
 	   && m_main == nullptr
 	   && strcmp (name, "main") == 0)
     m_main = result;
@@ -146,13 +147,14 @@ cooked_index::handle_gnat_encoded_entry (cooked_index_entry *entry,
       /* CUs are processed in order, so we only need to check the most
 	 recent entry.  */
       cooked_index_entry *last = (cooked_index_entry *) *slot;
-      if (last == nullptr || last->per_cu != entry->per_cu)
+      if (last == nullptr || last->m_per_cu_lang->per_cu != entry->m_per_cu_lang->per_cu)
 	{
 	  gdb::unique_xmalloc_ptr<char> new_name
 	    = make_unique_xstrndup (name.data (), name.length ());
 	  last = create (entry->die_offset, DW_TAG_namespace,
 			 0, new_name.get (), parent,
-			 entry->per_cu);
+			 entry->m_per_cu_lang->per_cu,
+			 entry->m_per_cu_lang->lang);
 	  last->canonical = last->name;
 	  m_names.push_back (std::move (new_name));
 	  *slot = last;
@@ -196,13 +198,13 @@ cooked_index::do_finalize ()
   for (cooked_index_entry *entry : m_entries)
     {
       gdb_assert (entry->canonical == nullptr);
-      if ((entry->per_cu->lang () != language_cplus
-	   && entry->per_cu->lang () != language_ada)
+      if ((entry->m_per_cu_lang->lang != language_cplus
+	   && entry->m_per_cu_lang->lang != language_ada)
 	  || (entry->flags & IS_LINKAGE) != 0)
 	entry->canonical = entry->name;
       else
 	{
-	  if (entry->per_cu->lang () == language_ada)
+	  if (entry->m_per_cu_lang->lang == language_ada)
 	    {
 	      gdb::unique_xmalloc_ptr<char> canon_name
 		= handle_gnat_encoded_entry (entry, gnat_entries.get ());
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 439cbb19fa7..761b4d1266a 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -34,9 +34,21 @@
 #include "dwarf2/mapped-index.h"
 #include "dwarf2/tag.h"
 #include "gdbsupport/range-chain.h"
+#include <utility>
+#include <map>
 
 struct dwarf2_per_cu_data;
 
+struct per_cu_lang
+{
+  per_cu_lang (dwarf2_per_cu_data *_per_cu, enum language _lang)
+    : per_cu(_per_cu), lang(_lang)
+  {}
+
+  dwarf2_per_cu_data *per_cu;
+  enum language lang;
+};
+
 /* Flags that describe an entry in the index.  */
 enum cooked_index_flag_enum : unsigned char
 {
@@ -63,14 +75,24 @@ struct cooked_index_entry : public allocate_on_obstack
   cooked_index_entry (sect_offset die_offset_, enum dwarf_tag tag_,
 		      cooked_index_flag flags_, const char *name_,
 		      const cooked_index_entry *parent_entry_,
-		      dwarf2_per_cu_data *per_cu_)
+		      dwarf2_per_cu_data *per_cu_,
+		      enum language lang_)
     : name (name_),
       tag (tag_),
       flags (flags_),
       die_offset (die_offset_),
-      parent_entry (parent_entry_),
-      per_cu (per_cu_)
+      parent_entry (parent_entry_)
   {
+    static thread_local std::map<std::pair<dwarf2_per_cu_data *, enum language>, per_cu_lang *> map;
+    auto it = map.find (std::make_pair (per_cu_, lang_));
+    if (it != map.end())
+      {
+	m_per_cu_lang = it->second;
+	return;
+      }
+
+    m_per_cu_lang = new per_cu_lang (per_cu_, lang_);
+    map[std::make_pair (per_cu_, lang_)] = m_per_cu_lang;
   }
 
   /* Return true if this entry matches SEARCH_FLAGS.  */
@@ -154,7 +176,7 @@ struct cooked_index_entry : public allocate_on_obstack
      class.  */
   const cooked_index_entry *parent_entry;
   /* The CU from which this entry originates.  */
-  dwarf2_per_cu_data *per_cu;
+  per_cu_lang* m_per_cu_lang;
 
 private:
 
@@ -182,7 +204,8 @@ class cooked_index
 				 cooked_index_flag flags,
 				 const char *name,
 				 const cooked_index_entry *parent_entry,
-				 dwarf2_per_cu_data *per_cu);
+				 dwarf2_per_cu_data *per_cu,
+				 enum language lang);
 
   /* Install a new fixed addrmap from the given mutable addrmap.  */
   void install_addrmap (addrmap_mutable *map)
@@ -243,11 +266,13 @@ class cooked_index
 			      cooked_index_flag flags,
 			      const char *name,
 			      const cooked_index_entry *parent_entry,
-			      dwarf2_per_cu_data *per_cu)
+			      dwarf2_per_cu_data *per_cu,
+			      enum language lang)
   {
     return new (&m_storage) cooked_index_entry (die_offset, tag, flags,
 						name, parent_entry,
-						per_cu);
+						per_cu,
+						lang);
   }
 
   /* GNAT only emits mangled ("encoded") names in the DWARF, and does
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index 8cbd97661a5..d40dd094b09 100644
--- a/gdb/dwarf2/cu.c
+++ b/gdb/dwarf2/cu.c
@@ -62,7 +62,7 @@ dwarf2_cu::start_compunit_symtab (const char *name, const char *comp_dir,
 
   m_builder.reset (new struct buildsym_compunit
 		   (this->per_objfile->objfile,
-		    name, comp_dir, per_cu->lang (), low_pc));
+		    name, comp_dir, lang (), low_pc));
 
   list_in_scope = get_builder ()->get_file_symbols ();
 
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index 6b72ec234bf..23cb3d21b2e 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -23,6 +23,7 @@
 #include "buildsym.h"
 #include "dwarf2/comp-unit-head.h"
 #include "gdbsupport/gdb_optional.h"
+#include "language.h"
 
 /* Type used for delaying computation of method physnames.
    See comments for compute_delayed_physnames.  */
@@ -105,6 +106,12 @@ struct dwarf2_cu
   /* The language we are debugging.  */
   const struct language_defn *language_defn = nullptr;
 
+  enum language lang () const
+  {
+    gdb_assert (language_defn != language_def (language_unknown));
+    return language_defn->la_language;
+  }
+
   const char *producer = nullptr;
 
 private:
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index c3aad8dd999..7ee8f721171 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -567,7 +567,7 @@ class debug_names
 
   void insert (const cooked_index_entry *entry)
   {
-    const auto it = m_cu_index_htab.find (entry->per_cu);
+    const auto it = m_cu_index_htab.find (entry->m_per_cu_lang->per_cu);
     gdb_assert (it != m_cu_index_htab.cend ());
     const char *name = entry->full_name (&m_string_obstack);
 
@@ -582,8 +582,8 @@ class debug_names
       tag = DW_TAG_variable;
 
     insert (tag, name, it->second, (entry->flags & IS_STATIC) != 0,
-	    entry->per_cu->is_debug_types ? unit_kind::tu : unit_kind::cu,
-	    entry->per_cu->lang ());
+	    entry->m_per_cu_lang->per_cu->is_debug_types ? unit_kind::tu : unit_kind::cu,
+	    entry->m_per_cu_lang->lang);
   }
 
   /* Build all the tables.  All symbols must be already inserted.
@@ -1122,7 +1122,7 @@ write_cooked_index (cooked_index_vector *table,
       if ((entry->flags & IS_LINKAGE) != 0)
 	continue;
 
-      const auto it = cu_index_htab.find (entry->per_cu);
+      const auto it = cu_index_htab.find (entry->m_per_cu_lang->per_cu);
       gdb_assert (it != cu_index_htab.cend ());
 
       const char *name = entry->full_name (&symtab->m_string_obstack);
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 23fe5679cbd..bc19f36e7b3 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6594,9 +6594,10 @@ class cooked_index_storage
 				 cooked_index_flag flags,
 				 const char *name,
 				 const cooked_index_entry *parent_entry,
-				 dwarf2_per_cu_data *per_cu)
+				 dwarf2_per_cu_data *per_cu,
+				 enum language lang)
   {
-    return m_index->add (die_offset, tag, flags, name, parent_entry, per_cu);
+    return m_index->add (die_offset, tag, flags, name, parent_entry, per_cu, lang);
   }
 
   /* Install the current addrmap into the index being constructed,
@@ -6808,7 +6809,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
 	  prepare_one_comp_unit (reader.cu, reader.comp_unit_die,
 				 language_minimal);
 	  gdb_assert (storage != nullptr);
-	  cooked_indexer indexer (storage, this_cu, reader.cu->per_cu->lang ());
+	  cooked_indexer indexer (storage, this_cu, reader.cu->lang ());
 	  indexer.make_index (&reader);
 	}
     }
@@ -6832,7 +6833,7 @@ build_type_psymtabs_reader (cutu_reader *reader,
   prepare_one_comp_unit (cu, type_unit_die, language_minimal);
 
   gdb_assert (storage != nullptr);
-  cooked_indexer indexer (storage, per_cu, cu->per_cu->lang ());
+  cooked_indexer indexer (storage, per_cu, cu->lang ());
   indexer.make_index (reader);
 }
 
@@ -7142,7 +7143,7 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
   const cooked_index_entry *main_entry = vec->get_main ();
   if (main_entry != nullptr)
     set_objfile_main_name (objfile, main_entry->name,
-			   main_entry->per_cu->lang ());
+			   main_entry->m_per_cu_lang->lang);
 
   dwarf_read_debug_printf ("Done building psymtabs of %s",
 			   objfile_name (objfile));
@@ -7745,7 +7746,7 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
   /* Only C++ delays computing physnames.  */
   if (cu->method_list.empty ())
     return;
-  gdb_assert (cu->per_cu->lang () == language_cplus);
+  gdb_assert (cu->lang () == language_cplus);
 
   for (const delayed_method_info &mi : cu->method_list)
     {
@@ -8174,7 +8175,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
 static void
 rust_union_quirks (struct dwarf2_cu *cu)
 {
-  gdb_assert (cu->per_cu->lang () == language_rust);
+  gdb_assert (cu->lang () == language_rust);
   for (type *type_ : cu->rust_unions)
     quirk_rust_enum (type_, cu->per_objfile->objfile);
   /* We don't need this any more.  */
@@ -8368,7 +8369,7 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
   process_die (cu->dies, cu);
 
   /* For now fudge the Go package.  */
-  if (cu->per_cu->lang () == language_go)
+  if (cu->lang () == language_go)
     fixup_go_packaging (cu);
 
   /* Now that we have processed all the DIEs in the CU, all the types
@@ -8376,7 +8377,7 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
      physnames.  */
   compute_delayed_physnames (cu);
 
-  if (cu->per_cu->lang () == language_rust)
+  if (cu->lang () == language_rust)
     rust_union_quirks (cu);
 
   /* Some compilers don't define a DW_AT_high_pc attribute for the
@@ -8405,9 +8406,9 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
       /* Set symtab language to language from DW_AT_language.  If the
 	 compilation is from a C file generated by language preprocessors, do
 	 not set the language if it was already deduced by start_subfile.  */
-      if (!(cu->per_cu->lang () == language_c
+      if (!(cu->lang () == language_c
 	    && cust->primary_filetab ()->language () != language_unknown))
-	cust->primary_filetab ()->set_language (cu->per_cu->lang ());
+	cust->primary_filetab ()->set_language (cu->lang ());
 
       /* GCC-4.0 has started to support -fvar-tracking.  GCC-3.x still can
 	 produce DW_AT_location with location lists but it can be possibly
@@ -8461,7 +8462,7 @@ process_full_type_unit (dwarf2_cu *cu,
   process_die (cu->dies, cu);
 
   /* For now fudge the Go package.  */
-  if (cu->per_cu->lang () == language_go)
+  if (cu->lang () == language_go)
     fixup_go_packaging (cu);
 
   /* Now that we have processed all the DIEs in the CU, all the types
@@ -8469,7 +8470,7 @@ process_full_type_unit (dwarf2_cu *cu,
      physnames.  */
   compute_delayed_physnames (cu);
 
-  if (cu->per_cu->lang () == language_rust)
+  if (cu->lang () == language_rust)
     rust_union_quirks (cu);
 
   /* TUs share symbol tables.
@@ -8490,9 +8491,9 @@ process_full_type_unit (dwarf2_cu *cu,
 	     compilation is from a C file generated by language preprocessors,
 	     do not set the language if it was already deduced by
 	     start_subfile.  */
-	  if (!(cu->per_cu->lang () == language_c
+	  if (!(cu->lang () == language_c
 		&& cust->primary_filetab ()->language () != language_c))
-	    cust->primary_filetab ()->set_language (cu->per_cu->lang ());
+	    cust->primary_filetab ()->set_language (cu->lang ());
 	}
     }
   else
@@ -8532,6 +8533,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
 	= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
 					    per_objfile->per_bfd);
 
+#if 0
       /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
 	 into another compilation unit, at root level.  Regard this as a hint,
 	 and ignore it.  */
@@ -8539,12 +8541,13 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
 	  && per_cu->unit_type () == DW_UT_compile
 	  && per_cu->lang () == language_cplus)
 	return;
+#endif
 
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, per_objfile,
-				 cu->per_cu->lang ()))
+				 cu->lang ()))
 	load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
-			     false, cu->per_cu->lang ());
+			     false, cu->lang ());
 
       cu->per_cu->imported_symtabs_push (per_cu);
     }
@@ -8602,7 +8605,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       break;
     case DW_TAG_subprogram:
       /* Nested subprograms in Fortran get a prefix.  */
-      if (cu->per_cu->lang () == language_fortran
+      if (cu->lang () == language_fortran
 	  && die->parent != NULL
 	  && die->parent->tag == DW_TAG_subprogram)
 	cu->processing_has_namespace_info = true;
@@ -8646,7 +8649,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       /* We only need to handle this case for Ada -- in other
 	 languages, it's normal for the compiler to emit a typedef
 	 instead.  */
-      if (cu->per_cu->lang () != language_ada)
+      if (cu->lang () != language_ada)
 	break;
       /* FALLTHROUGH */
     case DW_TAG_base_type:
@@ -8680,7 +8683,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_imported_module:
       cu->processing_has_namespace_info = true;
       if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
-				 || cu->per_cu->lang () != language_fortran))
+				 || cu->lang () != language_fortran))
 	complaint (_("Tag '%s' has unexpected children"),
 		   dwarf_tag_name (die->tag));
       read_import_statement (die, cu);
@@ -8792,7 +8795,7 @@ dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
 
   /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
      See https://github.com/rust-lang/rust/issues/32925.  */
-  if (cu->per_cu->lang () == language_rust && linkage_name != NULL
+  if (cu->lang () == language_rust && linkage_name != NULL
       && strchr (linkage_name, '{') != NULL)
     linkage_name = NULL;
 
@@ -8824,7 +8827,7 @@ dwarf2_compute_name (const char *name,
   if (name == NULL)
     name = dwarf2_name (die, cu);
 
-  enum language lang = cu->per_cu->lang ();
+  enum language lang = cu->lang ();
 
   /* For Fortran GDB prefers DW_AT_*linkage_name for the physname if present
      but otherwise compute it by typename_concat inside GDB.
@@ -9073,7 +9076,7 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
   if (!die_needs_namespace (die, cu))
     return dwarf2_compute_name (name, die, cu, 1);
 
-  if (cu->per_cu->lang () != language_rust)
+  if (cu->lang () != language_rust)
     mangled = dw2_linkage_name (die, cu);
 
   /* DW_AT_linkage_name is missing in some cases - depend on what GDB
@@ -9230,7 +9233,7 @@ read_alias (struct die_info *die, struct dwarf2_cu *cu)
 static struct using_direct **
 using_directives (struct dwarf2_cu *cu)
 {
-  if (cu->per_cu->lang () == language_ada
+  if (cu->lang () == language_ada
       && cu->get_builder ()->outermost_context_p ())
     return cu->get_builder ()->get_global_using_directives ();
   else
@@ -9321,7 +9324,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   else if (strlen (imported_name_prefix) > 0)
     canonical_name = obconcat (&objfile->objfile_obstack,
 			       imported_name_prefix,
-			       (cu->per_cu->lang () == language_d
+			       (cu->lang () == language_d
 				? "."
 				: "::"),
 			       imported_name, (char *) NULL);
@@ -9329,7 +9332,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
     canonical_name = imported_name;
 
   if (die->tag == DW_TAG_imported_module
-      && cu->per_cu->lang () == language_fortran)
+      && cu->lang () == language_fortran)
     for (child_die = die->child; child_die && child_die->tag;
 	 child_die = child_die->sibling)
       {
@@ -9555,7 +9558,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   CORE_ADDR baseaddr;
 
-  prepare_one_comp_unit (cu, die, cu->per_cu->lang ());
+  prepare_one_comp_unit (cu, die, cu->lang ());
   baseaddr = objfile->text_section_offset ();
 
   get_scope_pc_bounds (die, &lowpc, &highpc, cu);
@@ -11717,7 +11720,7 @@ queue_and_load_dwo_tu (void **slot, void *info)
 	 a real dependency of PER_CU on SIG_TYPE.  That is detected later
 	 while processing PER_CU.  */
       if (maybe_queue_comp_unit (NULL, sig_type, cu->per_objfile,
-				 cu->per_cu->lang ()))
+				 cu->lang ()))
 	load_full_type_unit (sig_type, cu->per_objfile);
       cu->per_cu->imported_symtabs_push (sig_type);
     }
@@ -12007,7 +12010,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
     set_objfile_main_name (objfile, newobj->name->linkage_name (),
-			   cu->per_cu->lang ());
+			   cu->lang ());
 
   /* If there is a location expression for DW_AT_frame_base, record
      it.  */
@@ -12052,7 +12055,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   /* If we have a DW_AT_specification, we might need to import using
      directives from the context of the specification DIE.  See the
      comment in determine_prefix.  */
-  if (cu->per_cu->lang () == language_cplus
+  if (cu->lang () == language_cplus
       && dwarf2_attr (die, DW_AT_specification, cu))
     {
       struct dwarf2_cu *spec_cu = cu;
@@ -12080,10 +12083,10 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 				     cstk.static_link, lowpc, highpc);
 
   /* For C++, set the block's scope.  */
-  if ((cu->per_cu->lang () == language_cplus
-       || cu->per_cu->lang () == language_fortran
-       || cu->per_cu->lang () == language_d
-       || cu->per_cu->lang () == language_rust)
+  if ((cu->lang () == language_cplus
+       || cu->lang () == language_fortran
+       || cu->lang () == language_d
+       || cu->lang () == language_rust)
       && cu->processing_has_namespace_info)
     block_set_scope (block, determine_prefix (die, cu),
 		     &objfile->objfile_obstack);
@@ -12583,7 +12586,7 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct rust_vtable_symbol *storage = NULL;
 
-  if (cu->per_cu->lang () == language_rust)
+  if (cu->lang () == language_rust)
     {
       struct type *containing_type = rust_containing_type (die, cu);
 
@@ -13097,7 +13100,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
 
   /* If the language does not allow nested subprograms (either inside
      subprograms or lexical blocks), we're done.  */
-  if (cu->per_cu->lang () != language_ada)
+  if (cu->lang () != language_ada)
     return;
 
   /* Check all the children of the given DIE.  If it contains nested
@@ -13902,7 +13905,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
   type->set_fields
     ((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));
 
-  if (fip->non_public_fields && cu->per_cu->lang () != language_ada)
+  if (fip->non_public_fields && cu->lang () != language_ada)
     {
       ALLOCATE_CPLUS_STRUCT_TYPE (type);
 
@@ -13921,7 +13924,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
 
   /* If the type has baseclasses, allocate and clear a bit vector for
      TYPE_FIELD_VIRTUAL_BITS.  */
-  if (!fip->baseclasses.empty () && cu->per_cu->lang () != language_ada)
+  if (!fip->baseclasses.empty () && cu->lang () != language_ada)
     {
       int num_bytes = B_BYTES (fip->baseclasses.size ());
       unsigned char *pointer;
@@ -13947,12 +13950,12 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
       switch (field.accessibility)
 	{
 	case DW_ACCESS_private:
-	  if (cu->per_cu->lang () != language_ada)
+	  if (cu->lang () != language_ada)
 	    SET_TYPE_FIELD_PRIVATE (type, i);
 	  break;
 
 	case DW_ACCESS_protected:
-	  if (cu->per_cu->lang () != language_ada)
+	  if (cu->lang () != language_ada)
 	    SET_TYPE_FIELD_PROTECTED (type, i);
 	  break;
 
@@ -13973,7 +13976,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
 	    {
 	    case DW_VIRTUALITY_virtual:
 	    case DW_VIRTUALITY_pure_virtual:
-	      if (cu->per_cu->lang () == language_ada)
+	      if (cu->lang () == language_ada)
 		error (_("unexpected virtuality in component of Ada type"));
 	      SET_TYPE_FIELD_VIRTUAL (type, i);
 	      break;
@@ -14024,7 +14027,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   const char *fieldname;
   struct type *this_type;
 
-  if (cu->per_cu->lang () == language_ada)
+  if (cu->lang () == language_ada)
     error (_("unexpected member function in Ada type"));
 
   /* Get name of member function.  */
@@ -14057,7 +14060,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   fnp = &flp->fnfields.back ();
 
   /* Delay processing of the physname until later.  */
-  if (cu->per_cu->lang () == language_cplus)
+  if (cu->lang () == language_cplus)
     add_to_method_list (type, i, flp->fnfields.size () - 1, fieldname,
 			die, cu);
   else
@@ -14212,7 +14215,7 @@ static void
 dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
 				 struct dwarf2_cu *cu)
 {
-  if (cu->per_cu->lang () == language_ada)
+  if (cu->lang () == language_ada)
     error (_("unexpected member functions in Ada type"));
 
   ALLOCATE_CPLUS_STRUCT_TYPE (type);
@@ -14355,7 +14358,7 @@ static void
 quirk_ada_thick_pointer_struct (struct die_info *die, struct dwarf2_cu *cu,
 				struct type *type)
 {
-  gdb_assert (cu->per_cu->lang () == language_ada);
+  gdb_assert (cu->lang () == language_ada);
 
   /* Check for a structure with two children.  */
   if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
@@ -14534,9 +14537,9 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   name = dwarf2_name (die, cu);
   if (name != NULL)
     {
-      if (cu->per_cu->lang  () == language_cplus
-	  || cu->per_cu->lang () == language_d
-	  || cu->per_cu->lang () == language_rust)
+      if (cu->lang  () == language_cplus
+	  || cu->lang () == language_d
+	  || cu->lang () == language_rust)
 	{
 	  const char *full_name = dwarf2_full_name (name, die, cu);
 
@@ -14572,7 +14575,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       type->set_code (TYPE_CODE_STRUCT);
     }
 
-  if (cu->per_cu->lang () == language_cplus && die->tag == DW_TAG_class_type)
+  if (cu->lang () == language_cplus && die->tag == DW_TAG_class_type)
     type->set_is_declared_class (true);
 
   /* Store the calling convention in the type if it's available in
@@ -14784,7 +14787,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
       /* Rust doesn't have member functions in the C++ sense.
 	 However, it does emit ordinary functions as children
 	 of a struct DIE.  */
-      if (cu->per_cu->lang () == language_rust)
+      if (cu->lang () == language_rust)
 	read_func_scope (child_die, cu);
       else
 	{
@@ -14948,7 +14951,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       /* Copy fi.nested_types_list linked list elements content into the
 	 allocated array TYPE_NESTED_TYPES_ARRAY (type).  */
       if (!fi.nested_types_list.empty ()
-	  && cu->per_cu->lang () != language_ada)
+	  && cu->lang () != language_ada)
 	{
 	  int count = fi.nested_types_list.size ();
 
@@ -14964,9 +14967,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   quirk_gcc_member_function_pointer (type, objfile);
-  if (cu->per_cu->lang () == language_rust && die->tag == DW_TAG_union_type)
+  if (cu->lang () == language_rust && die->tag == DW_TAG_union_type)
     cu->rust_unions.push_back (type);
-  else if (cu->per_cu->lang () == language_ada)
+  else if (cu->lang () == language_ada)
     quirk_ada_thick_pointer_struct (die, cu, type);
 
   /* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its
@@ -15670,7 +15673,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   maybe_set_alignment (cu, die, type);
 
   struct type *replacement_type = nullptr;
-  if (cu->per_cu->lang () == language_ada)
+  if (cu->lang () == language_ada)
     {
       replacement_type = quirk_ada_thick_pointer (die, cu, type);
       if (replacement_type != nullptr)
@@ -15707,7 +15710,7 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu)
      FIXME: dsl/2004-8-20: If G77 is ever fixed, this will also need
      version checking.  */
 
-  if (cu->per_cu->lang () == language_fortran
+  if (cu->lang () == language_fortran
       && cu->producer && strstr (cu->producer, "GNU F77"))
     {
       return DW_ORD_row_major;
@@ -16446,9 +16449,9 @@ prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
      languages that allow unprototyped functions (Eg: Objective C).
      For all other languages, assume that functions are always
      prototyped.  */
-  if (cu->per_cu->lang () != language_c
-      && cu->per_cu->lang () != language_objc
-      && cu->per_cu->lang () != language_opencl)
+  if (cu->lang () != language_c
+      && cu->lang () != language_objc
+      && cu->lang () != language_opencl)
     return 1;
 
   /* RealView does not emit DW_AT_prototyped.  We can not distinguish
@@ -16573,7 +16576,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 	      /* RealView does not mark THIS as const, which the testsuite
 		 expects.  GCC marks THIS as const in method definitions,
 		 but not in the class specifications (GCC PR 43053).  */
-	      if (cu->per_cu->lang () == language_cplus
+	      if (cu->lang () == language_cplus
 		  && !TYPE_CONST (arg_type)
 		  && TYPE_FIELD_ARTIFICIAL (ftype, iparams))
 		{
@@ -17009,7 +17012,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
   /* Try to find a suitable floating point builtin type of size BITS.
      We're going to use the name of this type as the name for the complex
      target type that we are about to create.  */
-  switch (cu->per_cu->lang ())
+  switch (cu->lang ())
     {
     case language_fortran:
       switch (bits)
@@ -17099,7 +17102,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   if ((encoding == DW_ATE_signed_fixed || encoding == DW_ATE_unsigned_fixed)
-      && cu->per_cu->lang () == language_ada
+      && cu->lang () == language_ada
       && has_zero_over_zero_small_attribute (die, cu))
     {
       /* brobecker/2018-02-24: This is a fixed point type for which
@@ -17121,7 +17124,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
      than an "else if".  */
   const char *gnat_encoding_suffix = nullptr;
   if ((encoding == DW_ATE_signed || encoding == DW_ATE_unsigned)
-      && cu->per_cu->lang () == language_ada
+      && cu->lang () == language_ada
       && name != nullptr)
     {
       gnat_encoding_suffix = gnat_encoded_fixed_point_type_info (name);
@@ -17178,7 +17181,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 	type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
 	break;
       case DW_ATE_unsigned:
-	if (cu->per_cu->lang () == language_fortran
+	if (cu->lang () == language_fortran
 	    && name
 	    && startswith (name, "character("))
 	  type = init_character_type (objfile, bits, 1, name);
@@ -17186,20 +17189,20 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 	  type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
 	break;
       case DW_ATE_signed_char:
-	if (cu->per_cu->lang () == language_ada
-	    || cu->per_cu->lang () == language_m2
-	    || cu->per_cu->lang () == language_pascal
-	    || cu->per_cu->lang () == language_fortran)
+	if (cu->lang () == language_ada
+	    || cu->lang () == language_m2
+	    || cu->lang () == language_pascal
+	    || cu->lang () == language_fortran)
 	  type = init_character_type (objfile, bits, 0, name);
 	else
 	  type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
 	break;
       case DW_ATE_unsigned_char:
-	if (cu->per_cu->lang () == language_ada
-	    || cu->per_cu->lang () == language_m2
-	    || cu->per_cu->lang () == language_pascal
-	    || cu->per_cu->lang () == language_fortran
-	    || cu->per_cu->lang () == language_rust)
+	if (cu->lang () == language_ada
+	    || cu->lang () == language_m2
+	    || cu->lang () == language_pascal
+	    || cu->lang () == language_fortran
+	    || cu->lang () == language_rust)
 	  type = init_character_type (objfile, bits, 1, name);
 	else
 	  type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
@@ -17497,7 +17500,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
      omitting DW_AT_lower_bound.  */
-  switch (cu->per_cu->lang ())
+  switch (cu->lang ())
     {
     case language_c:
     case language_cplus:
@@ -17633,7 +17636,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
     range_type->bounds ()->flag_upper_bound_is_count = 1;
 
   /* Ada expects an empty array on no boundary attributes.  */
-  if (attr == NULL && cu->per_cu->lang () != language_ada)
+  if (attr == NULL && cu->lang () != language_ada)
     range_type->bounds ()->high.set_undefined ();
 
   name = dwarf2_name (die, cu);
@@ -17666,7 +17669,7 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
      of the type is deferred to a different unit.  When encountering
      such a type, we treat it as a stub, and try to resolve it later on,
      when needed.  */
-  if (cu->per_cu->lang () == language_ada)
+  if (cu->lang () == language_ada)
     type->set_is_stub (true);
 
   return set_die_type (die, type, cu);
@@ -18347,7 +18350,7 @@ cooked_indexer::index_dies (cutu_reader *reader,
 	  else
 	    this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
 					       name, this_parent_entry,
-					       m_per_cu);
+					       m_per_cu, m_language);
 	}
 
       if (linkage_name != nullptr)
@@ -18364,7 +18367,7 @@ cooked_indexer::index_dies (cutu_reader *reader,
 	          && abbrev->tag != DW_TAG_entry_point))
 	    flags = flags | IS_LINKAGE;
 	  m_index_storage->add (this_die, abbrev->tag, flags,
-				linkage_name, nullptr, m_per_cu);
+				linkage_name, nullptr, m_per_cu, m_language);
 	}
 
       if (abbrev->has_children)
@@ -18452,7 +18455,7 @@ cooked_indexer::make_index (cutu_reader *reader)
       cooked_index_entry *parent
 	= (cooked_index_entry *) m_die_range_map.find (key);
       m_index_storage->add (entry.die_offset, entry.tag, entry.flags,
-			    entry.name, parent, m_per_cu);
+			    entry.name, parent, m_per_cu, m_language);
     }
 }
 
@@ -18566,7 +18569,7 @@ cooked_index_functions::expand_matching_symbols
 	continue;
 
       if (name_match (entry->canonical, lookup_name, nullptr))
-	dw2_instantiate_symtab (entry->per_cu, per_objfile, false);
+	dw2_instantiate_symtab (entry->m_per_cu_lang->per_cu, per_objfile, false);
     }
 }
 
@@ -18632,12 +18635,12 @@ cooked_index_functions::expand_symtabs_matching
 							  completing))
 	{
 	  /* No need to consider symbols from expanded CUs.  */
-	  if (per_objfile->symtab_set_p (entry->per_cu))
+	  if (per_objfile->symtab_set_p (entry->m_per_cu_lang->per_cu))
 	    continue;
 
 	  /* If file-matching was done, we don't need to consider
 	     symbols from unmarked CUs.  */
-	  if (file_matcher != nullptr && !entry->per_cu->mark)
+	  if (file_matcher != nullptr && !entry->m_per_cu_lang->per_cu->mark)
 	    continue;
 
 	  /* See if the symbol matches the type filter.  */
@@ -18690,7 +18693,8 @@ cooked_index_functions::expand_symtabs_matching
 		continue;
 	    }
 
-	  if (!dw2_expand_symtabs_matching_one (entry->per_cu, per_objfile,
+	  if (!dw2_expand_symtabs_matching_one (entry->m_per_cu_lang->per_cu,
+						per_objfile,
 						file_matcher,
 						expansion_notify))
 	    return false;
@@ -20685,16 +20689,16 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
       OBJSTAT (objfile, n_syms++);
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
-      sym->set_language (cu->per_cu->lang (), &objfile->objfile_obstack);
+      sym->set_language (cu->lang (), &objfile->objfile_obstack);
       /* Fortran does not have mangling standard and the mangling does differ
 	 between gfortran, iFort etc.  */
       const char *physname
-	= (cu->per_cu->lang () == language_fortran
+	= (cu->lang () == language_fortran
 	   ? dwarf2_full_name (name, die, cu)
 	   : dwarf2_physname (name, die, cu));
       const char *linkagename = dw2_linkage_name (die, cu);
 
-      if (linkagename == nullptr || cu->per_cu->lang () == language_ada)
+      if (linkagename == nullptr || cu->lang () == language_ada)
 	sym->set_linkage_name (physname);
       else
 	{
@@ -20766,8 +20770,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  sym->set_aclass_index (LOC_BLOCK);
 	  attr2 = dwarf2_attr (die, DW_AT_external, cu);
 	  if ((attr2 != nullptr && attr2->as_boolean ())
-	      || cu->per_cu->lang () == language_ada
-	      || cu->per_cu->lang () == language_fortran)
+	      || cu->lang () == language_ada
+	      || cu->lang () == language_fortran)
 	    {
 	      /* Subprograms marked external are stored as a global symbol.
 		 Ada and Fortran subprograms, whether marked external or
@@ -20832,7 +20836,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
 	      /* Fortran explicitly imports any global symbols to the local
 		 scope by DW_TAG_common_block.  */
-	      if (cu->per_cu->lang () == language_fortran && die->parent
+	      if (cu->lang () == language_fortran && die->parent
 		  && die->parent->tag == DW_TAG_common_block)
 		attr2 = NULL;
 
@@ -20886,7 +20890,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
 	      /* Fortran explicitly imports any global symbols to the local
 		 scope by DW_TAG_common_block.  */
-	      if (cu->per_cu->lang () == language_fortran && die->parent
+	      if (cu->lang () == language_fortran && die->parent
 		  && die->parent->tag == DW_TAG_common_block)
 		{
 		  /* SYMBOL_CLASS doesn't matter here because
@@ -20980,16 +20984,16 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 		buildsym_compunit *builder = cu->get_builder ();
 		list_to_add
 		  = (cu->list_in_scope == builder->get_file_symbols ()
-		     && cu->per_cu->lang () == language_cplus
+		     && cu->lang () == language_cplus
 		     ? builder->get_global_symbols ()
 		     : cu->list_in_scope);
 
 		/* The semantics of C++ state that "struct foo {
 		   ... }" also defines a typedef for "foo".  */
-		if (cu->per_cu->lang () == language_cplus
-		    || cu->per_cu->lang () == language_ada
-		    || cu->per_cu->lang () == language_d
-		    || cu->per_cu->lang () == language_rust)
+		if (cu->lang () == language_cplus
+		    || cu->lang () == language_ada
+		    || cu->lang () == language_d
+		    || cu->lang () == language_rust)
 		  {
 		    /* The symbol's name is already allocated along
 		       with this objfile, so we don't need to
@@ -21025,7 +21029,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
 	    list_to_add
 	      = (cu->list_in_scope == cu->get_builder ()->get_file_symbols ()
-		 && cu->per_cu->lang () == language_cplus
+		 && cu->lang () == language_cplus
 		 ? cu->get_builder ()->get_global_symbols ()
 		 : cu->list_in_scope);
 	  }
@@ -21068,7 +21072,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */
       if (!cu->processing_has_namespace_info
-	  && cu->per_cu->lang () == language_cplus)
+	  && cu->lang () == language_cplus)
 	cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
     }
   return (sym);
@@ -21280,7 +21284,7 @@ need_gnat_info (struct dwarf2_cu *cu)
 {
   /* Assume that the Ada compiler was GNAT, which always produces
      the auxiliary information.  */
-  return (cu->per_cu->lang () == language_ada);
+  return (cu->lang () == language_ada);
 }
 
 /* Return the auxiliary type of the die in question using its
@@ -21657,10 +21661,10 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
   struct type *parent_type;
   const char *retval;
 
-  if (cu->per_cu->lang () != language_cplus
-      && cu->per_cu->lang () != language_fortran
-      && cu->per_cu->lang () != language_d
-      && cu->per_cu->lang () != language_rust)
+  if (cu->lang () != language_cplus
+      && cu->lang () != language_fortran
+      && cu->lang () != language_d
+      && cu->lang () != language_rust)
     return "";
 
   retval = anonymous_struct_prefix (die, cu);
@@ -21748,7 +21752,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 	/* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus
 	   DW_TAG_namespace DIEs with a name of "::" for the global namespace.
 	   Work around this problem here.  */
-	if (cu->per_cu->lang () == language_cplus
+	if (cu->lang () == language_cplus
 	    && strcmp (parent_type->name (), "::") == 0)
 	  return "";
 	/* We give a name to even anonymous namespaces.  */
@@ -21769,7 +21773,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
       case DW_TAG_compile_unit:
       case DW_TAG_partial_unit:
 	/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace.  Cope.  */
-	if (cu->per_cu->lang () == language_cplus
+	if (cu->lang () == language_cplus
 	    && !per_objfile->per_bfd->types.empty ()
 	    && die->child != NULL
 	    && (die->tag == DW_TAG_class_type
@@ -21784,7 +21788,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
       case DW_TAG_subprogram:
 	/* Nested subroutines in Fortran get a prefix with the name
 	   of the parent's subroutine.  */
-	if (cu->per_cu->lang () == language_fortran)
+	if (cu->lang () == language_fortran)
 	  {
 	    if ((die->tag ==  DW_TAG_subprogram)
 		&& (dwarf2_name (parent, cu) != NULL))
@@ -21823,7 +21827,7 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix,
   if (suffix == NULL || suffix[0] == '\0'
       || prefix == NULL || prefix[0] == '\0')
     sep = "";
-  else if (cu->per_cu->lang () == language_d)
+  else if (cu->lang () == language_d)
     {
       /* For D, the 'main' function could be defined in any module, but it
 	 should never be prefixed.  */
@@ -21835,7 +21839,7 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix,
       else
 	sep = ".";
     }
-  else if (cu->per_cu->lang () == language_fortran && physname)
+  else if (cu->lang () == language_fortran && physname)
     {
       /* This is gfortran specific mangling.  Normally DW_AT_linkage_name or
 	 DW_AT_MIPS_linkage_name is preferred and used instead.  */
@@ -21876,7 +21880,7 @@ static const char *
 dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
 			  struct objfile *objfile)
 {
-  if (name && cu->per_cu->lang () == language_cplus)
+  if (name && cu->lang () == language_cplus)
     {
       gdb::unique_xmalloc_ptr<char> canon_name
 	= cp_canonicalize_string (name);
@@ -22253,10 +22257,10 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
 	 Even if maybe_queue_comp_unit doesn't require us to load the CU's DIEs,
 	 it doesn't mean they are currently loaded.  Since we require them
 	 to be loaded, we must check for ourselves.  */
-      if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->per_cu->lang ())
+      if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->lang ())
 	  || per_objfile->get_cu (per_cu) == nullptr)
 	load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
-			     false, cu->per_cu->lang ());
+			     false, cu->lang ());
 
       target_cu = per_objfile->get_cu (per_cu);
       gdb_assert (target_cu != nullptr);
@@ -23585,7 +23589,6 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
   else
     lang = pretend_language;
 
-  cu->per_cu->set_lang (lang);
   cu->language_defn = language_def (lang);
 }
 
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 22b4dc2f867..b73ac0f8661 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -109,7 +109,6 @@ struct dwarf2_per_cu_data
       mark (false),
       files_read (false),
       m_unit_type {},
-      m_lang (language_unknown),
       scanned (false)
   {
   }
@@ -182,11 +181,6 @@ struct dwarf2_per_cu_data
     ENUM_BITFIELD (dwarf_unit_type) m_unit_type : 8;
   };
 
-  struct { 
-    /* The language of this CU.  */
-    ENUM_BITFIELD (language) m_lang : LANGUAGE_BITS;
-  };
-
 public:
   /* True if this CU has been scanned by the indexer; false if
      not.  */
@@ -329,21 +323,6 @@ struct dwarf2_per_cu_data
       gdb_assert (m_unit_type == unit_type);
   }
 
-  enum language lang () const
-  {
-    gdb_assert (m_lang != language_unknown);
-    return m_lang;
-  }
-
-  void set_lang (enum language lang)
-  {
-    /* We'd like to be more strict here, similar to what is done in
-       set_unit_type,  but currently a partial unit can go from unknown to
-       minimal to ada to c.  */
-    if (m_lang != lang)
-      m_lang = lang;
-  }
-
   /* Free any cached file names.  */
   void free_cached_file_names ();
 };

  parent reply	other threads:[~2022-07-05 15:19 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-29 15:29 [PATCH 1/5] [COVER-LETTER, RFC] Fix some fsanitize=thread issues in gdb's cooked index Tom de Vries
2022-06-29 15:29 ` [PATCH 2/5] [gdb/symtab] Fix data race on per_cu->dwarf_version Tom de Vries
2022-07-01 11:16   ` Tom de Vries
2022-07-02 11:07     ` Tom de Vries
2022-07-04 18:51       ` Tom Tromey
2022-07-04 19:43         ` Tom de Vries
2022-07-04 19:53           ` Tom Tromey
2022-06-29 15:29 ` [PATCH 3/5] [gdb/symtab] Work around fsanitize=address false positive for per_cu->lang Tom de Vries
2022-06-29 17:38   ` Pedro Alves
2022-06-29 18:25     ` Pedro Alves
2022-06-29 18:28       ` Pedro Alves
2022-07-04  7:04         ` [PATCH 3/5] [gdb/symtab] Work around fsanitize=address false positive for per_ cu->lang Tom de Vries
2022-07-04 18:32   ` [PATCH 3/5] [gdb/symtab] Work around fsanitize=address false positive for per_cu->lang Tom Tromey
2022-07-04 19:45     ` Tom de Vries
2022-07-06 19:20       ` [PATCH] Introduce struct packed template, fix -fsanitize=thread for per_cu fields Pedro Alves
2022-07-07 10:18         ` Tom de Vries
2022-07-07 15:26           ` Pedro Alves
2022-07-08 14:54             ` Tom de Vries
2022-07-12 10:22               ` Tom de Vries
2022-06-29 15:29 ` [PATCH 4/5] [gdb/symtab] Work around fsanitize=address false positive for per_cu->unit_type Tom de Vries
2022-06-29 15:29 ` [PATCH 5/5] [gdb/symtab] Fix data race on per_cu->lang Tom de Vries
2022-07-04 18:30   ` Tom Tromey
2022-07-05  8:17     ` Tom de Vries
2022-07-05 15:19     ` Tom de Vries [this message]
2022-07-06 15:42       ` Tom de Vries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=35591557-02e9-d87c-e07b-49919282666e@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).