Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] [gdb/symtab] Factor out new_symbol variant
@ 2026-04-23 12:58 Tom de Vries
  2026-04-28 16:05 ` Tom Tromey
  0 siblings, 1 reply; 2+ messages in thread
From: Tom de Vries @ 2026-04-23 12:58 UTC (permalink / raw)
  To: gdb-patches

Factor out a new_symbol variant out of new_symbol, containing mostly the
die->tag switch.

While we're at it, modernize the code using bool and nullptr.  Also, remove
some unnecessary braces, and apply this simplification:
...
if (c)
   foo (a);
else
   foo (b);
->
foo (c
     ? a
     : b);
...

I wondered about naming the new variant new_symbol_tag or new_symbol_1, but
I stuck with new_symbol.

Refactoring made we wonder why we use linkagename instead of sym->linkagename ()
after sym->set_linkage_name (), but since there are cornercases where these are
different, I've left it as is.

Also, I suspect the cp_scan_for_anonymous_namespaces can be hoisted, but I
also left that as is.

Finally, I noticed that physname == linkagename uses a pointer equivalence
test, which seems fragile to me.  Also that I left as is.

The patch is easier to view with git show -w.
---
 gdb/dwarf2/read.c | 865 +++++++++++++++++++++++-----------------------
 1 file changed, 431 insertions(+), 434 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index bc7b8b46d87..629de258339 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -15472,497 +15472,494 @@ new_symbol_file_line (struct die_info *die, struct dwarf2_cu *cu,
   sym->set_symtab (fe->symtab (*file_cu));
 }
 
-/* Given a pointer to a DWARF information entry, figure out if we need
-   to make a symbol table entry for it, and if so, create a new entry
-   and return a pointer to it.
-   If TYPE is NULL, determine symbol type from the die, otherwise
-   used the passed type.
-   If SPACE is not NULL, use it to hold the new symbol.  If it is
-   NULL, allocate a new symbol on the objfile's obstack.  */
+/* Given a DWARF information entry CU/DIE with LINKAGENAME and PHYSNAME, fill
+   in SYM according to DIE->tag.  */
 
-static struct symbol *
-new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
-	    struct symbol *space)
+static void
+new_symbol (struct die_info *die, struct dwarf2_cu *cu, struct symbol *sym,
+	    const char *linkagename, const char *physname)
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
-  struct symbol *sym = NULL;
-  const char *name;
-  struct attribute *attr = NULL;
-  struct attribute *attr2 = NULL;
+  struct attribute *attr = nullptr;
+  struct attribute *attr2 = nullptr;
   std::vector<symbol *> *list_to_add = nullptr;
+  bool suppress_add = false;
 
-  name = dwarf2_name (die, cu);
-  if (name == nullptr && (die->tag == DW_TAG_subprogram
-			  || die->tag == DW_TAG_inlined_subroutine
-			  || die->tag == DW_TAG_entry_point))
-    name = dw2_linkage_name (die, cu);
-
-  if (name)
+  switch (die->tag)
     {
-      int suppress_add = 0;
-
-      if (space)
-	sym = space;
-      else
-	sym = objfile->new_symbol<symbol> ();
-
-      /* Cache this symbol's name and the name's demangled form (if any).  */
-      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->lang () == language_fortran || cu->lang () == language_ada)
-	   ? dwarf2_full_name (name, die, cu)
-	   : dwarf2_physname (name, die, cu));
-      const char *linkagename = dw2_linkage_name (die, cu);
-
-      if (linkagename == nullptr)
-	sym->set_linkage_name (physname);
-      else if (cu->lang () == language_ada)
-	sym->set_linkage_name (linkagename);
+    case DW_TAG_label:
+      {
+	attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+	if (attr != nullptr)
+	  {
+	    CORE_ADDR addr = per_objfile->relocate (attr->as_address ());
+	    sym->set_section_index (SECT_OFF_TEXT (objfile));
+	    sym->set_value_address (addr);
+	    sym->set_loc_class_index (LOC_LABEL);
+	  }
+	else
+	  sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
+	type_allocator alloc (objfile, cu->lang ());
+	struct type *addr_type
+	  = alloc.copy_type (builtin_type (objfile)->builtin_core_addr);
+	sym->set_type (addr_type);
+	sym->set_domain (LABEL_DOMAIN);
+	list_to_add = cu->list_in_scope;
+      }
+      break;
+    case DW_TAG_entry_point:
+      /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+	 finish_block.  */
+      sym->set_domain (FUNCTION_DOMAIN);
+      sym->set_loc_class_index (LOC_BLOCK);
+      /* DW_TAG_entry_point provides an additional entry_point to an
+	 existing sub_program.  Therefore, we inherit the "external"
+	 attribute from the sub_program to which the entry_point
+	 belongs to.  */
+      attr2 = dwarf2_attr (die->parent, DW_AT_external, cu);
+      if (attr2 != nullptr && attr2->as_boolean ())
+	list_to_add = &cu->get_builder ()->get_global_symbols ();
       else
+	list_to_add = cu->list_in_scope;
+      break;
+    case DW_TAG_subprogram:
+      /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+	 finish_block.  */
+      sym->set_domain (FUNCTION_DOMAIN);
+      sym->set_loc_class_index (LOC_BLOCK);
+      attr2 = dwarf2_attr (die, DW_AT_external, cu);
+      if ((attr2 != nullptr && attr2->as_boolean ())
+	  || cu->lang () == language_ada
+	  || cu->lang () == language_fortran)
 	{
-	  if (physname == linkagename)
-	    sym->set_demangled_name (name, &objfile->objfile_obstack);
-	  else
-	    sym->set_demangled_name (physname, &objfile->objfile_obstack);
-
-	  sym->set_linkage_name (linkagename);
+	  /* Subprograms marked external are stored as a global symbol.
+	     Ada and Fortran subprograms, whether marked external or
+	     not, are always stored as a global symbol, because we want
+	     to be able to access them globally.  For instance, we want
+	     to be able to break on a nested subprogram without having
+	     to specify the context.  */
+	  list_to_add = &cu->get_builder ()->get_global_symbols ();
 	}
-
-      /* Handle DW_AT_artificial.  */
-      attr = dwarf2_attr (die, DW_AT_artificial, cu);
-      if (attr != nullptr)
-	sym->set_is_artificial (attr->as_boolean ());
-
-      /* Default assumptions.
-	 Use the passed type or decode it from the die.  */
-      sym->set_domain (UNDEF_DOMAIN);
-      sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-      if (type != NULL)
-	sym->set_type (type);
       else
-	sym->set_type (die_type (die, cu));
+	list_to_add = cu->list_in_scope;
 
-      /* Handle DW_AT_{call,decl}_{file,line}.  */
-      new_symbol_file_line (die, cu, sym);
-
-      switch (die->tag)
+      if (is_ada_import_or_export (cu, physname, linkagename))
 	{
-	case DW_TAG_label:
-	  {
-	    attr = dwarf2_attr (die, DW_AT_low_pc, cu);
-	    if (attr != nullptr)
-	      {
-		CORE_ADDR addr = per_objfile->relocate (attr->as_address ());
-		sym->set_section_index (SECT_OFF_TEXT (objfile));
-		sym->set_value_address (addr);
-		sym->set_loc_class_index (LOC_LABEL);
-	      }
-	    else
-	      sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-	    type_allocator alloc (objfile, cu->lang ());
-	    struct type *addr_type
-	      = alloc.copy_type (builtin_type (objfile)->builtin_core_addr);
-	    sym->set_type (addr_type);
-	    sym->set_domain (LABEL_DOMAIN);
-	    list_to_add = cu->list_in_scope;
-	  }
-	  break;
-	case DW_TAG_entry_point:
-	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
-	     finish_block.  */
-	  sym->set_domain (FUNCTION_DOMAIN);
-	  sym->set_loc_class_index (LOC_BLOCK);
-	  /* DW_TAG_entry_point provides an additional entry_point to an
-	     existing sub_program.  Therefore, we inherit the "external"
-	     attribute from the sub_program to which the entry_point
-	     belongs to.  */
-	  attr2 = dwarf2_attr (die->parent, DW_AT_external, cu);
-	  if (attr2 != nullptr && attr2->as_boolean ())
-	    list_to_add = &cu->get_builder ()->get_global_symbols ();
-	  else
-	    list_to_add = cu->list_in_scope;
-	  break;
-	case DW_TAG_subprogram:
-	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
-	     finish_block.  */
-	  sym->set_domain (FUNCTION_DOMAIN);
-	  sym->set_loc_class_index (LOC_BLOCK);
-	  attr2 = dwarf2_attr (die, DW_AT_external, cu);
-	  if ((attr2 != nullptr && attr2->as_boolean ())
-	      || cu->lang () == language_ada
-	      || cu->lang () == language_fortran)
+	  /* This is either a Pragma Import or Export.  They can
+	     be distinguished by the declaration flag.  */
+	  sym->set_linkage_name (physname);
+	  if (die_is_declaration (die, cu))
 	    {
-	      /* Subprograms marked external are stored as a global symbol.
-		 Ada and Fortran subprograms, whether marked external or
-		 not, are always stored as a global symbol, because we want
-		 to be able to access them globally.  For instance, we want
-		 to be able to break on a nested subprogram without having
-		 to specify the context.  */
-	      list_to_add = &cu->get_builder ()->get_global_symbols ();
+	      /* For Import, create a symbol using the source
+		 name, and have it refer to the linkage name.  */
+	      SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
+	      sym->set_loc_class_index (ada_block_index);
 	    }
 	  else
 	    {
-	      list_to_add = cu->list_in_scope;
+	      /* For Export, create a symbol using the source
+		 name, then create a second symbol that refers
+		 back to it.  */
+	      add_ada_export_symbol (sym, linkagename, physname, cu,
+				     *list_to_add);
 	    }
+	}
+      break;
+    case DW_TAG_inlined_subroutine:
+      /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+	 finish_block.  */
+      sym->set_domain (FUNCTION_DOMAIN);
+      sym->set_loc_class_index (LOC_BLOCK);
+      sym->set_is_inlined (1);
+      list_to_add = cu->list_in_scope;
+      break;
+    case DW_TAG_template_value_param:
+      suppress_add = true;
+      [[fallthrough]];
+    case DW_TAG_constant:
+    case DW_TAG_variable:
+    case DW_TAG_member:
+      sym->set_domain (VAR_DOMAIN);
+      /* Compilation with minimal debug info may result in
+	 variables with missing type entries.  Change the
+	 misleading `void' type to something sensible.  */
+      if (sym->type ()->code () == TYPE_CODE_VOID)
+	{
+	  type_allocator alloc (objfile, cu->lang ());
+	  struct type *int_type
+	    = alloc.copy_type (builtin_type (objfile)->builtin_int);
+	  sym->set_type (int_type);
+	}
 
