1 // C++ IA64 / g++ v3 demangler  -*- C++ -*-
2 
3 // Copyright (C) 2002 - 2004, by
4 //
5 // Carlo Wood, Run on IRC <carlo@alinoe.com>
6 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
8 //
9 // This file may be distributed under the terms of the Q Public License
10 // version 1.0 as appearing in the file LICENSE.QPL included in the
11 // packaging of this file.
12 
13 // This file implements demangling of "C++ ABI for Itanium"-mangled symbol
14 // and type names as described in Revision 1.74 of the C++ ABI as can be found
15 // at http://www.codesourcery.com/cxx-abi/abi.html#mangling
16 
17 #ifndef _DEMANGLER_H
18 #define _DEMANGLER_H 1
19 
20 #include <vector>
21 #include <string>
22 
23 #ifndef _GLIBCXX_DEMANGLER_DEBUG
24 #define _GLIBCXX_DEMANGLER_CWDEBUG 0
25 #define _GLIBCXX_DEMANGLER_DEBUG(x)
26 #define _GLIBCXX_DEMANGLER_DOUT(cntrl, data)
27 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x)
28 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x)
29 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x)
30 #define _GLIBCXX_DEMANGLER_RETURN return M_result
31 #define _GLIBCXX_DEMANGLER_RETURN2 return M_result
32 #define _GLIBCXX_DEMANGLER_RETURN3
33 #define _GLIBCXX_DEMANGLER_FAILURE \
34     do { M_result = false; return false; } while(0)
35 #else
36 #define _GLIBCXX_DEMANGLER_CWDEBUG 1
37 #endif
38 
39 namespace __gnu_cxx
40 {
41   namespace demangler
42   {
43 
44     enum substitution_nt
45     {
46       type,
47       template_template_param,
48       nested_name_prefix,
49       nested_name_template_prefix,
50       unscoped_template_name
51     };
52 
53     struct substitution_st
54     {
55       int M_start_pos;
56       substitution_nt M_type;
57       int M_number_of_prefixes;
58 
substitution_stsubstitution_st59       substitution_st(int start_pos,
60 		      substitution_nt type,
61 		      int number_of_prefixes)
62       : M_start_pos(start_pos), M_type(type),
63 	M_number_of_prefixes(number_of_prefixes)
64       { }
65     };
66 
67     enum simple_qualifier_nt
68     {
69       complex_or_imaginary = 'G',
70       pointer = 'P',
71       reference = 'R'
72     };
73 
74     enum cv_qualifier_nt
75     {
76       cv_qualifier = 'K'
77     };
78 
79     enum param_qualifier_nt
80     {
81       vendor_extension = 'U',
82       array = 'A',
83       pointer_to_member = 'M'
84     };
85 
86     template<typename Allocator>
87       class qualifier;
88 
89     template<typename Allocator>
90       class qualifier_list;
91 
92     template<typename Allocator>
93       class session;
94 
95     template<typename Allocator>
96       class qualifier
97       {
98 	typedef typename Allocator::template rebind<char>::other
99 	        char_Allocator;
100 	typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
101 	    string_type;
102 
103       private:
104 	char M_qualifier1;
105 	char M_qualifier2;
106 	char M_qualifier3;
107 	mutable unsigned char M_cnt;
108 	string_type M_optional_type;
109 	int M_start_pos;
110 	bool M_part_of_substitution;
111 
112       public:
qualifier(int start_pos,simple_qualifier_nt simple_qualifier,int inside_substitution)113 	qualifier(int start_pos,
114 	          simple_qualifier_nt simple_qualifier,
115 		  int inside_substitution)
116 	: M_qualifier1(simple_qualifier),
117 	  M_start_pos(start_pos),
118 	  M_part_of_substitution(inside_substitution)
119 	{ }
120 
qualifier(int start_pos,cv_qualifier_nt,char const * start,int count,int inside_substitution)121 	qualifier(int start_pos,
122 	          cv_qualifier_nt,
123 		  char const* start,
124 		  int count,
125 		  int inside_substitution)
126 	: M_qualifier1(start[0]),
127 	  M_qualifier2((count > 1) ? start[1] : '\0'),
128 	  M_qualifier3((count > 2) ? start[2] : '\0'),
129 	  M_start_pos(start_pos),
130 	  M_part_of_substitution(inside_substitution)
131 	{ }
132 
qualifier(int start_pos,param_qualifier_nt param_qualifier,string_type optional_type,int inside_substitution)133 	qualifier(int start_pos,
134 	          param_qualifier_nt param_qualifier,
135 		  string_type optional_type,
136 		  int inside_substitution)
137 	: M_qualifier1(param_qualifier),
138 	  M_optional_type(optional_type),
139 	  M_start_pos(start_pos),
140 	  M_part_of_substitution(inside_substitution)
141 	{ }
142 
143 	int
get_start_pos(void)144 	get_start_pos(void) const
145 	{ return M_start_pos; }
146 
147 	char
first_qualifier(void)148 	first_qualifier(void) const
149 	{ M_cnt = 1; return M_qualifier1; }
150 
151 	char
next_qualifier(void)152 	next_qualifier(void) const
153 	{
154 	  return (++M_cnt == 2) ? M_qualifier2
155 	                        : ((M_cnt == 3) ? M_qualifier3 : 0);
156 	}
157 
158 	string_type const&
get_optional_type(void)159 	get_optional_type(void) const
160 	{ return M_optional_type; }
161 
162 	bool
part_of_substitution(void)163 	part_of_substitution(void) const
164 	{ return M_part_of_substitution; }
165 
166 #if _GLIBCXX_DEMANGLER_CWDEBUG
167 	friend std::ostream& operator<<(std::ostream& os, qualifier const& qual)
168 	{
169 	  os << (char)qual.M_qualifier1;
170 	  if (qual.M_qualifier1 == vendor_extension ||
171 	      qual.M_qualifier1 == array ||
172 	      qual.M_qualifier1 == pointer_to_member)
173 	    os << " [" << qual.M_optional_type << ']';
174 	  else if (qual.M_qualifier1 == 'K' ||
175 		   qual.M_qualifier1 == 'V' ||
176 		   qual.M_qualifier1 == 'r')
177 	  {
178 	    if (qual.M_qualifier2)
179 	    {
180 	      os << (char)qual.M_qualifier2;
181 	      if (qual.M_qualifier3)
182 		os << (char)qual.M_qualifier3;
183 	    }
184 	  }
185 	  return os;
186 	}
187 #endif
188       };
189 
190     template<typename Allocator>
191       class qualifier_list
192       {
193 	typedef typename Allocator::template rebind<char>::other
194   	  char_Allocator;
195 	typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
196 	  string_type;
197 
198       private:
199 	mutable bool M_printing_suppressed;
200 	typedef qualifier<Allocator> qual;
201         typedef typename Allocator::template rebind<qual>::other qual_Allocator;
202 	typedef std::vector<qual, qual_Allocator> qual_vector;
203 	qual_vector M_qualifier_starts;
204 	session<Allocator>& M_demangler;
205 
206 	void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
207 			 typename qual_vector::
208 			   const_reverse_iterator const& iter_array) const;
209 
210       public:
qualifier_list(session<Allocator> & demangler_obj)211 	qualifier_list(session<Allocator>& demangler_obj)
212 	: M_printing_suppressed(false), M_demangler(demangler_obj)
213 	{ }
214 
215 	void
add_qualifier_start(simple_qualifier_nt simple_qualifier,int start_pos,int inside_substitution)216 	add_qualifier_start(simple_qualifier_nt simple_qualifier,
217 			    int start_pos,
218 			    int inside_substitution)
219 	{ M_qualifier_starts.
220 	      push_back(qualifier<Allocator>(start_pos,
221 		  simple_qualifier, inside_substitution)); }
222 
223 	void
add_qualifier_start(cv_qualifier_nt cv_qualifier,int start_pos,int count,int inside_substitution)224 	add_qualifier_start(cv_qualifier_nt cv_qualifier,
225 			    int start_pos,
226 			    int count,
227 			    int inside_substitution)
228 	{ M_qualifier_starts.
229 	      push_back(qualifier<Allocator>(start_pos,
230 		    cv_qualifier, &M_demangler.M_str[start_pos],
231 		    count, inside_substitution)); }
232 
233 	void
add_qualifier_start(param_qualifier_nt param_qualifier,int start_pos,string_type optional_type,int inside_substitution)234 	add_qualifier_start(param_qualifier_nt param_qualifier,
235 	    		    int start_pos,
236 			    string_type optional_type,
237 			    int inside_substitution)
238 	{ M_qualifier_starts.
239 	      push_back(qualifier<Allocator>(start_pos,
240 		    param_qualifier, optional_type, inside_substitution)); }
241 
242 	void
243 	decode_qualifiers(string_type& prefix,
244 	    		  string_type& postfix,
245 			  bool member_function_pointer_qualifiers = false) const;
246 
247 	bool
suppressed(void)248 	suppressed(void) const
249 	{ return M_printing_suppressed; }
250 
251 	void
printing_suppressed(void)252 	printing_suppressed(void)
253 	{ M_printing_suppressed = true; }
254 
255 	size_t
size(void)256 	size(void) const
257 	{ return M_qualifier_starts.size(); }
258 
259 #if _GLIBCXX_DEMANGLER_CWDEBUG
260 	friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
261 	{
262 	  typename qual_vector::const_iterator
263 	      iter = list.M_qualifier_starts.begin();
264 	  if (iter != list.M_qualifier_starts.end())
265 	  {
266 	    os << "{ " << *iter;
267 	    while (++iter != list.M_qualifier_starts.end())
268 	      os << ", " << *iter;
269 	    os << " }";
270 	  }
271 	  else
272 	    os << "{ }";
273 	  return os;
274 	}
275 #endif
276       };
277 
278     struct implementation_details
279     {
280       private:
281         unsigned int M_style;
282 
283       public:
284 	// The following flags change the behaviour of the demangler.  The
285 	// default behaviour is that none of these flags is set.
286 
287         static unsigned int const style_void = 1;
288 	// Default behaviour:				int f()
289 	// Use (void) instead of ():			int f(void)
290 
291         static unsigned int const style_literal = 2;
292 	// Default behaviour:				(long)13,
293 	//						(unsigned long long)19
294 	// Use extensions 'u', 'l' and 'll' for integral
295 	// literals (as in template arguments):		13l, 19ull
296 
297         static unsigned int const style_literal_int = 4;
298 	// Default behaviour:				4
299 	// Use also an explicit
300 	//   cast for int in literals:			(int)4
301 
302         static unsigned int const style_compact_expr_ops = 8;
303 	// Default behaviour:				(i) < (3), sizeof (int)
304 	// Don't output spaces around
305 	//   operators in expressions:			(i)<(3), sizeof(int)
306 
307         static unsigned int const style_sizeof_typename = 16;
308 	// Default behaviour:				sizeof (X::t)
309 	// Put 'typename' infront of <nested-name>
310 	// types inside a 'sizeof':			sizeof (typename X::t)
311 
312       public:
313 	implementation_details(unsigned int style_flags = 0) :
M_styleimplementation_details314 	    M_style(style_flags) { }
~implementation_detailsimplementation_details315 	virtual ~implementation_details() { }
get_style_voidimplementation_details316 	bool get_style_void(void) const
317 	    { return (M_style & style_void); }
get_style_literalimplementation_details318 	bool get_style_literal(void) const
319 	    { return (M_style & style_literal); }
get_style_literal_intimplementation_details320 	bool get_style_literal_int(void) const
321 	    { return (M_style & style_literal_int); }
get_style_compact_expr_opsimplementation_details322 	bool get_style_compact_expr_ops(void) const
323 	    { return (M_style & style_compact_expr_ops); }
get_style_sizeof_typenameimplementation_details324 	bool get_style_sizeof_typename(void) const
325 	    { return (M_style & style_sizeof_typename); }
326         // This can be overridden by user implementations.
decode_realimplementation_details327         virtual bool decode_real(char* /* output */, unsigned long* /* input */,
328 				 size_t /* size_of_real */) const
329             { return false; }
330     };
331 
332     template<typename Allocator>
333       class session
334       {
335 	friend class qualifier_list<Allocator>;
336 	typedef typename Allocator::template rebind<char>::other
337     	    char_Allocator;
338 	typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
339 	    string_type;
340 
341       private:
342 	char const* M_str;
343 	int M_pos;
344 	int M_maxpos;
345 	bool M_result;
346 	int M_inside_template_args;
347 	int M_inside_type;
348 	int M_inside_substitution;
349 	bool M_saw_destructor;
350 	bool M_name_is_cdtor;
351 	bool M_name_is_template;
352 	bool M_name_is_conversion_operator;
353 	bool M_template_args_need_space;
354 	string_type M_function_name;
355         typedef typename Allocator::template rebind<int>::other
356                 int_Allocator;
357         typedef typename Allocator::template rebind<substitution_st>::other
358                 subst_Allocator;
359 	std::vector<int, int_Allocator> M_template_arg_pos;
360 	int M_template_arg_pos_offset;
361 	std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
362 	implementation_details const& M_implementation_details;
363 #if _GLIBCXX_DEMANGLER_CWDEBUG
364 	bool M_inside_add_substitution;
365 #endif
366 
367       public:
368 	explicit session(char const* in, int len,
369 	    implementation_details const& id = implementation_details())
M_str(in)370 	: M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true),
371 	  M_inside_template_args(0), M_inside_type(0),
372 	  M_inside_substitution(0), M_saw_destructor(false),
373 	  M_name_is_cdtor(false), M_name_is_template(false),
374 	  M_name_is_conversion_operator(false),
375 	  M_template_args_need_space(false), M_template_arg_pos_offset(0),
376 	  M_implementation_details(id)
377 #if _GLIBCXX_DEMANGLER_CWDEBUG
378 	  , M_inside_add_substitution(false)
379 #endif
380 	{ }
381 
382 	static int
383 	decode_encoding(string_type& output, char const* input, int len,
384 	  implementation_details const& id = implementation_details());
385 
386 	bool
387 	decode_type(string_type& output,
388 	            qualifier_list<Allocator>* qualifiers = NULL)
389 	{
390 	  string_type postfix;
391 	  bool res = decode_type_with_postfix(output, postfix, qualifiers);
392 	  output += postfix;
393 	  return res;
394 	}
395 
396 	bool
remaining_input_characters(void)397 	remaining_input_characters(void) const
398 	{ return current() != 0; }
399 
400       private:
401 	char
current(void)402 	current(void) const
403 	{ return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; }
404 
405 	char
next_peek(void)406 	next_peek(void) const
407 	{ return (M_pos >= M_maxpos) ? 0 : M_str[M_pos + 1]; }
408 
409 	char
next(void)410 	next(void)
411 	{ return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; }
412 
413 	char
eat_current(void)414 	eat_current(void)
415 	{ return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; }
416 
417 	void
store(int & saved_pos)418 	store(int& saved_pos)
419 	{ saved_pos = M_pos; }
420 
421 	void
restore(int saved_pos)422 	restore(int saved_pos)
423 	{ M_pos = saved_pos; M_result = true; }
424 
425 	void
426 	add_substitution(int start_pos,
427 	                 substitution_nt sub_type,
428 			 int number_of_prefixes = 0);
429 
430 	bool decode_type_with_postfix(string_type& prefix,
431 	    string_type& postfix, qualifier_list<Allocator>* qualifiers = NULL);
432 	bool decode_bare_function_type(string_type& output);
433 	bool decode_builtin_type(string_type& output);
434 	bool decode_call_offset(string_type& output);
435 	bool decode_class_enum_type(string_type& output);
436 	bool decode_expression(string_type& output);
437 	bool decode_literal(string_type& output);
438 	bool decode_local_name(string_type& output);
439 	bool decode_name(string_type& output,
440 	    string_type& nested_name_qualifiers);
441 	bool decode_nested_name(string_type& output,
442 	    string_type& qualifiers);
443 	bool decode_number(string_type& output);
444 	bool decode_operator_name(string_type& output);
445 	bool decode_source_name(string_type& output);
446 	bool decode_substitution(string_type& output,
447 	    qualifier_list<Allocator>* qualifiers = NULL);
448 	bool decode_template_args(string_type& output);
449 	bool decode_template_param(string_type& output,
450 	    qualifier_list<Allocator>* qualifiers = NULL);
451 	bool decode_unqualified_name(string_type& output);
452 	bool decode_unscoped_name(string_type& output);
453 	bool decode_non_negative_decimal_integer(string_type& output);
454 	bool decode_special_name(string_type& output);
455         bool decode_real(string_type& output, size_t size_of_real);
456       };
457 
458     template<typename Allocator>
459 #if !_GLIBCXX_DEMANGLER_CWDEBUG
460       inline
461 #endif
462       void
add_substitution(int start_pos,substitution_nt sub_type,int number_of_prefixes)463       session<Allocator>::add_substitution(int start_pos,
464 					   substitution_nt sub_type,
465 					   int number_of_prefixes)
466       {
467 	if (!M_inside_substitution)
468 	{
469 #if _GLIBCXX_DEMANGLER_CWDEBUG
470 	  if (M_inside_add_substitution)
471 	    return;
472 #endif
473 	  M_substitutions_pos.
474 	      push_back(substitution_st(start_pos,
475 		  sub_type, number_of_prefixes));
476 #if _GLIBCXX_DEMANGLER_CWDEBUG
477 	  if (!libcwd::channels::dc::demangler.is_on())
478 	    return;
479 	  string_type substitution_name("S");
480 	  int n = M_substitutions_pos.size() - 1;
481 	  if (n > 0)
482 	    substitution_name += (n <= 10) ? (char)(n + '0' - 1)
483 	      				   : (char)(n + 'A' - 11);
484 	  substitution_name += '_';
485 	  string_type subst;
486 	  int saved_pos = M_pos;
487 	  M_pos = start_pos;
488 	  M_inside_add_substitution = true;
489 	  _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.off() );
490 	  switch(sub_type)
491 	  {
492 	    case type:
493 	      decode_type(subst);
494 	      break;
495 	    case template_template_param:
496 	      decode_template_param(subst);
497 	      break;
498 	    case nested_name_prefix:
499 	    case nested_name_template_prefix:
500 	      for (int cnt = number_of_prefixes; cnt > 0; --cnt)
501 	      {
502 		if (current() == 'I')
503 		{
504 		  subst += ' ';
505 		  decode_template_args(subst);
506 		}
507 		else
508 		{
509 		  if (cnt < number_of_prefixes)
510 		    subst += "::";
511 		  if (current() == 'S')
512 		    decode_substitution(subst);
513 		  else if (current() == 'T')
514 		    decode_template_param(subst);
515 		  else
516 		    decode_unqualified_name(subst);
517 		}
518 	      }
519 	      break;
520 	    case unscoped_template_name:
521 	      decode_unscoped_name(subst);
522 	      break;
523 	  }
524 	  M_pos = saved_pos;
525 	  _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.on() );
526 	  _GLIBCXX_DEMANGLER_DOUT(dc::demangler,
527 	      "Adding substitution " << substitution_name
528 	      << " : " << subst
529 	      << " (from " << location_ct((char*)__builtin_return_address(0)
530 		                          + builtin_return_address_offset)
531 	      << " <- " << location_ct((char*)__builtin_return_address(1)
532 		                       + builtin_return_address_offset)
533 	      << " <- " << location_ct((char*)__builtin_return_address(2)
534 		                       + builtin_return_address_offset)
535 	      << ").");
536 	  M_inside_add_substitution = false;
537 #endif
538 	}
539       }
540 
541     // We don't want to depend on locale (or include <cctype> for that matter).
542     // We also don't want to use "safe-ctype.h" because that headerfile is not
543     // available to the users.
isdigit(char c)544     inline bool isdigit(char c) { return c >= '0' && c <= '9'; }
islower(char c)545     inline bool islower(char c) { return c >= 'a' && c <= 'z'; }
isupper(char c)546     inline bool isupper(char c) { return c >= 'A' && c <= 'Z'; }
tolower(char c)547     inline char tolower(char c) { return isupper(c) ? c - 'A' + 'a' : c; }
548 
549     //
550     // <non-negative decimal integer> ::= 0
551     //                                ::= 1|2|3|4|5|6|7|8|9 [<digit>+]
552     // <digit>                        ::= 0|1|2|3|4|5|6|7|8|9
553     //
554     template<typename Allocator>
555       bool
556       session<Allocator>::
decode_non_negative_decimal_integer(string_type & output)557 	  decode_non_negative_decimal_integer(string_type& output)
558       {
559 	char c = current();
560 	if (c == '0')
561 	{
562 	  output += '0';
563 	  eat_current();
564 	}
565 	else if (!isdigit(c))
566 	  M_result = false;
567 	else
568 	{
569 	  do
570 	  {
571 	    output += c;
572 	  }
573 	  while (isdigit((c = next())));
574 	}
575 	return M_result;
576       }
577 
578     // <number> ::= [n] <non-negative decimal integer>
579     //
580     template<typename Allocator>
581       bool
decode_number(string_type & output)582       session<Allocator>::decode_number(string_type& output)
583       {
584 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_number");
585 	if (current() != 'n')
586 	  decode_non_negative_decimal_integer(output);
587 	else
588 	{
589 	  output += '-';
590 	  eat_current();
591 	  decode_non_negative_decimal_integer(output);
592 	}
593 	_GLIBCXX_DEMANGLER_RETURN;
594       }
595 
596     // <builtin-type> ::= v  # void
597     //                ::= w  # wchar_t
598     //                ::= b  # bool
599     //                ::= c  # char
600     //                ::= a  # signed char
601     //                ::= h  # unsigned char
602     //                ::= s  # short
603     //                ::= t  # unsigned short
604     //                ::= i  # int
605     //                ::= j  # unsigned int
606     //                ::= l  # long
607     //                ::= m  # unsigned long
608     //                ::= x  # long long, __int64
609     //                ::= y  # unsigned long long, __int64
610     //                ::= n  # __int128
611     //                ::= o  # unsigned __int128
612     //                ::= f  # float
613     //                ::= d  # double
614     //                ::= e  # long double, __float80
615     //                ::= g  # __float128
616     //                ::= z  # ellipsis
617     //                ::= u <source-name>    # vendor extended type
618     //
619     char const* const builtin_type_c[26] =
620     {
621       "signed char",	// a
622       "bool",		// b
623       "char",		// c
624       "double",		// d
625       "long double",	// e
626       "float",		// f
627       "__float128",		// g
628       "unsigned char",	// h
629       "int",		// i
630       "unsigned int",	// j
631       NULL,			// k
632       "long",		// l
633       "unsigned long",	// m
634       "__int128",		// n
635       "unsigned __int128",	// o
636       NULL,			// p
637       NULL,			// q
638       NULL,			// r
639       "short",		// s
640       "unsigned short",	// t
641       NULL,			// u
642       "void",		// v
643       "wchar_t",		// w
644       "long long",		// x
645       "unsigned long long",	// y
646       "..."			// z
647     };
648 
649     //
650     template<typename Allocator>
651       bool
decode_builtin_type(string_type & output)652       session<Allocator>::decode_builtin_type(string_type& output)
653       {
654 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_builtin_type");
655 	if (!islower(current()))
656 	  _GLIBCXX_DEMANGLER_FAILURE;
657 	char const* bt = builtin_type_c[current() - 'a'];
658 	if (!bt)
659 	  _GLIBCXX_DEMANGLER_FAILURE;
660 	output += bt;
661 	eat_current();
662 	_GLIBCXX_DEMANGLER_RETURN;
663       }
664 
665     // <class-enum-type> ::= <name>
666     //
667     template<typename Allocator>
668       bool
decode_class_enum_type(string_type & output)669       session<Allocator>::decode_class_enum_type(string_type& output)
670       {
671 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_class_enum_type");
672 	string_type nested_name_qualifiers;
673 	if (!decode_name(output, nested_name_qualifiers))
674 	  _GLIBCXX_DEMANGLER_FAILURE;
675 	output += nested_name_qualifiers;
676 	_GLIBCXX_DEMANGLER_RETURN;
677       }
678 
679     // <substitution> ::=
680     //   S <seq-id> _
681     //   S_
682     //   St # ::std::
683     //   Sa # ::std::allocator
684     //   Sb # ::std::basic_string
685     //   Ss # ::std::basic_string<char, std::char_traits<char>,
686     //                            std::allocator<char> >
687     //   Si # ::std::basic_istream<char,  std::char_traits<char> >
688     //   So # ::std::basic_ostream<char,  std::char_traits<char> >
689     //   Sd # ::std::basic_iostream<char, std::char_traits<char> >
690     //
691     // <seq-id> ::=
692     //   0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
693     //       [<seq-id>]	# Base 36 number
694     //
695     template<typename Allocator>
696       bool
decode_substitution(string_type & output,qualifier_list<Allocator> * qualifiers)697       session<Allocator>::decode_substitution(string_type& output,
698 	  qualifier_list<Allocator>* qualifiers)
699       {
700 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_substitution");
701 	unsigned int value = 0;
702 	char c = next();
703 	if (c != '_')
704 	{
705 	  switch(c)
706 	  {
707 	    case 'a':
708 	    {
709 	      output += "std::allocator";
710 	      if (!M_inside_template_args)
711 	      {
712 		M_function_name = "allocator";
713 		M_name_is_template = true;
714 		M_name_is_cdtor = false;
715 		M_name_is_conversion_operator = false;
716 	      }
717 	      eat_current();
718 	      if (qualifiers)
719 		qualifiers->printing_suppressed();
720 	      _GLIBCXX_DEMANGLER_RETURN;
721 	    }
722 	    case 'b':
723 	    {
724 	      output += "std::basic_string";
725 	      if (!M_inside_template_args)
726 	      {
727 		M_function_name = "basic_string";
728 		M_name_is_template = true;
729 		M_name_is_cdtor = false;
730 		M_name_is_conversion_operator = false;
731 	      }
732 	      eat_current();
733 	      if (qualifiers)
734 		qualifiers->printing_suppressed();
735 	      _GLIBCXX_DEMANGLER_RETURN;
736 	    }
737 	    case 'd':
738 	      output += "std::iostream";
739 	      if (!M_inside_template_args)
740 	      {
741 		M_function_name = "iostream";
742 		M_name_is_template = true;
743 		M_name_is_cdtor = false;
744 		M_name_is_conversion_operator = false;
745 	      }
746 	      eat_current();
747 	      if (qualifiers)
748 		qualifiers->printing_suppressed();
749 	      _GLIBCXX_DEMANGLER_RETURN;
750 	    case 'i':
751 	      output += "std::istream";
752 	      if (!M_inside_template_args)
753 	      {
754 		M_function_name = "istream";
755 		M_name_is_template = true;
756 		M_name_is_cdtor = false;
757 		M_name_is_conversion_operator = false;
758 	      }
759 	      eat_current();
760 	      if (qualifiers)
761 		qualifiers->printing_suppressed();
762 	      _GLIBCXX_DEMANGLER_RETURN;
763 	    case 'o':
764 	      output += "std::ostream";
765 	      if (!M_inside_template_args)
766 	      {
767 		M_function_name = "ostream";
768 		M_name_is_template = true;
769 		M_name_is_cdtor = false;
770 		M_name_is_conversion_operator = false;
771 	      }
772 	      eat_current();
773 	      if (qualifiers)
774 		qualifiers->printing_suppressed();
775 	      _GLIBCXX_DEMANGLER_RETURN;
776 	    case 's':
777 	      output += "std::string";
778 	      if (!M_inside_template_args)
779 	      {
780 		M_function_name = "string";
781 		M_name_is_template = true;
782 		M_name_is_cdtor = false;
783 		M_name_is_conversion_operator = false;
784 	      }
785 	      eat_current();
786 	      if (qualifiers)
787 		qualifiers->printing_suppressed();
788 	      _GLIBCXX_DEMANGLER_RETURN;
789 	    case 't':
790 	      output += "std";
791 	      eat_current();
792 	      if (qualifiers)
793 		qualifiers->printing_suppressed();
794 	      _GLIBCXX_DEMANGLER_RETURN;
795 	    default:
796 	      for(;; c = next())
797 	      {
798 		if (isdigit(c))
799 		  value = value * 36 + c - '0';
800 		else if (isupper(c))
801 		  value = value * 36 + c - 'A' + 10;
802 		else if (c == '_')
803 		  break;
804 		else
805 		  _GLIBCXX_DEMANGLER_FAILURE;
806 	      }
807 	      ++value;
808 	      break;
809 	  }
810 	}
811 	eat_current();
812 	if (value >= M_substitutions_pos.size() ||
813 	    M_inside_type > 20)			// Rather than core dump.
814 	  _GLIBCXX_DEMANGLER_FAILURE;
815 	++M_inside_substitution;
816 	int saved_pos = M_pos;
817 	substitution_st& substitution(M_substitutions_pos[value]);
818 	M_pos = substitution.M_start_pos;
819 	switch(substitution.M_type)
820 	{
821 	  case type:
822 	    decode_type(output, qualifiers);
823 	    break;
824 	  case template_template_param:
825 	    decode_template_param(output, qualifiers);
826 	    break;
827 	  case nested_name_prefix:
828 	  case nested_name_template_prefix:
829 	    for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt)
830 	    {
831 	      if (current() == 'I')
832 	      {
833 		if (M_template_args_need_space)
834 		  output += ' ';
835 		M_template_args_need_space = false;
836 		if (!decode_template_args(output))
837 		  _GLIBCXX_DEMANGLER_FAILURE;
838 	      }
839 	      else
840 	      {
841 		if (cnt < substitution.M_number_of_prefixes)
842 		  output += "::";
843 		if (current() == 'S')
844 		{
845 		  if (!decode_substitution(output))
846 		    _GLIBCXX_DEMANGLER_FAILURE;
847 		}
848 		else if (!decode_unqualified_name(output))
849 		  _GLIBCXX_DEMANGLER_FAILURE;
850 	      }
851 	    }
852 	    if (qualifiers)
853 	      qualifiers->printing_suppressed();
854 	    break;
855 	  case unscoped_template_name:
856 	    decode_unscoped_name(output);
857 	    if (qualifiers)
858 	      qualifiers->printing_suppressed();
859 	    break;
860 	}
861 	M_pos = saved_pos;
862 	--M_inside_substitution;
863 	_GLIBCXX_DEMANGLER_RETURN;
864       }
865 
866     // <template-param> ::= T_			# first template parameter
867     //                  ::= T <parameter-2 non-negative number> _
868     //
869     template<typename Allocator>
870       bool
decode_template_param(string_type & output,qualifier_list<Allocator> * qualifiers)871       session<Allocator>::decode_template_param(string_type& output,
872 	  qualifier_list<Allocator>* qualifiers)
873       {
874 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_parameter");
875 	if (current() != 'T')
876 	  _GLIBCXX_DEMANGLER_FAILURE;
877 	unsigned int value = 0;
878 	char c;
879 	if ((c = next()) != '_')
880 	{
881 	  while(isdigit(c))
882 	  {
883 	    value = value * 10 + c - '0';
884 	    c = next();
885 	  }
886 	  ++value;
887 	}
888 	if (eat_current() != '_')
889 	  _GLIBCXX_DEMANGLER_FAILURE;
890 	value += M_template_arg_pos_offset;
891 	if (value >= M_template_arg_pos.size())
892 	  _GLIBCXX_DEMANGLER_FAILURE;
893 	int saved_pos = M_pos;
894 	M_pos = M_template_arg_pos[value];
895 	if (M_inside_type > 20)		// Rather than core dump.
896 	  _GLIBCXX_DEMANGLER_FAILURE;
897 	++M_inside_substitution;
898 	if (current() == 'X')
899 	{
900 	  eat_current();
901 	  decode_expression(output);
902 	}
903 	else if (current() == 'L')
904 	  decode_literal(output);
905 	else
906 	  decode_type(output, qualifiers);
907 	--M_inside_substitution;
908 	M_pos = saved_pos;
909 	_GLIBCXX_DEMANGLER_RETURN;
910       }
911 
912     template<typename Allocator>
913       bool
decode_real(string_type & output,size_t size_of_real)914       session<Allocator>::decode_real(string_type& output, size_t size_of_real)
915       {
916 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real");
917 
918 	unsigned long words[4];	// 32 bit per long, maximum of 128 bits.
919 	unsigned long* word = &words[0];
920 
921 	int saved_pos;
922 	store(saved_pos);
923 
924 	// The following assumes that leading zeroes are also included in the
925 	// mangled name, I am not sure that is conforming to the C++-ABI, but
926 	// it is what g++ does.
927 	unsigned char nibble, c = current();
928 	for(size_t word_cnt = size_of_real / 4; word_cnt > 0; --word_cnt)
929 	{
930 	  for (int nibble_cnt = 0; nibble_cnt < 8; ++nibble_cnt)
931 	  {
932 	    // Translate character into nibble.
933 	    if (c < '0' || c > 'f')
934 	      _GLIBCXX_DEMANGLER_FAILURE;
935 	    if (c <= '9')
936 	      nibble = c - '0';
937 	    else if (c >= 'a')
938 	      nibble = c - 'a' + 10;
939 	    else
940 	      _GLIBCXX_DEMANGLER_FAILURE;
941 	    // Write nibble into word array.
942 	    if (nibble_cnt == 0)
943 	      *word = nibble << 28;
944 	    else
945 	      *word |= (nibble << (28 - 4 * nibble_cnt));
946 	    c = next();
947 	  }
948 	  ++word;
949 	}
950 	char buf[24];
951 	if (M_implementation_details.decode_real(buf, words, size_of_real))
952 	{
953 	  output += buf;
954 	  _GLIBCXX_DEMANGLER_RETURN;
955 	}
956 	restore(saved_pos);
957 
958 	output += '[';
959 	c = current();
960 	for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt)
961 	{
962 	  if (c < '0' || c > 'f' || (c > '9' && c < 'a'))
963 	    _GLIBCXX_DEMANGLER_FAILURE;
964 	  output += c;
965 	  c = next();
966 	}
967 	output += ']';
968 
969 	_GLIBCXX_DEMANGLER_RETURN;
970       }
971 
972     template<typename Allocator>
973       bool
decode_literal(string_type & output)974       session<Allocator>::decode_literal(string_type& output)
975       {
976 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal");
977 	eat_current();	// Eat the 'L'.
978 	if (current() == '_')
979 	{
980 	  if (next() != 'Z')
981 	    _GLIBCXX_DEMANGLER_FAILURE;
982 	  eat_current();
983 	  if ((M_pos += decode_encoding(output, M_str + M_pos,
984 		  M_maxpos - M_pos + 1, M_implementation_details)) < 0)
985 	    _GLIBCXX_DEMANGLER_FAILURE;
986 	}
987 	else
988 	{
989 	  // Special cases
990 	  if (current() == 'b')
991 	  {
992 	    if (next() == '0')
993 	      output += "false";
994 	    else
995 	      output += "true";
996 	    eat_current();
997 	    _GLIBCXX_DEMANGLER_RETURN;
998 	  }
999 	  char c = current();
1000 	  if ((c == 'i' || c == 'j' || c == 'l' ||
1001 	       c == 'm' || c == 'x' || c == 'y') &&
1002               M_implementation_details.get_style_literal())
1003 	    eat_current();
1004 	  else if (c == 'i' &&
1005 	      !M_implementation_details.get_style_literal_int())
1006 	    eat_current();
1007 	  else
1008 	  {
1009 	    output += '(';
1010 	    if (!decode_type(output))
1011 	      _GLIBCXX_DEMANGLER_FAILURE;
1012 	    output += ')';
1013 	  }
1014 	  if (c >= 'd' && c <= 'g')
1015 	  {
1016 	    size_t size_of_real = (c == 'd') ? sizeof(double) :
1017 	        ((c == 'f') ? sizeof(float) :
1018 		(c == 'e') ?  sizeof(long double) : 16);
1019 	    if (!decode_real(output, size_of_real))
1020 		_GLIBCXX_DEMANGLER_FAILURE;
1021 	  }
1022 	  else if (!decode_number(output))
1023 	    _GLIBCXX_DEMANGLER_FAILURE;
1024           if (M_implementation_details.get_style_literal())
1025 	  {
1026 	    if (c == 'j' || c == 'm' || c == 'y')
1027 	      output += 'u';
1028 	    if (c == 'l' || c == 'm')
1029 	      output += 'l';
1030 	    if (c == 'x' || c == 'y')
1031 	      output += "ll";
1032 	  }
1033 	}
1034 	_GLIBCXX_DEMANGLER_RETURN;
1035       }
1036 
1037     // <operator-name> ::=
1038     //   nw				# new
1039     //   na				# new[]
1040     //   dl				# delete
1041     //   da				# delete[]
1042     //   ps				# + (unary)
1043     //   ng				# - (unary)
1044     //   ad				# & (unary)
1045     //   de				# * (unary)
1046     //   co				# ~
1047     //   pl				# +
1048     //   mi				# -
1049     //   ml				# *
1050     //   dv				# /
1051     //   rm				# %
1052     //   an				# &
1053     //   or				# |
1054     //   eo				# ^
1055     //   aS				# =
1056     //   pL				# +=
1057     //   mI				# -=
1058     //   mL				# *=
1059     //   dV				# /=
1060     //   rM				# %=
1061     //   aN				# &=
1062     //   oR				# |=
1063     //   eO				# ^=
1064     //   ls				# <<
1065     //   rs				# >>
1066     //   lS				# <<=
1067     //   rS				# >>=
1068     //   eq				# ==
1069     //   ne				# !=
1070     //   lt				# <
1071     //   gt				# >
1072     //   le				# <=
1073     //   ge				# >=
1074     //   nt				# !
1075     //   aa				# &&
1076     //   oo				# ||
1077     //   pp				# ++
1078     //   mm				# --
1079     //   cm				# ,
1080     //   pm				# ->*
1081     //   pt				# ->
1082     //   cl				# ()
1083     //   ix				# []
1084     //   qu				# ?
1085     //   st				# sizeof (a type)
1086     //   sz				# sizeof (an expression)
1087     //   cv <type>			# (cast)
1088     //   v <digit> <source-name>	# vendor extended operator
1089     //
1090     // Symbol operator codes exist of two characters, we need to find a
1091     // quick hash so that their names can be looked up in a table.
1092     //
1093     // The puzzle :)
1094     // Shift the rows so that there is at most one character per column.
1095     //
1096     // A perfect solution (Oh no, it's THE MATRIX!):
1097     //                                              horizontal
1098     //    .......................................   offset + 'a'
1099     // a, a||d|||||||||n||||s||||||||||||||||||||       0
1100     // c,  || |||||||lm o||| ||||||||||||||||||||       0
1101     // d,  || a|||e||    l|| ||||||v|||||||||||||       4
1102     // e,  ||  ||| ||     || |||o|q |||||||||||||       8
1103     // g,  ||  ||| ||     || e|| |  ||||||||t||||      15
1104     // i,  ||  ||| ||     ||  || |  |||||||| |||x      15
1105     // l,  |e  ||| ||     st  || |  |||||||| |||       -2
1106     // m,  |   |i| lm         || |  |||||||| |||       -2
1107     // n,  a   e g            t| w  |||||||| |||        1
1108     // o,                      |    ||||o||r |||       16
1109     // p,                      |    ||lm |p  st|       17
1110     // q,                      |    u|   |     |        6
1111     // r,                      m     s   |     |        9
1112     // s,                                t     z       12
1113     //    .......................................
1114     // ^            ^__ second character
1115     // |___ first character
1116     //
1117 
1118     // Putting that solution in tables:
1119 
1120     char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] =
1121     {
1122       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1123       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1124       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1125       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1126       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1127       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1128 #if (CHAR_MIN < 0)
1129       // Add -CHAR_MIN extra zeroes (128):
1130       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1131       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1132       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1133       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1134       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1135       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1136       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1137       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1138       //   a    b    c    d    e    f    g    h    i    j    k
1139       0, -97,   0, -97, -93, -89,   0, -82,   0, -82,   0,   0,
1140       //   l    m    n    o    p    q    r    s    t    u    v
1141 	 -99, -99, -96, -81, -80, -91, -88, -85,   0,   0,   0,
1142 #else
1143       //   a    b    c    d    e    f    g    h    i    j    k
1144       0, 159,   0, 159, 163, 167,   0, 174,   0, 174,   0,   0,
1145       //   l    m    n    o    p    q    r    s    t    u    v
1146 	 157, 157, 160, 175, 176, 165, 168, 171,   0,   0,   0,
1147 #endif
1148       // ... more zeros
1149     };
1150 
1151     enum xary_nt {
1152       unary,
1153       binary,
1154       trinary
1155     };
1156 
1157     struct entry_st
1158     {
1159       char const* opcode;
1160       char const* symbol_name;
1161       xary_nt type;
1162     };
1163 
1164     entry_st const symbol_name_table_c[39] = {
1165       { "aa",  "operator&&", binary },
1166       { "na",  "operator new[]", unary },
1167       { "le",  "operator<=", binary },
1168       { "ad",  "operator&", unary },
1169       { "da",  "operator delete[]", unary },
1170       { "ne",  "operator!=", binary },
1171       { "mi=", "operator-", binary },
1172       { "ng",  "operator-", unary },
1173       { "de",  "operator*", unary },
1174       { "ml=", "operator*", binary },
1175       { "mm",  "operator--", unary },
1176       { "cl",  "operator()", unary },
1177       { "cm",  "operator,", binary },
1178       { "an=", "operator&", binary },
1179       { "co",  "operator~", binary },
1180       { "dl",  "operator delete", unary },
1181       { "ls=", "operator<<", binary },
1182       { "lt",  "operator<", binary },
1183       { "as=", "operator", binary },
1184       { "ge",  "operator>=", binary },
1185       { "nt",  "operator!", unary },
1186       { "rm=", "operator%", binary },
1187       { "eo=", "operator^", binary },
1188       { "nw",  "operator new", unary },
1189       { "eq",  "operator==", binary },
1190       { "dv=", "operator/", binary },
1191       { "qu",  "operator?", trinary },
1192       { "rs=", "operator>>", binary },
1193       { "pl=", "operator+", binary },
1194       { "pm",  "operator->*", binary },
1195       { "oo",  "operator||", binary },
1196       { "st",  "sizeof", unary },
1197       { "pp",  "operator++", unary },
1198       { "or=", "operator|", binary },
1199       { "gt",  "operator>", binary },
1200       { "ps",  "operator+", unary },
1201       { "pt",  "operator->", binary },
1202       { "sz",  "sizeof", unary },
1203       { "ix",  "operator[]", unary }
1204     };
1205 
1206     template<typename Allocator>
1207       bool
decode_operator_name(string_type & output)1208       session<Allocator>::decode_operator_name(string_type& output)
1209       {
1210 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_operator_name");
1211 
1212 	char opcode0 = current();
1213 	char opcode1 = tolower(next());
1214 
1215 	register char hash = offset_table_c[opcode0 - CHAR_MIN];
1216 	if (hash)
1217 	{
1218 	  hash += opcode1;
1219 	  if (
1220 #if (CHAR_MIN < 0)
1221 	      hash >= 0 &&
1222 #endif
1223 	      hash < 39)
1224 	  {
1225 	    int index = static_cast<int>(static_cast<unsigned char>(hash));
1226 	    entry_st entry = symbol_name_table_c[index];
1227 	    if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1228 		&& (opcode1 == current() || entry.opcode[2] == '='))
1229 	    {
1230 	      output += entry.symbol_name;
1231 	      if (opcode1 != current())
1232 		output += '=';
1233 	      eat_current();
1234 	      if (hash == 16 || hash == 17)
1235 		M_template_args_need_space = true;
1236 	      _GLIBCXX_DEMANGLER_RETURN;
1237 	    }
1238 	    else if (opcode0 == 'c' && opcode1 == 'v')	// casting operator
1239 	    {
1240 	      eat_current();
1241 	      output += "operator ";
1242 	      if (current() == 'T')
1243 	      {
1244 		// This is a templated cast operator.
1245 		// It must be of the form "cvT_I...E".
1246 		// Let M_template_arg_pos already point
1247 		// to the template argument.
1248 		M_template_arg_pos_offset = M_template_arg_pos.size();
1249 		M_template_arg_pos.push_back(M_pos + 3);
1250 	      }
1251 	      if (!decode_type(output))
1252 		_GLIBCXX_DEMANGLER_FAILURE;
1253 	      if (!M_inside_template_args)
1254 		M_name_is_conversion_operator = true;
1255 	      _GLIBCXX_DEMANGLER_RETURN;
1256 	    }
1257 	  }
1258 	}
1259 	_GLIBCXX_DEMANGLER_FAILURE;
1260       }
1261 
1262     //
1263     // <expression> ::= <unary operator-name> <expression>
1264     //              ::= <binary operator-name> <expression> <expression>
1265     //              ::= <trinary operator-name> <expression> <expression> <expression>
1266     //              ::= st <type>
1267     //              ::= <template-param>
1268     //              ::= sr <type> <unqualified-name>                   # dependent name
1269     //              ::= sr <type> <unqualified-name> <template-args>   # dependent template-id
1270     //              ::= <expr-primary>
1271     //
1272     // <expr-primary> ::= L <type> <value number> E     # integer literal
1273     //                ::= L <type> <value float> E	# floating literal
1274     //                ::= L <mangled-name> E		# external name
1275     //
1276     template<typename Allocator>
1277       bool
decode_expression(string_type & output)1278       session<Allocator>::decode_expression(string_type& output)
1279       {
1280 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_expression");
1281 	if (current() == 'T')
1282 	{
1283 	  if (!decode_template_param(output))
1284 	    _GLIBCXX_DEMANGLER_FAILURE;
1285 	  _GLIBCXX_DEMANGLER_RETURN;
1286 	}
1287 	else if (current() == 'L')
1288 	{
1289 	  if (!decode_literal(output))
1290 	    _GLIBCXX_DEMANGLER_FAILURE;
1291 	  if (current() != 'E')
1292 	    _GLIBCXX_DEMANGLER_FAILURE;
1293 	  eat_current();
1294 	  _GLIBCXX_DEMANGLER_RETURN;
1295 	}
1296 	else if (current() == 's')
1297 	{
1298 	  char opcode1 = next();
1299 	  if (opcode1 == 't' || opcode1 == 'z')
1300 	  {
1301 	    eat_current();
1302 	    if (M_implementation_details.get_style_compact_expr_ops())
1303 	      output += "sizeof(";
1304 	    else
1305 	      output += "sizeof (";
1306 	    if (opcode1 == 't')
1307 	    {
1308 	      // I cannot think of a mangled name that is valid for both cases
1309 	      // when just replacing the 't' by a 'z' or vica versa, which
1310 	      // indicates that there is no ambiguity that dictates the need
1311 	      // for a seperate "st" case, except to be able catch invalid
1312 	      // mangled names.  However there CAN be ambiguity in the demangled
1313 	      // name when there are both a type and a symbol of the same name,
1314 	      // which then leads to different encoding (of course) with
1315 	      // sizeof (type) or sizeof (expression) respectively, but that
1316 	      // ambiguity is not per se related to "sizeof" except that that
1317 	      // is the only place where both a type AND an expression are valid
1318 	      // in as part of a (template function) type.
1319 	      //
1320 	      // Example:
1321 	      //
1322 	      // struct B { typedef int t; };
1323 	      // struct A : public B { static int t[2]; };
1324 	      // template<int i, int j> struct C { typedef int q; };
1325 	      // template<int i, typename T>
1326 	      //   void f(typename C<sizeof (typename T::t),
1327 	      //                     sizeof (T::t)>::q) { }
1328 	      // void instantiate() { f<5, A>(0); }
1329 	      //
1330 	      // Leads to _Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE which
1331 	      // demangles as
1332 	      // void f<5, A>(C<sizeof (T::t), sizeof (T::t)>::q)
1333 	      //
1334 	      // This is ambiguity is very unlikely to happen and it is kind
1335 	      // of fuzzy to detect when adding a 'typename' makes sense.
1336 	      //
1337 	      if (M_implementation_details.get_style_sizeof_typename())
1338 	      {
1339 		// We can only get here inside a template parameter,
1340 		// so this is syntactically correct if the given type is
1341 		// a typedef.  The only disadvantage is that it is inconsistent
1342 		// with all other places where the 'typename' keyword should be
1343 		// used and we don't.
1344 		// With this, the above example will demangle as
1345 		// void f<5, A>(C<sizeof (typename T::t), sizeof (T::t)>::q)
1346 		if (current() == 'N' ||	// <nested-name>
1347 					  // This should be a safe bet.
1348 		    (current() == 'S' &&
1349 		     next_peek() == 't'))	// std::something, guess that
1350 					  // this involves a typedef.
1351 		  output += "typename ";
1352 	      }
1353 	      if (!decode_type(output))
1354 		_GLIBCXX_DEMANGLER_FAILURE;
1355 	    }
1356 	    else
1357 	    {
1358 	      if (!decode_expression(output))
1359 		_GLIBCXX_DEMANGLER_FAILURE;
1360 	    }
1361 	    output += ')';
1362 	    _GLIBCXX_DEMANGLER_RETURN;
1363 	  }
1364 	  else if (current() == 'r')
1365 	  {
1366 	    eat_current();
1367 	    if (!decode_type(output))
1368 	      _GLIBCXX_DEMANGLER_FAILURE;
1369 	    output += "::";
1370 	    if (!decode_unqualified_name(output))
1371 	      _GLIBCXX_DEMANGLER_FAILURE;
1372 	    if (current() != 'I' || decode_template_args(output))
1373 	      _GLIBCXX_DEMANGLER_RETURN;
1374 	  }
1375 	}
1376 	else
1377 	{
1378 	  char opcode0 = current();
1379 	  char opcode1 = tolower(next());
1380 
1381 	  register char hash = offset_table_c[opcode0 - CHAR_MIN];
1382 	  if (hash)
1383 	  {
1384 	    hash += opcode1;
1385 	    if (
1386 #if (CHAR_MIN < 0)
1387 		hash >= 0 &&
1388 #endif
1389 		hash < 39)
1390 	    {
1391 	      int index = static_cast<int>(static_cast<unsigned char>(hash));
1392 	      entry_st entry = symbol_name_table_c[index];
1393 	      if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1394 		  && (opcode1 == current() || entry.opcode[2] == '='))
1395 	      {
1396 		char const* op = entry.symbol_name + 8;	// Skip "operator".
1397 		if (*op == ' ')				// operator new and delete.
1398 		  ++op;
1399 		if (entry.type == unary)
1400 		  output += op;
1401 		bool is_eq = (opcode1 != current());
1402 		eat_current();
1403 		if (index == 34 && M_inside_template_args)	// operator>
1404 		  output += '(';
1405 		output += '(';
1406 		if (!decode_expression(output))
1407 		  _GLIBCXX_DEMANGLER_FAILURE;
1408 		output += ')';
1409 		if (entry.type != unary)
1410 		{
1411 	          if (!M_implementation_details.get_style_compact_expr_ops())
1412 		    output += ' ';
1413 		  output += op;
1414 		  if (is_eq)
1415 		    output += '=';
1416 	          if (!M_implementation_details.get_style_compact_expr_ops())
1417 		    output += ' ';
1418 		  output += '(';
1419 		  if (!decode_expression(output))
1420 		    _GLIBCXX_DEMANGLER_FAILURE;
1421 		  output += ')';
1422 		  if (index == 34 && M_inside_template_args)
1423 		    output += ')';
1424 		  if (entry.type == trinary)
1425 		  {
1426 		    if (M_implementation_details.get_style_compact_expr_ops())
1427 		      output += ":(";
1428 		    else
1429 		      output += " : (";
1430 		    if (!decode_expression(output))
1431 		      _GLIBCXX_DEMANGLER_FAILURE;
1432 		    output += ')';
1433 		  }
1434 		}
1435 		_GLIBCXX_DEMANGLER_RETURN;
1436 	      }
1437 	      else if (opcode0 == 'c' &&
1438 	               opcode1 == 'v')		// casting operator.
1439 	      {
1440 		eat_current();
1441 		output += '(';
1442 		if (!decode_type(output))
1443 		  _GLIBCXX_DEMANGLER_FAILURE;
1444 		output += ")(";
1445 		if (!decode_expression(output))
1446 		  _GLIBCXX_DEMANGLER_FAILURE;
1447 		output += ')';
1448 		_GLIBCXX_DEMANGLER_RETURN;
1449 	      }
1450 	    }
1451 	  }
1452 	}
1453 	_GLIBCXX_DEMANGLER_FAILURE;
1454       }
1455 
1456     //
1457     // <template-args> ::= I <template-arg>+ E
1458     // <template-arg> ::= <type>			# type or template
1459     //                ::= L <type> <value number> E	# integer literal
1460     //                ::= L <type> <value float> E	# floating literal
1461     //                ::= L <mangled-name> E		# external name
1462     //                ::= X <expression> E		# expression
1463     template<typename Allocator>
1464       bool
decode_template_args(string_type & output)1465       session<Allocator>::decode_template_args(string_type& output)
1466       {
1467 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_args");
1468 	if (eat_current() != 'I')
1469 	  _GLIBCXX_DEMANGLER_FAILURE;
1470 	int prev_size = M_template_arg_pos.size();
1471 	++M_inside_template_args;
1472 	if (M_template_args_need_space)
1473 	{
1474 	  output += ' ';
1475 	  M_template_args_need_space = false;
1476 	}
1477 	output += '<';
1478 	for(;;)
1479 	{
1480 	  if (M_inside_template_args == 1 && !M_inside_type)
1481 	    M_template_arg_pos.push_back(M_pos);
1482 	  if (current() == 'X')
1483 	  {
1484 	    eat_current();
1485 	    if (!decode_expression(output))
1486 	      _GLIBCXX_DEMANGLER_FAILURE;
1487 	    if (current() != 'E')
1488 	      _GLIBCXX_DEMANGLER_FAILURE;
1489 	    eat_current();
1490 	  }
1491 	  else if (current() == 'L')
1492 	  {
1493 	    if (!decode_literal(output))
1494 	      _GLIBCXX_DEMANGLER_FAILURE;
1495 	    if (current() != 'E')
1496 	      _GLIBCXX_DEMANGLER_FAILURE;
1497 	    eat_current();
1498 	  }
1499 	  else if (!decode_type(output))
1500 	    _GLIBCXX_DEMANGLER_FAILURE;
1501 	  if (current() == 'E')
1502 	    break;
1503 	  output += ", ";
1504 	}
1505 	eat_current();
1506 	if (*(output.rbegin()) == '>')
1507 	  output += ' ';
1508 	output += '>';
1509 	--M_inside_template_args;
1510 	if (!M_inside_template_args && !M_inside_type)
1511 	{
1512 	  M_name_is_template = true;
1513 	  M_template_arg_pos_offset = prev_size;
1514 	}
1515 	_GLIBCXX_DEMANGLER_RETURN;
1516       }
1517 
1518     // <bare-function-type> ::=
1519     //   <signature type>+		# Types are parameter types.
1520     //
1521     // Note that the possible return type of the <bare-function-type>
1522     // has already been eaten before we call this function.  This makes
1523     // our <bare-function-type> slightly different from the one in
1524     // the C++-ABI description.
1525     //
1526     template<typename Allocator>
1527       bool
decode_bare_function_type(string_type & output)1528       session<Allocator>::decode_bare_function_type(string_type& output)
1529       {
1530 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_bare_function_type");
1531 	if (M_saw_destructor)
1532 	{
1533 	  if (eat_current() != 'v' || (current() != 'E' && current() != 0))
1534 	    _GLIBCXX_DEMANGLER_FAILURE;
1535 	  output += "()";
1536 	  M_saw_destructor = false;
1537 	  _GLIBCXX_DEMANGLER_RETURN;
1538 	}
1539 	if (current() == 'v' && !M_implementation_details.get_style_void())
1540 	{
1541 	  eat_current();
1542 	  if (current() != 'E' && current() != 0)
1543 	    _GLIBCXX_DEMANGLER_FAILURE;
1544 	  output += "()";
1545 	  M_saw_destructor = false;
1546 	  _GLIBCXX_DEMANGLER_RETURN;
1547 	}
1548 	output += '(';
1549 	M_template_args_need_space = false;
1550 	if (!decode_type(output))	// Must have at least one parameter.
1551 	  _GLIBCXX_DEMANGLER_FAILURE;
1552 	while (current() != 'E' && current() != 0)
1553 	{
1554 	  output += ", ";
1555 	  if (!decode_type(output))
1556 	    _GLIBCXX_DEMANGLER_FAILURE;
1557 	}
1558 	output += ')';
1559 	_GLIBCXX_DEMANGLER_RETURN;
1560       }
1561 
1562     // <type> ::=
1563     //   <builtin-type>		# Starts with a lower case character != r.
1564     //   <function-type>	# Starts with F
1565     //   <class-enum-type>	# Starts with N, S, C, D, Z, a digit or a lower
1566     //   			# case character.  Since a lower case character
1567     //   			# would be an operator name, that would be an
1568     //   			# error.  The S is a substitution or St
1569     //   			# (::std::).  A 'C' would be a constructor and
1570     //   			# thus also an error.
1571     //   <template-param>	# Starts with T
1572     //   <substitution>         # Starts with S
1573     //   <template-template-param> <template-args>  # Starts with T or S,
1574     //   					    # equivalent with the above.
1575     //
1576     //   <array-type>			# Starts with A
1577     //   <pointer-to-member-type>	# Starts with M
1578     //   <CV-qualifiers> <type>		# Starts with r, V or K
1579     //   P <type>   # pointer-to	# Starts with P
1580     //   R <type>   # reference-to	# Starts with R
1581     //   C <type>   # complex (C 2000)	# Starts with C
1582     //   G <type>   # imaginary (C 2000)# Starts with G
1583     //   U <source-name> <type>     	# vendor extended type qualifier,
1584     //   				# starts with U
1585     //
1586     // <template-template-param> ::= <template-param>
1587     //                           ::= <substitution>
1588 
1589     // My own analysis of how to decode qualifiers:
1590     //
1591     // F is a <function-type>, <T> is a <builtin-type>, <class-enum-type>,
1592     //   <template-param> or <template-template-param> <template-args>.
1593     // <Q> represents a series of qualifiers (not G or C).
1594     // <C> is an unqualified type.
1595     // <R> is a qualified type.
1596     // <B> is the bare-function-type without return type.
1597     // <I> is the array index.
1598     //						Substitutions:
1599     // <Q>M<C><Q2>F<R><B>E  ==> R (C::*Q)B Q2	"<C>", "F<R><B>E"
1600     // 						    (<R> and <B> recursive),
1601     // 						    "M<C><Q2>F<R><B>E".
1602     // <Q>F<R><B>E 	    ==> R (Q)B		"<R>", "<B>" (<B> recursive)
1603     //                                              and "F<R><B>E".
1604     //
1605     // Note that if <R> has postfix qualifiers (an array or function), then
1606     // those are added AFTER the (member) function type.  For example:
1607     // <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix
1608     // "(*" and the postfix ") []".
1609     //
1610     // <Q>G<T>     	    ==> imaginary T Q	"<T>", "G<T>" (<T> recursive).
1611     // <Q>C<T>     	    ==> complex T Q	"<T>", "C<T>" (<T> recursive).
1612     // <Q><T>      	    ==> T Q		"<T>" (<T> recursive).
1613     //
1614     // where <Q> is any of:
1615     //
1616     // <Q>P   		==> *Q				"P..."
1617     // <Q>R   		==> &Q				"R..."
1618     // <Q>[K|V|r]+	==> [ const| volatile| restrict]+Q	"KVr..."
1619     // <Q>U<S>		==>  SQ				"U<S>..."
1620     // <Q>M<C>		==> C::*Q			"M<C>..." (<C> recurs.)
1621     // A<I>		==>  [I]			"A<I>..." (<I> recurs.)
1622     // <Q>A<I>		==>  (Q) [I]			"A<I>..." (<I> recurs.)
1623     //   Note that when <Q> ends on an A<I2> then the brackets are omitted
1624     //   and no space is written between the two:
1625     //   A<I2>A<I>	==>  [I2][I]
1626     //   If <Q> ends on [KVr]+, which can happen in combination with
1627     //   substitutions only, then special handling is required, see below.
1628     //
1629     // A <substitution> is handled with an input position switch during which
1630     // new substitutions are turned off.  Because recursive handling of types
1631     // (and therefore the order in which substitutions must be generated) must
1632     // be done left to right, but the generation of Q needs processing right to
1633     // left, substitutions per <type> are generated by reading the input left
1634     // to right and marking the starts of all substitutions only - implicitly
1635     // finishing them at the end of the type.  Then the output and real
1636     // substitutions are generated.
1637     //
1638     // The following comment was for the demangling of g++ version 3.0.x.  The
1639     // mangling (and I believe even the ABI description) have been fixed now
1640     // (as of g++ version 3.1).
1641     //
1642     // g++ 3.0.x only:
1643     // The ABI specifies for pointer-to-member function types the format
1644     // <Q>M<T>F<R><B>E.  In other words, the qualifier <Q2> (see above) is
1645     // implicitely contained in <T> instead of explicitly part of the M format.
1646     // I am convinced that this is a bug in the ABI.  Unfortunately, this is
1647     // how we have to demangle things as it has a direct impact on the order
1648     // in which substitutions are stored.  This ill-formed design results in
1649     // rather ill-formed demangler code too however :/
1650     //
1651     // <Q2> is now explicitely part of the M format.
1652     // For some weird reason, g++ (3.2.1) does not add substitutions for
1653     // qualified member function pointers.  I think that is another bug.
1654     //
1655 
1656     // In the case of
1657     // <Q>A<I>
1658     // where <Q> ends on [K|V|r]+ then that part should be processed as
1659     // if it was behind the A<I> instead of in front of it.  This is
1660     // because a constant array of ints is normally always mangled as
1661     // an array of constant ints.  KVr qualifiers can end up in front
1662     // of an array when the array is part of a substitution or template
1663     // parameter, but the demangling should still result in the same
1664     // syntax; thus KA2_i (const array of ints) must result in the same
1665     // demangling as A2_Ki (array of const ints).  As a result we must
1666     // demangle ...[...[[KVr]+A<I0>][KVr]+A<I1>]...[KVr]+A<In>[KVr]+
1667     // as A<I0>A<I1>...A<In>[KVr]+ where each K, V and r in the series
1668     // collapses to a single character at the right of the string.
1669     // For example:
1670     // VA9_KrA6_KVi --> A9_A6_KVri --> int volatile const restrict [9][6]
1671     // Note that substitutions are still added as usual (the translation
1672     // to A9_A6_KVri does not really happen).
1673     //
1674     // This decoding is achieved by delaying the decoding of any sequence
1675     // of [KVrA]'s and processing them together in the order: first the
1676     // short-circuited KVr part and then the arrays.
1677     static int const cvq_K = 1;		// Saw at least one K
1678     static int const cvq_V = 2;		// Saw at least one V
1679     static int const cvq_r = 4;		// Saw at least one r
1680     static int const cvq_A = 8;		// Saw at least one A
1681     static int const cvq_last = 16;	// No remaining qualifiers.
1682     static int const cvq_A_cnt = 32;	// Bit 5 and higher represent the
1683     					//   number of A's in the series.
1684     // In the function below, iter_array points to the first (right most)
1685     // A in the series, if any.
1686     template<typename Allocator>
1687       void
decode_KVrA(string_type & prefix,string_type & postfix,int cvq,typename qual_vector::const_reverse_iterator const & iter_array)1688       qualifier_list<Allocator>::decode_KVrA(
1689           string_type& prefix, string_type& postfix, int cvq,
1690           typename qual_vector::const_reverse_iterator const& iter_array) const
1691 	{
1692 	  _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
1693 	  if ((cvq & cvq_K))
1694 	    prefix += " const";
1695 	  if ((cvq & cvq_V))
1696 	    prefix += " volatile";
1697 	  if ((cvq & cvq_r))
1698 	    prefix += " restrict";
1699 	  if ((cvq & cvq_A))
1700 	  {
1701 	    int n = cvq >> 5;
1702 	    for (typename qual_vector::
1703 	        const_reverse_iterator iter = iter_array;
1704 		iter != M_qualifier_starts.rend(); ++iter)
1705 	    {
1706 	      switch((*iter).first_qualifier())
1707 	      {
1708 		case 'K':
1709 		case 'V':
1710 		case 'r':
1711 		  break;
1712 		case 'A':
1713 		{
1714 		  string_type index = (*iter).get_optional_type();
1715 		  if (--n == 0 && (cvq & cvq_last))
1716 		    postfix = " [" + index + "]" + postfix;
1717 		  else if (n > 0)
1718 		    postfix = "[" + index + "]" + postfix;
1719 		  else
1720 		  {
1721 		    prefix += " (";
1722 		    postfix = ") [" + index + "]" + postfix;
1723 		  }
1724 		  break;
1725 		}
1726 		default:
1727 		  _GLIBCXX_DEMANGLER_RETURN3;
1728 	      }
1729 	    }
1730 	  }
1731 	  _GLIBCXX_DEMANGLER_RETURN3;
1732 	}
1733 
1734     template<typename Allocator>
1735       void
decode_qualifiers(string_type & prefix,string_type & postfix,bool member_function_pointer_qualifiers)1736       qualifier_list<Allocator>::decode_qualifiers(
1737 	  string_type& prefix,
1738 	  string_type& postfix,
1739 	  bool member_function_pointer_qualifiers) const
1740       {
1741 	_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
1742 	int cvq = 0;
1743 	typename qual_vector::const_reverse_iterator iter_array;
1744 	for(typename qual_vector::
1745 	    const_reverse_iterator iter = M_qualifier_starts.rbegin();
1746 	    iter != M_qualifier_starts.rend(); ++iter)
1747 	{
1748 	  if (!member_function_pointer_qualifiers
1749 	      && !(*iter).part_of_substitution())
1750 	  {
1751 	    int saved_inside_substitution = M_demangler.M_inside_substitution;
1752 	    M_demangler.M_inside_substitution = 0;
1753 	    M_demangler.add_substitution((*iter).get_start_pos(), type);
1754 	    M_demangler.M_inside_substitution = saved_inside_substitution;
1755 	  }
1756 	  char qualifier_char = (*iter).first_qualifier();
1757 	  for(; qualifier_char; qualifier_char = (*iter).next_qualifier())
1758 	  {
1759 	    switch(qualifier_char)
1760 	    {
1761 	      case 'P':
1762 		if (cvq)
1763 		{
1764 		  decode_KVrA(prefix, postfix, cvq, iter_array);
1765 		  cvq = 0;
1766 		}
1767 		prefix += "*";
1768 		break;
1769 	      case 'R':
1770 		if (cvq)
1771 		{
1772 		  decode_KVrA(prefix, postfix, cvq, iter_array);
1773 		  cvq = 0;
1774 		}
1775 		prefix += "&";
1776 		break;
1777 	      case 'K':
1778 		cvq |= cvq_K;
1779 		continue;
1780 	      case 'V':
1781 		cvq |= cvq_V;
1782 		continue;
1783 	      case 'r':
1784 		cvq |= cvq_r;
1785 		continue;
1786 	      case 'A':
1787 	        if (!(cvq & cvq_A))
1788 		{
1789 		  cvq |= cvq_A;
1790 		  iter_array = iter;
1791 		}
1792 		cvq += cvq_A_cnt;
1793 		break;
1794 	      case 'M':
1795 	        if (cvq)
1796 		{
1797 		  decode_KVrA(prefix, postfix, cvq, iter_array);
1798 		  cvq = 0;
1799 		}
1800 		prefix += " ";
1801 		prefix += (*iter).get_optional_type();
1802 		prefix += "::*";
1803 		break;
1804 	      case 'U':
1805 	        if (cvq)
1806 		{
1807 		  decode_KVrA(prefix, postfix, cvq, iter_array);
1808 		  cvq = 0;
1809 		}
1810 		prefix += " ";
1811 		prefix += (*iter).get_optional_type();
1812 		break;
1813 	      case 'G':	// Only here so we added a substitution.
1814 		break;
1815 	    }
1816 	    break;
1817 	  }
1818 	}
1819 	if (cvq)
1820 	  decode_KVrA(prefix, postfix, cvq|cvq_last, iter_array);
1821 	M_printing_suppressed = false;
1822 	_GLIBCXX_DEMANGLER_RETURN3;
1823       }
1824 
1825     //
1826     template<typename Allocator>
1827       bool
decode_type_with_postfix(string_type & prefix,string_type & postfix,qualifier_list<Allocator> * qualifiers)1828       session<Allocator>::decode_type_with_postfix(
1829 	  string_type& prefix, string_type& postfix,
1830 	  qualifier_list<Allocator>* qualifiers)
1831       {
1832 	_GLIBCXX_DEMANGLER_DOUT_ENTERING2("decode_type");
1833 	++M_inside_type;
1834 	bool recursive_template_param_or_substitution_call;
1835 	if (!(recursive_template_param_or_substitution_call = qualifiers))
1836 	    qualifiers = new qualifier_list<Allocator>(*this);
1837 	// First eat all qualifiers.
1838 	bool failure = false;
1839 	for(;;)		// So we can use 'continue' to eat the next qualifier.
1840 	{
1841 	  int start_pos = M_pos;
1842 	  switch(current())
1843 	  {
1844 	    case 'P':
1845 	      qualifiers->add_qualifier_start(pointer, start_pos,
1846 		  M_inside_substitution);
1847 	      eat_current();
1848 	      continue;
1849 	    case 'R':
1850 	      qualifiers->add_qualifier_start(reference, start_pos,
1851 		  M_inside_substitution);
1852 	      eat_current();
1853 	      continue;
1854 	    case 'K':
1855 	    case 'V':
1856 	    case 'r':
1857 	    {
1858 	      char c;
1859 	      int count = 0;
1860 	      do
1861 	      {
1862 		++count;
1863 		c = next();
1864 	      }
1865 	      while(c == 'K' || c == 'V' || c == 'r');
1866 	      qualifiers->add_qualifier_start(cv_qualifier, start_pos, count,
1867 		  M_inside_substitution);
1868 	      continue;
1869 	    }
1870 	    case 'U':
1871 	    {
1872 	      eat_current();
1873 	      string_type source_name;
1874 	      if (!decode_source_name(source_name))
1875 	      {
1876 		failure = true;
1877 		break;
1878 	      }
1879 	      qualifiers->add_qualifier_start(vendor_extension, start_pos,
1880 		  source_name, M_inside_substitution);
1881 	      continue;
1882 	    }
1883 	    case 'A':
1884 	    {
1885 	      // <array-type> ::= A <positive dimension number> _ <element type>
1886 	      //              ::= A [<dimension expression>] _ <element type>
1887 	      //
1888 	      string_type index;
1889 	      int saved_pos;
1890 	      store(saved_pos);
1891 	      if (next() == 'n' || !decode_number(index))
1892 	      {
1893 		restore(saved_pos);
1894 		if (next() != '_' && !decode_expression(index))
1895 		{
1896 		  failure = true;
1897 		  break;
1898 		}
1899 	      }
1900 	      if (eat_current() != '_')
1901 	      {
1902 		failure = true;
1903 		break;
1904 	      }
1905 	      qualifiers->add_qualifier_start(array, start_pos, index,
1906 		  M_inside_substitution);
1907 	      continue;
1908 	    }
1909 	    case 'M':
1910 	    {
1911 	      // <pointer-to-member-type> ::= M <class type> <member type>
1912 	      // <Q>M<C> or <Q>M<C><Q2>F<R><B>E
1913 	      eat_current();
1914 	      string_type class_type;
1915 	      if (!decode_type(class_type))		// Substitution: "<C>".
1916 	      {
1917 		failure = true;
1918 		break;
1919 	      }
1920 	      char c = current();
1921 	      if (c == 'F' || c == 'K' || c == 'V' || c == 'r')
1922 		  // Must be CV-qualifiers and a member function pointer.
1923 	      {
1924 		// <Q>M<C><Q2>F<R><B>E	==> R (C::*Q)B Q2
1925 		//     substitutions: "<C>", "F<R><B>E" (<R> and <B>
1926 		//                    recursive), "M<C><Q2>F<R><B>E".
1927 		int count = 0;
1928 		int Q2_start_pos = M_pos;
1929 		while(c == 'K' || c == 'V' || c == 'r')		// Decode <Q2>.
1930 		{
1931 		  ++count;
1932 		  c = next();
1933 		}
1934 		qualifier_list<Allocator> class_type_qualifiers(*this);
1935 		if (count)
1936 		  class_type_qualifiers.
1937 		      add_qualifier_start(cv_qualifier, Q2_start_pos,
1938 			  count, M_inside_substitution);
1939 		string_type member_function_qualifiers;
1940 		// It is unclear why g++ doesn't add a substitution for
1941 		// "<Q2>F<R><B>E" as it should I think.
1942 		string_type member_function_qualifiers_postfix;
1943 		class_type_qualifiers.
1944 		    decode_qualifiers(member_function_qualifiers,
1945 			member_function_qualifiers_postfix, true);
1946 		member_function_qualifiers +=
1947 		    member_function_qualifiers_postfix;
1948 		// I don't think this substitution is actually ever used.
1949 		int function_pos = M_pos;
1950 		if (eat_current() != 'F')
1951 		{
1952 		  failure = true;
1953 		  break;
1954 		}
1955 		// Return type.
1956 		// Constructors, destructors and conversion operators don't
1957 		// have a return type, but seem to never get here.
1958 		string_type return_type_postfix;
1959 		if (!decode_type_with_postfix(prefix, return_type_postfix))
1960 		    // substitution: <R> recursive
1961 		{
1962 		  failure = true;
1963 		  break;
1964 		}
1965 		prefix += " (";
1966 		prefix += class_type;
1967 		prefix += "::*";
1968 		string_type bare_function_type;
1969 		if (!decode_bare_function_type(bare_function_type)
1970 		    || eat_current() != 'E')	// Substitution: <B> recursive.
1971 		{
1972 		  failure = true;
1973 		  break;
1974 		}
1975 		// substitution: "F<R><B>E".
1976 		add_substitution(function_pos, type);
1977 		// substitution: "M<C><Q2>F<R><B>E".
1978 		add_substitution(start_pos, type);
1979 		// substitution: all qualified types if any.
1980 		qualifiers->decode_qualifiers(prefix, postfix);
1981 		postfix += ")";
1982 		postfix += bare_function_type;
1983 		postfix += member_function_qualifiers;
1984 		postfix += return_type_postfix;
1985 		goto decode_type_exit;
1986 	      }
1987 	      qualifiers->add_qualifier_start(pointer_to_member, start_pos,
1988 		  class_type, M_inside_substitution);
1989 	      continue;
1990 	    }
1991 	    default:
1992 	      break;
1993 	  }
1994 	  break;
1995 	}
1996 	if (!failure)
1997 	{
1998 	  // <Q>G<T>     		==> imaginary T Q
1999 	  //     substitutions: "<T>", "G<T>" (<T> recursive).
2000 	  // <Q>C<T>     		==> complex T Q
2001 	  //     substitutions: "<T>", "C<T>" (<T> recursive).
2002 	  if (current() == 'C' || current() == 'G')
2003 	  {
2004 	    prefix += current() == 'C' ? "complex " : "imaginary ";
2005 	    qualifiers->add_qualifier_start(complex_or_imaginary, M_pos,
2006 		M_inside_substitution);
2007 	    eat_current();
2008 	  }
2009 	  int start_pos = M_pos;
2010 	  switch(current())
2011 	  {
2012 	    case 'F':
2013 	    {
2014 	      // <function-type> ::= F [Y] <bare-function-type> E
2015 	      //
2016 	      // Note that g++ never generates the 'Y', but we try to
2017 	      // demangle it anyway.
2018 	      bool extern_C = (next() == 'Y');
2019 	      if (extern_C)
2020 		eat_current();
2021 
2022 	      // <Q>F<R><B>E 		==> R (Q)B
2023 	      //     substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E".
2024 
2025 	      // Return type.
2026 	      string_type return_type_postfix;
2027 	      if (!decode_type_with_postfix(prefix, return_type_postfix))
2028 		  // Substitution: "<R>".
2029 	      {
2030 		failure = true;
2031 		break;
2032 	      }
2033 	      // Only array and function (pointer) types have a postfix.
2034 	      // In that case we don't want the space but expect something
2035 	      // like prefix is "int (*" and postfix is ") [1]".
2036 	      // We do want the space if this pointer is qualified.
2037 	      if (return_type_postfix.size() == 0 ||
2038 	          (prefix.size() > 0 && *prefix.rbegin() != '*'))
2039 		prefix += ' ';
2040 	      prefix += '(';
2041 	      string_type bare_function_type;
2042 	      if (!decode_bare_function_type(bare_function_type)
2043 		  // substitution: "<B>" (<B> recursive).
2044 		  || eat_current() != 'E')
2045 	      {
2046 		failure = true;
2047 		break;
2048 	      }
2049 	      add_substitution(start_pos, type);  // Substitution: "F<R><B>E".
2050 	      qualifiers->decode_qualifiers(prefix, postfix);
2051 		  // substitution: all qualified types, if any.
2052 	      postfix += ")";
2053 	      if (extern_C)
2054 	        postfix += " [extern \"C\"] ";
2055 	      postfix += bare_function_type;
2056 	      postfix += return_type_postfix;
2057 	      break;
2058 	    }
2059 	    case 'T':
2060 	      if (!decode_template_param(prefix, qualifiers))
2061 	      {
2062 		failure = true;
2063 		break;
2064 	      }
2065 	      if (current() == 'I')
2066 	      {
2067 		add_substitution(start_pos, template_template_param);
2068 		    // substitution: "<template-template-param>".
2069 		if (!decode_template_args(prefix))
2070 		{
2071 		  failure = true;
2072 		  break;
2073 		}
2074 	      }
2075 	      if (!recursive_template_param_or_substitution_call
2076 		  && qualifiers->suppressed())
2077 	      {
2078 		add_substitution(start_pos, type);
2079 		    // substitution: "<template-param>" or
2080 		    // "<template-template-param> <template-args>".
2081 		qualifiers->decode_qualifiers(prefix, postfix);
2082 		    // substitution: all qualified types, if any.
2083 	      }
2084 	      break;
2085 	    case 'S':
2086 	      if (M_pos >= M_maxpos)
2087 	      {
2088 		failure = true;
2089 		break;
2090 	      }
2091 	      if (M_str[M_pos + 1] != 't')
2092 	      {
2093 		if (!decode_substitution(prefix, qualifiers))
2094 		{
2095 		  failure = true;
2096 		  break;
2097 		}
2098 		if (current() == 'I')
2099 		{
2100 		  if (!decode_template_args(prefix))
2101 		  {
2102 		    failure = true;
2103 		    break;
2104 		  }
2105 		  if (!recursive_template_param_or_substitution_call
2106 		      && qualifiers->suppressed())
2107 		    add_substitution(start_pos, type);
2108 			// Substitution:
2109 			//   "<template-template-param> <template-args>".
2110 		}
2111 		if (!recursive_template_param_or_substitution_call
2112 		    && qualifiers->suppressed())
2113 		  qualifiers->decode_qualifiers(prefix, postfix);
2114 		      // Substitution: all qualified types, if any.
2115 		break;
2116 	      }
2117 	      /* Fall-through for St */
2118 	    case 'N':
2119 	    case 'Z':
2120 	    case '0':
2121 	    case '1':
2122 	    case '2':
2123 	    case '3':
2124 	    case '4':
2125 	    case '5':
2126 	    case '6':
2127 	    case '7':
2128 	    case '8':
2129 	    case '9':
2130 	      // <Q><T>      		==> T Q
2131 	      //     substitutions: "<T>" (<T> recursive).
2132 	      if (!decode_class_enum_type(prefix))
2133 	      {
2134 		failure = true;
2135 		break;
2136 	      }
2137 	      if (!recursive_template_param_or_substitution_call)
2138 	      {
2139 		add_substitution(start_pos, type);
2140 		    // substitution: "<class-enum-type>".
2141 		qualifiers->decode_qualifiers(prefix, postfix);
2142 		    // substitution: all qualified types, if any.
2143 	      }
2144 	      else
2145 		qualifiers->printing_suppressed();
2146 	      break;
2147 	    default:
2148 	      // <Q><T>      		==> T Q
2149 	      //     substitutions: "<T>" (<T> recursive).
2150 	      if (!decode_builtin_type(prefix))
2151 	      {
2152 		failure = true;
2153 		break;
2154 	      }
2155 	      // If decode_type was called from decode_template_param then we
2156 	      // need to suppress calling qualifiers here in order to get a
2157 	      // substitution added anyway (for the <template-param>).
2158 	      if (!recursive_template_param_or_substitution_call)
2159 		qualifiers->decode_qualifiers(prefix, postfix);
2160 	      else
2161 		qualifiers->printing_suppressed();
2162 	      break;
2163 	  }
2164 	}
2165     decode_type_exit:
2166 	--M_inside_type;
2167 	if (!recursive_template_param_or_substitution_call)
2168 	  delete qualifiers;
2169 	if (failure)
2170 	  _GLIBCXX_DEMANGLER_FAILURE;
2171 	_GLIBCXX_DEMANGLER_RETURN2;
2172       }
2173 
2174     // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
2175     //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
2176     //
2177     // <prefix> ::= <prefix> <unqualified-name>
2178     //          ::= <template-prefix> <template-args>
2179     //          ::= <template-param>
2180     //          ::= # empty
2181     //          ::= <substitution>
2182     //
2183     // <template-prefix> ::= <prefix> <template unqualified-name>
2184     //                   ::= <template-param>
2185     //                   ::= <substitution>
2186     //
2187     template<typename Allocator>
2188       bool
decode_nested_name(string_type & output,string_type & qualifiers)2189       session<Allocator>::decode_nested_name(string_type& output,
2190 					     string_type& qualifiers)
2191       {
2192 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_nested_name");
2193 
2194 	if (current() != 'N' || M_pos >= M_maxpos)
2195 	  _GLIBCXX_DEMANGLER_FAILURE;
2196 
2197 	// <CV-qualifiers> ::= [r] [V] [K]  # restrict (C99), volatile, const
2198 	char const* qualifiers_start = &M_str[M_pos + 1];
2199 	for (char c = next(); c == 'K' || c == 'V' || c == 'r'; c = next()) ;
2200 	for (char const* qualifier_ptr = &M_str[M_pos - 1];
2201 	     qualifier_ptr >= qualifiers_start; --qualifier_ptr)
2202 	  switch(*qualifier_ptr)
2203 	  {
2204 	    case 'K':
2205 	      qualifiers += " const";
2206 	      break;
2207 	    case 'V':
2208 	      qualifiers += " volatile";
2209 	      break;
2210 	    case 'r':
2211 	      qualifiers += " restrict";
2212 	      break;
2213 	  }
2214 
2215 	int number_of_prefixes = 0;
2216 	int substitution_start = M_pos;
2217 	for(;;)
2218 	{
2219 	  ++number_of_prefixes;
2220 	  if (current() == 'S')
2221 	  {
2222 	    if (!decode_substitution(output))
2223 	      _GLIBCXX_DEMANGLER_FAILURE;
2224 	  }
2225 	  else if (current() == 'I')
2226 	  {
2227 	    if (!decode_template_args(output))
2228 	      _GLIBCXX_DEMANGLER_FAILURE;
2229 	    if (current() != 'E')
2230 	    {
2231 	      // substitution: "<template-prefix> <template-args>".
2232 	      add_substitution(substitution_start, nested_name_prefix,
2233 		  	       number_of_prefixes);
2234 	    }
2235 	  }
2236 	  else
2237 	  {
2238 	    if (current() == 'T')
2239 	    {
2240 	      if (!decode_template_param(output))
2241 		_GLIBCXX_DEMANGLER_FAILURE;
2242 	    }
2243 	    else if (!decode_unqualified_name(output))
2244 	      _GLIBCXX_DEMANGLER_FAILURE;
2245 	    if (current() != 'E')
2246 	    {
2247 	      // substitution: "<prefix> <unqualified-name>" or
2248 	      // "<prefix> <template unqualified-name>".
2249 	      add_substitution(substitution_start,
2250 		  (current() == 'I') ?  nested_name_template_prefix
2251 		                     : nested_name_prefix,
2252 		  number_of_prefixes);
2253 	    }
2254 	  }
2255 	  if (current() == 'E')
2256 	  {
2257 	    eat_current();
2258 	    _GLIBCXX_DEMANGLER_RETURN;
2259 	  }
2260 	  if (current() != 'I')
2261 	    output += "::";
2262 	  else if (M_template_args_need_space)
2263 	    output += ' ';
2264 	  M_template_args_need_space = false;
2265 	}
2266 	_GLIBCXX_DEMANGLER_FAILURE;
2267       }
2268 
2269     // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2270     //              := Z <function encoding> E s [<discriminator>]
2271     // <discriminator> := _ <non-negative number>
2272     //
2273     template<typename Allocator>
2274       bool
decode_local_name(string_type & output)2275       session<Allocator>::decode_local_name(string_type& output)
2276       {
2277 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_local_name");
2278 	if (current() != 'Z' || M_pos >= M_maxpos)
2279 	  _GLIBCXX_DEMANGLER_FAILURE;
2280 	if ((M_pos += decode_encoding(output, M_str + M_pos + 1,
2281 		M_maxpos - M_pos, M_implementation_details) + 1) < 0 ||
2282 		eat_current() != 'E')
2283 	  _GLIBCXX_DEMANGLER_FAILURE;
2284 	output += "::";
2285 	if (current() == 's')
2286 	{
2287 	  eat_current();
2288 	  output += "string literal";
2289 	}
2290 	else
2291 	{
2292 	  string_type nested_name_qualifiers;
2293 	  if (!decode_name(output, nested_name_qualifiers))
2294 	    _GLIBCXX_DEMANGLER_FAILURE;
2295 	  output += nested_name_qualifiers;
2296 	}
2297 	string_type discriminator;
2298 	if (current() == '_' && next() != 'n' && !decode_number(discriminator))
2299 	  _GLIBCXX_DEMANGLER_FAILURE;
2300 	_GLIBCXX_DEMANGLER_RETURN;
2301       }
2302 
2303     // <source-name> ::= <positive length number> <identifier>
2304     //
2305     template<typename Allocator>
2306       bool
decode_source_name(string_type & output)2307       session<Allocator>::decode_source_name(string_type& output)
2308       {
2309 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_source_name");
2310 	int length = current() - '0';
2311 	if (length < 1 || length > 9)
2312 	  _GLIBCXX_DEMANGLER_FAILURE;
2313 	while(isdigit(next()))
2314 	  length = 10 * length + current() - '0';
2315 	char const* ptr = &M_str[M_pos];
2316 	if (length > 11 && !strncmp(ptr, "_GLOBAL_", 8) && ptr[9] == 'N'
2317 	    && ptr[8] == ptr[10])
2318 	{
2319 	  output += "(anonymous namespace)";
2320 	  if ((M_pos += length) > M_maxpos + 1)
2321 	    _GLIBCXX_DEMANGLER_FAILURE;
2322 	}
2323 	else
2324 	  while(length--)
2325 	  {
2326 	    if (current() == 0)
2327 	      _GLIBCXX_DEMANGLER_FAILURE;
2328 	    output += eat_current();
2329 	  }
2330 	_GLIBCXX_DEMANGLER_RETURN;
2331       }
2332 
2333     // <unqualified-name> ::= <operator-name>	# Starts with lower case.
2334     //                    ::= <ctor-dtor-name>  # Starts with 'C' or 'D'.
2335     //                    ::= <source-name>   	# Starts with a digit.
2336     //
2337     template<typename Allocator>
2338       bool
decode_unqualified_name(string_type & output)2339       session<Allocator>::decode_unqualified_name(string_type& output)
2340       {
2341 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unqualified_name");
2342 	if (M_inside_template_args)
2343 	{
2344 	  if (!decode_source_name(output))
2345 	    _GLIBCXX_DEMANGLER_FAILURE;
2346 	}
2347 	else if (isdigit(current()))
2348 	{
2349 	  bool recursive_unqualified_name = (&M_function_name == &output);
2350 	  // This can be a recursive call when we are decoding
2351 	  // an <operator-name> that is a cast operator for a some
2352 	  // <unqualified-name>; for example "operator Foo()".
2353 	  // In that case this is thus not a ctor or dtor and we
2354 	  // are not interested in updating M_function_name.
2355 	  if (!recursive_unqualified_name)
2356 	    M_function_name.clear();
2357 	  M_name_is_template = false;
2358 	  M_name_is_cdtor = false;
2359 	  M_name_is_conversion_operator = false;
2360 	  if (!decode_source_name(M_function_name))
2361 	    _GLIBCXX_DEMANGLER_FAILURE;
2362 	  if (!recursive_unqualified_name)
2363 	    output += M_function_name;
2364 	}
2365 	else if (islower(current()))
2366 	{
2367 	  M_function_name.clear();
2368 	  M_name_is_template = false;
2369 	  M_name_is_cdtor = false;
2370 	  M_name_is_conversion_operator = false;
2371 	  if (!decode_operator_name(M_function_name))
2372 	    _GLIBCXX_DEMANGLER_FAILURE;
2373 	  output += M_function_name;
2374 	}
2375 	else if (current() == 'C' || current() == 'D')
2376 	{
2377 	  // <ctor-dtor-name> ::=
2378 	  //   C1	# complete object (in-charge) constructor
2379 	  //   C2	# base object (not-in-charge) constructor
2380 	  //   C3	# complete object (in-charge) allocating constructor
2381 	  //   D0	# deleting (in-charge) destructor
2382 	  //   D1	# complete object (in-charge) destructor
2383 	  //   D2	# base object (not-in-charge) destructor
2384 	  //
2385 	  if (current() == 'C')
2386 	  {
2387 	    char c = next();
2388 	    if (c < '1' || c > '3')
2389 	      _GLIBCXX_DEMANGLER_FAILURE;
2390 	  }
2391 	  else
2392 	  {
2393 	    char c = next();
2394 	    if (c < '0' || c > '2')
2395 	      _GLIBCXX_DEMANGLER_FAILURE;
2396 	    output += '~';
2397 	    M_saw_destructor = true;
2398 	  }
2399 	  M_name_is_cdtor = true;
2400 	  eat_current();
2401 	  output += M_function_name;
2402 	}
2403 	else
2404 	  _GLIBCXX_DEMANGLER_FAILURE;
2405 	_GLIBCXX_DEMANGLER_RETURN;
2406       }
2407 
2408     // <unscoped-name> ::=
2409     //   <unqualified-name>		# Starts not with an 'S'
2410     //   St <unqualified-name>		# ::std::
2411     //
2412     template<typename Allocator>
2413       bool
decode_unscoped_name(string_type & output)2414       session<Allocator>::decode_unscoped_name(string_type& output)
2415       {
2416 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unscoped_name");
2417 	if (current() == 'S')
2418 	{
2419 	  if (next() != 't')
2420 	    _GLIBCXX_DEMANGLER_FAILURE;
2421 	  eat_current();
2422 	  output += "std::";
2423 	}
2424 	decode_unqualified_name(output);
2425 	_GLIBCXX_DEMANGLER_RETURN;
2426       }
2427 
2428     // <name> ::=
2429     //   <nested-name>				# Starts with 'N'
2430     //   <unscoped-template-name> <template-args> # idem
2431     //   <local-name>				# Starts with 'Z'
2432     //   <unscoped-name>			# Starts with 'S', 'C', 'D',
2433     //   					# a digit or a lower case
2434     //   					# character.
2435     //
2436     // <unscoped-template-name> ::= <unscoped-name>
2437     //                          ::= <substitution>
2438     template<typename Allocator>
2439       bool
decode_name(string_type & output,string_type & nested_name_qualifiers)2440       session<Allocator>::decode_name(string_type& output,
2441 				      string_type& nested_name_qualifiers)
2442       {
2443 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_name");
2444 	int substitution_start = M_pos;
2445 	if (current() == 'S' && (M_pos >= M_maxpos || M_str[M_pos + 1] != 't'))
2446 	{
2447 	  if (!decode_substitution(output))
2448 	    _GLIBCXX_DEMANGLER_FAILURE;
2449 	}
2450 	else if (current() == 'N')
2451 	{
2452 	  decode_nested_name(output, nested_name_qualifiers);
2453 	  _GLIBCXX_DEMANGLER_RETURN;
2454 	}
2455 	else if (current() == 'Z')
2456 	{
2457 	  decode_local_name(output);
2458 	  _GLIBCXX_DEMANGLER_RETURN;
2459 	}
2460 	else if (!decode_unscoped_name(output))
2461 	  _GLIBCXX_DEMANGLER_FAILURE;
2462 	if (current() == 'I')
2463 	{
2464 	  // Must have been an <unscoped-template-name>.
2465 	  add_substitution(substitution_start, unscoped_template_name);
2466 	  if (!decode_template_args(output))
2467 	    _GLIBCXX_DEMANGLER_FAILURE;
2468 	}
2469 	M_template_args_need_space = false;
2470 	_GLIBCXX_DEMANGLER_RETURN;
2471       }
2472 
2473     // <call-offset> ::= h <nv-offset> _
2474     //               ::= v <v-offset> _
2475     // <nv-offset>   ::= <offset number>
2476     //     non-virtual base override
2477     //
2478     // <v-offset>    ::= <offset number> _ <virtual offset number>
2479     //     virtual base override, with vcall offset
2480     template<typename Allocator>
2481       bool
decode_call_offset(string_type & output)2482       session<Allocator>::decode_call_offset(string_type&
2483 #if _GLIBCXX_DEMANGLER_CWDEBUG
2484 	  output
2485 #endif
2486 	  )
2487       {
2488 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_call_offset");
2489 	if (current() == 'h')
2490 	{
2491 	  string_type dummy;
2492 	  eat_current();
2493 	  if (decode_number(dummy) && current() == '_')
2494 	  {
2495 	    eat_current();
2496 	    _GLIBCXX_DEMANGLER_RETURN;
2497 	  }
2498 	}
2499 	else if (current() == 'v')
2500 	{
2501 	  string_type dummy;
2502 	  eat_current();
2503 	  if (decode_number(dummy) && current() == '_')
2504 	  {
2505 	    eat_current();
2506 	    if (decode_number(dummy) && current() == '_')
2507 	    {
2508 	      eat_current();
2509 	      _GLIBCXX_DEMANGLER_RETURN;
2510 	    }
2511 	  }
2512 	}
2513 	_GLIBCXX_DEMANGLER_FAILURE;
2514       }
2515 
2516     //
2517     // <special-name> ::=
2518     //   TV <type>			# virtual table
2519     //   TT <type>			# VTT structure (construction
2520     //                                    vtable index).
2521     //   TI <type>			# typeinfo structure
2522     //   TS <type>			# typeinfo name (null-terminated
2523     //                                    byte string).
2524     //   GV <object name>		# Guard variable for one-time
2525     //   				  initialization of static objects in
2526     //   				  a local scope.
2527     //   T <call-offset> <base encoding># base is the nominal target function
2528     //   				  of thunk.
2529     //   Tc <call-offset> <call-offset> <base encoding> # base is the nominal
2530     //                                    target function of thunk; first
2531     //                                    call-offset is 'this' adjustment;
2532     //					  second call-offset is result
2533     //					  adjustment
2534     //
2535     template<typename Allocator>
2536       bool
decode_special_name(string_type & output)2537       session<Allocator>::decode_special_name(string_type& output)
2538       {
2539 	_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_special_name");
2540 	if (current() == 'G')
2541 	{
2542 	  if (next() != 'V')
2543 	    _GLIBCXX_DEMANGLER_FAILURE;
2544 	  output += "guard variable for ";
2545 	  string_type nested_name_qualifiers;
2546 	  eat_current();
2547 	  if (!decode_name(output, nested_name_qualifiers))
2548 	    _GLIBCXX_DEMANGLER_FAILURE;
2549 	  output += nested_name_qualifiers;
2550 	  _GLIBCXX_DEMANGLER_RETURN;
2551 	}
2552 	else if (current() != 'T')
2553 	  _GLIBCXX_DEMANGLER_FAILURE;
2554 	switch(next())
2555 	{
2556 	  case 'V':
2557 	    output += "vtable for ";
2558 	    eat_current();
2559 	    decode_type(output);
2560 	    _GLIBCXX_DEMANGLER_RETURN;
2561 	  case 'T':
2562 	    output += "VTT for ";
2563 	    eat_current();
2564 	    decode_type(output);
2565 	    _GLIBCXX_DEMANGLER_RETURN;
2566 	  case 'I':
2567 	    output += "typeinfo for ";
2568 	    eat_current();
2569 	    decode_type(output);
2570 	    _GLIBCXX_DEMANGLER_RETURN;
2571 	  case 'S':
2572 	    output += "typeinfo name for ";
2573 	    eat_current();
2574 	    decode_type(output);
2575 	    _GLIBCXX_DEMANGLER_RETURN;
2576 	  case 'c':
2577 	    output += "covariant return thunk to ";
2578 	    if (!decode_call_offset(output)
2579 		|| !decode_call_offset(output)
2580 		|| (M_pos += decode_encoding(output, M_str + M_pos,
2581 		    M_maxpos - M_pos + 1, M_implementation_details)) < 0)
2582 	      _GLIBCXX_DEMANGLER_FAILURE;
2583 	    _GLIBCXX_DEMANGLER_RETURN;
2584 	  case 'C':		// GNU extension?
2585 	  {
2586 	    string_type first;
2587 	    output += "construction vtable for ";
2588 	    eat_current();
2589 	    if (!decode_type(first))
2590 	      _GLIBCXX_DEMANGLER_FAILURE;
2591 	    while(isdigit(current()))
2592 	      eat_current();
2593 	    if (eat_current() != '_')
2594 	      _GLIBCXX_DEMANGLER_FAILURE;
2595 	    if (!decode_type(output))
2596 	      _GLIBCXX_DEMANGLER_FAILURE;
2597 	    output += "-in-";
2598 	    output += first;
2599 	    _GLIBCXX_DEMANGLER_RETURN;
2600 	  }
2601 	  default:
2602 	    if (current() == 'v')
2603 	      output += "virtual thunk to ";
2604 	    else
2605 	      output += "non-virtual thunk to ";
2606 	    if (!decode_call_offset(output)
2607 		|| (M_pos += decode_encoding(output, M_str + M_pos,
2608 		    M_maxpos - M_pos + 1, M_implementation_details)) < 0)
2609 	      _GLIBCXX_DEMANGLER_FAILURE;
2610 	    _GLIBCXX_DEMANGLER_RETURN;
2611 	}
2612       }
2613 
2614     // <encoding> ::=
2615     //   <function name> <bare-function-type>	# Starts with 'C', 'D', 'N',
2616     //                                        	  'S', a digit or a lower case
2617     //                                        	  character.
2618     //   <data name>				# Idem.
2619     //   <special-name>				# Starts with 'T' or 'G'.
2620     template<typename Allocator>
2621       int
decode_encoding(string_type & output,char const * in,int len,implementation_details const & id)2622       session<Allocator>::decode_encoding(string_type& output,
2623           char const* in, int len, implementation_details const& id)
2624       {
2625 #if _GLIBCXX_DEMANGLER_CWDEBUG
2626 	_GLIBCXX_DEMANGLER_DOUT(dc::demangler,
2627 	    "Output thus far: \"" << output << '"');
2628 	string_type input(in, len > 0x40000000 ? strlen(in) : len);
2629 	_GLIBCXX_DEMANGLER_DOUT(
2630 	    dc::demangler, "Entering decode_encoding(\"" << input << "\")");
2631 #endif
2632 	if (len <= 0)
2633 	  return INT_MIN;
2634 	session<Allocator> demangler_session(in, len, id);
2635 	string_type nested_name_qualifiers;
2636 	int saved_pos;
2637 	demangler_session.store(saved_pos);
2638 	if (demangler_session.decode_special_name(output))
2639 	  return demangler_session.M_pos;
2640 	demangler_session.restore(saved_pos);
2641 	string_type name;
2642 	if (!demangler_session.decode_name(name, nested_name_qualifiers))
2643 	  return INT_MIN;
2644 	if (demangler_session.current() == 0
2645 	    || demangler_session.current() == 'E')
2646 	{
2647 	  output += name;
2648 	  output += nested_name_qualifiers;
2649 	  return demangler_session.M_pos;
2650 	}
2651 	// Must have been a <function name>.
2652 	string_type return_type_postfix;
2653 	if (demangler_session.M_name_is_template
2654 	    && !(demangler_session.M_name_is_cdtor
2655 	         || demangler_session.M_name_is_conversion_operator))
2656 	{
2657 	  // Return type of function
2658 	  if (!demangler_session.decode_type_with_postfix(output,
2659 	      return_type_postfix))
2660 	    return INT_MIN;
2661 	  output += ' ';
2662 	}
2663 	output += name;
2664 	if (!demangler_session.decode_bare_function_type(output))
2665 	  return INT_MIN;
2666 	output += nested_name_qualifiers;
2667 	output += return_type_postfix;
2668 	return demangler_session.M_pos;
2669       }
2670 
2671     } // namespace demangler
2672 
2673   // Public interface
2674   template<typename Allocator>
2675     struct demangle
2676     {
2677       typedef typename Allocator::template rebind<char>::other char_Allocator;
2678       typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
2679 	  string_type;
2680       static string_type symbol(char const* in,
2681                                 demangler::implementation_details const& id);
2682       static string_type type(char const* in,
2683                               demangler::implementation_details const& id);
2684     };
2685 
2686   // demangle::symbol()
2687   //
2688   // Demangle `input' which should be a mangled function name as for
2689   // instance returned by nm(1).
2690   template<typename Allocator>
2691     typename demangle<Allocator>::string_type
symbol(char const * input,demangler::implementation_details const & id)2692     demangle<Allocator>::symbol(char const* input,
2693                                 demangler::implementation_details const& id)
2694     {
2695       // <mangled-name> ::= _Z <encoding>
2696       // <mangled-name> ::= _GLOBAL_ _<type>_ <disambiguation part>
2697       //                    <type> can be I or D (GNU extension)
2698       typedef demangler::session<Allocator> demangler_type;
2699       string_type result;
2700       bool failure = (input[0] != '_');
2701 
2702       if (!failure)
2703       {
2704 	if (input[1] == 'G')
2705 	{
2706 	  if (!strncmp(input, "_GLOBAL__", 9)
2707 	      && (input[9] == 'D' || input[9] == 'I')
2708 	      && input[10] == '_')
2709 	  {
2710 	    if (input[9] == 'D')
2711 	      result.assign("global destructors keyed to ", 28);
2712 	    else
2713 	      result.assign("global constructors keyed to ", 29);
2714 	    // Output the disambiguation part as-is.
2715 	    result += input + 11;
2716 	  }
2717 	  else
2718 	    failure = true;
2719 	}
2720 	else if (input[1] == 'Z')
2721 	{
2722 	  int cnt =
2723 	      demangler_type::decode_encoding(result, input + 2, INT_MAX, id);
2724 	  if (cnt < 0 || input[cnt + 2] != 0)
2725 	    failure = true;
2726 	}
2727 	else
2728 	  failure = true;
2729       }
2730 
2731       // Failure to demangle, return the mangled name.
2732       if (failure)
2733 	result.assign(input, strlen(input));
2734 
2735       return result;
2736     }
2737 
2738   // demangle::type()
2739   // Demangle `input' which must be a zero terminated mangled type
2740   // name as for instance returned by std::type_info::name().
2741   template<typename Allocator>
2742     typename demangle<Allocator>::string_type
type(char const * input,demangler::implementation_details const & id)2743     demangle<Allocator>::type(char const* input,
2744                               demangler::implementation_details const& id)
2745     {
2746       std::basic_string<char, std::char_traits<char>, Allocator> result;
2747       if (input == NULL)
2748 	result = "(null)";
2749       else
2750       {
2751 	demangler::session<Allocator> demangler_session(input, INT_MAX, id);
2752 	if (!demangler_session.decode_type(result)
2753 	    || demangler_session.remaining_input_characters())
2754 	{
2755 	  // Failure to demangle, return the mangled name.
2756 	  result = input;
2757 	}
2758       }
2759       return result;
2760     }
2761 
2762 } // namespace __gnu_cxx
2763 
2764 #endif // __DEMANGLE_H
2765