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

📄 demangle.h

📁 mingw32.rar
💻 H
📖 第 1 页 / 共 5 页
字号:
// C++ IA64 / g++ v3 demangler  -*- C++ -*-

// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
// Written by Carlo Wood <carlo@alinoe.com>
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

// This file implements demangling of "C++ ABI for Itanium"-mangled symbol
// and type names as described in Revision 1.73 of the C++ ABI as can be found
// at http://www.codesourcery.com/cxx-abi/abi.html#mangling

#ifndef _DEMANGLER_H
#define _DEMANGLER_H 1

#include <vector>
#include <string>
#include <ext/new_allocator.h>

#ifndef _GLIBCXX_DEMANGLER_DEBUG
#define _GLIBCXX_DEMANGLER_CWDEBUG 0
#define _GLIBCXX_DEMANGLER_DEBUG(x)
#define _GLIBCXX_DEMANGLER_DOUT(cntrl, data)
#define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x)
#define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x)
#define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x)
#define _GLIBCXX_DEMANGLER_RETURN return M_result
#define _GLIBCXX_DEMANGLER_RETURN2 return M_result
#define _GLIBCXX_DEMANGLER_RETURN3
#define _GLIBCXX_DEMANGLER_FAILURE \
    do { M_result = false; return false; } while(0)
#else
#define _GLIBCXX_DEMANGLER_CWDEBUG 1
#endif

namespace __gnu_cxx
{
  namespace demangler
  {
    enum substitution_nt
    {
      type,
      template_template_param,
      nested_name_prefix,
      nested_name_template_prefix,
      unscoped_template_name
    };

    struct substitution_st
    {
      int M_start_pos;
      substitution_nt M_type;
      int M_number_of_prefixes;

      substitution_st(int start_pos,
		      substitution_nt type,
		      int number_of_prefixes)
      : M_start_pos(start_pos), M_type(type),
	M_number_of_prefixes(number_of_prefixes)
      { }
    };

    enum simple_qualifier_nt
    {
      complex_or_imaginary = 'G',
      pointer = 'P',
      reference = 'R'
    };

    enum cv_qualifier_nt
    {
      cv_qualifier = 'K'
    };

    enum param_qualifier_nt
    {
      vendor_extension = 'U',
      array = 'A',
      pointer_to_member = 'M'
    };

    template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> >
      class qualifier;

    template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> >
      class qualifier_list;

    template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> >
      class session;

    template<typename Tp, typename Allocator>
      class qualifier
      {
	typedef typename Allocator::template rebind<char>::other
	        char_Allocator;
	typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
	    string_type;

      private:
	char M_qualifier1;
	char M_qualifier2;
	char M_qualifier3;
	mutable unsigned char M_cnt;
	string_type M_optional_type;
	int M_start_pos;
	bool M_part_of_substitution;

      public:
	qualifier(int start_pos,
	          simple_qualifier_nt simple_qualifier,
		  int inside_substitution)
	: M_qualifier1(simple_qualifier),
	  M_start_pos(start_pos),
	  M_part_of_substitution(inside_substitution)
	{ }

	qualifier(int start_pos,
	          cv_qualifier_nt,
		  char const* start,
		  int count,
		  int inside_substitution)
	: M_qualifier1(start[0]),
	  M_qualifier2((count > 1) ? start[1] : '\0'),
	  M_qualifier3((count > 2) ? start[2] : '\0'),
	  M_start_pos(start_pos),
	  M_part_of_substitution(inside_substitution)
	{ }

	qualifier(int start_pos,
	          param_qualifier_nt param_qualifier,
		  string_type optional_type,
		  int inside_substitution)
	: M_qualifier1(param_qualifier),
	  M_optional_type(optional_type),
	  M_start_pos(start_pos),
	  M_part_of_substitution(inside_substitution)
	{ }

	int
	get_start_pos(void) const
	{ return M_start_pos; }

	char
	first_qualifier(void) const
	{ M_cnt = 1; return M_qualifier1; }