-	  if (is_ada_import_or_export (cu, physname, linkagename))
+      attr = dwarf2_attr (die, DW_AT_const_value, cu);
+      /* In the case of DW_TAG_member, we should only be called for
+	 static const members.  */
+      if (die->tag == DW_TAG_member)
+	{
+	  /* dwarf2_add_field uses die_is_declaration,
+	     so we do the same.  */
+	  gdb_assert (die_is_declaration (die, cu));
+	  gdb_assert (attr);
+	}
+      if (attr != nullptr)
+	{
+	  dwarf2_const_value (attr, sym, cu);
+	  attr2 = dwarf2_attr (die, DW_AT_external, cu);
+	  if (!suppress_add)
 	    {
-	      /* This is either a Pragma Import or Export.  They can
-		 be distinguished by the declaration flag.  */
-	      sym->set_linkage_name (physname);
-	      if (die_is_declaration (die, cu))
-		{
-		  /* For Import, create a symbol using the source
-		     name, and have it refer to the linkage name.  */
-		  SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
-		  sym->set_loc_class_index (ada_block_index);
-		}
+	      if (attr2 != nullptr && attr2->as_boolean ())
+		list_to_add = &cu->get_builder ()->get_global_symbols ();
 	      else
-		{
-		  /* For Export, create a symbol using the source
-		     name, then create a second symbol that refers
-		     back to it.  */
-		  add_ada_export_symbol (sym, linkagename, physname, cu,
-					 *list_to_add);
-		}
+		list_to_add = cu->list_in_scope;
 	    }
 	  break;
-	case DW_TAG_inlined_subroutine:
-	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
-	     finish_block.  */
-	  sym->set_domain (FUNCTION_DOMAIN);
-	  sym->set_loc_class_index (LOC_BLOCK);
-	  sym->set_is_inlined (1);
-	  list_to_add = cu->list_in_scope;
-	  break;
-	case DW_TAG_template_value_param:
-	  suppress_add = 1;
-	  [[fallthrough]];
-	case DW_TAG_constant:
-	case DW_TAG_variable:
-	case DW_TAG_member:
-	  sym->set_domain (VAR_DOMAIN);
-	  /* Compilation with minimal debug info may result in
-	     variables with missing type entries.  Change the
-	     misleading `void' type to something sensible.  */
-	  if (sym->type ()->code () == TYPE_CODE_VOID)
-	    {
-	      type_allocator alloc (objfile, cu->lang ());
-	      struct type *int_type
-		= alloc.copy_type (builtin_type (objfile)->builtin_int);
-	      sym->set_type (int_type);
-	    }
+	}
+      attr = dwarf2_attr (die, DW_AT_location, cu);
+      if (attr != nullptr)
+	{
+	  var_decode_location (attr, sym, cu);
+	  attr2 = dwarf2_attr (die, DW_AT_external, cu);
 
-	  attr = dwarf2_attr (die, DW_AT_const_value, cu);
-	  /* In the case of DW_TAG_member, we should only be called for
-	     static const members.  */
-	  if (die->tag == DW_TAG_member)
-	    {
-	      /* dwarf2_add_field uses die_is_declaration,
-		 so we do the same.  */
-	      gdb_assert (die_is_declaration (die, cu));
-	      gdb_assert (attr);
-	    }
-	  if (attr != nullptr)
+	  /* Fortran explicitly imports any global symbols to the local
+	     scope by DW_TAG_common_block.  */
+	  if (cu->lang () == language_fortran && die->parent
+	      && die->parent->tag == DW_TAG_common_block)
+	    attr2 = nullptr;
+
+	  if (sym->loc_class () == LOC_STATIC
+	      && sym->value_address () == 0
+	      && !per_objfile->per_bfd->has_section_at_zero)
 	    {
-	      dwarf2_const_value (attr, sym, cu);
-	      attr2 = dwarf2_attr (die, DW_AT_external, cu);
-	      if (!suppress_add)
-		{
-		  if (attr2 != nullptr && attr2->as_boolean ())
-		    list_to_add = &cu->get_builder ()->get_global_symbols ();
-		  else
-		    list_to_add = cu->list_in_scope;
-		}
-	      break;
+	      /* When a static variable is eliminated by the linker,
+		 the corresponding debug information is not stripped
+		 out, but the variable address is set to null;
+		 do not add such variables into symbol table.  */
 	    }
-	  attr = dwarf2_attr (die, DW_AT_location, cu);
-	  if (attr != nullptr)
+	  else if (attr2 != nullptr && attr2->as_boolean ())
 	    {
-	      var_decode_location (attr, sym, cu);
-	      attr2 = dwarf2_attr (die, DW_AT_external, cu);
-
-	      /* Fortran explicitly imports any global symbols to the local
-		 scope by DW_TAG_common_block.  */
-	      if (cu->lang () == language_fortran && die->parent
-		  && die->parent->tag == DW_TAG_common_block)
-		attr2 = NULL;
-
 	      if (sym->loc_class () == LOC_STATIC
-		  && sym->value_address () == 0
-		  && !per_objfile->per_bfd->has_section_at_zero)
-		{
-		  /* When a static variable is eliminated by the linker,
-		     the corresponding debug information is not stripped
-		     out, but the variable address is set to null;
-		     do not add such variables into symbol table.  */
-		}
-	      else if (attr2 != nullptr && attr2->as_boolean ())
+		  && (objfile->flags & OBJF_MAINLINE) == 0
+		  && per_objfile->per_bfd->can_copy)
 		{
-		  if (sym->loc_class () == LOC_STATIC
-		      && (objfile->flags & OBJF_MAINLINE) == 0
-		      && per_objfile->per_bfd->can_copy)
-		    {
-		      /* A global static variable might be subject to
-			 copy relocation.  We first check for a local
-			 minsym, though, because maybe the symbol was
-			 marked hidden, in which case this would not
-			 apply.  */
-		      bound_minimal_symbol found
-			= (lookup_minimal_symbol_linkage
-			   (sym->linkage_name (), objfile, false));
-		      if (found.minsym != nullptr)
-			sym->maybe_copied = 1;
-		    }
-
-		  /* A variable with DW_AT_external is never static,
-		     but it may be block-scoped.  */
-		  list_to_add
-		    = ((cu->list_in_scope
-			== &cu->get_builder ()->get_file_symbols ())
-		       ? &cu->get_builder ()->get_global_symbols ()
-		       : cu->list_in_scope);
+		  /* A global static variable might be subject to
+		     copy relocation.  We first check for a local
+		     minsym, though, because maybe the symbol was
+		     marked hidden, in which case this would not
+		     apply.  */
+		  bound_minimal_symbol found
+		    = (lookup_minimal_symbol_linkage
+		       (sym->linkage_name (), objfile, false));
+		  if (found.minsym != nullptr)
+		    sym->maybe_copied = 1;
 		}
-	      else
-		list_to_add = cu->list_in_scope;
 
-	      if (list_to_add != nullptr
-		  && is_ada_import_or_export (cu, physname, linkagename))
-		{
-		  /* This is a Pragma Export.  A Pragma Import won't
-		     be seen here, because it will not have a location
-		     and so will be handled below.  */
-		  add_ada_export_symbol (sym, physname, linkagename, cu,
-					 *list_to_add);
-		}
+	      /* A variable with DW_AT_external is never static,
+		 but it may be block-scoped.  */
+	      list_to_add
+		= ((cu->list_in_scope
+		    == &cu->get_builder ()->get_file_symbols ())
+		   ? &cu->get_builder ()->get_global_symbols ()
+		   : cu->list_in_scope);
 	    }
 	  else
