⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stabsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	 2.0 language feature.  */      int via_virtual;      *pp += 1;      ALLOCATE_CPLUS_STRUCT_TYPE(type);      n_baseclasses = read_number (pp, ',');      /* Some stupid compilers have trouble with the following, so break	 it up into simpler expressions.  */#if 0      TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)	TYPE_ALLOC (type, B_BYTES (n_baseclasses));#else      {	int num_bytes = B_BYTES (n_baseclasses);	char *pointer;		pointer = (char *) TYPE_ALLOC (type, num_bytes);	TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;      }#endif /* 0 */      B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), n_baseclasses);      for (i = 0; i < n_baseclasses; i++)	{	  if (**pp == '\\')	    *pp = next_symbol_text ();	  switch (**pp)	    {	    case '0':	      via_virtual = 0;	      break;	    case '1':	      via_virtual = 1;	      break;	    default:	      /* Bad visibility format.  */	      return error_type (pp);	    }	  ++*pp;	  switch (**pp)	    {	    case '0':	      via_public = 0;	      non_public_fields++;	      break;	    case '2':	      via_public = 2;	      break;	    default:	      /* Bad visibility format.  */	      return error_type (pp);	    }	  if (via_virtual) 	    SET_TYPE_FIELD_VIRTUAL (type, i);	  ++*pp;	  /* Offset of the portion of the object corresponding to	     this baseclass.  Always zero in the absence of	     multiple inheritance.  */	  offset = read_number (pp, ',');	  baseclass = read_type (pp, objfile);	  *pp += 1;		/* skip trailing ';' */	  /* Make this baseclass visible for structure-printing purposes.  */	  new = (struct nextfield *) alloca (sizeof (struct nextfield));	  memset (new, 0, sizeof (struct nextfield));	  new->next = list;	  list = new;	  list->visibility = via_public;	  list->field.type = baseclass;	  list->field.name = type_name_no_tag (baseclass);	  list->field.bitpos = offset;	  list->field.bitsize = 0;	/* this should be an unpacked field! */	  nfields++;	}      TYPE_N_BASECLASSES (type) = n_baseclasses;    }  /* Now come the fields, as NAME:?TYPENUM,BITPOS,BITSIZE; for each one.     At the end, we see a semicolon instead of a field.     In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for     a static field.     The `?' is a placeholder for one of '/2' (public visibility),     '/1' (protected visibility), '/0' (private visibility), or nothing     (C style symbol table, public visibility).  */  /* We better set p right now, in case there are no fields at all...    */  p = *pp;  while (**pp != ';')    {      /* Check for and handle cretinous dbx symbol name continuation!  */      if (**pp == '\\') *pp = next_symbol_text ();      /* Get space to record the next field's data.  */      new = (struct nextfield *) alloca (sizeof (struct nextfield));      memset (new, 0, sizeof (struct nextfield));      new->next = list;      list = new;      /* Get the field name.  */      p = *pp;      if (*p == CPLUS_MARKER)	{	  if (*p == '_')    /* GNU C++ anonymous type.  */	    ;	  /* Special GNU C++ name.  */	  else if (*++p == 'v')	    {	      const char *prefix;	      char *name = 0;	      struct type *context;	      switch (*++p)		{		case 'f':		  prefix = vptr_name;		  break;		case 'b':		  prefix = vb_name;		  break;		default:		  complain (&invalid_cpp_abbrev_complaint, *pp);		  prefix = "INVALID_C++_ABBREV";		  break;		}	      *pp = p + 1;	      context = read_type (pp, objfile);#ifdef maybe_this_is_fixed	      /*	       * Patch from Michael N. Lipp.	       * 9204021327.AA02196@mailhost.dtro.e-technik.th-darmstadt.de>	       * XXX - this isn't the right way to fix it, but it will at 	       * least keep gdb from faulting.	       */	      /* if the ommitted type name is the name of the struct		 being read, the name is not yet in TYPE_NAME(context).		 Use long_kludge_name as a quick fix. */	      if (context == type)		      name = long_kludge_name;	      else#endif	      name = type_name_no_tag (context);	      if (name == 0)		{		  complain (&invalid_cpp_type_complaint, (char *) symnum);		  name = "FOO";		}	      list->field.name = obconcat (&objfile -> type_obstack,					   prefix, name, "");	      p = ++(*pp);	      if (p[-1] != ':')		complain (&invalid_cpp_abbrev_complaint, *pp);	      list->field.type = read_type (pp, objfile);	      (*pp)++;			/* Skip the comma.  */	      list->field.bitpos = read_number (pp, ';');	      /* This field is unpacked.  */	      list->field.bitsize = 0;	      list->visibility = 0;	/* private */	      non_public_fields++;	      nfields++;	      continue;	    }	  else	    complain (&invalid_cpp_abbrev_complaint, *pp);	}      while (*p != ':') p++;      list->field.name = obsavestring (*pp, p - *pp,				       &objfile -> type_obstack);      /* C++: Check to see if we have hit the methods yet.  */      if (p[1] == ':')	break;      *pp = p + 1;      /* This means we have a visibility for a field coming. */      if (**pp == '/')	{	  switch (*++*pp)	    {	    case '0':	      list->visibility = 0;	/* private */	      non_public_fields++;	      *pp += 1;	      break; 	    case '1': 	      list->visibility = 1;	/* protected */	      non_public_fields++; 	      *pp += 1; 	      break; 	    case '2': 	      list->visibility = 2;	/* public */ 	      *pp += 1; 	      break; 	    } 	}       else /* normal dbx-style format.  */	list->visibility = 2;		/* public */      list->field.type = read_type (pp, objfile);      if (**pp == ':') 	{ 	  p = ++(*pp);#if 0	  /* Possible future hook for nested types. */	  if (**pp == '!')	    {	      list->field.bitpos = (long)-2; /* nested type */ 	      p = ++(*pp);	    }	  else#endif	    { /* Static class member.  */	      list->field.bitpos = (long)-1;	    } 	  while (*p != ';') p++; 	  list->field.bitsize = (long) savestring (*pp, p - *pp); 	  *pp = p + 1; 	  nfields++; 	  continue; 	}       else if (**pp != ',')	 /* Bad structure-type format.  */	 return error_type (pp);      (*pp)++;			/* Skip the comma.  */      list->field.bitpos = read_number (pp, ',');      list->field.bitsize = read_number (pp, ';');#if 0      /* FIXME-tiemann: Can't the compiler put out something which	 lets us distinguish these? (or maybe just not put out anything	 for the field).  What is the story here?  What does the compiler	really do?  Also, patch gdb.texinfo for this case; I document	it as a possible problem there.  Search for "DBX-style".  */      /* This is wrong because this is identical to the symbols	 produced for GCC 0-size arrays.  For example:         typedef union {	   int num;	   char str[0];	 } foo;	 The code which dumped core in such circumstances should be	 fixed not to dump core.  */      /* g++ -g0 can put out bitpos & bitsize zero for a static	 field.  This does not give us any way of getting its	 class, so we can't know its name.  But we can just	 ignore the field so we don't dump core and other nasty	 stuff.  */      if (list->field.bitpos == 0	  && list->field.bitsize == 0)	{	  complain (&dbx_class_complaint, 0);	  /* Ignore this field.  */	  list = list->next;	}      else#endif /* 0 */	{	  /* Detect an unpacked field and mark it as such.	     dbx gives a bit size for all fields.	     Note that forward refs cannot be packed,	     and treat enums as if they had the width of ints.  */	  if (TYPE_CODE (list->field.type) != TYPE_CODE_INT	      && TYPE_CODE (list->field.type) != TYPE_CODE_ENUM)	    list->field.bitsize = 0;	  if ((list->field.bitsize == 8 * TYPE_LENGTH (list->field.type)	       || (TYPE_CODE (list->field.type) == TYPE_CODE_ENUM		   && (list->field.bitsize		       == 8 * TYPE_LENGTH (lookup_fundamental_type (objfile, FT_INTEGER)))		   )	       )	      &&	      list->field.bitpos % 8 == 0)	    list->field.bitsize = 0;	  nfields++;	}    }  if (p[1] == ':')    /* chill the list of fields: the last entry (at the head)       is a partially constructed entry which we now scrub.  */    list = list->next;  /* Now create the vector of fields, and record how big it is.     We need this info to record proper virtual function table information     for this class's virtual functions.  */  TYPE_NFIELDS (type) = nfields;  TYPE_FIELDS (type) = (struct field *)    TYPE_ALLOC (type, sizeof (struct field) * nfields);  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);  if (non_public_fields)    {      ALLOCATE_CPLUS_STRUCT_TYPE (type);      TYPE_FIELD_PRIVATE_BITS (type) = (B_TYPE *)	TYPE_ALLOC (type, B_BYTES (nfields));      B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);      TYPE_FIELD_PROTECTED_BITS (type) = (B_TYPE *)	TYPE_ALLOC (type, B_BYTES (nfields));      B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);    }  /* Copy the saved-up fields into the field vector.  */  for (n = nfields; list; list = list->next)    {      n -= 1;      TYPE_FIELD (type, n) = list->field;      if (list->visibility == 0)	SET_TYPE_FIELD_PRIVATE (type, n);      else if (list->visibility == 1)	SET_TYPE_FIELD_PROTECTED (type, n);    }  /* Now come the method fields, as NAME::methods     where each method is of the form TYPENUM,ARGS,...:PHYSNAME;     At the end, we see a semicolon instead of a field.     For the case of overloaded operators, the format is     op$::*.methods, where $ is the CPLUS_MARKER (usually '$'),     `*' holds the place for an operator name (such as `+=')     and `.' marks the end of the operator name.  */  if (p[1] == ':')    {      /* Now, read in the methods.  To simplify matters, we	 "unread" the name that has been read, so that we can	 start from the top.  */      ALLOCATE_CPLUS_STRUCT_TYPE (type);      /* For each list of method lists... */      do	{	  int i;	  struct next_fnfield *sublist = 0;	  struct type *look_ahead_type = NULL;	  int length = 0;	  struct next_fnfieldlist *new_mainlist;	  char *main_fn_name;	  new_mainlist = (struct next_fnfieldlist *)	      alloca (sizeof (struct next_fnfieldlist));	  memset (new_mainlist, 0, sizeof (struct next_fnfieldlist));	  p = *pp;	  /* read in the name.  */	  while (*p != ':') p++;	  if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == CPLUS_MARKER)	    {	      /* This is a completely wierd case.  In order to stuff in the		 names that might contain colons (the usual name delimiter),		 Mike Tiemann defined a different name format which is		 signalled if the identifier is "op$".  In that case, the		 format is "op$::XXXX." where XXXX is the name.  This is		 used for names like "+" or "=".  YUUUUUUUK!  FIXME!  */	      /* This lets the user type "break operator+".	         We could just put in "+" as the name, but that wouldn't		 work for "*".  */	      static char opname[32] = {'o', 'p', CPLUS_MARKER};	      char *o = opname + 3;	      /* Skip past '::'.  */	      *pp = p + 2;	      if (**pp == '\\') *pp = next_symbol_text ();	      p = *pp;	      while (*p != '.')		*o++ = *p++;	      main_fn_name = savestring (opname, o - opname);	      /* Skip past '.'  */	      *pp = p + 1;	    }	  else	    {	      main_fn_name = savestring (*pp, p - *pp);	      /* Skip past '::'.  */	      *pp = p + 2;	    }	  new_mainlist->fn_fieldlist.name = main_fn_name;	  do	    {	      struct next_fnfield *new_sublist =		(struct next_fnfield *) alloca (sizeof (struct next_fnfield));	      memset (new_sublist, 0, sizeof (struct next_fnfield));	      /* Check for and handle cretinous dbx symbol name continuation!  */	      if (look_ahead_type == NULL) /* Normal case. */		{		  if (**pp == '\\') *pp = next_symbol_text ();		  new_sublist->fn_field.type = read_type (pp, objfile);		  if (**pp != ':')		    /* Invalid symtab info for method.  */		    return error_type (pp);	        }	      else		{ /* g++ version 1 kludge */		  new_sublist->fn_field.type = look_ahead_type;		  look_ahead_type = NULL;	        }	      *pp += 1;	      p = *pp;	      while (*p != ';') p++;	      /* If this is just a stub, then we don't have the		 real name here.  */	      if (TYPE_FLAGS (new_sublist->fn_field.type) & TYPE_FLAG_STUB)		new_sublist->fn_field.is_stub = 1;	      new_sublist->fn_field.physname = savestring (*pp, p - *pp);	      *pp = p + 1;	      /* Set this method's visibility fields.  */	      switch (*(*pp)++ - '0')		{		case 0:		  new_sublist->fn_field.is_private = 1;		  break;		case 1:		  new_sublist->fn_field.is_protected = 1;		  break;		}	      if (**pp == '\\') *pp = next_symbol_text ();	      switch (**pp)		{		case 'A': /* Normal functions. */		  new_sublist->fn_field.is_const = 0;		  new_sublist->fn_field.is_volatile = 0;	          (*pp)++;		  break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -