[gdb/symtab] Add get/set functions for per_cu->lang/unit_type

The dwarf2_per_cu_data fields lang and unit_type both have a dont-know
initial value (respectively language_unknown and (dwarf_unit_type)0), which
allows us to add certain checks, f.i. checking that that a field is not read
before written.

Add get/set member functions for the two fields as a convenient location to
add such checks, make the fields private to enforce using the member
functions, and add the m_ prefix.

Tested on x86_64-linux.
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 3e34ad0..adb0046 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -54,7 +54,7 @@
     return canonical;
 
   const char *sep = nullptr;
-  switch (per_cu->lang)
+  switch (per_cu->lang ())
     {
     case language_cplus:
     case language_rust:
@@ -104,7 +104,7 @@
      implicit "main" discovery.  */
   if ((flags & IS_MAIN) != 0)
     m_main = result;
-  else if (per_cu->lang != language_ada
+  else if (per_cu->lang () != language_ada
 	   && m_main == nullptr
 	   && strcmp (name, "main") == 0)
     m_main = result;
@@ -196,13 +196,13 @@
   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->per_cu->lang () != language_cplus
+	   && entry->per_cu->lang () != language_ada)
 	  || (entry->flags & IS_LINKAGE) != 0)
 	entry->canonical = entry->name;
       else
 	{
-	  if (entry->per_cu->lang == language_ada)
+	  if (entry->per_cu->lang () == language_ada)
 	    {
 	      gdb::unique_xmalloc_ptr<char> canon_name
 		= handle_gnat_encoded_entry (entry, gnat_entries.get ());
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index fcb0d77..8cbd976 100644
--- a/gdb/dwarf2/cu.c
+++ b/gdb/dwarf2/cu.c
@@ -62,7 +62,7 @@
 
   m_builder.reset (new struct buildsym_compunit
 		   (this->per_objfile->objfile,
-		    name, comp_dir, per_cu->lang, low_pc));
+		    name, comp_dir, per_cu->lang (), low_pc));
 
   list_in_scope = get_builder ()->get_file_symbols ();
 
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index 7f8df0b..c3aad8d 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -583,7 +583,7 @@
 
     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->per_cu->lang ());
   }
 
   /* Build all the tables.  All symbols must be already inserted.
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 410cc90..23fe567 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6779,13 +6779,13 @@
   switch (reader.comp_unit_die->tag)
     {
     case DW_TAG_compile_unit:
-      this_cu->unit_type = DW_UT_compile;
+      this_cu->set_unit_type (DW_UT_compile);
       break;
     case DW_TAG_partial_unit:
-      this_cu->unit_type = DW_UT_partial;
+      this_cu->set_unit_type (DW_UT_partial);
       break;
     case DW_TAG_type_unit:
-      this_cu->unit_type = DW_UT_type;
+      this_cu->set_unit_type (DW_UT_type);
       break;
     default:
       error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
@@ -6808,7 +6808,7 @@
 	  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->per_cu->lang ());
 	  indexer.make_index (&reader);
 	}
     }
@@ -6832,7 +6832,7 @@
   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->per_cu->lang ());
   indexer.make_index (reader);
 }
 
@@ -7142,7 +7142,7 @@
   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->per_cu->lang ());
 
   dwarf_read_debug_printf ("Done building psymtabs of %s",
 			   objfile_name (objfile));
@@ -7745,7 +7745,7 @@
   /* Only C++ delays computing physnames.  */
   if (cu->method_list.empty ())
     return;