+	    list_to_add = cu->list_in_scope;
+
+	  if (list_to_add != nullptr
+	      && is_ada_import_or_export (cu, physname, linkagename))
 	    {
-	      /* We do not know the address of this symbol.
-		 If it is an external symbol and we have type information
-		 for it, enter the symbol as a LOC_UNRESOLVED symbol.
-		 The address of the variable will then be determined from
-		 the minimal symbol table whenever the variable is
-		 referenced.  */
-	      attr2 = dwarf2_attr (die, DW_AT_external, cu);
-
-	      /* Fortran explicitly imports any global symbols to the local
-		 scope by DW_TAG_common_block.  */
-	      if (cu->lang () == language_fortran && die->parent
-		  && die->parent->tag == DW_TAG_common_block)
-		{
-		  /* SYMBOL_CLASS doesn't matter here because
-		     read_common_block is going to reset it.  */
-		  if (!suppress_add)
-		    list_to_add = cu->list_in_scope;
-		}
-	      else if (is_ada_import_or_export (cu, physname, linkagename))
-		{
-		  /* This is a Pragma Import.  A Pragma Export won't
-		     be seen here, because it will have a location and
-		     so will be handled above.  */
-		  sym->set_linkage_name (physname);
-		  list_to_add
-		    = ((cu->list_in_scope
-			== &cu->get_builder ()->get_file_symbols ())
-		       ? &cu->get_builder ()->get_global_symbols ()
-		       : cu->list_in_scope);
-		  SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
-		  sym->set_loc_class_index (ada_imported_index);
-		}
-	      else if (attr2 != nullptr && attr2->as_boolean ()
-		       && dwarf2_attr (die, DW_AT_type, cu) != NULL)
-		{
-		  /* A variable with DW_AT_external is never static, but it
-		     may be block-scoped.  */
-		  list_to_add
-		    = ((cu->list_in_scope
-			== &cu->get_builder ()->get_file_symbols ())
-		       ? &cu->get_builder ()->get_global_symbols ()
-		       : cu->list_in_scope);
-
-		  sym->set_loc_class_index (LOC_UNRESOLVED);
-		}
-	      else if (!die_is_declaration (die, cu))
-		{
-		  /* Use the default LOC_OPTIMIZED_OUT class.  */
-		  gdb_assert (sym->loc_class () == LOC_OPTIMIZED_OUT);
-		  if (!suppress_add)
-		    list_to_add = cu->list_in_scope;
-		}
+	      /* This is a Pragma Export.  A Pragma Import won't
+		 be seen here, because it will not have a location
+		 and so will be handled below.  */
+	      add_ada_export_symbol (sym, physname, linkagename, cu,
+				     *list_to_add);
 	    }
