This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfa] generate fully-qualified names for types


Elena Zannoni writes:
 > 
 > As usual I'd like to split this patch in mechanical
 > changes/replacements and not so mechanical ones.  After the mechanical
 > changes are in, it would be more obvious what has changed.
 > It looks ok to me, but I'd like to minimize the diffs and take another look.
 > I can see:
 > 1. the processing_current_namespace --> processing_current_prefix rename
 > 2. the read_namespace changes of previous namespace-->previous_prefix
 > 3. introduction of namespace_name() 
 > 
 > as mechanical/obvious
 > 
 > I can check in those changes if you are busy. I am too, but now I can
 > swing a day for this.

I've done the above.

 > 
 > Other minor nag is about comments, I think we need more examples in
 > the comments about how the names get composed, etc.

I haven't done this.



Here is what is left for dwarf2read.c, cp-namespace.c and cp-support.h
(nothing).  Valops.c is ok as it was.

you can check those in.

elena


--- dwarf2read.c	2004-01-09 15:36:21.000000000 -0500
+++ dwarf2read-dc.c	2004-01-09 14:44:35.000000000 -0500
@@ -666,12 +666,19 @@ static char *scan_partial_symbols (char 
 static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *,
 				const char *namespace);
 
+static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace);
+
 static char *add_partial_namespace (struct partial_die_info *pdi,
 				    char *info_ptr,
 				    CORE_ADDR *lowpc, CORE_ADDR *highpc,
 				    struct dwarf2_cu *cu,
 				    const char *namespace);
 
+static char *add_partial_structure (struct partial_die_info *struct_pdi,
+				    char *info_ptr,
+				    struct dwarf2_cu *cu,
+				    const char *namespace);
+
 static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
 				      char *info_ptr,
 				      struct dwarf2_cu *cu,