-  gdb_assert (cu->per_cu->lang == language_cplus);
+  gdb_assert (cu->per_cu->lang () == language_cplus);
 
   for (const delayed_method_info &mi : cu->method_list)
     {
@@ -8174,7 +8174,7 @@
 static void
 rust_union_quirks (struct dwarf2_cu *cu)
 {
-  gdb_assert (cu->per_cu->lang == language_rust);
+  gdb_assert (cu->per_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 +8368,7 @@
   process_die (cu->dies, cu);
 
   /* For now fudge the Go package.  */
-  if (cu->per_cu->lang == language_go)
+  if (cu->per_cu->lang () == language_go)
     fixup_go_packaging (cu);
 
   /* Now that we have processed all the DIEs in the CU, all the types
@@ -8376,7 +8376,7 @@
      physnames.  */
   compute_delayed_physnames (cu);
 
-  if (cu->per_cu->lang == language_rust)
+  if (cu->per_cu->lang () == language_rust)
     rust_union_quirks (cu);
 
   /* Some compilers don't define a DW_AT_high_pc attribute for the
@@ -8405,9 +8405,9 @@
       /* 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->per_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->per_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 +8461,7 @@
   process_die (cu->dies, cu);
 
   /* For now fudge the Go package.  */
-  if (cu->per_cu->lang == language_go)
+  if (cu->per_cu->lang () == language_go)
     fixup_go_packaging (cu);
 
   /* Now that we have processed all the DIEs in the CU, all the types
@@ -8469,7 +8469,7 @@
      physnames.  */
   compute_delayed_physnames (cu);
 
-  if (cu->per_cu->lang == language_rust)
+  if (cu->per_cu->lang () == language_rust)
     rust_union_quirks (cu);
 
   /* TUs share symbol tables.
@@ -8490,9 +8490,9 @@
 	     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->per_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->per_cu->lang ());
 	}
     }
   else
@@ -8536,15 +8536,15 @@
 	 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)
+	  && per_cu->unit_type () == DW_UT_compile
+	  && per_cu->lang () == language_cplus)
 	return;
 
       /* 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->per_cu->lang ()))
 	load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
-			     false, cu->per_cu->lang);
+			     false, cu->per_cu->lang ());
 
       cu->per_cu->imported_symtabs_push (per_cu);
     }
@@ -8602,7 +8602,7 @@
       break;
     case DW_TAG_subprogram:
       /* Nested subprograms in Fortran get a prefix.  */
-      if (cu->per_cu->lang == language_fortran
+      if (cu->per_cu->lang () == language_fortran
 	  && die->parent != NULL
 	  && die->parent->tag == DW_TAG_subprogram)
 	cu->processing_has_namespace_info = true;
@@ -8646,7 +8646,7 @@
       /* 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->per_cu->lang () != language_ada)
 	break;
       /* FALLTHROUGH */
     case DW_TAG_base_type:
@@ -8680,7 +8680,7 @@
     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->per_cu->lang () != language_fortran))
 	complaint (_("Tag '%s' has unexpected children"),
 		   dwarf_tag_name (die->tag));
       read_import_statement (die, cu);
@@ -8792,7 +8792,7 @@
 
   /* 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->per_cu->lang () == language_rust && linkage_name != NULL
       && strchr (linkage_name, '{') != NULL)
     linkage_name = NULL;
 
@@ -8824,7 +8824,7 @@
   if (name == NULL)
     name = dwarf2_name (die, cu);
 
-  enum language lang = cu->per_cu->lang;
+  enum language lang = cu->per_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 +9073,7 @@
   if (!die_needs_namespace (die, cu))
     return dwarf2_compute_name (name, die, cu, 1);
 
-  if (cu->per_cu->lang != language_rust)
+  if (cu->per_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 +9230,7 @@
 static struct using_direct **
 using_directives (struct dwarf2_cu *cu)
 {
-  if (cu->per_cu->lang == language_ada
+  if (cu->per_cu->lang () == language_ada
       && cu->get_builder ()->outermost_context_p ())
     return cu->get_builder ()->get_global_using_directives ();
   else
@@ -9321,7 +9321,7 @@
   else if (strlen (imported_name_prefix) > 0)
     canonical_name = obconcat (&objfile->objfile_obstack,
 			       imported_name_prefix,
-			       (cu->per_cu->lang == language_d
+			       (cu->per_cu->lang () == language_d
 				? "."
 				: "::"),
 			       imported_name, (char *) NULL);
@@ -9329,7 +9329,7 @@
     canonical_name = imported_name;
 
   if (die->tag == DW_TAG_imported_module
-      && cu->per_cu->lang == language_fortran)
+      && cu->per_cu->lang () == language_fortran)
     for (child_die = die->child; child_die && child_die->tag;
 	 child_die = child_die->sibling)
       {
@@ -9555,7 +9555,7 @@
   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->per_cu->lang ());
   baseaddr = objfile->text_section_offset ();
 
   get_scope_pc_bounds (die, &lowpc, &highpc, cu);
@@ -11717,7 +11717,7 @@
 	 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->per_cu->lang ()))
 	load_full_type_unit (sig_type, cu->per_objfile);
       cu->per_cu->imported_symtabs_push (sig_type);
     }
@@ -12007,7 +12007,7 @@
 
   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->per_cu->lang ());
 
   /* If there is a location expression for DW_AT_frame_base, record
      it.  */
@@ -12052,7 +12052,7 @@
   /* 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->per_cu->lang () == language_cplus
       && dwarf2_attr (die, DW_AT_specification, cu))
     {
       struct dwarf2_cu *spec_cu = cu;
@@ -12080,10 +12080,10 @@
 				     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->per_cu->lang () == language_cplus
+       || cu->per_cu->lang () == language_fortran
+       || cu->per_cu->lang () == language_d
+       || cu->per_cu->lang () == language_rust)
       && cu->processing_has_namespace_info)
     block_set_scope (block, determine_prefix (die, cu),
 		     &objfile->objfile_obstack);
@@ -12583,7 +12583,7 @@
 {
   struct rust_vtable_symbol *storage = NULL;
 
-  if (cu->per_cu->lang == language_rust)
+  if (cu->per_cu->lang () == language_rust)
     {
       struct type *containing_type = rust_containing_type (die, cu);
 
@@ -13097,7 +13097,7 @@
 
   /* 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->per_cu->lang () != language_ada)
     return;
 
   /* Check all the children of the given DIE.  If it contains nested
@@ -13902,7 +13902,7 @@
   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->per_cu->lang () != language_ada)
     {
       ALLOCATE_CPLUS_STRUCT_TYPE (type);
 
@@ -13921,7 +13921,7 @@
 
   /* 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->per_cu->lang () != language_ada)
     {
       int num_bytes = B_BYTES (fip->baseclasses.size ());
       unsigned char *pointer;
@@ -13947,12 +13947,12 @@
       switch (field.accessibility)
 	{
 	case DW_ACCESS_private:
-	  if (cu->per_cu->lang != language_ada)
+	  if (cu->per_cu->lang () != language_ada)
 	    SET_TYPE_FIELD_PRIVATE (type, i);
 	  break;
 
 	case DW_ACCESS_protected:
-	  if (cu->per_cu->lang != language_ada)
+	  if (cu->per_cu->lang () != language_ada)
 	    SET_TYPE_FIELD_PROTECTED (type, i);
 	  break;
 
@@ -13973,7 +13973,7 @@
 	    {
 	    case DW_VIRTUALITY_virtual:
 	    case DW_VIRTUALITY_pure_virtual:
-	      if (cu->per_cu->lang == language_ada)
+	      if (cu->per_cu->lang () == language_ada)
 		error (_("unexpected virtuality in component of Ada type"));
 	      SET_TYPE_FIELD_VIRTUAL (type, i);
 	      break;
@@ -14024,7 +14024,7 @@
   const char *fieldname;
   struct type *this_type;
 
-  if (cu->per_cu->lang == language_ada)
+  if (cu->per_cu->lang () == language_ada)
     error (_("unexpected member function in Ada type"));
 
   /* Get name of member function.  */
@@ -14057,7 +14057,7 @@
   fnp = &flp->fnfields.back ();
 
   /* Delay processing of the physname until later.  */
-  if (cu->per_cu->lang == language_cplus)
+  if (cu->per_cu->lang () == language_cplus)
     add_to_method_list (type, i, flp->fnfields.size () - 1, fieldname,
 			die, cu);
   else
@@ -14212,7 +14212,7 @@
 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->per_cu->lang () == language_ada)
     error (_("unexpected member functions in Ada type"));
 
   ALLOCATE_CPLUS_STRUCT_TYPE (type);
@@ -14355,7 +14355,7 @@
 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->per_cu->lang () == language_ada);
 
   /* Check for a structure with two children.  */
   if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