-	  break;
-	case DW_TAG_formal_parameter:
-	  {
-	    /* If we are inside a function, mark this as an argument.  If
-	       not, we might be looking at an argument to an inlined function
-	       when we do not have enough information to show inlined frames;
-	       pretend it's a local variable in that case so that the user can
-	       still see it.  */
-	    sym->set_domain (VAR_DOMAIN);
-	    if (cu->get_builder ()->current_context_has_function ())
-	      sym->set_is_argument (true);
-	    attr = dwarf2_attr (die, DW_AT_location, cu);
-	    if (attr != nullptr)
-	      {
-		var_decode_location (attr, sym, cu);
-	      }
-	    attr = dwarf2_attr (die, DW_AT_const_value, cu);
-	    if (attr != nullptr)
-	      {
-		dwarf2_const_value (attr, sym, cu);
-	      }
+	}
+      else
+	{
+	  /* We do not know the address of this symbol.
+	     If it is an external symbol and we have type information
+	     for it, enter the symbol as a LOC_UNRESOLVED symbol.
+	     The address of the variable will then be determined from
+	     the minimal symbol table whenever the variable is
+	     referenced.  */
+	  attr2 = dwarf2_attr (die, DW_AT_external, cu);
 
-	    list_to_add = cu->list_in_scope;
-	  }
-	  break;
-	case DW_TAG_unspecified_parameters:
-	  /* From varargs functions; gdb doesn't seem to have any
-	     interest in this information, so just ignore it for now.
-	     (FIXME?) */
-	  break;
-	case DW_TAG_template_type_param:
-	  suppress_add = 1;
-	  [[fallthrough]];
-	case DW_TAG_class_type:
-	case DW_TAG_interface_type:
-	case DW_TAG_structure_type:
-	case DW_TAG_union_type:
-	case DW_TAG_set_type:
-	case DW_TAG_enumeration_type:
-	  if (cu->lang () == language_c
-	      || cu->lang () == language_cplus
-	      || cu->lang () == language_objc
-	      || cu->lang () == language_opencl
-	      || cu->lang () == language_minimal)
+	  /* Fortran explicitly imports any global symbols to the local
+	     scope by DW_TAG_common_block.  */
+	  if (cu->lang () == language_fortran && die->parent
+	      && die->parent->tag == DW_TAG_common_block)
 	    {
-	      /* These languages have a tag namespace.  Note that
-		 there's a special hack for C++ in the matching code,
-		 so we don't need to enter a separate typedef for the
-		 tag.  */
-	      sym->set_loc_class_index (LOC_TYPEDEF);
-	      sym->set_domain (STRUCT_DOMAIN);
+	      /* SYMBOL_CLASS doesn't matter here because
+		 read_common_block is going to reset it.  */
+	      if (!suppress_add)
+		list_to_add = cu->list_in_scope;
 	    }
