char *
cp_canonicalize_string (const char *string)
{
  struct demangle_component *ret_comp;
  unsigned int estimated_len;
  char *ret;

  if (cp_already_canonical (string))
    return NULL;

  ret_comp = cp_demangled_name_to_comp (string, NULL);
  if (ret_comp == NULL)
    return NULL;

  estimated_len = strlen (string) * 2;
  ret = cp_comp_to_string (ret_comp, estimated_len);

  if (strcmp (string, ret) == 0)
    {
      xfree (ret);
      return NULL;
    }

  return ret;
}
char *
cp_func_name (const char *full_name)
{
  char *ret;
  struct demangle_component *ret_comp;

  ret_comp = cp_demangled_name_to_comp (full_name, NULL);
  if (!ret_comp)
    return NULL;

  ret_comp = unqualified_name_from_comp (ret_comp);

  ret = NULL;
  if (ret_comp != NULL)
    ret = cp_comp_to_string (ret_comp, 10);

  return ret;
}
char *
cp_remove_params (const char *demangled_name)
{
  int done = 0;
  struct demangle_component *ret_comp;
  char *ret = NULL;

  if (demangled_name == NULL)
    return NULL;

  ret_comp = cp_demangled_name_to_comp (demangled_name, NULL);
  if (ret_comp == NULL)
    return NULL;

  /* First strip off any qualifiers, if we have a function or method.  */
  while (!done)
    switch (ret_comp->type)
      {
      case DEMANGLE_COMPONENT_CONST:
      case DEMANGLE_COMPONENT_RESTRICT:
      case DEMANGLE_COMPONENT_VOLATILE:
      case DEMANGLE_COMPONENT_CONST_THIS:
      case DEMANGLE_COMPONENT_RESTRICT_THIS:
      case DEMANGLE_COMPONENT_VOLATILE_THIS:
      case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
        ret_comp = d_left (ret_comp);
        break;
      default:
	done = 1;
	break;
      }

  /* What we have now should be a function.  Return its name.  */
  if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
    ret = cp_comp_to_string (d_left (ret_comp), 10);

  return ret;
}
static struct demangle_component *
mangled_name_to_comp (const char *mangled_name, int options,
		      void **memory, char **demangled_p)
{
  struct demangle_component *ret;
  char *demangled_name;

  /* If it looks like a v3 mangled name, then try to go directly
     to trees.  */
  if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
    {
      ret = cplus_demangle_v3_components (mangled_name, options, memory);
      if (ret)
	{
	  *demangled_p = NULL;
	  return ret;
	}
    }

  /* If it doesn't, or if that failed, then try to demangle the name.  */
  demangled_name = cplus_demangle (mangled_name, options);
  if (demangled_name == NULL)
   return NULL;
  
  /* If we could demangle the name, parse it to build the component tree.  */
  ret = cp_demangled_name_to_comp (demangled_name, NULL);

  if (ret == NULL)
    {
      xfree (demangled_name);
      return NULL;
    }

  *demangled_p = demangled_name;
  return ret;
}
Esempio n. 5
0
static int
inspect_type (struct demangle_parse_info *info,
	      struct demangle_component *ret_comp,
	      canonicalization_ftype *finder,
	      void *data)
{
  int i;
  char *name;
  struct symbol *sym;

  /* Copy the symbol's name from RET_COMP and look it up
     in the symbol table.  */
  name = (char *) alloca (ret_comp->u.s_name.len + 1);
  memcpy (name, ret_comp->u.s_name.s, ret_comp->u.s_name.len);
  name[ret_comp->u.s_name.len] = '\0';

  /* Ignore any typedefs that should not be substituted.  */
  for (i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i)
    {
      if (strcmp (name, ignore_typedefs[i]) == 0)
	return 0;
    }

  sym = NULL;

  TRY
    {
      sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      return 0;
    }
  END_CATCH

  if (sym != NULL)
    {
      struct type *otype = SYMBOL_TYPE (sym);

      if (finder != NULL)
	{
	  const char *new_name = (*finder) (otype, data);

	  if (new_name != NULL)
	    {
	      ret_comp->u.s_name.s = new_name;
	      ret_comp->u.s_name.len = strlen (new_name);
	      return 1;
	    }

	  return 0;
	}

      /* If the type is a typedef or namespace alias, replace it.  */
      if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF
	  || TYPE_CODE (otype) == TYPE_CODE_NAMESPACE)
	{
	  long len;
	  int is_anon;
	  struct type *type;
	  struct demangle_parse_info *i;
	  struct ui_file *buf;

	  /* Get the real type of the typedef.  */
	  type = check_typedef (otype);

	  /* If the symbol is a namespace and its type name is no different
	     than the name we looked up, this symbol is not a namespace
	     alias and does not need to be substituted.  */
	  if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE
	      && strcmp (TYPE_NAME (type), name) == 0)
	    return 0;

	  is_anon = (TYPE_TAG_NAME (type) == NULL
		     && (TYPE_CODE (type) == TYPE_CODE_ENUM
			 || TYPE_CODE (type) == TYPE_CODE_STRUCT
			 || TYPE_CODE (type) == TYPE_CODE_UNION));
	  if (is_anon)
	    {
	      struct type *last = otype;

	      /* Find the last typedef for the type.  */
	      while (TYPE_TARGET_TYPE (last) != NULL
		     && (TYPE_CODE (TYPE_TARGET_TYPE (last))
			 == TYPE_CODE_TYPEDEF))
		last = TYPE_TARGET_TYPE (last);

	      /* If there is only one typedef for this anonymous type,
		 do not substitute it.  */
	      if (type == otype)
		return 0;
	      else
		/* Use the last typedef seen as the type for this
		   anonymous type.  */
		type = last;
	    }

	  buf = mem_fileopen ();
	  TRY
	  {
	    type_print (type, "", buf, -1);
	  }

	  /* If type_print threw an exception, there is little point
	     in continuing, so just bow out gracefully.  */
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      ui_file_delete (buf);
	      return 0;
	    }
	  END_CATCH

	  name = ui_file_obsavestring (buf, &info->obstack, &len);
	  ui_file_delete (buf);

	  /* Turn the result into a new tree.  Note that this
	     tree will contain pointers into NAME, so NAME cannot
	     be free'd until all typedef conversion is done and
	     the final result is converted into a string.  */
	  i = cp_demangled_name_to_comp (name, NULL);
	  if (i != NULL)
	    {
	      /* Merge the two trees.  */
	      cp_merge_demangle_parse_infos (info, ret_comp, i);

	      /* Replace any newly introduced typedefs -- but not
		 if the type is anonymous (that would lead to infinite
		 looping).  */
	      if (!is_anon)
		replace_typedefs (info, ret_comp, finder, data);
	    }
	  else
	    {
	      /* This shouldn't happen unless the type printer has
		 output something that the name parser cannot grok.
		 Nonetheless, an ounce of prevention...

		 Canonicalize the name again, and store it in the
		 current node (RET_COMP).  */
	      char *canon = cp_canonicalize_string_no_typedefs (name);

	      if (canon != NULL)
		{
		  /* Copy the canonicalization into the obstack and
		     free CANON.  */
		  name = copy_string_to_obstack (&info->obstack, canon, &len);
		  xfree (canon);
		}

	      ret_comp->u.s_name.s = name;
	      ret_comp->u.s_name.len = len;
	    }

	  return 1;
	}