@@ -14534,9 +14534,9 @@
   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->per_cu->lang  () == language_cplus
+	  || cu->per_cu->lang () == language_d
+	  || cu->per_cu->lang () == language_rust)
 	{
 	  const char *full_name = dwarf2_full_name (name, die, cu);
 
@@ -14572,7 +14572,7 @@
       type->set_code (TYPE_CODE_STRUCT);
     }
 
-  if (cu->per_cu->lang == language_cplus && die->tag == DW_TAG_class_type)
+  if (cu->per_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 +14784,7 @@
       /* 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->per_cu->lang () == language_rust)
 	read_func_scope (child_die, cu);
       else
 	{
@@ -14948,7 +14948,7 @@
       /* 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->per_cu->lang () != language_ada)
 	{
 	  int count = fi.nested_types_list.size ();
 
@@ -14964,9 +14964,9 @@
     }
 
   quirk_gcc_member_function_pointer (type, objfile);
-  if (cu->per_cu->lang == language_rust && die->tag == DW_TAG_union_type)
+  if (cu->per_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->per_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 +15670,7 @@
   maybe_set_alignment (cu, die, type);
 
   struct type *replacement_type = nullptr;
-  if (cu->per_cu->lang == language_ada)
+  if (cu->per_cu->lang () == language_ada)
     {
       replacement_type = quirk_ada_thick_pointer (die, cu, type);
       if (replacement_type != nullptr)
@@ -15707,7 +15707,7 @@
      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->per_cu->lang () == language_fortran
       && cu->producer && strstr (cu->producer, "GNU F77"))
     {
       return DW_ORD_row_major;
@@ -16446,9 +16446,9 @@
      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->per_cu->lang () != language_c
+      && cu->per_cu->lang () != language_objc
+      && cu->per_cu->lang () != language_opencl)
     return 1;
 
   /* RealView does not emit DW_AT_prototyped.  We can not distinguish
@@ -16573,7 +16573,7 @@
 	      /* 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->per_cu->lang () == language_cplus
 		  && !TYPE_CONST (arg_type)
 		  && TYPE_FIELD_ARTIFICIAL (ftype, iparams))
 		{
@@ -17009,7 +17009,7 @@
   /* 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->per_cu->lang ())
     {
     case language_fortran:
       switch (bits)
@@ -17099,7 +17099,7 @@
     }
 
   if ((encoding == DW_ATE_signed_fixed || encoding == DW_ATE_unsigned_fixed)
-      && cu->per_cu->lang == language_ada
+      && cu->per_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 +17121,7 @@
      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->per_cu->lang () == language_ada
       && name != nullptr)
     {
       gnat_encoding_suffix = gnat_encoded_fixed_point_type_info (name);
@@ -17178,7 +17178,7 @@
 	type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
 	break;
       case DW_ATE_unsigned:
-	if (cu->per_cu->lang == language_fortran
+	if (cu->per_cu->lang () == language_fortran
 	    && name
 	    && startswith (name, "character("))
 	  type = init_character_type (objfile, bits, 1, name);
@@ -17186,20 +17186,20 @@
 	  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->per_cu->lang () == language_ada
+	    || cu->per_cu->lang () == language_m2
+	    || cu->per_cu->lang () == language_pascal
+	    || cu->per_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->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)
 	  type = init_character_type (objfile, bits, 1, name);
 	else
 	  type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
@@ -17497,7 +17497,7 @@
 
   /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
      omitting DW_AT_lower_bound.  */
-  switch (cu->per_cu->lang)
+  switch (cu->per_cu->lang ())
     {
     case language_c:
     case language_cplus:
@@ -17633,7 +17633,7 @@
     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->per_cu->lang () != language_ada)
     range_type->bounds ()->high.set_undefined ();
 
   name = dwarf2_name (die, cu);
@@ -17666,7 +17666,7 @@
      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->per_cu->lang () == language_ada)
     type->set_is_stub (true);
 
   return set_die_type (die, type, cu);