-	  else
+	  else if (is_ada_import_or_export (cu, physname, linkagename))
 	    {
-	      /* Other languages don't have a tag namespace.  */
-	      sym->set_loc_class_index (LOC_TYPEDEF);
-	      sym->set_domain (TYPE_DOMAIN);
+	      /* This is a Pragma Import.  A Pragma Export won't
+		 be seen here, because it will have a location and
+		 so will be handled above.  */
+	      sym->set_linkage_name (physname);
+	      list_to_add
+		= ((cu->list_in_scope
+		    == &cu->get_builder ()->get_file_symbols ())
+		   ? &cu->get_builder ()->get_global_symbols ()
+		   : cu->list_in_scope);
+	      SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
+	      sym->set_loc_class_index (ada_imported_index);
 	    }
-
-	  /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
-	     really ever be static objects: otherwise, if you try
-	     to, say, break of a class's method and you're in a file
-	     which doesn't mention that class, it won't work unless
-	     the check for all static symbols in lookup_symbol_aux
-	     saves you.  See the OtherFileClass tests in
-	     gdb.c++/namespace.exp.  */
-
-	  if (!suppress_add)
+	  else if (attr2 != nullptr && attr2->as_boolean ()
+		   && dwarf2_attr (die, DW_AT_type, cu) != nullptr)
 	    {
-	      buildsym_compunit *builder = cu->get_builder ();
+	      /* A variable with DW_AT_external is never static, but it
+		 may be block-scoped.  */
 	      list_to_add
-		= ((cu->list_in_scope == &builder->get_file_symbols ()
-		    && cu->lang () == language_cplus)
-		   ? &builder->get_global_symbols ()
+		= ((cu->list_in_scope
+		    == &cu->get_builder ()->get_file_symbols ())
+		   ? &cu->get_builder ()->get_global_symbols ()
 		   : cu->list_in_scope);
 
-	      /* The semantics of C++ state that "struct foo {
-		 ... }" also defines a typedef for "foo".  */
-	      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
-		     duplicate it for the type.  */
-		  if (sym->type ()->name () == 0)
-		    sym->type ()->set_name (sym->search_name ());
-		}
+	      sym->set_loc_class_index (LOC_UNRESOLVED);
 	    }
