ieee_error (info, spec_start, "unrecognized C++ object spec");
ieee_error (info, spec_start, _("unrecognized C++ object spec"));
ieee_read_cxx_class (info, pp, count)     struct ieee_info *info;     const bfd_byte **pp;     unsigned long count;{  const bfd_byte *start;  bfd_vma class;  const char *tag;  unsigned long taglen;  struct ieee_tag *it;  PTR dhandle;  debug_field *fields;  unsigned int field_count, field_alloc;  debug_baseclass *baseclasses;  unsigned int baseclasses_count, baseclasses_alloc;  const debug_field *structfields;  struct ieee_method    {      const char *name;      unsigned long namlen;      debug_method_variant *variants;      unsigned count;      unsigned int alloc;    } *methods;  unsigned int methods_count, methods_alloc;  debug_type vptrbase;  boolean ownvptr;  debug_method *dmethods;  start = *pp;  if (! ieee_require_asn (info, pp, &class))    return false;  --count;  if (! ieee_require_atn65 (info, pp, &tag, &taglen))    return false;  --count;  /* Find the C struct with this name.  */  for (it = info->tags; it != NULL; it = it->next)    if (it->name[0] == tag[0]	&& strncmp (it->name, tag, taglen) == 0	&& strlen (it->name) == taglen)      break;  if (it == NULL)    {      ieee_error (info, start, "undefined C++ object");      return false;    }  dhandle = info->dhandle;  fields = NULL;  field_count = 0;  field_alloc = 0;  baseclasses = NULL;  baseclasses_count = 0;  baseclasses_alloc = 0;  methods = NULL;  methods_count = 0;  methods_alloc = 0;  vptrbase = DEBUG_TYPE_NULL;  ownvptr = false;  structfields = debug_get_fields (dhandle, it->type);  while (count > 0)    {      bfd_vma id;      const bfd_byte *spec_start;      spec_start = *pp;      if (! ieee_require_asn (info, pp, &id))	return false;      --count;      switch (id)	{	default:	  ieee_error (info, spec_start, "unrecognized C++ object spec");	  return false;	case 'b':	  {	    bfd_vma flags, cinline;	    const char *basename, *fieldname;	    unsigned long baselen, fieldlen;	    char *basecopy;	    debug_type basetype;	    bfd_vma bitpos;	    boolean virtualp;	    enum debug_visibility visibility;	    debug_baseclass baseclass;	    /* This represents a base or friend class.  */	    if (! ieee_require_asn (info, pp, &flags)		|| ! ieee_require_atn65 (info, pp, &basename, &baselen)		|| ! ieee_require_asn (info, pp, &cinline)		|| ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))	      return false;	    count -= 4;	    /* We have no way of recording friend information, so we               just ignore it.  */	    if ((flags & BASEFLAGS_FRIEND) != 0)	      break;	    /* I assume that either all of the members of the               baseclass are included in the object, starting at the               beginning of the object, or that none of them are               included.  */	    if ((fieldlen == 0) == (cinline == 0))	      {		ieee_error (info, start, "unsupported C++ object type");		return false;	      }	    basecopy = savestring (basename, baselen);	    basetype = debug_find_tagged_type (dhandle, basecopy,					       DEBUG_KIND_ILLEGAL);	    free (basecopy);	    if (basetype == DEBUG_TYPE_NULL)	      {		ieee_error (info, start, "C++ base class not defined");		return false;	      }	    if (fieldlen == 0)	      bitpos = 0;	    else	      {		const debug_field *pf;		if (structfields == NULL)		  {		    ieee_error (info, start, "C++ object has no fields");		    return false;		  }		for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)		  {		    const char *fname;		    fname = debug_get_field_name (dhandle, *pf);		    if (fname == NULL)		      return false;		    if (fname[0] == fieldname[0]			&& strncmp (fname, fieldname, fieldlen) == 0			&& strlen (fname) == fieldlen)		      break;		  }		if (*pf == DEBUG_FIELD_NULL)		  {		    ieee_error (info, start,				"C++ base class not found in container");		    return false;		  }		bitpos = debug_get_field_bitpos (dhandle, *pf);	      }	    if ((flags & BASEFLAGS_VIRTUAL) != 0)	      virtualp = true;	    else	      virtualp = false;	    if ((flags & BASEFLAGS_PRIVATE) != 0)	      visibility = DEBUG_VISIBILITY_PRIVATE;	    else	      visibility = DEBUG_VISIBILITY_PUBLIC;	    baseclass = debug_make_baseclass (dhandle, basetype, bitpos,					      virtualp, visibility);	    if (baseclass == DEBUG_BASECLASS_NULL)	      return false;	    if (baseclasses_count + 1 >= baseclasses_alloc)	      {		baseclasses_alloc += 10;		baseclasses = ((debug_baseclass *)			       xrealloc (baseclasses,					 (baseclasses_alloc					  * sizeof *baseclasses)));	      }	    baseclasses[baseclasses_count] = baseclass;	    ++baseclasses_count;	    baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;	  }	  break;	case 'd':	  {	    bfd_vma flags;	    const char *fieldname, *mangledname;	    unsigned long fieldlen, mangledlen;	    char *fieldcopy;	    boolean staticp;	    debug_type ftype;	    const debug_field *pf;	    enum debug_visibility visibility;	    debug_field field;	    /* This represents a data member.  */	    if (! ieee_require_asn (info, pp, &flags)		|| ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)		|| ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))	      return false;	    count -= 3;	    fieldcopy = savestring (fieldname, fieldlen);	    staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false;	    if (staticp)	      {		struct ieee_var *pv, *pvend;		/* See if we can find a definition for this variable.  */		pv = info->vars.vars;		pvend = pv + info->vars.alloc;		for (; pv < pvend; pv++)		  if (pv->namlen == mangledlen		      && strncmp (pv->name, mangledname, mangledlen) == 0)		    break;		if (pv < pvend)		  ftype = pv->type;		else		  {		    /* This can happen if the variable is never used.  */		    ftype = ieee_builtin_type (info, start,					       (unsigned int) builtin_void);		  }	      }	    else	      {		unsigned int findx;		if (structfields == NULL)		  {		    ieee_error (info, start, "C++ object has no fields");		    return false;		  }		for (pf = structfields, findx = 0;		     *pf != DEBUG_FIELD_NULL;		     pf++, findx++)		  {		    const char *fname;		    fname = debug_get_field_name (dhandle, *pf);		    if (fname == NULL)		      return false;		    if (fname[0] == mangledname[0]			&& strncmp (fname, mangledname, mangledlen) == 0			&& strlen (fname) == mangledlen)		      break;		  }		if (*pf == DEBUG_FIELD_NULL)		  {		    ieee_error (info, start,				"C++ data member not found in container");		    return false;		  }		ftype = debug_get_field_type (dhandle, *pf);		if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)		  {		    /* We might need to convert this field into a                       reference type later on, so make it an indirect                       type.  */		    if (it->fslots == NULL)		      {			unsigned int fcnt;			const debug_field *pfcnt;			fcnt = 0;			for (pfcnt = structfields;			     *pfcnt != DEBUG_FIELD_NULL;			     pfcnt++)			  ++fcnt;			it->fslots = ((debug_type *)				      xmalloc (fcnt * sizeof *it->fslots));			memset (it->fslots, 0,				fcnt * sizeof *it->fslots);		      }		    if (ftype == DEBUG_TYPE_NULL)		      return false;		    it->fslots[findx] = ftype;		    ftype = debug_make_indirect_type (dhandle,						      it->fslots + findx,						      (const char *) NULL);		  }	      }	    if (ftype == DEBUG_TYPE_NULL)	      return false;	    switch (flags & CXXFLAGS_VISIBILITY)	      {	      default:		ieee_error (info, start, "unknown C++ visibility");		return false;	      case CXXFLAGS_VISIBILITY_PUBLIC:		visibility = DEBUG_VISIBILITY_PUBLIC;		break;	      case CXXFLAGS_VISIBILITY_PRIVATE:		visibility = DEBUG_VISIBILITY_PRIVATE;		break;	      case CXXFLAGS_VISIBILITY_PROTECTED:		visibility = DEBUG_VISIBILITY_PROTECTED;		break;	      }	    if (staticp)	      {		char *mangledcopy;		mangledcopy = savestring (mangledname, mangledlen);		field = debug_make_static_member (dhandle, fieldcopy,						  ftype, mangledcopy,						  visibility);	      }	    else	      {		bfd_vma bitpos, bitsize;		bitpos = debug_get_field_bitpos (dhandle, *pf);		bitsize = debug_get_field_bitsize (dhandle, *pf);		if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)		  {		    ieee_error (info, start, "bad C++ field bit pos or size");		    return false;		  }		field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,					  bitsize, visibility);	      }	    if (field == DEBUG_FIELD_NULL)	      return false;	    if (field_count + 1 >= field_alloc)	      {		field_alloc += 10;		fields = ((debug_field *)			  xrealloc (fields, field_alloc * sizeof *fields));	      }	    fields[field_count] = field;	    ++field_count;	    fields[field_count] = DEBUG_FIELD_NULL;	  }	  break;	case 'm':	case 'v':	  {	    bfd_vma flags, voffset, control;	    const char *name, *mangled;	    unsigned long namlen, mangledlen;	    struct ieee_var *pv, *pvend;	    debug_type type;	    enum debug_visibility visibility;	    boolean constp, volatilep;	    char *mangledcopy;	    debug_method_variant mv;	    struct ieee_method *meth;	    unsigned int im;	    if (! ieee_require_asn (info, pp, &flags)		|| ! ieee_require_atn65 (info, pp, &name, &namlen)		|| ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))	      return false;	    count -= 3;	    if (id != 'v')	      voffset = 0;	    else	      {		if (! ieee_require_asn (info, pp, &voffset))		  return false;		--count;	      }	    if (! ieee_require_asn (info, pp, &control))	      return false;	    --count;	    /* We just ignore the control information.  */	    /* We have no way to represent friend information, so we               just ignore it.  */	    if ((flags & CXXFLAGS_FRIEND) != 0)	      break;	    /* We should already have seen a type for the function.  */	    pv = info->vars.vars;	    pvend = pv + info->vars.alloc;	    for (; pv < pvend; pv++)	      if (pv->namlen == mangledlen		  && strncmp (pv->name, mangled, mangledlen) == 0)		break;	    if (pv >= pvend)	      {		/* We won't have type information for this function if		   it is not included in this file.  We don't try to		   handle this case.  FIXME.  */		type = (debug_make_function_type			(dhandle,			 ieee_builtin_type (info, start,					    (unsigned int) builtin_void),			 (debug_type *) NULL,			 false));	      }	    else	      {		debug_type return_type;		const debug_type *arg_types;		boolean varargs;		if (debug_get_type_kind (dhandle, pv->type)		    != DEBUG_KIND_FUNCTION)		  {		    ieee_error (info, start,				"bad type for C++ method function");		    return false;		  }		return_type = debug_get_return_type (dhandle, pv->type);		arg_types = debug_get_parameter_types (dhandle, pv->type,						       &varargs);		if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)		  {		    ieee_error (info, start,				"no type information for C++ method function");		    return false;		  }		type = debug_make_method_type (dhandle, return_type, it->type,					       (debug_type *) arg_types,					       varargs);	      }	    if (type == DEBUG_TYPE_NULL)	      return false;	    switch (flags & CXXFLAGS_VISIBILITY)	      {	      default:		ieee_error (info, start, "unknown C++ visibility");		return false;	      case CXXFLAGS_VISIBILITY_PUBLIC:		visibility = DEBUG_VISIBILITY_PUBLIC;		break;	      case CXXFLAGS_VISIBILITY_PRIVATE:		visibility = DEBUG_VISIBILITY_PRIVATE;		break;	      case CXXFLAGS_VISIBILITY_PROTECTED:		visibility = DEBUG_VISIBILITY_PROTECTED;		break;	      }	    constp = (flags & CXXFLAGS_CONST) != 0 ? true : false;	    volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false;	    mangledcopy = savestring (mangled, mangledlen);	    if ((flags & CXXFLAGS_STATIC) != 0)	      {		if (id == 'v')		  {		    ieee_error (info, start, "C++ static virtual method");		    return false;		  }		mv = debug_make_static_method_variant (dhandle, mangledcopy,						       type, visibility,						       constp, volatilep);	      }	    else	      {		debug_type vcontext;		if (id != 'v')		  vcontext = DEBUG_TYPE_NULL;		else		  {		    /* FIXME: How can we calculate this correctly?  */		    vcontext = it->type;		  }		mv = debug_make_method_variant (dhandle, mangledcopy, type,						visibility, constp,						volatilep, voffset,						vcontext);	      }	    if (mv == DEBUG_METHOD_VARIANT_NULL)	      return false;	    for (meth = methods, im = 0; im < methods_count; meth++, im++)	      if (meth->namlen == namlen		  && strncmp (meth->name, name, namlen) == 0)		break;	    if (im >= methods_count)	      {		if (methods_count >= methods_alloc)		  {		    methods_alloc += 10;		    methods = ((struct ieee_method *)			       xrealloc (methods,					 methods_alloc * sizeof *methods));		  }		methods[methods_count].name = name;		methods[methods_count].namlen = namlen;		methods[methods_count].variants = NULL;		methods[methods_count].count = 0;		methods[methods_count].alloc = 0;		meth = methods + methods_count;		++methods_count;	      }	    if (meth->count + 1 >= meth->alloc)	      {		meth->alloc += 10;		meth->variants = ((debug_method_variant *)				  xrealloc (meth->variants,					    (meth->alloc					     * sizeof *meth->variants)));	      }	    meth->variants[meth->count] = mv;	    ++meth->count;	    meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;	  }	  break;	case 'o':	  {	    bfd_vma spec;	    /* We have no way to store this information, so we just	       ignore it.  */	    if (! ieee_require_asn (info, pp, &spec))	      return false;	    --count;	    if ((spec & 4) != 0)	      {		const char *filename;		unsigned long filenamlen;		bfd_vma lineno;		if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)		    || ! ieee_require_asn (info, pp, &lineno))		  return false;		count -= 2;	      }	    else if ((spec & 8) != 0)	      {		const char *mangled;		unsigned long mangledlen;		if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))		  return false;		--count;	      }	    else	      {		ieee_error (info, start,			    "unrecognized C++ object overhead spec");		return false;	      }	  }	  break;	case 'z':	  {	    const char *vname, *basename;	    unsigned long vnamelen, baselen;	    bfd_vma vsize, control;	    /* A virtual table pointer.  */	    if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)		|| ! ieee_require_asn (info, pp, &vsize)		|| ! ieee_require_atn65 (info, pp, &basename, &baselen)		|| ! ieee_require_asn (info, pp, &control))	      return false;	    count -= 4;	    /* We just ignore the control number.  We don't care what	       the virtual table name is.  We have no way to store the	       virtual table size, and I don't think we care anyhow.  */	    /* FIXME: We can't handle multiple virtual table pointers.  */	    if (baselen == 0)	      ownvptr = true;	    else	      {		char *basecopy;		basecopy = savestring (basename, baselen);		vptrbase = debug_find_tagged_type (dhandle, basecopy,						   DEBUG_KIND_ILLEGAL);		free (basecopy);		if (vptrbase == DEBUG_TYPE_NULL)		  {		    ieee_error (info, start, "undefined C++ vtable");		    return false;		  }	      }	  }	  break;	}    }  /* Now that we have seen all the method variants, we can call     debug_make_method for each one.  */  if (methods_count == 0)    dmethods = NULL;  else    {      unsigned int i;      dmethods = ((debug_method *)		  xmalloc ((methods_count + 1) * sizeof *dmethods));      for (i = 0; i < methods_count; i++)	{	  char *namcopy;	  namcopy = savestring (methods[i].name, methods[i].namlen);	  dmethods[i] = debug_make_method (dhandle, namcopy,					   methods[i].variants);	  if (dmethods[i] == DEBUG_METHOD_NULL)	    return false;	}      dmethods[i] = DEBUG_METHOD_NULL;      free (methods);    }  /* The struct type was created as an indirect type pointing at     it->slot.  We update it->slot to automatically update all     references to this struct.  */  it->slot = debug_make_object_type (dhandle,				     class != 'u',				     debug_get_type_size (dhandle,							  it->slot),				     fields, baseclasses, dmethods,				     vptrbase, ownvptr);  if (it->slot == DEBUG_TYPE_NULL)    return false;  return true;}