@@ -20685,16 +20685,16 @@
       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->per_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->per_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->per_cu->lang () == language_ada)
 	sym->set_linkage_name (physname);
       else
 	{
@@ -20766,8 +20766,8 @@
 	  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->per_cu->lang () == language_ada
+	      || cu->per_cu->lang () == language_fortran)
 	    {
 	      /* Subprograms marked external are stored as a global symbol.
 		 Ada and Fortran subprograms, whether marked external or
@@ -20832,7 +20832,7 @@
 
 	      /* 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->per_cu->lang () == language_fortran && die->parent
 		  && die->parent->tag == DW_TAG_common_block)
 		attr2 = NULL;
 
@@ -20886,7 +20886,7 @@
 
 	      /* 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->per_cu->lang () == language_fortran && die->parent
 		  && die->parent->tag == DW_TAG_common_block)
 		{
 		  /* SYMBOL_CLASS doesn't matter here because
@@ -20980,16 +20980,16 @@
 		buildsym_compunit *builder = cu->get_builder ();
 		list_to_add
 		  = (cu->list_in_scope == builder->get_file_symbols ()
-		     && cu->per_cu->lang == language_cplus
+		     && cu->per_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->per_cu->lang () == language_cplus
+		    || cu->per_cu->lang () == language_ada
+		    || cu->per_cu->lang () == language_d
+		    || cu->per_cu->lang () == language_rust)
 		  {
 		    /* The symbol's name is already allocated along
 		       with this objfile, so we don't need to
@@ -21025,7 +21025,7 @@
 
 	    list_to_add
 	      = (cu->list_in_scope == cu->get_builder ()->get_file_symbols ()
-		 && cu->per_cu->lang == language_cplus
+		 && cu->per_cu->lang () == language_cplus
 		 ? cu->get_builder ()->get_global_symbols ()
 		 : cu->list_in_scope);
 	  }
@@ -21068,7 +21068,7 @@
       /* 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->per_cu->lang () == language_cplus)
 	cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
     }
   return (sym);
@@ -21280,7 +21280,7 @@
 {
   /* Assume that the Ada compiler was GNAT, which always produces
      the auxiliary information.  */
-  return (cu->per_cu->lang == language_ada);
+  return (cu->per_cu->lang () == language_ada);
 }
 
 /* Return the auxiliary type of the die in question using its
@@ -21657,10 +21657,10 @@
   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->per_cu->lang () != language_cplus
+      && cu->per_cu->lang () != language_fortran
+      && cu->per_cu->lang () != language_d
+      && cu->per_cu->lang () != language_rust)
     return "";
 
   retval = anonymous_struct_prefix (die, cu);
@@ -21748,7 +21748,7 @@
 	/* 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->per_cu->lang () == language_cplus
 	    && strcmp (parent_type->name (), "::") == 0)
 	  return "";
 	/* We give a name to even anonymous namespaces.  */