-	  break;
-	case DW_TAG_unspecified_type:
-	  if (cu->lang () == language_ada)
-	    break;
-	  [[fallthrough]];
-	case DW_TAG_typedef:
-	case DW_TAG_array_type:
-	case DW_TAG_base_type:
-	case DW_TAG_subrange_type:
-	case DW_TAG_generic_subrange:
-	  sym->set_loc_class_index (LOC_TYPEDEF);
-	  sym->set_domain (TYPE_DOMAIN);
-	  list_to_add = cu->list_in_scope;
-	  break;
-	case DW_TAG_enumerator:
-	  sym->set_domain (VAR_DOMAIN);
-	  attr = dwarf2_attr (die, DW_AT_const_value, cu);
-	  if (attr != nullptr)
+	  else if (!die_is_declaration (die, cu))
 	    {
-	      dwarf2_const_value (attr, sym, cu);
+	      /* Use the default LOC_OPTIMIZED_OUT class.  */
+	      gdb_assert (sym->loc_class () == LOC_OPTIMIZED_OUT);
+	      if (!suppress_add)
+		list_to_add = cu->list_in_scope;
 	    }
+	}
+      break;
+    case DW_TAG_formal_parameter:
+      {
+	/* If we are inside a function, mark this as an argument.  If
+	   not, we might be looking at an argument to an inlined function
+	   when we do not have enough information to show inlined frames;
+	   pretend it's a local variable in that case so that the user can
+	   still see it.  */
+	sym->set_domain (VAR_DOMAIN);
+	if (cu->get_builder ()->current_context_has_function ())
+	  sym->set_is_argument (true);
+	attr = dwarf2_attr (die, DW_AT_location, cu);
+	if (attr != nullptr)
+	  var_decode_location (attr, sym, cu);
+	attr = dwarf2_attr (die, DW_AT_const_value, cu);
+	if (attr != nullptr)
+	  dwarf2_const_value (attr, sym, cu);
+
+	list_to_add = cu->list_in_scope;
+      }
+      break;
+    case DW_TAG_unspecified_parameters:
+      /* From varargs functions; gdb doesn't seem to have any
+	 interest in this information, so just ignore it for now.
+	 (FIXME?) */
+      break;
+    case DW_TAG_template_type_param:
+      suppress_add = true;
+      [[fallthrough]];
+    case DW_TAG_class_type:
+    case DW_TAG_interface_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_set_type:
+    case DW_TAG_enumeration_type:
+      if (cu->lang () == language_c
+	  || cu->lang () == language_cplus
+	  || cu->lang () == language_objc
+	  || cu->lang () == language_opencl
+	  || cu->lang () == language_minimal)
+	{
+	  /* These languages have a tag namespace.  Note that
+	     there's a special hack for C++ in the matching code,
+	     so we don't need to enter a separate typedef for the
+	     tag.  */
+	  sym->set_loc_class_index (LOC_TYPEDEF);
+	  sym->set_domain (STRUCT_DOMAIN);
+	}
+      else
+	{
+	  /* Other languages don't have a tag namespace.  */
+	  sym->set_loc_class_index (LOC_TYPEDEF);
+	  sym->set_domain (TYPE_DOMAIN);
+	}
 
