text: /*
   *      CPP Demangler.
   *      Copyright (c) 2000-2006 by Iouri Kharon.
   *                        E-mail: yjh@styx.cabel.net
   *
   *      ALL RIGHTS RESERVED.
   *
   */
  
  #ifndef _DEMANGLE_HPP
  #define _DEMANGLE_HPP
  
  // long result code
  #define ME_INTERR   -1  // Internal error
  #define ME_PARAMERR -2  // Input parameters are wrong
  #define ME_ILLSTR   -3  // Incorrectly mangled name
  #define ME_SMALLANS -4  // Output buffer is too small
                          // This code is possible only with the 'old' calling
                          // form. With the new calling form the output buffer
                          // will have '...' as the last characters and the
                          // result code or'ed with the sign bit
  #define ME_FRAME    -5  // Partial demanging is possible (the input name has
                          // unrecognized suffix)
  #define ME_NOCOMP   -6  // Could not determine the compiler
  #define ME_ERRAUTO  -7  // Specified compiler is impossible for the input name
  #define ME_NOHASHMEM -8 // Out of internal indexes-most likely bad input name
  #define ME_NOSTRMEM  -9 // Out of internal buffers (can't be!:)
  
  #define ME_NOERROR_LIMIT  -10 // Lowest error number. Lower values
                                // signal about the truncated output name
                                // (the output buffer is too small)
  
  #define M_PRCMSK     0x0000000F // If = 0, then data
  #define MT_DEFAULT    0x00000001 // 1 - default (for  watcom/gnu only this)
  #define MT_CDECL      0x00000002 // 2 - __cdecl
  #define MT_PASCAL     0x00000003 // 3 - __pascal
  #define MT_STDCALL    0x00000004 // 4 - __stdcall
  #define MT_FASTCALL   0x00000005 // 5 - __fastcall
  #define MT_THISCALL   0x00000006 // 6 - __thiscall [ms & bc => pragma only]
  #define MT_FORTRAN    0x00000007 // 7 - __fortran
  #define MT_SYSCALL    0x00000008 // 8 - __syscall  [without ms]
  #define MT_INTERRUPT  0x00000009 // 9 - __interrupt (only with __cdecl!)
  #define MT_MSFASTCALL 0x0000000A // A - __msfastcall (bc)
  #define MT_CLRCALL    0x0000000B // B - __clrcall (vc7)
  
  //   reserved
  #define MT_LOCALNAME  0x0000000F // f - might be function or data. Currently
                                   //     is used only for bc - as the
                                   //     identifier for local pascal labels
  
  #define M_SAVEREGS   0x00000010 // For functions with "__saveregs"
  
  #define M_CLASS     0x000000E0  // 0 - no keyword (not a member field)
  #define MT_PUBLIC    0x00000020 // 1 - public,
  #define MT_PRIVATE   0x00000040 // 2 - private,
  #define MT_PROTECT   0x00000060 // 3 - protected
  #define MT_MEMBER    0x00000080 // 4 - undetermined (bc/wat)
  #define MT_VTABLE    0x000000A0 // 5 - vtable (bc/gnu)
  #define MT_RTTI      0x000000C0 // 6 - typeinfo table (gcc3)
  //   reserved
  
  #define M_PARMSK   0x0000FF00 // Parameter number mask (excluding ellipsis)
                                // 255 - >= 255
  #define MT_PARSHF      8      // shift to PARMSK
  #define MT_PARMAX     0xFF    // Number limiter
  #define M_ELLIPSIS 0x00010000   // The function _certainly_ has '...'
  #define MT_VOIDARG  0x0001FF00  // If = 0, the func(void), i.e. no parameters
  #define M_STATIC   0x00020000   // static
                                  // gcc3 - static data in a function
                                  // might be encountered in object files and
                                  // (possibly) in binaries with debug info
  #define M_VIRTUAL  0x00040000   // virtual
  #define M_AUTOCRT  0x00080000   // Most likely "autogenerated" function (data)
  
  #define M_TYPMASK  0x00700000   // Special functions (0-regular function)
  #define MT_OPERAT   0x00100000    // 1 - operator
  #define MT_CONSTR   0x00200000    // 2 - constructor
  #define MT_DESTR    0x00300000    // 3 - destructor
  #define MT_CASTING  0x00400000    // 4 - type conversion
  //  reserved
  
  #define M_TRUNCATE 0x00800000 // Name was truncated by the compiler (bc/va)
  #define M_THUNK    0x01000000 // [thunk]:
  #define M_ANONNSP  0x02000000 // ms  => Anonymous Namespace for field
                                // gc3 => Item placed in Anonymous namespace
                                // wat => anonymous_enum
                                // bc  => + TMPLNAM = PascalTemplate (for DCC)
                                //  If separate - "automatic" except_t
                                //  from CBuilder for "external" variables
                                //  or a template for global object
                                //  constructor/destructor tables (for CBuilder
                                //  as well)
  #define M_TMPLNAM  0x04000000 // ms  => template name (?)
                                // wat =>
                                // bc  => template name => its description table
                                // gc3 => any template funciton/data
  #define M_DBGNAME  0x08000000 // ms  =>  CV:
                                // wat => xxxx: (T?xxxx-form)
                                // bc  => old pascal format (capitalized)
                                // gc3 => unicode symbols or 'vendor-extension'
                                //        qualifiers are present
  
  #define M_COMPILER 0x70000000 // Compiler mask (0-unknown)
  #define MT_MSCOMP   0x10000000  // 1 - microsoft/symantec
  #define MT_BORLAN   0x20000000  // 2 - borland
  #define MT_WATCOM   0x30000000  // 3 - watcom
  //#define MT_         0x40000000  // 4 - reserved
  // !!! The following definitions must be last and in this order!
  #define MT_GNU      0x50000000  // 5 - GNU - (over VA for autodetection)
  #define MT_GCC3     0x60000000  // 6 - gcc-v3
                                   // In the short form this answer is possible
                                   // for GNU/VA as well, but gcc3 can be
                                   // explicitly requested only with it.
                                   // Autodetection works but not very reliable.
  #define MT_VISAGE   0x70000000  // 7 - Visual Age - never autodetected
                                   // In the short form this answer means VA
                                   // or GNU. In the automatic mode GNU will
                                   // be used!
  //========================================================================
  // Flags to inhibit different parts of the demangled name
  #define MNG_PTRMSK       0x7  // Memory model mask
  // DO NOT change order in this group (PtrType)
  #define MNG_DEFNEAR       0x0 // inhibit near, display everything else
  #define MNG_DEFNEARANY    0x1 // inhibit near/__ptr64, display everything else
  #define MNG_DEFFAR        0x2 // inhibit far, display everything else
  #define MNG_NOPTRTYP16    0x3 // inhibit everything (disables vc7-extensions)
  #define MNG_DEFHUGE       0x4 // inhibit huge, display everything else
  #define MNG_DEFPTR64      0x5 // inhibit __pt64, display everything else
  #define MNG_DEFNONE       0x6 // display everything
  #define MNG_NOPTRTYP      0x7 // inhibit everything
  //
  #define MNG_NODEFINIT    0x00000008 // Inhibit everything except the main name
                                      // This flag is not recommended
                                      // for __fastcall/__stdcall GCC3 names
                                      // because there is a high probablity of
                                      // incorrect demangling. Use it only when
                                      // you are sure that the input is a
                                      // cygwin/mingw function name
  //
  #define MNG_NOUNDERSCORE 0x00000010 // Inhibit underscores in __ccall, __pascal... +
  #define MNG_NOTYPE       0x00000020 // Inhibit callc&based
  #define MNG_NORETTYPE    0x00000040 // Inhibit return type of functions
  #define MNG_NOBASEDT     0x00000080 // Inhibit base types
  #define MNG_NOCALLC      0x00000100 // Inhibit __pascal/__ccall/etc
  #define MNG_NOPOSTFC     0x00000200 // Inhibit postfix const
  #define MNG_NOSCTYP      0x00000400 // Inhibit public/private/protected
  #define MNG_NOTHROW      0x00000800 // Inhibit throw description
  #define MNG_NOSTVIR      0x00001000 // Inhibit "static" & "virtual"
  #define MNG_NOECSU       0x00002000 // Inhibit class/struct/union/enum
  #define MNG_NOCSVOL      0x00004000 // Inhibit const/volatile/restrict
                                      //   NOTE: also inhibits "__unaligned"
  #define MNG_NOCLOSUR     0x00008000 // Inhibit __closure for borland
  #define MNG_NOUNALG      0x00010000 // Inhibit __unaligned (see NOCSVOL)
  #define MNG_NOMANAGE     0x00020000 // Inhibit __pin/__box/__gc for ms(.net)
  //                       0x00040000
  //                       0x00080000
  //++++++
  #define MNG_SHORT_S      0x00100000 // signed (int) is displayed as s(int)
  #define MNG_SHORT_U      0x00200000 // unsigned (int) is displayed as u(int)
  #define MNG_ZPT_SPACE    0x00400000 // Display space after comma in the arglist
  #define MNG_DROP_IMP     0x00800000 // Inhibit __declspec(dllimport)
  //                       0x01000000
  //
  #define MNG_IGN_ANYWAY   0x02000000 // Ingore '_nn' at the end of name
  #define MNG_IGN_JMP      0x04000000 // Ingore 'j_'  at the beginning of name
  #define MNG_MOVE_JMP     0x08000000 // Move 'j_' prefix to the demangled name
                                        // If both MNG_IGN_JMP and MNG_MOVE_JMP
                                        // are set then move the prefix only if
                                        // the name was not truncated
  //
  #define MNG_COMPILER_MSK 0x70000000 // Compiler mask (0-autodetect)
  
  #define MNG_SHORT_FORM  (MNG_NOTYPE|MNG_NORETTYPE|MNG_NOPOSTFC|MNG_NOPTRTYP| \
          MNG_NOSCTYP|MNG_NOTHROW|MNG_NOSTVIR|MNG_NOECSU|MNG_NOCLOSUR| \
               MNG_SHORT_U|MNG_DROP_IMP|MNG_NOUNALG|MNG_NOMANAGE| \
               MNG_IGN_JMP|MNG_MOVE_JMP|MNG_IGN_ANYWAY)
  #define MNG_LONG_FORM (MNG_ZPT_SPACE | MNG_IGN_JMP | MNG_IGN_ANYWAY | MNG_NOPTRTYP)
  
  //========================================================================
  #ifndef H2ASH
  
  typedef signed long ida_export demangler_t(char *answer, unsigned answer_length,
                                  const char *str,
                                  ulong disable_mask);
  
  idaman demangler_t demangle;
  
  // If answer == NULL then the demangler will return check if the demangling
  // is possible and only return the flags.
  // In this case answer_length should be enough to hold the demangled name
  
  // If answer_length == 0 then no demangling is performed neither. The function
  // will check if demangling is possible and what compiler is used to mangle
  // the name. If the name can not be demangled then the function will return 0.
  // NOTE: the answer MT_MSCOMP+1 means __msfastcall
  //       (or borland class name with "_4" suffix) and the demangling is possible
  //        either as MS (__fastcall) or as bc (__msfastcall)
  // NOTE: the answer MT_GCC3+1 means POSSIBLE mingw/cygwin with
  //       __stdcall/__fastcall but it might also mean ms-stdcall.
  //       In essense it means that the demangler can not determine the compiler
  //       precisely.
  //       It also means that the demangling is possible in the gcc3 mode
  //       ONLY when the compiler is explicitly set to gcc3 and MNG_NODEFINIT
  //       bit is not set.
  // NOTE: if long(answer_length) < 0 then the buffer size will be -answer_length
  //       but 'answer' is interpreted not as a pointer to the output buffer but
  //       as a pointer to pointer to the output buffer (char**).
  //       In this case if the function succeeds,a pointer to the answer end
  //       will be returned in the pointer (like stpcpy). In this form 'answer'
  //       can not be NULL and *(char**)answer can not be NULL.
  //       answer_length must be greater than 9 for the 'truncated' answer.
  
  typedef int mangled_name_type_t;
  const mangled_name_type_t MANGLED_CODE = 0;
  const mangled_name_type_t MANGLED_DATA = 1;
  const mangled_name_type_t MANGLED_UNKNOWN = 2;
  
  idaman mangled_name_type_t ida_export get_mangled_name_type(const char *name);
  
  void init_demangler(bool mode16);
  
  #endif // H2ASH
  #endif // _DEMANGLE_HPP
  