@@ -21769,7 +21769,7 @@
       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->per_cu->lang () == language_cplus
 	    && !per_objfile->per_bfd->types.empty ()
 	    && die->child != NULL
 	    && (die->tag == DW_TAG_class_type
@@ -21784,7 +21784,7 @@
       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->per_cu->lang () == language_fortran)
 	  {
 	    if ((die->tag ==  DW_TAG_subprogram)
 		&& (dwarf2_name (parent, cu) != NULL))
@@ -21823,7 +21823,7 @@
   if (suffix == NULL || suffix[0] == '\0'
       || prefix == NULL || prefix[0] == '\0')
     sep = "";
-  else if (cu->per_cu->lang == language_d)
+  else if (cu->per_cu->lang () == language_d)
     {
       /* For D, the 'main' function could be defined in any module, but it
 	 should never be prefixed.  */
@@ -21835,7 +21835,7 @@
       else
 	sep = ".";
     }
-  else if (cu->per_cu->lang == language_fortran && physname)
+  else if (cu->per_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 +21876,7 @@
 dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
 			  struct objfile *objfile)
 {
-  if (name && cu->per_cu->lang == language_cplus)
+  if (name && cu->per_cu->lang () == language_cplus)
     {
       gdb::unique_xmalloc_ptr<char> canon_name
 	= cp_canonicalize_string (name);
@@ -22253,10 +22253,10 @@
 	 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->per_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->per_cu->lang ());
 
       target_cu = per_objfile->get_cu (per_cu);
       gdb_assert (target_cu != nullptr);
@@ -23564,6 +23564,7 @@
 
   /* Set the language we're debugging.  */
   attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu);
+  enum language lang;
   if (cu->producer != nullptr
       && strstr (cu->producer, "IBM XL C for OpenCL") != NULL)
     {
@@ -23571,19 +23572,21 @@
 	 attribute is not standardised yet.  As a workaround for the
 	 language detection we fall back to the DW_AT_producer
 	 string.  */
-      cu->per_cu->lang = language_opencl;
+      lang = language_opencl;
     }
   else if (cu->producer != nullptr
 	   && strstr (cu->producer, "GNU Go ") != NULL)
     {
       /* Similar hack for Go.  */
-      cu->per_cu->lang = language_go;
+      lang = language_go;
     }
   else if (attr != nullptr)
-    cu->per_cu->lang = dwarf_lang_to_enum_language (attr->constant_value (0));
+    lang = dwarf_lang_to_enum_language (attr->constant_value (0));
   else
-    cu->per_cu->lang = pretend_language;
-  cu->language_defn = language_def (cu->per_cu->lang);
+    lang = pretend_language;
+
+  cu->per_cu->set_lang (lang);
+  cu->language_defn = language_def (lang);
 }
 
 /* See read.h.  */
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index b7a0393..1d9c66a 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -108,8 +108,8 @@
       addresses_seen (false),
       mark (false),
       files_read (false),