	char
	next_qualifier(void) const
	{
	  return (++M_cnt == 2) ? M_qualifier2
	                        : ((M_cnt == 3) ? M_qualifier3 : 0);
	}

	string_type const&
	get_optional_type(void) const
	{ return M_optional_type; }

	bool
	part_of_substitution(void) const
	{ return M_part_of_substitution; }

#if _GLIBCXX_DEMANGLER_CWDEBUG
	friend std::ostream& operator<<(std::ostream& os, qualifier const& qual)
	{
	  os << (char)qual.M_qualifier1;
	  if (qual.M_qualifier1 == vendor_extension ||
	      qual.M_qualifier1 == array ||
	      qual.M_qualifier1 == pointer_to_member)
	    os << " [" << qual.M_optional_type << ']';
	  else if (qual.M_qualifier1 == 'K' ||
		   qual.M_qualifier1 == 'V' ||
		   qual.M_qualifier1 == 'r')
	  {
	    if (qual.M_qualifier2)
	    {
	      os << (char)qual.M_qualifier2;
	      if (qual.M_qualifier3)
		os << (char)qual.M_qualifier3;
	    }
	  }
	  return os;
	}
#endif
      };

    template<typename Tp, typename Allocator>
      class qualifier_list
      {
	typedef typename Allocator::template rebind<char>::other
	  char_Allocator;
	typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
	  string_type;

      private:
	mutable bool M_printing_suppressed;
	typedef qualifier<Tp, Allocator> qual;
        typedef typename Allocator::template rebind<qual>::other qual_Allocator;
	typedef std::vector<qual, qual_Allocator> qual_vector;
	qual_vector M_qualifier_starts;
	session<Tp, Allocator>& M_demangler;

	void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
			 typename qual_vector::
			   const_reverse_iterator const& iter_array) const;

      public:
	qualifier_list(session<Tp, Allocator>& demangler_obj)
	: M_printing_suppressed(false), M_demangler(demangler_obj)
	{ }

	void
	add_qualifier_start(simple_qualifier_nt simple_qualifier,
			    int start_pos,
			    int inside_substitution)
	{ M_qualifier_starts.
	      push_back(qualifier<Tp, Allocator>(start_pos,
		  simple_qualifier, inside_substitution)); }

	void
	add_qualifier_start(cv_qualifier_nt cv_qualifier,
			    int start_pos,
			    int count,
			    int inside_substitution)
	{ M_qualifier_starts.
	      push_back(qualifier<Tp, Allocator>(start_pos,
		    cv_qualifier, &M_demangler.M_str[start_pos],
		    count, inside_substitution)); }

	void
	add_qualifier_start(param_qualifier_nt param_qualifier,
			    int start_pos,
			    string_type optional_type,
			    int inside_substitution)
	{ M_qualifier_starts.
	      push_back(qualifier<Tp, Allocator>(start_pos,
		    param_qualifier, optional_type, inside_substitution)); }

	void
	decode_qualifiers(string_type& prefix,
			  string_type& postfix,
			  bool member_function_pointer_qualifiers) const;

	bool
	suppressed(void) const
	{ return M_printing_suppressed; }

	void
	printing_suppressed(void)
	{ M_printing_suppressed = true; }

	size_t
	size(void) const
	{ return M_qualifier_starts.size(); }

#if _GLIBCXX_DEMANGLER_CWDEBUG
	friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
	{
	  typename qual_vector::const_iterator
	      iter = list.M_qualifier_starts.begin();
	  if (iter != list.M_qualifier_starts.end())
	  {
	    os << "{ " << *iter;
	    while (++iter != list.M_qualifier_starts.end())
	      os << ", " << *iter;
	    os << " }";
	  }
	  else
	    os << "{ }";
	  return os;
	}
#endif
      };

    struct implementation_details
    {
      private:
        unsigned int M_style;

      public:
	// The following flags change the behaviour of the demangler.  The
	// default behaviour is that none of these flags is set.

