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

📄 cplus-dem.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
    string_appendn (declp, *mangled, p - *mangled);    string_append (declp, "<");    /* should do error checking here */    while (args < e) {      string_clear (&arg);      do_type (work, &args, &arg);      string_appends (declp, &arg);      string_append (declp, ",");    }    string_delete (&arg);    --declp->p;    string_append (declp, ">");  }  else  {    string_appendn (declp, *mangled, n);  }  *mangled += n;}static intdemangle_class_name (work, mangled, declp)     struct work_stuff *work;     const char **mangled;     string *declp;{  int n;  int success = 0;  n = consume_count (mangled);  if (strlen (*mangled) >= n)  {    demangle_arm_pt (work, mangled, n, declp);    success = 1;  }  return (success);}/*LOCAL FUNCTION	demangle_class -- demangle a mangled class sequenceSYNOPSIS	static int	demangle_class (struct work_stuff *work, const char **mangled,			strint *declp)DESCRIPTION	DECLP points to the buffer into which demangling is being done.	*MANGLED points to the current token to be demangled.  On input,	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)	On exit, it points to the next token after the mangled class on	success, or the first unconsumed token on failure.	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then	we are demangling a constructor or destructor.  In this case	we prepend "class::class" or "class::~class" to DECLP.	Otherwise, we prepend "class::" to the current DECLP.	Reset the constructor/destructor flags once they have been	"consumed".  This allows demangle_class to be called later during	the same demangling, to do normal class demangling.	Returns 1 if demangling is successful, 0 otherwise.*/static intdemangle_class (work, mangled, declp)     struct work_stuff *work;     const char **mangled;     string *declp;{  int success = 0;  string class_name;  string_init (&class_name);  if (demangle_class_name (work, mangled, &class_name))    {      if ((work->constructor & 1) || (work->destructor & 1))	{	  string_prepends (declp, &class_name);	  if (work -> destructor & 1)	    {	      string_prepend (declp, "~");              work -> destructor -= 1;	    }	  else	    {	      work -> constructor -= 1; 	    }	}      string_prepend (declp, "::");      string_prepends (declp, &class_name);      success = 1;    }  string_delete (&class_name);  return (success);}/*LOCAL FUNCTION	demangle_prefix -- consume the mangled name prefix and find signatureSYNOPSIS	static int	demangle_prefix (struct work_stuff *work, const char **mangled,			 string *declp);DESCRIPTION	Consume and demangle the prefix of the mangled name.	DECLP points to the string buffer into which demangled output is	placed.  On entry, the buffer is empty.  On exit it contains	the root function name, the demangled operator name, or in some	special cases either nothing or the completely demangled result.	MANGLED points to the current pointer into the mangled name.  As each	token of the mangled name is consumed, it is updated.  Upon entry	the current mangled name pointer points to the first character of	the mangled name.  Upon exit, it should point to the first character	of the signature if demangling was successful, or to the first	unconsumed character if demangling of the prefix was unsuccessful.		Returns 1 on success, 0 otherwise. */static intdemangle_prefix (work, mangled, declp)     struct work_stuff *work;     const char **mangled;     string *declp;{  int success = 1;  const char *scan;  int i;  if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)    {      char *marker = strchr (cplus_markers, (*mangled)[8]);      if (marker != NULL && *marker == (*mangled)[10])	{	  if ((*mangled)[9] == 'D')	    {	      /* it's a GNU global destructor to be executed at program exit */	      (*mangled) += 11;	      work->destructor = 2;	      if (gnu_special (work, mangled, declp))		return success;	    }	  else if ((*mangled)[9] == 'I')	    {	      /* it's a GNU global constructor to be executed at program init */	      (*mangled) += 11;	      work->constructor = 2;	      if (gnu_special (work, mangled, declp))		return success;	    }	}    }  else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)    {      /* it's a ARM global destructor to be executed at program exit */      (*mangled) += 7;      work->destructor = 2;    }  else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)    {      /* it's a ARM global constructor to be executed at program initial */      (*mangled) += 7;      work->constructor = 2;    }/*  This block of code is a reduction in strength time optimization    of:    	scan = mystrstr (*mangled, "__"); */  {    scan = *mangled;    do {      scan = strchr (scan, '_');    } while (scan != NULL && *++scan != '_');    if (scan != NULL) --scan;  }  if (scan != NULL)    {      /* We found a sequence of two or more '_', ensure that we start at	 the last pair in the sequence. */      i = strspn (scan, "_");      if (i > 2)	{	  scan += (i - 2); 	}    }   if (scan == NULL)    {      success = 0;    }  else if (work -> static_type)    {      if (!isdigit (scan[0]) && (scan[0] != 't'))	{	  success = 0;	}    }  else if ((scan == *mangled) &&	   (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))    {      /* The ARM says nothing about the mangling of local variables.	 But cfront mangles local variables by prepending __<nesting_level>	 to them. As an extension to ARM demangling we handle this case.  */      if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))	{	  *mangled = scan + 2;	  consume_count (mangled);	  string_append (declp, *mangled);	  *mangled += strlen (*mangled);	  success = 1; 	}      else	{	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses	     names like __Q2_3foo3bar for nested type names.  So don't accept	     this style of constructor for cfront demangling.  */	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING))	    work -> constructor += 1;	  *mangled = scan + 2;	}    }  else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))    {      /* Mangled name starts with "__".  Skip over any leading '_' characters,	 then find the next "__" that separates the prefix from the signature.	 */      if (!(ARM_DEMANGLING || LUCID_DEMANGLING)	  || (arm_special (work, mangled, declp) == 0))	{	  while (*scan == '_')	    {	      scan++;	    }	  if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))	    {	      /* No separator (I.E. "__not_mangled"), or empty signature		 (I.E. "__not_mangled_either__") */	      success = 0;	    }	  else	    {	      demangle_function_name (work, mangled, declp, scan);	    }	}    }  else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')    {      /* Cfront-style parameterized type.  Handled later as a signature. */      success = 1;      /* ARM template? */      demangle_arm_pt (work, mangled, strlen (*mangled), declp);    }  else if (*(scan + 2) != '\0')    {      /* Mangled name does not start with "__" but does have one somewhere	 in there with non empty stuff after it.  Looks like a global	 function name. */      demangle_function_name (work, mangled, declp, scan);    }  else    {      /* Doesn't look like a mangled name */      success = 0;    }  if (!success && (work->constructor == 2 || work->destructor == 2))    {      string_append (declp, *mangled);      *mangled += strlen (*mangled);      success = 1;    }   return (success);}/*LOCAL FUNCTION	gnu_special -- special handling of gnu mangled stringsSYNOPSIS	static int	gnu_special (struct work_stuff *work, const char **mangled,		     string *declp);DESCRIPTION	Process some special GNU style mangling forms that don't fit	the normal pattern.  For example:		_$_3foo		(destructor for class foo)		_vt$foo		(foo virtual table)		_vt$foo$bar	(foo::bar virtual table)		__vt_foo	(foo virtual table, new style with thunks)		_3foo$varname	(static data member)		_Q22rs2tu$vw	(static data member)		__t6vector1Zii	(constructor with template)		__thunk_4__$_7ostream (virtual function thunk) */static intgnu_special (work, mangled, declp)     struct work_stuff *work;     const char **mangled;     string *declp;{  int n;  int success = 1;  const char *p;  if ((*mangled)[0] == '_'      && strchr (cplus_markers, (*mangled)[1]) != NULL      && (*mangled)[2] == '_')    {      /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */      (*mangled) += 3;      work -> destructor += 1;    }  else if ((*mangled)[0] == '_'	   && (((*mangled)[1] == '_'		&& (*mangled)[2] == 'v'		&& (*mangled)[3] == 't'		&& (*mangled)[4] == '_')	     || ((*mangled)[1] == 'v'		 && (*mangled)[2] == 't'		 && strchr (cplus_markers, (*mangled)[3]) != NULL)))    {      /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"         and create the decl.  Note that we consume the entire mangled	 input string, which means that demangle_signature has no work	 to do. */      if ((*mangled)[2] == 'v')	(*mangled) += 5; /* New style, with thunks: "__vt_" */      else	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */      while (**mangled != '\0')	{	  p = strpbrk (*mangled, cplus_markers);	  switch (**mangled)	    {	    case 'Q':	      success = demangle_qualified (work, mangled, declp, 0, 1);	      break;	    case 't':	      success = demangle_template (work, mangled, declp, 0);	      break;	    default:	      if (isdigit(*mangled[0]))		{		  n = consume_count(mangled);		}	      else		{		  n = strcspn (*mangled, cplus_markers);		}	      string_appendn (declp, *mangled, n);	      (*mangled) += n;	    }	  if (success && ((p == NULL) || (p == *mangled)))	    {	      if (p != NULL)		{		  string_append (declp, "::");		  (*mangled)++;		}	    }	  else	    {	      success = 0;	      break;	    }	}      if (success)	string_append (declp, " virtual table");    }  else if ((*mangled)[0] == '_'	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)    {      /* static data member, "_3foo$varname" for example */      (*mangled)++;      switch (**mangled)	{	  case 'Q':	    success = demangle_qualified (work, mangled, declp, 0, 1);	    break;	  case 't':	    success = demangle_template (work, mangled, declp, 0);	    break;	  default:	    n = consume_count (mangled);	    string_appendn (declp, *mangled, n);	    (*mangled) += n;	}      if (success && (p == *mangled))	{	  /* Consumed everything up to the cplus_marker, append the	     variable name. */	  (*mangled)++;	  string_append (declp, "::");	  n = strlen (*mangled);	  string_appendn (declp, *mangled, n);	  (*mangled) += n;	}      else	{	  success = 0;	}    }  else if (strncmp (*mangled, "__thunk_", 8) == 0)    {      int delta = ((*mangled) += 8, consume_count (mangled));      char *method = cplus_demangle (++*mangled, work->options);      if (method)	{	  char buf[50];	  sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);	  string_append (declp, buf);	  string_append (declp, method);	  free (method);	  n = strlen (*mangled);	  (*mangled) += n;	}      else	{	  success = 0;	}    }  else    {      success = 0;    }  return (success);}/*LOCAL FUNCTION	arm_special -- special handling of ARM/lucid mangled stringsSYNOPSIS	static int	arm_special (struct work_stuff *work, const char **mangled,			string *declp);DESCRIPTION	Process some special ARM style mangling forms that don't fit	the normal pattern.  For example:		__vtbl__3foo		(foo virtual table)		__vtbl__3foo__3bar	(bar::foo virtual table) */static intarm_special (work, mangled, declp)     struct work_stuff *work;     const char **mangled;     string *declp;{  int n;  int success = 1;  const char *scan;  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)    {      /* Found a ARM style virtual table, get past ARM_VTABLE_STRING         and create the decl.  Note that we consume the entire mangled	 input string, which means that demangle_signature has no work	 to do. */      scan = *mangled + ARM_VTABLE_STRLEN;      while (*scan != '\0')        /* first check it can be demangled */        {          n = consume_count (&scan);          if (n==0)	    {	      return (0);           /* no good */	    }          scan += n;          if (scan[0] == '_' && scan[1] == '_')	    {	      scan += 2;	    }        }      (*mangled) += ARM_VTABLE_STRLEN;      while (**mangled != '\0')	{	  n = consume_count (mangled);	  string_prependn (declp, *mangled, n);	  (*mangled) += n;	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')	    {	      string_prepend (declp, "::");	      (*mangled) += 2;	    }	}      string_append (declp, " virtual table");    }  else    {      success = 0;    }  return (success);}/*LOCAL FUNCTION	demangle_qualified -- demangle 'Q' qualified name stringsSYNOPSIS	static int	demangle_qualified (struct work_stuff *, const char *mangled,			    string *result, int isfuncname, int append);DESCRIPTION	Demangle a qualified name, such as "Q25Outer5Inner" which is	the mangled form of "Outer::Inner".  The demangled output is	prepended or appended to the result string according to the	state of the append flag.	If isfuncname is nonzero, then the qualified name we are building	is going to be used as a member function name, so if it is a	constructor or destructor function, append an appropriate	constructor or destructor name.  I.E. for the above example,	the result for use as a constructor is "Outer::Inner::Inner"	and the result for use as a destructor is "Outer::Inner::~Inner".BUGS

⌨️ 快捷键说明

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