-      unit_type {},
-      lang (language_unknown),
+      m_unit_type {},
+      m_lang (language_unknown),
       scanned (false)
   {
   }
@@ -173,12 +173,14 @@
      point in trying to read it again next time.  */
   bool files_read : 1;
 
+private:
   /* The unit type of this CU.  */
-  ENUM_BITFIELD (dwarf_unit_type) unit_type : 8;
+  ENUM_BITFIELD (dwarf_unit_type) m_unit_type : 8;
 
   /* The language of this CU.  */
-  ENUM_BITFIELD (language) lang : LANGUAGE_BITS;
+  ENUM_BITFIELD (language) m_lang : LANGUAGE_BITS;
 
+public:
   /* True if this CU has been scanned by the indexer; false if
      not.  */
   std::atomic<bool> scanned;
@@ -304,6 +306,37 @@
       gdb_assert (m_dwarf_version == version);
   }
 
+  dwarf_unit_type unit_type () const
+  {
+    gdb_assert (m_unit_type != 0);
+    return m_unit_type;
+  }
+
+  void set_unit_type (dwarf_unit_type unit_type)
+  {
+    if (m_unit_type == 0)
+      /* Set if not set already.  */
+      m_unit_type = unit_type;
+    else
+      /* If already set, verify that it's the same value.  */
+      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 ();
 };