        static unsigned int const style_void = 1;
	// Default behaviour:				int f()
	// Use (void) instead of ():			int f(void)

        static unsigned int const style_literal = 2;
	// Default behaviour:				(long)13,
	//						(unsigned long long)19
	// Use extensions 'u', 'l' and 'll' for integral
	// literals (as in template arguments):		13l, 19ull

        static unsigned int const style_literal_int = 4;
	// Default behaviour:				4
	// Use also an explicit
	//   cast for int in literals:			(int)4

        static unsigned int const style_compact_expr_ops = 8;
	// Default behaviour:				(i) < (3), sizeof (int)
	// Don't output spaces around
	//   operators in expressions:			(i)<(3), sizeof(int)

        static unsigned int const style_sizeof_typename = 16;
	// Default behaviour:				sizeof (X::t)
	// Put 'typename' infront of <nested-name>
	// types inside a 'sizeof':			sizeof (typename X::t)

      public:
	implementation_details(unsigned int style_flags = 0) :
	    M_style(style_flags) { }
	virtual ~implementation_details() { }
	bool get_style_void(void) const
	    { return (M_style & style_void); }
	bool get_style_literal(void) const
	    { return (M_style & style_literal); }
	bool get_style_literal_int(void) const
	    { return (M_style & style_literal_int); }
	bool get_style_compact_expr_ops(void) const
	    { return (M_style & style_compact_expr_ops); }
	bool get_style_sizeof_typename(void) const
	    { return (M_style & style_sizeof_typename); }
        // This can be overridden by user implementations.
        virtual bool decode_real(char* /* output */, unsigned long* /* input */,
				 size_t /* size_of_real */) const
            { return false; }
    };

    template<typename Tp, typename Allocator>
      class session
      {
      public:
	friend class qualifier_list<Tp, Allocator>;
	typedef typename Allocator::template rebind<char>::other
	    char_Allocator;
	typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
	    string_type;

      private:
	char const* M_str;
	int M_pos;
	int M_maxpos;
	bool M_result;
	int M_inside_template_args;
	int M_inside_type;
	int M_inside_substitution;
	bool M_saw_destructor;
	bool M_name_is_cdtor;
	bool M_name_is_template;
	bool M_name_is_conversion_operator;
	bool M_template_args_need_space;
	string_type M_function_name;
        typedef typename Allocator::template rebind<int>::other
                int_Allocator;
        typedef typename Allocator::template rebind<substitution_st>::other
                subst_Allocator;
	std::vector<int, int_Allocator> M_template_arg_pos;
	int M_template_arg_pos_offset;
	std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
	implementation_details const& M_implementation_details;
	typedef typename Allocator::template
	    rebind<qualifier_list<Allocator> >::other qualifier_list_Allocator;
	qualifier_list_Allocator M_qualifier_list_alloc;
#if _GLIBCXX_DEMANGLER_CWDEBUG
	bool M_inside_add_substitution;
#endif

      public:
	explicit session(char const* in, int len,
	    implementation_details const& id = implementation_details())
	: M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true),
	  M_inside_template_args(0), M_inside_type(0),
	  M_inside_substitution(0), M_saw_destructor(false),
	  M_name_is_cdtor(false), M_name_is_template(false),
	  M_name_is_conversion_operator(false),
	  M_template_args_need_space(false), M_template_arg_pos_offset(0),
	  M_implementation_details(id)
#if _GLIBCXX_DEMANGLER_CWDEBUG
	  , M_inside_add_substitution(false)
#endif
	{ }

	static int
	decode_encoding(string_type& output, char const* input, int len,
	  implementation_details const& id = implementation_details());

	bool
	decode_type(string_type& output,
	            qualifier_list<Tp, Allocator>* qualifiers = NULL)
	{
	  string_type postfix;
	  bool res = decode_type_with_postfix(output, postfix, qualifiers);
	  output += postfix;
	  return res;
	}

⌨️ 快捷键说明

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