@@ -743,6 +750,8 @@ static struct attribute *dwarf_attr (str
 
 static int die_is_declaration (struct die_info *);
 
+static struct die_info *die_specification (struct die_info *die);
+
 static void free_line_header (struct line_header *lh);
 
 static struct line_header *(dwarf_decode_line_header
@@ -777,6 +786,12 @@ static struct type *tag_type_to_type (st
 
 static void read_type_die (struct die_info *, struct dwarf2_cu *);
 
+static char *determine_prefix (struct die_info *die);
+
+static char *typename_concat (const char *prefix, const char *suffix);
+
+static char *class_name (struct die_info *die);
+
 static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
 static void read_base_type (struct die_info *, struct dwarf2_cu *);
@@ -1368,11 +1383,18 @@ scan_partial_symbols (char *info_ptr, CO
 	    case DW_TAG_variable:
 	    case DW_TAG_typedef:
 	    case DW_TAG_union_type:
+	      if (!pdi.is_declaration)
+		{
+		  add_partial_symbol (&pdi, cu, namespace);
+		}
+	      break;
 	    case DW_TAG_class_type:
 	    case DW_TAG_structure_type:
 	      if (!pdi.is_declaration)
 		{
-		  add_partial_symbol (&pdi, cu, namespace);
+		  info_ptr = add_partial_structure (&pdi, info_ptr, cu,
+						    namespace);
+		  info_ptr_updated = 1;
 		}
 	      break;
 	    case DW_TAG_enumeration_type:
@@ -1430,6 +1452,17 @@ add_partial_symbol (struct partial_die_i
   char *actual_name = pdi->name;
   const struct partial_symbol *psym = NULL;
 
+  /* If we're not in the global namespace and if the namespace name
+     isn't encoded in a mangled actual_name, add it.  */
+  
+  if (pdi_needs_namespace (pdi->tag, namespace))
+    {
+      actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1);
+      strcpy (actual_name, namespace);
+      strcat (actual_name, "::");
+      strcat (actual_name, pdi->name);
+    }
+
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
@@ -1507,11 +1540,15 @@ add_partial_symbol (struct partial_die_i
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
          references.  */
+      /* NOTE: carlton/2003-10-07: See comment in new_symbol about
+	 static vs. global.  */
       if (pdi->has_children == 0)
 	return;
       add_psymbol_to_list (actual_name, strlen (actual_name),
 			   STRUCT_DOMAIN, LOC_TYPEDEF,
-			   &objfile->static_psymbols,
+			   cu_language == language_cplus
+			   ? &objfile->global_psymbols
+			   : &objfile->static_psymbols,
 			   0, (CORE_ADDR) 0, cu_language, objfile);
 
       if (cu_language == language_cplus)
@@ -1519,14 +1556,16 @@ add_partial_symbol (struct partial_die_i
 	  /* For C++, these implicitly act as typedefs as well. */
 	  add_psymbol_to_list (actual_name, strlen (actual_name),
 			       VAR_DOMAIN, LOC_TYPEDEF,
-			       &objfile->static_psymbols,
+			       &objfile->global_psymbols,
 			       0, (CORE_ADDR) 0, cu_language, objfile);
 	}
       break;
     case DW_TAG_enumerator:
       add_psymbol_to_list (actual_name, strlen (actual_name),
 			   VAR_DOMAIN, LOC_CONST,
-			   &objfile->static_psymbols,
+			   cu_language == language_cplus
+			   ? &objfile->static_psymbols
+			   : &objfile->global_psymbols,
 			   0, (CORE_ADDR) 0, cu_language, objfile);
       break;
     default:
@@ -1547,6 +1586,30 @@ add_partial_symbol (struct partial_die_i
 					 objfile);
 }
 
+/* Determine whether a die of type TAG living in the C++ namespace
+   NAMESPACE needs to have the name of the namespace prepended to the
+   name listed in the die.  */
+
+static int
+pdi_needs_namespace (enum dwarf_tag tag, const char *namespace)
+{
+  if (namespace == NULL || namespace[0] == '\0')
+    return 0;
+
+  switch (tag)
+    {
+    case DW_TAG_typedef:
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_enumerator:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 /* Read a partial die corresponding to a namespace; also, add a symbol
    corresponding to that namespace to the symbol table.  NAMESPACE is
    the name of the enclosing namespace.  */
@@ -1570,9 +1633,10 @@ add_partial_namespace (struct partial_di
     strcat (full_name, "::");
   strcat (full_name, new_name);
 
-  /* FIXME: carlton/2003-06-27: Once we build qualified names for more
-     symbols than just namespaces, we should replace this by a call to
-     add_partial_symbol.  */
+  /* FIXME: carlton/2003-10-07: We can't just replace this by a call
+     to add_partial_symbol, because we don't have a way to pass in the
+     full name to that function; that might be a flaw in
+     add_partial_symbol's interface.  */
 
   add_psymbol_to_list (full_name, strlen (full_name),
 		       VAR_DOMAIN, LOC_TYPEDEF,
@@ -1587,6 +1651,63 @@ add_partial_namespace (struct partial_di
   return info_ptr;
 }
 
+/* Read a partial die corresponding to a class or structure.  */
+
+static char *
+add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
+		       struct dwarf2_cu *cu,
+		       const char *namespace)
+{
+  bfd *abfd = cu->objfile->obfd;
+  char *actual_class_name = NULL;
+
+  if (cu_language == language_cplus
+      && namespace == NULL
+      && struct_pdi->name != NULL
+      && struct_pdi->has_children)
+    {
+      /* We don't have namespace debugging information, so see if we
+	 can figure out if this structure lives in a namespace.  Look
+	 for a member function; its demangled name will contain
+	 namespace info, if there is any.  */
+
+      /* NOTE: carlton/2003-10-07: Getting the info this way changes
+	 what template types look like, because the demangler
+	 frequently doesn't give the same name as the debug info.  We
+	 could fix this by only using the demangled name to get the
+	 prefix (but see comment in read_structure_scope).  */
+
+      char *next_child = info_ptr;
+
+      while (1)
+	{
+	  struct partial_die_info child_pdi;
+
+	  next_child = read_partial_die (&child_pdi, abfd, next_child,
+					 cu);
+	  if (!child_pdi.tag)
+	    break;
+	  if (child_pdi.tag == DW_TAG_subprogram)
+	    {
+	      actual_class_name = class_name_from_physname (child_pdi.name);
+	      if (actual_class_name != NULL)
+		struct_pdi->name = actual_class_name;
+	      break;
+	    }
+	  else
+	    {
+	      next_child = locate_pdi_sibling (&child_pdi, next_child,
+					       abfd, cu);
+	    }
+	}
+    }
+
+  add_partial_symbol (struct_pdi, cu, namespace);
+  xfree(actual_class_name);
+
+  return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
+}
+
 /* Read a partial die corresponding to an enumeration type.  */
 
 static char *
@@ -1711,6 +1832,9 @@ psymtab_to_symtab_1 (struct partial_symt
   cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
 
+  /* We're in the global namespace.  */
+  processing_current_prefix = "";
+
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
 
@@ -1864,11 +1988,7 @@ process_die (struct die_info *die, struc
     case DW_TAG_common_inclusion:
       break;
     case DW_TAG_namespace:
-      if (!processing_has_namespace_info)
-	{
-	  processing_has_namespace_info = 1;
-	  processing_current_prefix = "";
-	}
+      processing_has_namespace_info = 1;
       read_namespace (die, cu);
       break;
     case DW_TAG_imported_declaration:
@@ -1879,11 +1999,7 @@ process_die (struct die_info *die, struc
 	 shouldn't in the C++ case, but conceivably could in the
 	 Fortran case, so we'll have to replace this gdb_assert if
 	 Fortran compilers start generating that info.  */
-      if (!processing_has_namespace_info)
-	{
-	  processing_has_namespace_info = 1;
-	  processing_current_prefix = "";
-	}
+      processing_has_namespace_info = 1;
       gdb_assert (die->child == NULL);
       break;
     default:
@@ -2777,6 +2893,13 @@ read_structure_scope (struct die_info *d
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
+  const char *name = NULL;
+  const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
+  /* This says whether or not we want to try to update the structure's
+     name to include enclosing namespace/class information, if
+     any.  */
+  int need_to_update_name = 0;
 
   type = alloc_type (objfile);
 
@@ -2784,9 +2907,41 @@ read_structure_scope (struct die_info *d
   attr = dwarf_attr (die, DW_AT_name);
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-					   strlen (DW_STRING (attr)),
-					   &objfile->type_obstack);
+      name = DW_STRING (attr);
+
+      if (cu_language == language_cplus)
+	{
+	  struct die_info *spec_die = die_specification (die);
+
+	  if (spec_die != NULL)
+	    {
+	      char *specification_prefix = determine_prefix (spec_die);
+	      processing_current_prefix = specification_prefix;
+	      back_to = make_cleanup (xfree, specification_prefix);
+	    }
+	}
+
+      if (processing_has_namespace_info)
+	{
+	  /* FIXME: carlton/2003-11-10: This variable exists only for
+	     const-correctness reasons.  When I tried to change
+	     TYPE_TAG_NAME to be a const char *, I ran into a cascade
+	     of changes which would have forced decode_line_1 to take
+	     a const char **.  */
+	  char *new_prefix = obconcat (&objfile->type_obstack,
+				       processing_current_prefix,
+				       processing_current_prefix[0] == '\0'
+				       ? "" : "::",
+				       name);
+	  TYPE_TAG_NAME (type) = new_prefix;
+	  processing_current_prefix = new_prefix;
+	}
+      else
+	{
+	  TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+					       &objfile->type_obstack);
+	  need_to_update_name = (cu_language == language_cplus);
+	}
     }
 
   if (die->tag == DW_TAG_structure_type)
@@ -2846,6 +3001,41 @@ read_structure_scope (struct die_info *d
 	      /* C++ member function. */
 	      process_die (child_die, cu);
 	      dwarf2_add_member_fn (&fi, child_die, type, cu);
+	      if (need_to_update_name)
+		{
+		  /* The demangled names of member functions contain
+		     information about enclosing namespaces/classes,
+		     if any.  */
+
+		  /* FIXME: carlton/2003-11-10: The excessive
+		     demangling here is a bit wasteful, as is the
+		     memory usage for names.  */
+
+		  /* NOTE: carlton/2003-11-10: As commented in
+		     add_partial_structure, the demangler sometimes
+		     prints the type info in a different form from the
+		     debug info.  We could solve this by using the
+		     demangled name to get the prefix; if doing so,
+		     however, we'd need to be careful when reading a
+		     class that's nested inside a template class.
+		     That would also cause problems when trying to
+		     determine RTTI information, since we use the
+		     demangler to determine the appropriate class
+		     name.  */
+		  char *actual_class_name
+		    = class_name_from_physname (dwarf2_linkage_name
+						(child_die));
+		  if (actual_class_name != NULL
+		      && strcmp (actual_class_name, name) != 0)
+		    {
+		      TYPE_TAG_NAME (type)
+			= obsavestring (actual_class_name,
+					strlen (actual_class_name),
+					&objfile->type_obstack);
+		    }
+		  xfree (actual_class_name);
+		  need_to_update_name = 0;
+		}
 	    }
 	  else if (child_die->tag == DW_TAG_inheritance)
 	    {
@@ -2921,6 +3111,10 @@ read_structure_scope (struct die_info *d
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
+
+  processing_current_prefix = previous_prefix;
+  if (back_to != NULL)
+    do_cleanups (back_to);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -2950,9 +3144,21 @@ read_enumeration (struct die_info *die, 
   attr = dwarf_attr (die, DW_AT_name);
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-					   strlen (DW_STRING (attr)),
-					   &objfile->type_obstack);
+      const char *name = DW_STRING (attr);
+
+      if (processing_has_namespace_info)
+	{
+	  TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+					   processing_current_prefix,
+					   processing_current_prefix[0] == '\0'
+					   ? "" : "::",
+					   name);
+	}
+      else
+	{
+	  TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+					       &objfile->type_obstack);
+	}
     }
 
   attr = dwarf_attr (die, DW_AT_byte_size);
@@ -3223,7 +3429,7 @@ read_namespace (struct die_info *die, st
 {
   struct objfile *objfile = cu->objfile;
   const char *previous_prefix = processing_current_prefix;
-  const char *name = NULL;
+  const char *name;
   int is_anonymous;
   struct die_info *current_die;
 
@@ -4679,6 +4885,19 @@ die_is_declaration (struct die_info *die
 	  && ! dwarf_attr (die, DW_AT_specification));
 }
 
+/* Return the die giving the specification for DIE, if there is
+   one.  */
+
+static struct die_info *
+die_specification (struct die_info *die)
+{
+  struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
+
+  if (spec_attr == NULL)
+    return NULL;
+  else
+    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
+}
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
@@ -5322,39 +5541,108 @@ new_symbol (struct die_info *die, struct
 	case DW_TAG_enumeration_type:
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-	  add_symbol_to_list (sym, list_in_scope);
 
-	  /* The semantics of C++ state that "struct foo { ... }" also
-	     defines a typedef for "foo". Synthesize a typedef symbol so
-	     that "ptype foo" works as expected.  */
+	  /* Make sure that the symbol includes appropriate enclosing
+	     classes/namespaces in its name.  These are calculated in
+	     read_structure_scope, and the correct name is saved in
+	     the type.  */
+
 	  if (cu_language == language_cplus)
 	    {
-	      struct symbol *typedef_sym = (struct symbol *)
-	      obstack_alloc (&objfile->symbol_obstack,
-			     sizeof (struct symbol));
-	      *typedef_sym = *sym;
-	      SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
-	      if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-		TYPE_NAME (SYMBOL_TYPE (sym)) =
-		  obsavestring (DEPRECATED_SYMBOL_NAME (sym),
-				strlen (DEPRECATED_SYMBOL_NAME (sym)),
-				&objfile->type_obstack);
-	      add_symbol_to_list (typedef_sym, list_in_scope);
+	      struct type *type = SYMBOL_TYPE (sym);
+	      
+	      if (TYPE_TAG_NAME (type) != NULL)
+		{
+		  /* FIXME: carlton/2003-11-10: Should this use
+		     SYMBOL_SET_NAMES instead?  (The same problem also
+		     arises a further down in the function.)  */
+		  SYMBOL_LINKAGE_NAME (sym)
+		    = obsavestring (TYPE_TAG_NAME (type),
+				    strlen (TYPE_TAG_NAME (type)),
+				    &objfile->symbol_obstack);
+		}
 	    }
+
+	  {
+	    /* 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.  */
+
+	    struct pending **list_to_add;
+
+	    list_to_add = (list_in_scope == &file_symbols
+			   && cu_language == language_cplus
+			   ? &global_symbols : list_in_scope);
+	  
+	    add_symbol_to_list (sym, list_to_add);
+
+	    /* The semantics of C++ state that "struct foo { ... }" also
+	       defines a typedef for "foo". Synthesize a typedef symbol so
+	       that "ptype foo" works as expected.  */
+	    if (cu_language == language_cplus)
+	      {
+		struct symbol *typedef_sym = (struct symbol *)
+		  obstack_alloc (&objfile->symbol_obstack,
+				 sizeof (struct symbol));
+		*typedef_sym = *sym;
+		SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
+		if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+		  TYPE_NAME (SYMBOL_TYPE (sym)) =
+		    obsavestring (SYMBOL_NATURAL_NAME (sym),
+				  strlen (SYMBOL_NATURAL_NAME (sym)),
+				  &objfile->type_obstack);
+		add_symbol_to_list (typedef_sym, list_to_add);
+	      }
+	  }
 	  break;
 	case DW_TAG_typedef:
+	  if (processing_has_namespace_info
+	      && processing_current_prefix[0] != '\0')
+	    {
+	      SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+						    processing_current_prefix,
+						    "::",
+						    name);
+	    }
+	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+	  add_symbol_to_list (sym, list_in_scope);
+	  break;
 	case DW_TAG_base_type:
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  add_symbol_to_list (sym, list_in_scope);
 	  break;
 	case DW_TAG_enumerator:
+	  if (processing_has_namespace_info
+	      && processing_current_prefix[0] != '\0')
+	    {
+	      SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+						    processing_current_prefix,
+						    "::",
+						    name);
+	    }
 	  attr = dwarf_attr (die, DW_AT_const_value);
 	  if (attr)
 	    {
 	      dwarf2_const_value (attr, sym, cu);
 	    }
-	  add_symbol_to_list (sym, list_in_scope);
+	  {
+	    /* NOTE: carlton/2003-11-10: See comment above in the
+	       DW_TAG_class_type, etc. block.  */
+
+	    struct pending **list_to_add;
+
+	    list_to_add = (list_in_scope == &file_symbols
+			   && cu_language == language_cplus
+			   ? &global_symbols : list_in_scope);
+	  
+	    add_symbol_to_list (sym, list_to_add);
+	  }
 	  break;
 	case DW_TAG_namespace:
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -5588,6 +5876,11 @@ tag_type_to_type (struct die_info *die, 
 static void
 read_type_die (struct die_info *die, struct dwarf2_cu *cu)
 {
+  char *prefix = determine_prefix (die);
+  const char *old_prefix = processing_current_prefix;
+  struct cleanup *back_to = make_cleanup (xfree, prefix);
+  processing_current_prefix = prefix;
+  
   switch (die->tag)
     {
     case DW_TAG_class_type:
@@ -5634,6 +5927,114 @@ read_type_die (struct die_info *die, str
 		 dwarf_tag_name (die->tag));
       break;
     }
+
+  processing_current_prefix = old_prefix;
+  do_cleanups (back_to);
+}
+
+/* Return the name of the namespace/class that DIE is defined
+   within, or NULL if we can't tell.  The caller should xfree the
+   result.  */
+
+static char *
+determine_prefix (struct die_info *die)
+{
+  struct die_info *parent;
+
+  if (cu_language != language_cplus)
+    return NULL;
+
+  parent = die->parent;
+
+  if (parent == NULL)
+    {
+      return (processing_has_namespace_info ? xstrdup ("") : NULL);
+    }
+  else
+    {
+      char *parent_prefix = determine_prefix (parent);
+      char *retval;
+
+      switch (parent->tag) {
+      case DW_TAG_namespace:
+	{
+	  int dummy;
+
+	  retval = typename_concat (parent_prefix,
+				    namespace_name (parent, &dummy));
+	}
+	break;
+      case DW_TAG_class_type:
+      case DW_TAG_structure_type:
+	{
+	  if (parent_prefix != NULL)
+	    {
+	      const char *parent_name = dwarf2_name (parent);
+
+	      if (parent_name != NULL)
+		retval = typename_concat (parent_prefix, dwarf2_name (parent));
+	      else
+		/* FIXME: carlton/2003-11-10: I'm not sure what the
+		   best thing to do here is.  */
+		retval = typename_concat (parent_prefix,
+					  "<<anonymous class>>");
+	    }
+	  else
+	    retval = class_name (parent);
+	}
+	break;
+      default:
+	retval = parent_prefix;
+	break;
+      }
+
+      if (retval != parent_prefix)
+	xfree (parent_prefix);
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string formed by concatenating PREFIX,
+   "::", and SUFFIX, except that if PREFIX is NULL or the empty
+   string, just return a copy of SUFFIX.  */
+
+static char *
+typename_concat (const char *prefix, const char *suffix)
+{
+  if (prefix == NULL || prefix[0] == '\0')
+    return xstrdup (suffix);
+  else
+    {
+      char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+
+      strcpy (retval, prefix);
+      strcat (retval, "::");
+      strcat (retval, suffix);
+
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string giving the name of the class given
+   by DIE.  */
+
+static char *
+class_name (struct die_info *die)
+{
+  struct die_info *child;
+  const char *name;
+
+  for (child = die->child; child != NULL; child = sibling_die (child))
+    {
+      if (child->tag == DW_TAG_subprogram)
+	return class_name_from_physname (dwarf2_linkage_name (child));
+    }
+
+  name = dwarf2_name (die);
+  if (name != NULL)
+    return xstrdup (name);
+  else
+    return xstrdup ("");
 }
 
 static struct type *
--- cp-namespace.c	2004-01-09 17:15:58.000000000 -0500
+++ cp-namespace.c.dc	2003-11-13 15:38:32.000000000 -0500
@@ -32,9 +32,12 @@
 #include "dictionary.h"
 #include "command.h"
 
-/* When set, the file that we're processing seems to have debugging
-   info for C++ namespaces, so cp-namespace.c shouldn't try to guess
-   namespace info itself.  */
+/* When set, the file that we're processing is known to have debugging
+   info for C++ namespaces.  */
+
+/* NOTE: carlton/2003-11-10: No currently released version of GCC (the
+   latest of which is 3.3.x at the time of this writing) produces this
+   debug info.  */
 
 unsigned char processing_has_namespace_info;
 
@@ -222,12 +225,6 @@ cp_set_block_scope (const struct symbol 
 
   if (SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
     {
-#if 0
-      /* FIXME: carlton/2003-06-12: As mentioned above,
-	 'processing_has_namespace_info' currently isn't entirely
-	 reliable, so let's always use demangled names to get this
-	 information for now.  */
-
       if (processing_has_namespace_info)
 	{
 	  block_set_scope
@@ -237,7 +234,6 @@ cp_set_block_scope (const struct symbol 
 	     obstack);
 	}
       else
-#endif
 	{
 	  /* Try to figure out the appropriate namespace from the
 	     demangled name.  */
@@ -520,10 +516,6 @@ lookup_symbol_file (const char *name,
    class or namespace given by PARENT_TYPE, from within the context
    given by BLOCK.  Return NULL if there is no such nested type.  */
 
-/* FIXME: carlton/2003-09-24: For now, this only works for nested
-   namespaces; the patch to make this work on other sorts of nested
-   types is next on my TODO list.  */
-
 struct type *
 cp_lookup_nested_type (struct type *parent_type,
 		       const char *nested_name,
@@ -531,8 +523,16 @@ cp_lookup_nested_type (struct type *pare
 {
   switch (TYPE_CODE (parent_type))
     {
+    case TYPE_CODE_STRUCT:
     case TYPE_CODE_NAMESPACE:
       {
+	/* NOTE: carlton/2003-11-10: We don't treat C++ class members
+	   of classes like, say, data or function members.  Instead,
+	   they're just represented by symbols whose names are
+	   qualified by the name of the surrounding class.  This is
+	   just like members of namespaces; in particular,
+	   lookup_symbol_namespace works when looking them up.  */
+
 	const char *parent_name = TYPE_TAG_NAME (parent_type);
 	struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
 							 nested_name,
@@ -547,7 +547,7 @@ cp_lookup_nested_type (struct type *pare
       }
     default:
       internal_error (__FILE__, __LINE__,
-		      "cp_lookup_nested_type called on a non-namespace.");
+		      "cp_lookup_nested_type called on a non-aggregate type.");
     }
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]