-	  /* NOTE: carlton/2003-11-10: See comment above in the
-	     DW_TAG_class_type, etc. block.  */
+      /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+	 really ever be static objects: otherwise, if you try
+	 to, say, break of a class's method and you're in a file
+	 which doesn't mention that class, it won't work unless
+	 the check for all static symbols in lookup_symbol_aux
+	 saves you.  See the OtherFileClass tests in
+	 gdb.c++/namespace.exp.  */
 
+      if (!suppress_add)
+	{
+	  buildsym_compunit *builder = cu->get_builder ();
 	  list_to_add
-	    = ((cu->list_in_scope == &cu->get_builder ()->get_file_symbols ()
+	    = ((cu->list_in_scope == &builder->get_file_symbols ()
 		&& cu->lang () == language_cplus)
-	       ? &cu->get_builder ()->get_global_symbols ()
+	       ? &builder->get_global_symbols ()
 	       : cu->list_in_scope);
-	  break;
-	case DW_TAG_imported_declaration:
-	case DW_TAG_namespace:
-	  sym->set_domain (TYPE_DOMAIN);
-	  sym->set_loc_class_index (LOC_TYPEDEF);
-	  list_to_add = &cu->get_builder ()->get_global_symbols ();
-	  break;
-	case DW_TAG_module:
-	  sym->set_loc_class_index (LOC_TYPEDEF);
-	  sym->set_domain (MODULE_DOMAIN);
-	  list_to_add = &cu->get_builder ()->get_global_symbols ();
-	  break;
-	case DW_TAG_common_block:
-	  sym->set_loc_class_index (LOC_COMMON_BLOCK);
-	  sym->set_domain (COMMON_BLOCK_DOMAIN);
-	  list_to_add = cu->list_in_scope;
-	  break;
-	case DW_TAG_namelist:
-	  sym->set_loc_class_index (LOC_STATIC);
-	  sym->set_domain (VAR_DOMAIN);
-	  list_to_add = cu->list_in_scope;
-	  break;
-	default:
-	  /* Not a tag we recognize.  Hopefully we aren't processing
-	     trash data, but since we must specifically ignore things
-	     we don't recognize, there is nothing else we should do at
-	     this point.  */
-	  complaint (_("unsupported tag: '%s'"),
-		     dwarf_tag_name (die->tag));
-	  break;
-	}
 
-      if (suppress_add)
-	{
-	  sym->hash_next = objfile->template_symbols;
-	  objfile->template_symbols = sym;
-	  list_to_add = NULL;
+	  /* The semantics of C++ state that "struct foo {
+	     ... }" also defines a typedef for "foo".  */
+	  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
+		 duplicate it for the type.  */
+	      if (sym->type ()->name () == 0)
+		sym->type ()->set_name (sym->search_name ());
+	    }
 	}
+      break;
+    case DW_TAG_unspecified_type:
+      if (cu->lang () == language_ada)
+	break;
+      [[fallthrough]];
+    case DW_TAG_typedef:
+    case DW_TAG_array_type:
+    case DW_TAG_base_type:
+    case DW_TAG_subrange_type:
+    case DW_TAG_generic_subrange:
+      sym->set_loc_class_index (LOC_TYPEDEF);
+      sym->set_domain (TYPE_DOMAIN);
+      list_to_add = cu->list_in_scope;
+      break;
+    case DW_TAG_enumerator:
+      sym->set_domain (VAR_DOMAIN);
+      attr = dwarf2_attr (die, DW_AT_const_value, cu);
+      if (attr != nullptr)
+	dwarf2_const_value (attr, sym, cu);
 
-      if (list_to_add != NULL)
-	add_symbol_to_list (sym, *list_to_add);
+      /* NOTE: carlton/2003-11-10: See comment above in the
+	 DW_TAG_class_type, etc. block.  */
+
+      list_to_add
+	= ((cu->list_in_scope == &cu->get_builder ()->get_file_symbols ()
+	    && cu->lang () == language_cplus)
+	   ? &cu->get_builder ()->get_global_symbols ()
+	   : cu->list_in_scope);
+      break;
+    case DW_TAG_imported_declaration:
+    case DW_TAG_namespace:
+      sym->set_domain (TYPE_DOMAIN);
+      sym->set_loc_class_index (LOC_TYPEDEF);
+      list_to_add = &cu->get_builder ()->get_global_symbols ();
+      break;
+    case DW_TAG_module:
+      sym->set_loc_class_index (LOC_TYPEDEF);
+      sym->set_domain (MODULE_DOMAIN);
+      list_to_add = &cu->get_builder ()->get_global_symbols ();
+      break;
+    case DW_TAG_common_block:
+      sym->set_loc_class_index (LOC_COMMON_BLOCK);
+      sym->set_domain (COMMON_BLOCK_DOMAIN);
+      list_to_add = cu->list_in_scope;
+      break;
+    case DW_TAG_namelist:
+      sym->set_loc_class_index (LOC_STATIC);
+      sym->set_domain (VAR_DOMAIN);
+      list_to_add = cu->list_in_scope;
+      break;
+    default:
+      /* Not a tag we recognize.  Hopefully we aren't processing
+	 trash data, but since we must specifically ignore things
+	 we don't recognize, there is nothing else we should do at
+	 this point.  */
+      complaint (_("unsupported tag: '%s'"),
+		 dwarf_tag_name (die->tag));
+      break;
+    }
 
-      /* For the benefit of old versions of GCC, check for anonymous
-	 namespaces based on the demangled name.  */
-      if (!cu->processing_has_namespace_info
-	  && cu->lang () == language_cplus)
-	cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
+  if (suppress_add)
+    {
+      sym->hash_next = objfile->template_symbols;
+      objfile->template_symbols = sym;
+      return;
     }
-  return (sym);
+
+  if (list_to_add != nullptr)
+    add_symbol_to_list (sym, *list_to_add);
+}
+
+/* Given a pointer to a DWARF information entry, figure out if we need
+   to make a symbol table entry for it, and if so, create a new entry
+   and return a pointer to it.
+   If TYPE is nullptr, determine symbol type from the die, otherwise
+   used the passed type.
+   If SPACE is not nullptr, use it to hold the new symbol.  If it is
+   nullptr, allocate a new symbol on the objfile's obstack.  */
+
+static struct symbol *
+new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
+	    struct symbol *space)
+{
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
+
+  const char *name = dwarf2_name (die, cu);
+  if (name == nullptr && (die->tag == DW_TAG_subprogram
+			  || die->tag == DW_TAG_inlined_subroutine
+			  || die->tag == DW_TAG_entry_point))
+    name = dw2_linkage_name (die, cu);
+  if (name == nullptr)
+    return nullptr;
+
+  struct symbol *sym = space;
+  if (sym == nullptr)
+    sym = objfile->new_symbol<symbol> ();
+
+  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->lang () == language_fortran || cu->lang () == language_ada)
+       ? dwarf2_full_name (name, die, cu)
+       : dwarf2_physname (name, die, cu));
+  const char *linkagename = dw2_linkage_name (die, cu);
+
+  /* Cache this symbol's name and the name's demangled form (if any).  */
+  sym->set_linkage_name (linkagename != nullptr
+			 ? linkagename
+			 : physname);
+  if (linkagename != nullptr && cu->lang () != language_ada)
+    sym->set_demangled_name (physname == linkagename
+			     ? name
+			     : physname,
+			     &objfile->objfile_obstack);
+
+  /* Handle DW_AT_artificial.  */
+  struct attribute *attr = dwarf2_attr (die, DW_AT_artificial, cu);
+  if (attr != nullptr)
+    sym->set_is_artificial (attr->as_boolean ());
+
+  /* Default assumptions.
+     Use the passed type or decode it from the die.  */
+  sym->set_domain (UNDEF_DOMAIN);
+  sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
+  sym->set_type (type != nullptr
+		 ? type
+		 : die_type (die, cu));
+
+  /* Handle DW_AT_{call,decl}_{file,line}.  */
+  new_symbol_file_line (die, cu, sym);
+
+  /* Handle TAG-specific part.  */
+  new_symbol (die, cu, sym, linkagename, physname);
+
+  /* For the benefit of old versions of GCC, check for anonymous
+     namespaces based on the demangled name.  */
+  if (!cu->processing_has_namespace_info
+      && cu->lang () == language_cplus)
+    cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
+
+  return sym;
 }
 
 /* Read a constant value from an attribute.  Either set *VALUE, or if

base-commit: 4d11bf8cc73a1f56d2ffc5af7334ae2c251584b6
-- 
2.51.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] [gdb/symtab] Factor out new_symbol variant
  2026-04-23 12:58 [PATCH] [gdb/symtab] Factor out new_symbol variant Tom de Vries
@ 2026-04-28 16:05 ` Tom Tromey
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Tromey @ 2026-04-28 16:05 UTC (permalink / raw)
  To: Tom de Vries; +Cc: gdb-patches

>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

Tom> Factor out a new_symbol variant out of new_symbol, containing mostly the
Tom> die->tag switch.

Thanks.  This is a nice step in the direction I'd like to see this go.

Approved-By: Tom Tromey <tom@tromey.com>

Tom

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-04-28 16:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-23 12:58 [PATCH] [gdb/symtab] Factor out new_symbol variant Tom de Vries
2026-04-28 16:05 ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox