Hex-Rays Home > Decompiler
Hex-Rays Decompiler: SDK Reference
  • Decompiler
  • News
  • Comparisons
  • Sales
  • Support
  • SDK
  • Manual
  • Reference
  • Main Page
  • Modules
  • Classes
  • Files
  • Examples
  • File List
  • File Members

hexrays.hpp

Go to the documentation of this file.
00001 /*
00002  *      Hex-Rays Decompiler project
00003  *      Copyright (c) 2007-2009 by Hex-Rays, support@hex-rays.com
00004  *      ALL RIGHTS RESERVED.
00005  */
00006 
00007 #ifndef __HEXRAYS_HPP
00008 #define __HEXRAYS_HPP
00009 
00010 #define CHECKED_BUILD
00011 #include <pro.h>
00012 #include <fpro.h>
00013 #include <windows.h>
00014 #include <ida.hpp>
00015 #include <idp.hpp>
00016 #include <ieee.h>
00017 #include <loader.hpp>
00018 #include <kernwin.hpp>
00019 #include <typeinf.hpp>
00020 #include <set>
00021 #include <map>
00022 #include <deque>
00023 #include <queue>
00024 #include <algorithm>
00025 #pragma pack(push, 4)
00026 #ifdef __VC__
00027 #pragma warning(push)
00028 #pragma warning(disable:4062) // enumerator 'x' in switch of enum 'y' is not handled
00029 #pragma warning(disable:4265) // virtual functions without virtual destructor
00030 #endif
00031 
00032 #define hexapi                ///< Public functions are marked with this keyword
00033 
00034 class intseq_t;
00035 class mbl_array_t;
00036 struct vdui_t;
00037 struct hexrays_failure_t;
00038 struct mba_stats_t;
00039 struct mlist_t;
00040 typedef int mreg_t;     ///< Micro register
00041 
00042 struct cfunc_t;
00043 struct citem_t;
00044 struct cexpr_t;
00045 struct cinsn_t;
00046 struct cblock_t;
00047 struct cswitch_t;
00048 struct carg_t;
00049 struct carglist_t;
00050 
00051 typedef qvector<uchar> byteseq_t;       ///< Byte sequence
00052 typedef qvector<qstring> qstrvec_t;     ///< Vector of strings
00053 //-------------------------------------------------------------------------
00054 /// Macro to declare standard inline comparison operators
00055 #define DECLARE_COMPARISON_OPERATORS(type)                              \
00056   bool operator==(const type &r) const { return compare(r) == 0; }      \
00057   bool operator!=(const type &r) const { return compare(r) != 0; }      \
00058   bool operator< (const type &r) const { return compare(r) <  0; }      \
00059   bool operator> (const type &r) const { return compare(r) >  0; }      \
00060   bool operator<=(const type &r) const { return compare(r) <= 0; }      \
00061   bool operator>=(const type &r) const { return compare(r) >= 0; }
00062 
00063 /// Macro to declare comparisons for our classes
00064 /// All comparison operators call the compare() function which returns -1/0/1
00065 #define DECLARE_COMPARISONS(type)    \
00066   DECLARE_COMPARISON_OPERATORS(type) \
00067   friend int compare(const type &a, const type &b) { return a.compare(b); } \
00068   int compare(const type &r) const
00069 
00070 /// Operand locator.
00071 struct operand_locator_t
00072 {
00073   ea_t ea;              ///< address of the original instruction
00074   int opnum;            ///< operand number in the instruction
00075   operand_locator_t(void) {}
00076   operand_locator_t(ea_t _ea, int _opnum) : ea(_ea), opnum(_opnum) {}
00077   DECLARE_COMPARISONS(operand_locator_t);
00078   DEFINE_MEMORY_ALLOCATION_FUNCS()
00079 };
00080 
00081 //-------------------------------------------------------------------------
00082 /// Number represenation.
00083 /// This structure holds information about number format.
00084 struct number_format_t
00085 {
00086   DEFINE_MEMORY_ALLOCATION_FUNCS()
00087   flags_t flags;          ///< ida flags, which describe number radix, enum, etc
00088   char opnum;             ///< operand number: 0..UA_MAXOP
00089   char props;             ///< properties: combination of NF_ bits (\ref NF_)
00090 /// \defgroup NF_ Number format property bits
00091 /// Used in number_format_t::props
00092 //@{
00093 #define NF_FIXED   0x01   ///< number format has been defined by the user
00094 #define NF_NEGDONE 0x02   ///< temporary internal bit: negation has been performed
00095 #define NF_NEGATE  0x08   ///< The user asked to negate the constant
00096 //@}
00097   uchar serial;           ///< for enums: constant serial number
00098   char org_nbytes;        ///< original number size in bytes
00099   qstring type_name;      ///< for stroffs: structure for offsetof()\n
00100                           ///< for enums: enum name
00101   /// Contructor
00102   number_format_t(int _opnum=0)
00103     : flags(0), opnum(char(_opnum)), props(0), serial(0), org_nbytes(0) {}
00104   /// Get number radix
00105   /// \return 2,8,10, or 16
00106   int getRadix(void) const { return ::getRadix(flags, opnum); }
00107   /// Is number representation fixed?
00108   /// Fixed representation can not be modified by the decompiler
00109   bool is_fixed(void) const { return props != 0; }
00110   /// Is a hexadecimal number?
00111   bool isHex(void) const { return ::isNum(flags, opnum) && getRadix() == 16; }
00112   /// Is a decimal number?
00113   bool isDec(void) const { return ::isNum(flags, opnum) && getRadix() == 10; }
00114   /// Is a octal number?
00115   bool isOct(void) const { return ::isNum(flags, opnum) && getRadix() == 8; }
00116   /// Is a symbolic constant?
00117   bool isEnum(void) const { return ::isEnum(flags, opnum); }
00118   /// Is a character constant?
00119   bool isChar(void) const { return ::isChar(flags, opnum); }
00120   /// Is a structure field offset? (not used yet)
00121   bool isStroff(void) const { return ::isStroff(flags, opnum); }
00122   /// Is a number?
00123   bool isNum(void) const { return !isEnum() && !isChar() && !isStroff(); }
00124   /// Should the number be printed negated?
00125   /// In some cases the decompiler automatically negates numbers
00126   bool is_invsign(void) const { return is_signed_data(flags); }
00127 };
00128 
00129 // Number formats are attached to (ea,opnum) pairs
00130 typedef std::map<operand_locator_t, number_format_t> user_numforms_t;
00131 
00132 //-------------------------------------------------------------------------
00133 /// Base helper class to convert binary data structures into text.
00134 /// Other classes are derived from this class.
00135 struct vd_printer_t
00136 {
00137   int hdrlines;         ///< number of header lines (prototype+typedef+lvars)
00138                         ///< valid at the end of print process
00139   /// Print.
00140   /// This function is called to generate a portion of the output text.
00141   /// The output text may contain color codes.
00142   /// \return the number of printed characters
00143   /// \param indent  number of spaces to generate as prefix
00144   /// \param format  printf-style format specifier
00145   AS_PRINTF(3, 4) virtual int hexapi print(int indent, const char *format,...);
00146   AS_PRINTF(3, 0) int vprint(int indent, const char *format, va_list);
00147   DEFINE_MEMORY_ALLOCATION_FUNCS()
00148 };
00149 
00150 /// Helper class to convert cfunc_t into text.
00151 struct vc_printer_t : public vd_printer_t
00152 {
00153   const cfunc_t *func;          ///< cfunc_t to generate text for
00154   char lastchar;                ///< internal: last printed character
00155   /// Constructor
00156   vc_printer_t(const cfunc_t *f) : func(f), lastchar(0) {}
00157   /// Are we generating one-line text representation?
00158   /// \return \c true if the output will occupy one line without line breaks
00159   virtual bool idaapi oneliner(void) const { return false; }
00160 };
00161 
00162 /// Helper class to convert binary data structures into text and put into a file.
00163 struct file_printer_t : public vd_printer_t
00164 {
00165   FILE *fp;                     ///< Output file pointer
00166   /// Print.
00167   /// This function is called to generate a portion of the output text.
00168   /// The output text may contain color codes.
00169   /// \return the number of printed characters
00170   /// \param indent  number of spaces to generate as prefix
00171   /// \param format  printf-style format specifier
00172   int print(int indent, const char *format, ...);
00173   /// Constructor
00174   file_printer_t(FILE *_fp) : fp(_fp) {}
00175 };
00176 
00177 /// Helper class to convert cfunc_t into a text string
00178 struct qstring_printer_t : public vc_printer_t
00179 {
00180   bool with_tags;               ///< Generate output with color tags
00181   qstring &s;                   ///< Reference to the output string
00182   /// Constructor
00183   qstring_printer_t(const cfunc_t *f, qstring &_s, bool tags)
00184     : vc_printer_t(f), with_tags(tags), s(_s) {}
00185   /// Print.
00186   /// This function is called to generate a portion of the output text.
00187   /// The output text may contain color codes.
00188   /// \return the number of printed characters
00189   /// \param indent  number of spaces to generate as prefix
00190   /// \param format  printf-style format specifier
00191   AS_PRINTF(3, 4) int hexapi print(int indent, const char *format, ...);
00192   AS_PRINTF(3, 0) int vprint(int indent, const char *format, va_list);
00193 };
00194 
00195 //-------------------------------------------------------------------------
00196 /// \defgroup type Type string related declarations
00197 /// Type related functions and class.
00198 //@{
00199 
00200 /// Resolve a typedef.
00201 /// This function never returns NULL.
00202 /// If an invalid type is encountered, it throws \ref vd_failure_t with \ref MERR_UNKTYPE
00203 /// \return pointer to resolved type string. The pointer is valid until a type
00204 ///         is modified in IDA kernel. The pointer might also point to the input
00205 ///         \c type if the input type was not a typedef.
00206 /// \param type type string to resolve
00207 /// \param fields ptr to ptr to the accompanying \link typestring fields \endlink string
00208 
00209 const type_t *hexapi remove_typedef(const type_t *type, const p_list **fields=NULL);
00210 
00211 
00212 /// Verify a type string.
00213 /// \return true if type string is correct
00214 
00215 bool hexapi is_type_correct(const type_t *ptr);
00216 
00217 /// Is integral type?
00218 /// \return true if the type is an integer type
00219 
00220 bool hexapi is_type_integral(const type_t *type);
00221 
00222 
00223 /// Is a small structure or union?
00224 /// \return true if the type ia small s UDT (user defined type).
00225 ///              Small UDTs fit into a register (or pair or registers) as a rule.
00226 
00227 bool hexapi is_type_small_struni(const type_t *ptr);
00228 
00229 
00230 /// Is a pointer or array type?
00231 inline bool is_ptr_or_array(type_t t)
00232 {
00233   return is_type_ptr(t) || is_type_array(t);
00234 }
00235 
00236 /// Is a pointer, array, or function type?
00237 inline bool is_paf(type_t t)
00238 {
00239   return is_ptr_or_array(t) || is_type_func(t);
00240 }
00241 
00242 /// Skip pointer or array type header.
00243 /// \return pointer to the pointed object or array element.
00244 inline const type_t *skip_ptr_or_array_header(const type_t *t)
00245 {
00246   if ( is_type_ptr(*t) )
00247     return skip_ptr_type_header(t);
00248   else
00249     return skip_array_type_header(t);
00250 }
00251 
00252 
00253 /// Calculate number of partial subtypes.
00254 /// \return number of partial subtypes. The bigger is this number, the uglier is the type.
00255 
00256 int hexapi partial_type_num(const type_t *type);
00257 
00258 
00259 /// Get a type byte for a floating point value.
00260 /// \returns BT_FLOAT or'ed with the right modifier.
00261 /// \param width width of the desired type
00262 
00263 type_t hexapi get_float_bit(int width);
00264 
00265 
00266 
00267 
00268 /// Type string.
00269 /// All types in the decompiler are kept in instances of this class.
00270 /// The contents of the type string are described in typeinf.hpp\n
00271 /// In fact, type information consists of two strings: the type string
00272 /// itself and another string with the field names. The first string (pure
00273 /// type string) keeps information about the type without user-defined names.
00274 /// The second string keeps user-defined names. The second string is required for
00275 /// structures and unions (to keep the field names), enumerations (to keep the
00276 /// constant names), and functions (to keep the argument names). In all other cases
00277 /// the field string can be empty or missing.
00278 struct typestring : public qtype
00279 {
00280   const type_t *u_str(void) const
00281   {
00282     return (const type_t *)c_str();
00283   }
00284   typestring(void) {}
00285   typestring(const type_t *str) : qtype(str ? str : (type_t*)"")
00286   {
00287   }
00288   typestring(const type_t *str, int n) : qtype(str ? str : (type_t*)"", n)
00289   {
00290   }
00291   typestring(const qtype &str) : qtype(str)
00292   {
00293   }
00294   typestring(const qstring &str) : qtype((type_t *)str.c_str())
00295   {
00296   }
00297   const char *idaapi dstr(void) const;
00298   const char *idaapi dstr(const p_list *fields, const char *name=NULL) const;
00299   const char *idaapi dstr(const qtype &fields, const char *name=NULL) const
00300     { return dstr(fields.c_str(), name); }
00301   size_t hexapi print(char *buf, size_t bufsize) const;
00302   qstring multiprint(const p_list *fields, const char *name=NULL, int prflags=0) const;
00303   int size(void) const
00304   {
00305     return get_type_size0(idati, u_str());
00306   }
00307   int noarray_size(void) const;
00308   type_sign_t get_sign(void) const
00309   {
00310     return get_type_sign(idati, u_str());
00311   }
00312   bool hexapi change_sign(type_sign_t sign);
00313   cm_t hexapi get_cc(void) const;
00314   bool is_user_cc(void) const { return ::is_user_cc(get_cc()); }
00315   bool is_vararg(void) const { return ::is_vararg_cc(get_cc()); }
00316   typestring hexapi get_nth_arg(int n) const;
00317   DECLARE_COMPARISON_OPERATORS(typestring)
00318   int compare(const typestring &r) const { return typcmp(u_str(), r.u_str()); }
00319   bool common_type(const typestring &x);
00320   bool is_ptr_or_array(void) const
00321   {
00322     const type_t *t2 = resolve();
00323     return t2 != NULL && ::is_ptr_or_array(t2[0]);
00324   }
00325   bool remove_ptr_or_array(void)
00326   {
00327     const type_t *t2 = resolve();
00328     if ( t2 == NULL || !::is_ptr_or_array(t2[0]) )
00329       return false;
00330     t2 = skip_ptr_or_array_header(t2);
00331     *this = t2;
00332     return true;
00333   }
00334   bool is_paf(void) const
00335   {
00336     const type_t *t2 = resolve();
00337     return t2 != NULL && ::is_paf(t2[0]);
00338   }
00339   bool is_funcptr(void) const
00340   {
00341     if ( empty() )
00342       return false;
00343     const type_t *t2 = begin();
00344     if ( !is_type_ptr(*t2) )
00345       return false;
00346     t2 = skip_ptr_type_header(t2);
00347     return is_type_func(*t2);
00348   }
00349   bool is_ptr(void) const      { const type_t *ptr = resolve(); return ptr != NULL && is_type_ptr(*ptr); }
00350   bool is_enum(void) const     { const type_t *ptr = resolve(); return ptr != NULL && is_type_enum(*ptr); }
00351   bool is_func(void) const     { const type_t *ptr = resolve(); return ptr != NULL && is_type_func(*ptr); }
00352   bool is_void(void) const     { const type_t *ptr = resolve(); return ptr != NULL && is_type_void(*ptr); }
00353   bool is_array(void) const    { const type_t *ptr = resolve(); return ptr != NULL && is_type_array(*ptr); }
00354   bool is_float(void) const    { const type_t *ptr = resolve(); return ptr != NULL && is_type_float(*ptr); }
00355   bool is_union(void) const    { const type_t *ptr = resolve(); return ptr != NULL && is_type_union(*ptr); }
00356   bool is_struct(void) const   { const type_t *ptr = resolve(); return ptr != NULL && is_type_struct(*ptr); }
00357   bool is_struni(void) const   { const type_t *ptr = resolve(); return ptr != NULL && is_type_struni(*ptr); }
00358   bool is_double(void) const   { const type_t *ptr = resolve(); return ptr != NULL && is_type_double(*ptr); }
00359   bool is_ldouble(void) const  { const type_t *ptr = resolve(); return ptr != NULL && is_type_ldouble(*ptr); }
00360   bool is_floating(void) const { const type_t *ptr = resolve(); return ptr != NULL && is_type_floating(*ptr); }
00361   bool is_correct(void) const { return empty() || is_type_correct(u_str()); }
00362   const type_t *resolve(void) const { return remove_typedef(u_str()); }
00363   const type_t *resolve_func_type(const p_list **fields=NULL) const;
00364   bool is_scalar(void) const { return is_type_scalar2(idati, u_str()); }
00365   bool is_small_struni(void) const { return is_type_small_struni(u_str()); }
00366   bool is_like_scalar(void) const
00367   {
00368     const type_t *ptr = resolve();
00369     return is_type_scalar2(idati, ptr) || is_type_small_struni(ptr);
00370   }
00371   bool is_pvoid(void) const
00372   {
00373     const type_t *ptr = resolve();
00374     if ( !is_type_ptr(*ptr) )
00375       return false;
00376     ptr = skip_ptr_type_header(ptr);
00377     if ( !is_restype_void(idati, ptr) )
00378       return false;
00379     return true;
00380   }
00381   bool is_partial_ptr(void) const
00382   {
00383     const type_t *ptr = u_str();
00384     if ( !is_type_ptr(*ptr) )
00385       return false;
00386     ptr = skip_ptr_type_header(ptr);
00387     if ( !is_type_partial(*ptr) )
00388       return false;
00389     return true;
00390   }
00391   bool is_well_defined(void) const
00392   {
00393     if ( empty() )
00394       return false;
00395     return !is_type_partial((*this)[0]);
00396   }
00397   bool requires_cot_ref(void) const
00398   {
00399     // arrays and functions do not require &
00400     const type_t *t2 = resolve();
00401     if ( t2 == NULL )
00402       return true;
00403     type_t t = *t2;
00404     return !is_type_array(t) && !is_type_func(t);
00405   }
00406   int partial_type_num(void) const { return ::partial_type_num(u_str()); }
00407 };
00408 
00409 /// Create a type string by width and sign.
00410 /// Returns a simple type (examples: int, short) with the given width and sign.
00411 /// \param srcwidth size of the type in bytes
00412 /// \param sign sign of the type
00413 
00414 typestring hexapi get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign);
00415 
00416 
00417 /// Create a partial type string by width.
00418 /// Returns a partially defined type (examples: _DWORD, _BYTE) with the given width.
00419 /// \param size size of the type in bytes
00420 
00421 typestring hexapi get_unk_type(int size);
00422 
00423 
00424 /// Generate a dummy pointer type
00425 ///  \param buf output buffer
00426 ///  \param bufsize size of output buffer. must be bigger than 4 bytes (at least)
00427 ///  \param ptrsize size of pointed object
00428 ///  \param isfp is floating point object?
00429 
00430 typestring hexapi dummy_ptrtype(int ptrsize, bool isfp);
00431 
00432 
00433 /// Get type of a structure field.
00434 /// This function performs validity checks of the field type. Wrong types are rejected.
00435 /// \param mptr structure field
00436 /// \param type pointer to the variable where the type is returned. This parameter can be NULL.
00437 /// \param fields pointer to the variable where the fields are returned. This parameter can be NULL.
00438 /// \return false if failed
00439 
00440 bool hexapi get_member_type(const member_t *mptr, typestring *type, qtype *fields=NULL);
00441 
00442 
00443 /// Create an array type.
00444 /// This function performs the following conversion: "type" -> "type[N]"
00445 /// \param type array element type.
00446 /// \param nelems number of array elements. zero represents unknown array dimensions.
00447 
00448 typestring hexapi make_array(const type_t *type, int nelems);
00449 
00450 
00451 /// Create a pointer type.
00452 /// This function performs the following conversion: "type" -> "type*"
00453 /// \param type object type.
00454 /// \return "type*". for example, if 'char' is passed as the argument,
00455 //          the function will return 'char *'
00456 
00457 typestring hexapi make_pointer(const typestring &type);
00458 
00459 
00460 /// Create a reference to a named type.
00461 /// \param name type name
00462 /// \return type which refers to the specified name. For example, if name is "DWORD",
00463 ///             the type string which refers to "DWORD" is created.
00464 
00465 typestring hexapi create_typedef(const char *name);
00466 
00467 
00468 /// Get pointed object type.
00469 /// This function performs the following conversion: "type*" -> "type"
00470 /// \param type this parameter should be of a pointer type. The function will return
00471 ///             the pointed type. If the parameter is not a pointer, then it is
00472 ///             returned as is.
00473 
00474 typestring hexapi remove_pointer(const typestring &type);
00475 
00476 
00477 /// Convert array type into pointer type.
00478 /// This function performs the following conversion: "type[]" -> "type *"
00479 /// \param type array type.
00480 
00481 bool hexapi cnv_array_to_ptr(typestring &type);
00482 
00483 
00484 //@}
00485 
00486 //-------------------------------------------------------------------------
00487 struct meminfo_t
00488 {
00489   DEFINE_MEMORY_ALLOCATION_FUNCS()
00490   uval_t offset;
00491   int size;               // not used by build_struct_type, just for speed
00492   typestring type;
00493   typestring fields;
00494   qstring name;
00495 };
00496 
00497 struct strtype_info_t : public qvector<meminfo_t>
00498 {
00499   type_t basetype;
00500   int N;                // N from the type string
00501   bool hexapi create_from(const type_t *type, const p_list *fields, bool with_gaps);
00502   bool hexapi build_base_type(typestring *restype) const;
00503   bool hexapi build_udt_type(typestring *restype, typestring *resfields);
00504   int find_strmem(uval_t offset) const;
00505 };
00506 
00507 //-------------------------------------------------------------------------
00508 /// If there is only one register, use all argloc bits
00509 inline mreg_t get_lvarloc_reg1(argloc_t location) { return is_reg2_argloc(location) ? get_argloc_r1(location) : location & ~ARGLOC_REG; }
00510 inline mreg_t get_lvarloc_reg2(argloc_t location) { return get_argloc_r2(location); }
00511 
00512 /// Do two arglocs overlap?
00513 bool hexapi arglocs_overlap(argloc_t loc1, size_t w1, argloc_t loc2, size_t w2);
00514 
00515 /// Local variable locator. Local variables are located using: definition ea, location
00516 struct lvar_locator_t
00517 {
00518   argloc_t location;    ///< Variable mapping.
00519                         ///< registers: ARGLOC_REG|microreg\n
00520                         ///< stkvars: offset from the minimal sp
00521   ea_t defea;           ///< Definition address. This value is assigned
00522                         ///< to each lvar by lvar allocator.
00523                         ///< BADADDR for function arguments
00524   lvar_locator_t(void) : location(BAD_ARGLOC), defea(BADADDR) {}
00525   lvar_locator_t(argloc_t loc, ea_t ea) : location(loc), defea(ea) {}
00526   /// Calculate the variable location.
00527   /// \return if the variable is register-hosted, the register number
00528   ///         otherwise, return the virtual stack register number that
00529   ///         corresponds to the stack location
00530   sval_t hexapi get_regnum(void) const;
00531   /// Is variable located on a register?
00532   bool is_reg_lvar(void) const { return  is_reg_argloc(location); }
00533   /// Is variable located on two registers?
00534   bool is_reg2_lvar(void) const { return  is_reg2_argloc(location); }
00535   /// Is variable located on the stack?
00536   bool is_stk_lvar(void) const { return !is_reg_argloc(location); }
00537   /// Get number of the register for the variable
00538   mreg_t get_regloc1(void) const { return get_lvarloc_reg1(location); }
00539   /// Get number of the second register (only for tworeg lvars)
00540   mreg_t get_regloc2(void) const { return get_lvarloc_reg2(location); }
00541   DECLARE_COMPARISONS(lvar_locator_t);
00542   DEFINE_MEMORY_ALLOCATION_FUNCS()
00543 };
00544 
00545 /// Definition of a local variable (register or stack)
00546 class lvar_t : public lvar_locator_t
00547 {
00548   friend class mbl_array_t;
00549   int flags;                    ///< \ref CVAR_
00550 /// \defgroup CVAR_ Local variable property bits
00551 /// Used in lvar_t::flags
00552 //@{
00553 #define CVAR_USED    0x0001     ///< is used in the code?
00554 #define CVAR_TYPE    0x0002     ///< the type is defined?
00555 #define CVAR_NAME    0x0004     ///< has nice name?
00556 #define CVAR_MREG    0x0008     ///< corresponding mregs were replaced?
00557 #define CVAR_NOWD    0x0010     ///< width is unknown
00558 #define CVAR_UNAME   0x0020     ///< user-defined name
00559 #define CVAR_UTYPE   0x0040     ///< user-defined type
00560 #define CVAR_RESULT  0x0080     ///< function result variable
00561 #define CVAR_ARG     0x0100     ///< function argument
00562 #define CVAR_FAKE    0x0200     ///< fake return variable
00563 #define CVAR_OVER    0x0400     ///< overlapping variable
00564 #define CVAR_FLOAT   0x0800     ///< used in a fpu insn
00565 #define CVAR_SPOILED 0x1000     ///< internal flag, do not use: spoiled var
00566 #define CVAR_MAPDST  0x2000     ///< other variables are mapped to this var
00567 //@}
00568 
00569 public:
00570   qstring name;          ///< variable name.
00571                          ///< use mbl_array_t::set_nice_lvar_name() and
00572                          ///< mbl_array_t::set_user_lvar_name() to modify it
00573   qstring cmt;           ///< variable comment string
00574   typestring _type;      ///< variable type
00575   int width;             ///< variable size in bytes
00576   int defblk;            ///< first block defining the variable.
00577                          ///< 0 for args, -1 if unknown
00578   uint64 divisor;        ///< max known divisor of the variable
00579 
00580   lvar_t(void) : flags(CVAR_USED), width(0), defblk(-1), divisor(0) {}
00581   lvar_t(const qstring &n, uint32 l, ea_t e, const typestring &t, int w, int db)
00582     : lvar_locator_t(l, e), flags(CVAR_USED), name(n), _type(t), width(w),
00583       defblk(db), divisor(0) {}
00584   lvar_t(mreg_t reg, int width, const type_t *type, int nblock, ea_t defea);
00585 
00586   /// Is the variable used in the code?
00587   bool used(void)  const { return (flags & CVAR_USED) != 0; }
00588   /// Has the variable a type?
00589   bool typed(void) const { return (flags & CVAR_TYPE) != 0; }
00590   /// Have corresponding microregs been replaced by references to this variable?
00591   bool mreg_done(void) const { return (flags & CVAR_MREG) != 0; }
00592   /// Does the variable have a nice name?
00593   bool has_nice_name(void) const { return (flags & CVAR_NAME) != 0; }
00594   /// Do we know the width of the variable?
00595   bool is_unknown_width(void) const { return (flags & CVAR_NOWD) != 0; }
00596   /// Has any user-defined information?
00597   bool has_user_info(void) const { return (flags & (CVAR_UNAME|CVAR_UTYPE)) != 0 || !cmt.empty(); }
00598   /// Has user-defined name?
00599   bool has_user_name(void) const { return (flags & CVAR_UNAME) != 0; }
00600   /// Has user-defined type?
00601   bool has_user_type(void) const { return (flags & CVAR_UTYPE) != 0; }
00602   /// Is the function result?
00603   bool is_result_var(void) const { return (flags & CVAR_RESULT) != 0; }
00604   /// Is the function argument?
00605   bool is_arg_var(void) const { return (flags & CVAR_ARG) != 0; }
00606   /// Is the promoted function argument?
00607   bool is_promoted_arg(void) const { return is_arg_var() && width < inf.cc.size_i; }
00608   /// Is fake return variable?
00609   bool is_fake_var(void) const { return (flags & CVAR_FAKE) != 0; }
00610   /// Is overlapped variable?
00611   bool is_overlapped_var(void) const { return (flags & CVAR_OVER) != 0; }
00612   /// Used by a fpu insn?
00613   bool is_floating_var(void) const { return (flags & CVAR_FLOAT) != 0; }
00614   /// Is spoiled var? (meaningful only during lvar allocation)
00615   bool is_spoiled_var(void) const { return (flags & CVAR_SPOILED) != 0; }
00616   /// Other variable(s) map to this var?
00617   bool is_mapdst_var(void) const { return (flags & CVAR_MAPDST) != 0; }
00618   void set_used(void) { flags |= CVAR_USED; }
00619   void clear_used(void) { flags &= ~CVAR_USED; }
00620   void set_typed(void) { flags |= CVAR_TYPE; }
00621   void set_non_typed(void) { flags &= ~CVAR_TYPE; }
00622   void clr_user_info(void) { flags &= ~(CVAR_UNAME|CVAR_UTYPE); }
00623   void set_user_name(void) { flags |= CVAR_NAME|CVAR_UNAME; }
00624   void set_user_type(void) { flags |= CVAR_TYPE|CVAR_UTYPE; }
00625   void clr_user_type(void) { flags &= ~CVAR_UTYPE; }
00626   void clr_user_name(void) { flags &= ~CVAR_UNAME; }
00627   void set_mreg_done(void) { flags |= CVAR_MREG; }
00628   void clr_mreg_done(void) { flags &= ~CVAR_MREG; }
00629   void set_unknown_width(void) { flags |= CVAR_NOWD; }
00630   void clr_unknown_width(void) { flags &= ~CVAR_NOWD; }
00631   void set_arg_var(void) { flags |= CVAR_ARG; }
00632   void clr_arg_var(void) { flags &= ~CVAR_ARG; }
00633   void set_fake_var(void) { flags |= CVAR_FAKE; }
00634   void clr_fake_var(void) { flags &= ~CVAR_FAKE; }
00635   void set_overlapped_var(void) { flags |= CVAR_OVER; }
00636   void clr_overlapped_var(void) { flags &= ~CVAR_OVER; }
00637   void set_floating_var(void) { flags |= CVAR_FLOAT; }
00638   void clr_floating_var(void) { flags &= ~CVAR_FLOAT; }
00639   void set_spoiled_var(void) { flags |= CVAR_SPOILED; }
00640   void clr_spoiled_var(void) { flags &= ~CVAR_SPOILED; }
00641   void set_mapdst_var(void) { flags |= CVAR_MAPDST; }
00642   void clr_mapdst_var(void) { flags &= ~CVAR_MAPDST; }
00643 
00644   void set_reg_name(const char *n)
00645   {
00646     name = n;              // do not verify uniqueness
00647     flags &= ~CVAR_USED;   // do not display the declaration
00648     flags |= CVAR_NAME;    // do not autorename
00649   }
00650   /// Do variables overlap?
00651   bool has_common(const lvar_t &v) const
00652   {
00653     return arglocs_overlap(location, width, v.location, v.width);
00654   }
00655   /// Does the variable overlap with the specified location?
00656   bool has_common_bit(argloc_t loc, asize_t width2) const
00657   {
00658     return arglocs_overlap(location, width, loc, width2);
00659   }
00660   /// Get variable type
00661   const typestring &type(void) const
00662   {
00663     return _type;
00664   }
00665   /// Check if the variable accept the specified type.
00666   /// Some types are forbidden (void, function types, wrong arrays, etc)
00667   bool hexapi accepts_type(const typestring &t);
00668   /// Set variable type without any validation.
00669   void force_lvar_type(const typestring &t)
00670   {
00671     _type = t;
00672     setflag(flags, CVAR_FLOAT, t.is_floating()); // set_floating_var/clr_floating_var
00673   }
00674   /// Set variable type
00675   /// If the type is inacceptable, interr is generated.
00676   void hexapi set_lvar_type(const typestring &t);
00677   /// Set final variable type.
00678   void set_final_lvar_type(const typestring &t)
00679   {
00680     set_lvar_type(t);
00681     set_typed();
00682   }
00683 
00684   /// Change the variable width. This function also changes
00685   /// the variable type.
00686   void hexapi set_width(int w, bool is_float=false);
00687 
00688 };
00689 
00690 /// Set of local variables
00691 struct lvars_t : public qvector<lvar_t>
00692 {
00693   /// Find input variable at the specified location.
00694   /// \param argloc variable location
00695   /// \param size variable size
00696   /// \return -1 if failed, otherwise the index into the variables vector.
00697   int find_input_lvar(argloc_t argloc, int size) { return find_lvar(argloc, size, 0); }
00698 
00699   /// Find stack variable at the specified location.
00700   /// \param spoff offset from the minimal sp
00701   /// \param width variable size
00702   /// \return -1 if failed, otherwise the index into the variables vector.
00703   int hexapi find_stkvar(int32 spoff, int width);
00704 
00705   /// Find variable at the specified location.
00706   /// \param ll variable location
00707   /// \return pointer to variable or NULL
00708   lvar_t *hexapi find(const lvar_locator_t &ll);
00709 
00710 
00711   /// Find variable at the specified location.
00712   /// \param location variable location
00713   /// \param width variable size
00714   /// \param defblk definition block of the lvar. -1 means any block
00715   /// \return -1 if failed, otherwise the index into the variables vector.
00716   int hexapi find_lvar(argloc_t location, int width, int defblk=-1);
00717 };
00718 
00719 /// Saved user settings for local variables
00720 struct lvar_saved_info_t
00721 {
00722   lvar_locator_t ll;
00723   qstring name;
00724   typestring type;
00725   qstring cmt;
00726   bool has_info(void) const { return !name.empty() || !type.empty() || !cmt.empty(); }
00727 };
00728 
00729 /// Local variable mapping (is used to merge variables)
00730 typedef std::map<lvar_locator_t, lvar_locator_t> lvar_mapping_t;
00731 
00732 /// Saved user settings iterator for local variables
00733 struct user_lvar_visitor_t
00734 {
00735   /// Delta to add to IDA stack offset to calculate Hex-Rays stack offsets.
00736   /// Should be set by the caller before calling save_user_lvar_settings();
00737   int stkoff_delta;
00738 
00739   /// Various flags. Possible values are from \ref ULV_
00740   int flags;
00741 /// \defgroup ULV_ user_lvar_visitor_t property bits
00742 /// Used in user_lvar_visitor_t::flags
00743 //@{
00744 #define ULV_PRECISE_DEFEA 0x0001        ///< Use precise defea's for lvar locations
00745 //@}
00746 
00747   /// Visit user defined local variable information.
00748   /// This function is called while we retrieve information from the idb.
00749   /// \param lv saved information about variable
00750   virtual int idaapi handle_retrieved_info(const lvar_saved_info_t &lv) = 0;
00751 
00752   /// Visit user defined local variable information.
00753   /// This function is called while we retrieve information from the idb.
00754   /// \param lm saved information about variable mappings. may be modified.
00755   virtual int idaapi handle_retrieved_mapping(lvar_mapping_t &lm) = 0;
00756 
00757   /// Get number of lvars with user defined settings.
00758   /// This function is called while we save information to the idb.
00759   /// It resets the enumeration.
00760   /// \return number of user-defined lvars
00761   virtual int idaapi get_info_qty_for_saving(void) = 0;
00762 
00763   /// Get next user-defined lvar data
00764   /// This function is called while we save information to the idb.
00765   /// \param lv information to save about variable
00766   /// \returns true is success
00767   virtual bool idaapi get_info_for_saving(lvar_saved_info_t *lv) = 0;
00768 
00769   /// Get lvar mapping info
00770   /// This function is called while we save information to the idb.
00771   /// \returns lvar mapping or NULL
00772   virtual const lvar_mapping_t *idaapi get_info_mapping_for_saving(void) = 0;
00773 };
00774 
00775 /// Restore user defined local variable settings in the database.
00776 /// \param func_ea entry address of the function
00777 /// \param ulv helper visitor class for lvar settings
00778 /// \return 0 if all lvar settings have been enumerated. Otherwise returns
00779 ///           the code returned by the visitor class.
00780 
00781 int hexapi restore_user_lvar_settings(ea_t func_ea, user_lvar_visitor_t &ulv);
00782 
00783 
00784 /// Save user defined local variable settings into the database.
00785 /// \param func_ea entry address of the function
00786 /// \param uvl user lvar setting enumerator. get_user_lvar_qty() and get_next_user_lvar()
00787 ///            will be used to enumerate user settings.
00788 
00789 void hexapi save_user_lvar_settings(ea_t func_ea, user_lvar_visitor_t &ulv);
00790 
00791 
00792 //-------------------------------------------------------------------------
00793 struct fnumber_t        /// Floating point constant.
00794                         /// For more details, please see the ieee.h file from IDA SDK.
00795 {
00796   uint16 fnum[6];       ///< Internal representation of the number
00797   int nbytes;           ///< Original size of the constant in bytes
00798   operator       uint16 *(void)       { return fnum; }
00799   operator const uint16 *(void) const { return fnum; }
00800   size_t hexapi print(char *buf, size_t bufsize) const;
00801   DEFINE_MEMORY_ALLOCATION_FUNCS()
00802   DECLARE_COMPARISONS(fnumber_t)
00803   {
00804     return ecmp(fnum, r.fnum);
00805   }
00806 };
00807 
00808 //-------------------------------------------------------------------------
00809 // Warning ids
00810 enum warnid_t
00811 {
00812   WARN_VARARG_REGS,   //  0 can not handle register arguments in vararg function, discarded them
00813   WARN_ILL_PURGED,    //  1 odd caller purged bytes %d, correcting
00814   WARN_ILL_FUNCTYPE,  //  2 invalid function type has been ignored
00815   WARN_VARARG_TCAL,   //  3 can not handle tail call to vararg
00816   WARN_VARARG_NOSTK,  //  4 call vararg without local stack
00817   WARN_VARARG_MANY,   //  5 too many varargs, some ignored
00818   WARN_ADDR_OUTARGS,  //  6 can not handle address arithmetics in outgoing argument area of stack frame -- unused
00819   WARN_DEP_UNK_CALLS, //  7 found interdependent unknown calls
00820   WARN_ILL_ELLIPSIS,  //  8 erroneously detected ellipsis type has been ignored
00821   WARN_GUESSED_TYPE,  //  9 using guessed type %s;
00822   WARN_EXP_LINVAR,    // 10 failed to expand a linear variable
00823   WARN_WIDEN_CHAINS,  // 11 failed to widen chains
00824   WARN_BAD_PURGED,    // 12 inconsistent function type and number of purged bytes
00825   WARN_CBUILD_LOOPS,  // 13 too many cbuild loops
00826   WARN_NO_SAVE_REST,  // 14 could not find valid save-restore pair for %s
00827   WARN_ODD_INPUT_REG, // 15 odd input register %s
00828   WARN_ODD_ADDR_USE,  // 16 odd use of a variable address
00829   WARN_MUST_RET_FP,   // 17 function return type is incorrect (must be floating point)
00830   WARN_ILL_FPU_STACK, // 18 inconsistent fpu stack
00831   WARN_SELFREF_PROP,  // 19 self-referencing variable has been detected
00832   WARN_WOULD_OVERLAP, // 20 variables would overlap: %s
00833   WARN_ARRAY_INARG,   // 21 array has been used for an input argument
00834   WARN_MAX_ARGS,      // 22 too many input arguments, some ignored
00835   WARN_BAD_FIELD_TYPE,// 23 incorrect structure member type for %s::%s, ignored
00836 
00837   WARN_MAX,
00838 };
00839 
00840 // Warnings
00841 struct hexwarn_t
00842 {
00843   ea_t ea;
00844   warnid_t id;
00845   qstring text;
00846   DECLARE_COMPARISONS(hexwarn_t)
00847   {
00848     if ( ea < r.ea )
00849       return -1;
00850     if ( ea > r.ea )
00851       return 1;
00852     if ( id < r.id )
00853       return -1;
00854     if ( id > r.id )
00855       return 1;
00856     return strcmp(text.c_str(), r.text.c_str());
00857   }
00858 };
00859 typedef qvector<hexwarn_t> hexwarns_t;
00860 
00861 //-------------------------------------------------------------------------
00862 /// Get decompiler version.
00863 /// \return pointer to version string. For example: "1.0.071025"
00864 
00865 const char *hexapi get_hexrays_version(void);
00866 
00867 
00868 /// Open pseudocode window.
00869 /// The specified function is decompiled and the pseudocode window is opened.
00870 /// \param ea function to decompile
00871 /// \param new_window 0:reuse existing window; 1:open new window;
00872 ///        -1: reuse existing window if the current view is pseudocode
00873 /// \return false if failed
00874 
00875 vdui_t *hexapi open_pseudocode(ea_t ea, int new_window);
00876 
00877 
00878 /// Close pseudocode window.
00879 /// \param f pointer to window
00880 /// \return false if failed
00881 
00882 bool hexapi close_pseudocode(TForm *f);
00883 
00884 
00885 /// Decompile a function.
00886 /// \param pfn pointer to function to decompile
00887 /// \param hf extended error information (if failed)
00888 /// \return pointer to the decompilation result. It is the caller's
00889 ///         responsability to delete it. NULL if failed.
00890 
00891 cfunc_t *hexapi decompile(func_t *pfn, hexrays_failure_t *hf);
00892 
00893 
00894 /// \defgroup VDRUN_ Batch decompilation bits
00895 //@{
00896 #define VDRUN_NEWFILE 0x0000  ///< Create a new file or overwrite existing file
00897 #define VDRUN_APPEND  0x0001  ///< Create a new file or append to existing file
00898 #define VDRUN_ONLYNEW 0x0002  ///< Fail if output file already exists
00899 #define VDRUN_SILENT  0x0004  ///< Silent decompilation
00900 #define VDRUN_SENDIDB 0x0008  ///< Send problematic databases to hex-rays.com
00901 #define VDRUN_MAYSTOP 0x0010  ///< the user can cancel decompilation
00902 #define VDRUN_CMDLINE 0x0020  ///< called from ida's command line
00903 #define VDRUN_STATS   0x0040  ///< print statistics into vd_stats.txt
00904 //@}
00905 
00906 /// Batch decompilation.
00907 /// Decompile all or the specified functions
00908 /// \return true if no internal error occured and the user has not cancelled decompilation
00909 /// \param outfile name of the output file
00910 /// \param funcaddrs list of functions to decompile.
00911 ///                  If NULL or empty, then decompile all nonlib functions
00912 /// \param vdrun_flags \ref VDRUN_
00913 
00914 bool hexapi decompile_many(const char *outfile, eavec_t *funcaddrs, int vdrun_flags);
00915 
00916 
00917 /// Get textual description of an error code
00918 /// \return pointer to static error description string
00919 /// \param code \ref MERR_
00920 
00921 const char *hexapi micro_err_format(int code);
00922 
00923 /// \defgroup MERR_ Microcode error codes
00924 //@{
00925 #define MERR_OK        0       ///< ok
00926 #define MERR_BLOCK     1       ///< no error, switch to new block
00927 #define MERR_INTERR    (-1)    ///< internal error
00928 #define MERR_INSN      (-2)    ///< can not convert to microcode
00929 #define MERR_MEM       (-3)    ///< not enough memory
00930 #define MERR_BADBLK    (-4)    ///< bad block found
00931 #define MERR_BADSP     (-5)    ///< positive sp value has been found
00932 #define MERR_PROLOG    (-6)    ///< prolog analysis failed
00933 #define MERR_SWITCH    (-7)    ///< wrong switch idiom
00934 #define MERR_EXCEPTION (-8)    ///< exception analysis failed
00935 #define MERR_HUGESTACK (-9)    ///< stack frame is too big
00936 #define MERR_LVARS     (-10)   ///< local variable allocation failed
00937 #define MERR_BITNESS   (-11)   ///< 16bit programs are not supported (yet)
00938 #define MERR_BADCALL   (-12)   ///< could not determine call arguments
00939 #define MERR_BADFRAME  (-13)   ///< function frame is wrong
00940 #define MERR_UNKTYPE   (-14)   ///< undefined type %s
00941 #define MERR_BADIDB    (-15)   ///< inconsistent database information
00942 #define MERR_SIZEOF    (-16)   ///< wrong basic type sizes in compiler settings
00943 #define MERR_REDO      (-17)   ///< redecompilation has been requested
00944 #define MERR_CANCELED  (-18)   ///< decompilation has been cancelled
00945 #define MERR_RECDEPTH  (-19)   ///< max recursion depth reached during lvar allocation
00946 #define MERR_OVERLAP   (-20)   ///< variables would overlap: %s
00947 #define MERR_PARTINIT  (-21)   ///< partially initialized variable %s
00948 #define MERR_COMPLEX   (-22)   ///< too complex function
00949 #define MERR_LICENSE   (-23)   ///< no license available
00950 #define MERR_MAX_ERR   23
00951 #define MERR_LOOP      (-24)   ///< internal code: redo last loop (never reported)
00952 //@}
00953 
00954 /// Exception object: decompiler failure information
00955 struct hexrays_failure_t
00956 {
00957   int code;                     ///< \ref MERR_
00958   ea_t errea;                   ///< associated address
00959   qstring str;                  ///< string information
00960   hexrays_failure_t(void) : code(MERR_OK) {}
00961   hexrays_failure_t(int c, ea_t ea, const char *buf=NULL) : code(c), errea(ea), str(buf) {}
00962   hexrays_failure_t(int c, ea_t ea, const qstring &buf) : code(c), errea(ea), str(buf) {}
00963   qstring hexapi desc(void) const;
00964   DEFINE_MEMORY_ALLOCATION_FUNCS()
00965 };
00966 
00967 /// Exception object: decompiler exception
00968 struct vd_failure_t : public std::exception
00969 {
00970   hexrays_failure_t hf;
00971   vd_failure_t(void) {}
00972   vd_failure_t(int code, ea_t ea, const char *buf=NULL) : hf(code, ea, buf) {}
00973   vd_failure_t(int code, ea_t ea, const qstring &buf) : hf(code, ea, buf) {}
00974   vd_failure_t(const hexrays_failure_t &_hf) : hf(_hf) {}
00975   qstring desc(void) const { return hf.desc(); }
00976 #ifdef __GNUC__
00977   ~vd_failure_t(void) throw() {}
00978 #endif
00979   DEFINE_MEMORY_ALLOCATION_FUNCS()
00980 };
00981 
00982 /// Exception object: decompiler internal error
00983 struct vd_interr_t : public vd_failure_t
00984 {
00985   vd_interr_t(ea_t ea, const qstring &buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
00986   vd_interr_t(ea_t ea, const char *buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
00987 };
00988 
00989 /// Send the database to Hex-Rays.
00990 /// This function sends the current database to the hex-rays server.
00991 /// The database is sent in the compressed form over an encrypted (SSL) connection.
00992 /// \param err failure description object. Empty hexrays_failure_t object can be used if error information is not available.
00993 /// \param silent if false, a dialog box will be displayed before sending the database.
00994 
00995 void hexapi send_database(const hexrays_failure_t &err, bool silent);
00996 
00997 
00998 //-------------------------------------------------------------------------
00999 /// Template to compare any 2 values of the same type. Returns -1/0/1
01000 template <class T>
01001 int compare(const T &a, const T &b)
01002 {
01003   if ( a < b ) return -1;
01004   if ( a > b ) return 1;
01005   return 0;
01006 }
01007 
01008 template <class T>
01009 int compare(const qvector<T> &a, const qvector<T> &b)
01010 {
01011   return compare_containers(a, b);
01012 }
01013 
01014 template <class T>
01015 int compare(const qlist<T> &a, const qlist<T> &b)
01016 {
01017   return compare_containers(a, b);
01018 }
01019 
01020 template <class T, class U>
01021 int compare(const std::pair<T, U> &a, const std::pair<T, U> &b)
01022 {
01023   int code = compare(a.first, b.first);
01024   if ( code != 0 )
01025     return code;
01026   return compare(a.second, b.second);
01027 }
01028 
01029 /// Template to compare any 2 containers of the same type. Returns -1/0/1
01030 template <class T>
01031 int compare_containers(const T &l, const T &r)
01032 {
01033   typename T::const_iterator p = l.begin();
01034   typename T::const_iterator q = r.begin();
01035   for ( ; p != l.end() && q != r.end(); ++p,++q )
01036   {
01037     int code = compare(*p, *q);
01038     if ( code != 0 )
01039       return code;
01040   }
01041   if ( p == l.end() && q != r.end() ) return -1;
01042   if ( p != l.end() && q == r.end() ) return 1;
01043   return 0;
01044 }
01045 
01046 //-------------------------------------------------------------------------
01047 /// Ctree element type. At the beginning of this list there are expression
01048 /// elements (cot_...), followed by statement elements (cit_...).
01049 enum ctype_t
01050 {
01051   cot_empty    = 0,
01052   cot_comma    = 1,   ///< x, y
01053   cot_asg      = 2,   ///< x = y
01054   cot_asgbor   = 3,   ///< x |= y
01055   cot_asgxor   = 4,   ///< x ^= y
01056   cot_asgband  = 5,   ///< x &= y
01057   cot_asgadd   = 6,   ///< x += y
01058   cot_asgsub   = 7,   ///< x -= y
01059   cot_asgmul   = 8,   ///< x *= y
01060   cot_asgsshr  = 9,   ///< x >>= y signed
01061   cot_asgushr  = 10,  ///< x >>= y unsigned
01062   cot_asgshl   = 11,  ///< x <<= y
01063   cot_asgsdiv  = 12,  ///< x /= y signed
01064   cot_asgudiv  = 13,  ///< x /= y unsigned
01065   cot_asgsmod  = 14,  ///< x %= y signed
01066   cot_asgumod  = 15,  ///< x %= y unsigned
01067   cot_tern     = 16,  ///< x ? y : z
01068   cot_lor      = 17,  ///< x || y
01069   cot_land     = 18,  ///< x && y
01070   cot_bor      = 19,  ///< x | y
01071   cot_xor      = 20,  ///< x ^ y
01072   cot_band     = 21,  ///< x & y
01073   cot_eq       = 22,  ///< x == y int or fpu (see EXFL_FPOP)
01074   cot_ne       = 23,  ///< x != y int or fpu (see EXFL_FPOP)
01075   cot_sge      = 24,  ///< x >= y signed or fpu (see EXFL_FPOP)
01076   cot_uge      = 25,  ///< x >= y unsigned
01077   cot_sle      = 26,  ///< x <= y signed or fpu (see EXFL_FPOP)
01078   cot_ule      = 27,  ///< x <= y unsigned
01079   cot_sgt      = 28,  ///< x >  y signed or fpu (see EXFL_FPOP)
01080   cot_ugt      = 29,  ///< x >  y unsigned
01081   cot_slt      = 30,  ///< x <  y signed or fpu (see EXFL_FPOP)
01082   cot_ult      = 31,  ///< x <  y unsigned
01083   cot_sshr     = 32,  ///< x >> y signed
01084   cot_ushr     = 33,  ///< x >> y unsigned
01085   cot_shl      = 34,  ///< x << y
01086   cot_add      = 35,  ///< x + y
01087   cot_sub      = 36,  ///< x - y
01088   cot_mul      = 37,  ///< x * y
01089   cot_sdiv     = 38,  ///< x / y signed
01090   cot_udiv     = 39,  ///< x / y unsigned
01091   cot_smod     = 40,  ///< x % y signed
01092   cot_umod     = 41,  ///< x % y unsigned
01093   cot_fadd     = 42,  ///< x + y fp
01094   cot_fsub     = 43,  ///< x - y fp
01095   cot_fmul     = 44,  ///< x * y fp
01096   cot_fdiv     = 45,  ///< x / y fp
01097   cot_fneg     = 46,  ///< -x fp
01098   cot_neg      = 47,  ///< -x
01099   cot_cast     = 48,  ///< (type)x
01100   cot_lnot     = 49,  ///< !x
01101   cot_bnot     = 50,  ///< ~x
01102   cot_ptr      = 51,  ///< *x, access size in 'ptrsize'
01103   cot_ref      = 52,  ///< &x
01104   cot_postinc  = 53,  ///< x++
01105   cot_postdec  = 54,  ///< x--
01106   cot_preinc   = 55,  ///< ++x
01107   cot_predec   = 56,  ///< --x
01108   cot_call     = 57,  ///< x(...)
01109   cot_idx      = 58,  ///< x[y]
01110   cot_memref   = 59,  ///< x.m
01111   cot_memptr   = 60,  ///< x->m, access size in 'ptrsize'
01112   cot_num      = 61,  ///< n
01113   cot_fnum     = 62,  ///< fpc
01114   cot_str      = 63,  ///< string constant
01115   cot_obj      = 64,  ///< obj_ea
01116   cot_var      = 65,  ///< v
01117   cot_insn     = 66,  ///< instruction in expression, internal representation only
01118   cot_sizeof   = 67,  ///< sizeof(x)
01119   cot_helper   = 68,  ///< arbitrary name
01120   cot_last     = cot_helper,
01121   cit_empty    = 69,  ///< instruction types start here
01122   cit_block    = 70,  ///< block-statement: { ... }
01123   cit_expr     = 71,  ///< expression-statement: expr;
01124   cit_if       = 72,  ///< if-statement
01125   cit_for      = 73,  ///< for-statement
01126   cit_while    = 74,  ///< while-statement
01127   cit_do       = 75,  ///< do-statement
01128   cit_switch   = 76,  ///< switch-statement
01129   cit_break    = 77,  ///< break-statement
01130   cit_continue = 78,  ///< continue-statement
01131   cit_return   = 79,  ///< return-statement
01132   cit_goto     = 80,  ///< goto-statement
01133   cit_asm      = 81,  ///< asm-statement
01134   cit_end
01135 };
01136 
01137 /// \defgroup fixtype_t C operator writing styles
01138 /// Used in operator_info_t::fixtype
01139 //@{
01140 const uchar
01141   FX_NONE    = 0,       ///< not applicable
01142   FX_INFIX   = 1,       ///< infix: a + b
01143   FX_PREFIX  = 2,       ///< prefix: *a
01144   FX_POSTFIX = 3,       ///< postfix: a++
01145   FX_TERNARY = 4;       ///< ternary: a ? b : c
01146 //@}
01147 
01148 /// \defgroup opattrs_t C operator attributes
01149 /// Used in operator_info_t::flags
01150 //@{
01151 const uchar
01152   COI_RL     = 0x00,    ///< right to left
01153   COI_LR     = 0x01,    ///< left to right
01154   COI_INT    = 0x02,    ///< requires integer operands
01155   COI_FP     = 0x04,    ///< requires floating point operands
01156   COI_SH     = 0x08,    ///< is shift operation?
01157   COI_SGN    = 0x10,    ///< sign sensitive?
01158   COI_SBN    = 0x20;    ///< is simple binary?
01159 //@}
01160 
01161 /// Information about C operator
01162 struct operator_info_t
01163 {
01164   DEFINE_MEMORY_ALLOCATION_FUNCS()
01165   const char *text;     ///< Text representation
01166   uchar precedence;     ///< Operator precedence (lower: more priority)
01167   uchar valency;        ///< Number of operator arguments
01168   uchar fixtype;        ///< \ref fixtype_t
01169   uchar flags;          ///< \ref opattrs_t
01170 };
01171 
01172 
01173 
01174 /// Negate a comparison operator. For example, \ref cot_sge becomes \ref cot_slt
01175 ctype_t hexapi negated_relation(ctype_t op);
01176 /// Get operator sign. Meaningful for sign-dependent operators, like \ref cot_sdiv
01177 type_sign_t hexapi get_op_signness(ctype_t op);
01178 /// Convert plain operator into assignment operator. For example, \ref cot_add returns \ref cot_asgadd
01179 ctype_t hexapi asgop(ctype_t cop);
01180 /// Convert assignment operator into plain operator. For example, \ref cot_asgadd returns \ref cot_add
01181 /// \return cot_empty is the input operator is not an assignment operator.
01182 ctype_t hexapi asgop_revert(ctype_t cop);
01183 /// Does operator use the 'x' field of cexpr_t?
01184 inline bool op_uses_x(ctype_t op) { return op >= cot_comma && op <= cot_memptr; }
01185 /// Does operator use the 'y' field of cexpr_t?
01186 inline bool op_uses_y(ctype_t op) { return (op >= cot_comma && op <= cot_fdiv) || op == cot_idx; }
01187 /// Does operator use the 'z' field of cexpr_t?
01188 inline bool op_uses_z(ctype_t op) { return op == cot_tern; }
01189 /// Is binary operator?
01190 inline bool is_binary(ctype_t op) { return op_uses_y(op) && op != cot_tern; } // x,y
01191 /// Is unary operator?
01192 inline bool is_unary(ctype_t op) { return op >= cot_fneg && op <= cot_predec; }
01193 /// Is comparison operator?
01194 inline bool is_relational(ctype_t op) { return op >= cot_eq && op <= cot_ult; }
01195 /// Is assignment operator?
01196 inline bool is_assignment(ctype_t op) { return op >= cot_asg && op <= cot_asgumod; }
01197 // Can operate on UDTs?
01198 inline bool accepts_udts(ctype_t op) { return op == cot_asg || op == cot_comma || op > cot_last; }
01199 /// Is pre/post increment/decrement operator?
01200 inline bool is_prepost(ctype_t op)    { return op >= cot_postinc && op <= cot_predec; }
01201 /// Is commutative operator?
01202 inline bool is_commutative(ctype_t op)
01203 {
01204   return op == cot_bor
01205       || op == cot_xor
01206       || op == cot_band
01207       || op == cot_add
01208       || op == cot_mul
01209       || op == cot_fadd
01210       || op == cot_fmul
01211       || op == cot_ne
01212       || op == cot_eq;
01213 }
01214 /// Is additive operator?
01215 inline bool is_additive(ctype_t op)
01216 {
01217   return op == cot_add
01218       || op == cot_sub
01219       || op == cot_fadd
01220       || op == cot_fsub;
01221 }
01222 /// Is multiplicative operator?
01223 inline bool is_multiplicative(ctype_t op)
01224 {
01225   return op == cot_mul
01226       || op == cot_sdiv
01227       || op == cot_udiv
01228       || op == cot_fmul
01229       || op == cot_fdiv;
01230 }
01231 
01232 /// Is bit relatede operator?
01233 inline bool is_bitop(ctype_t op)
01234 {
01235   return op == cot_bor
01236       || op == cot_xor
01237       || op == cot_band
01238       || op == cot_bnot;
01239 }
01240 
01241 /// Is logical operator?
01242 inline bool is_logical(ctype_t op)
01243 {
01244   return op == cot_lor
01245       || op == cot_land
01246       || op == cot_lnot;
01247 }
01248 
01249 /// Is loop statement code?
01250 inline bool is_loop(ctype_t op)
01251 {
01252   return op == cit_for
01253       || op == cit_while
01254       || op == cit_do;
01255 }
01256 /// Does a break statement influence the specified statement code?
01257 inline bool is_break_consumer(ctype_t op)
01258 {
01259   return is_loop(op) || op == cit_switch;
01260 }
01261 
01262 /// Is Lvalue operator?
01263 inline bool is_lvalue(ctype_t op)
01264 {
01265   return op == cot_ptr      // *x
01266       || op == cot_idx      // x[y]
01267       || op == cot_memref   // x.m
01268       || op == cot_memptr   // x->m
01269       || op == cot_obj      // v
01270       || op == cot_var;     // l
01271 }
01272 
01273 /// Is the operator allowed on small struni (structure/union)?
01274 inline bool is_allowed_on_small_struni(ctype_t op)
01275 {
01276   return op == cit_return
01277       || op == cot_asg
01278       || op == cot_eq
01279       || op == cot_ne
01280       || op == cot_comma
01281       || (op > cot_last && op < cit_end); // any insn
01282 }
01283 
01284 /// An immediate number
01285 struct cnumber_t
01286 {
01287   uint64 _value;                ///< its value
01288   number_format_t nf;           ///< how to represent it
01289   cnumber_t(int _opnum=0) : nf(_opnum) {}
01290 
01291   /// Get text representation
01292   /// \param buf output buffer
01293   /// \param bufsize size of output buffer
01294   /// \param type number type
01295   size_t hexapi print(char *buf, size_t bufsize, const type_t *type) const;
01296 
01297   /// Get value.
01298   /// This function will properly extend the number sign to 64bits
01299   /// depending on the type sign.
01300   uint64 hexapi value(const typestring &type) const;
01301 
01302   /// Assign new value
01303   /// \param v new value
01304   /// \param nbytes size of the new value in bytes
01305   /// \param sign sign of the value
01306   void hexapi assign(uint64 v, int nbytes, type_sign_t sign);
01307 
01308   DECLARE_COMPARISONS(cnumber_t);
01309 };
01310 
01311 /// Reference to a local variable
01312 struct var_ref_t
01313 {
01314   mbl_array_t *mba;     ///< pointer to the underlying micro array
01315   int idx;              ///< index into lvars_t
01316   DEFINE_MEMORY_ALLOCATION_FUNCS()
01317   DECLARE_COMPARISONS(var_ref_t);
01318 };
01319 
01320 /// Vector of parents
01321 typedef qvector<citem_t *> parents_t;
01322 
01323 /// A generic helper class that is used for ctree traversal
01324 struct ctree_visitor_t
01325 {
01326   DEFINE_MEMORY_ALLOCATION_FUNCS()
01327   int cv_flags;           ///< \ref CV_
01328 /// \defgroup CV_ Ctree visitor property bits
01329 /// Used in ctree_visitor_t::cv_flags
01330 //@{
01331 #define CV_FAST    0x0000 ///< do not maintain parent information
01332 #define CV_PRUNE   0x0001 ///< this bit is set by visit...() to prune the walk
01333 #define CV_PARENTS 0x0002 ///< maintain parent information
01334 #define CV_POST    0x0004 ///< call the leave...() functions
01335 #define CV_RESTART 0x0008 ///< restart enumeration at the top expr (apply_to_exprs)
01336 #define CV_INSNS   0x0010 ///< visit only statements, prune all expressions
01337                           ///< do not use before the final ctree maturity because
01338                           ///< expressions may contain statements at intermediate
01339                           ///< stages (see cot_insn). Otherwise you risk missing
01340                           ///< statements embedded into expressions.
01341 //@}
01342   /// Should the parent information by maintained?
01343   bool maintain_parents(void) const { return (cv_flags & CV_PARENTS) != 0; }
01344   /// Should the traversal skip the children of the current item?
01345   bool must_prune(void)       const { return (cv_flags & CV_PRUNE) != 0; }
01346   /// Should the traversal restart?
01347   bool must_restart(void)     const { return (cv_flags & CV_RESTART) != 0; }
01348   /// Should the leave...() functions be called?
01349   bool is_postorder(void)     const { return (cv_flags & CV_POST) != 0; }
01350   /// Should all expressions be automatically pruned?
01351   bool only_insns(void)       const { return (cv_flags & CV_INSNS) != 0; }
01352   /// Prune children.
01353   /// This function may be called by a visitor() to skip all children of the current item.
01354   void prune_now(void) { cv_flags |= CV_PRUNE; }
01355   /// Do not prune children. This is an internal function, no need to call it.
01356   void clr_prune(void) { cv_flags &= ~CV_PRUNE; }
01357   /// Restart the travesal. Meaningful only in apply_to_exprs()
01358   void set_restart(void) { cv_flags |= CV_RESTART; }
01359   /// Do not restart. This is an internal function, no need to call it.
01360   void clr_restart(void) { cv_flags &= ~CV_RESTART; }
01361 
01362   parents_t parents;      ///< Vector of parents of the current item
01363 
01364   /// Constructor.
01365   /// This constructor can be used with CV_FAST, CV_PARENTS
01366   /// combined with CV_POST, CV_ONLYINS
01367   ctree_visitor_t(int _flags) : cv_flags(_flags) {}
01368 
01369   /// Traverse ctree.
01370   /// The traversal will start at the specified item and continue until
01371   /// of one the visit_...() functions return a non-zero value.
01372   /// \param item root of the ctree to traverse
01373   /// \param parent parent of the specified item. can be specified as NULL.
01374   /// \return 0 or a non-zero value returned by a visit_...() function
01375   int hexapi apply_to(citem_t *item, citem_t *parent);
01376 
01377   /// Traverse only expressions.
01378   /// The traversal will start at the specified item and continue until
01379   /// of one the visit_...() functions return a non-zero value.
01380   /// \param item root of the ctree to traverse
01381   /// \param parent parent of the specified item. can be specified as NULL.
01382   /// \return 0 or a non-zero value returned by a visit_...() function
01383   int hexapi apply_to_exprs(citem_t *item, citem_t *parent);
01384 
01385   /// Get parent of the current item as an expression
01386   cexpr_t *parent_expr(void) { return (cexpr_t *)parents.back(); }
01387   /// Get parent of the current item as a statement
01388   cinsn_t *parent_insn(void) { return (cinsn_t *)parents.back(); }
01389 
01390   // the following functions are redefined by the derived class
01391   // in order to perform the desired actions during the traversal
01392 
01393   /// Visit a statement.
01394   /// This is a visitor function which should be overridden by a derived
01395   /// class to do some useful work.
01396   /// This visitor performs pre-order traserval, i.e. an item is visited before
01397   /// its children.
01398   /// \return 0 to continue the traversal, nonzero to stop.
01399   virtual int idaapi visit_insn(cinsn_t *) { return 0; }
01400 
01401   /// Visit an expression.
01402   /// This is a visitor function which should be overridden by a derived
01403   /// class to do some useful work.
01404   /// This visitor performs pre-order traserval, i.e. an item is visited before
01405   /// its children.
01406   /// \return 0 to continue the traversal, nonzero to stop.
01407   virtual int idaapi visit_expr(cexpr_t *) { return 0; }
01408 
01409   /// Visit a statement after having visited its children
01410   /// This is a visitor function which should be overridden by a derived
01411   /// class to do some useful work.
01412   /// This visitor performs post-order traserval, i.e. an item is visited after
01413   /// its children.
01414   /// \return 0 to continue the traversal, nonzero to stop.
01415   virtual int idaapi leave_insn(cinsn_t *) { return 0; }
01416 
01417   /// Visit an expression after having visited its children
01418   /// This is a visitor function which should be overridden by a derived
01419   /// class to do some useful work.
01420   /// This visitor performs post-order traserval, i.e. an item is visited after
01421   /// its children.
01422   /// \return 0 to continue the traversal, nonzero to stop.
01423   virtual int idaapi leave_expr(cexpr_t *) { return 0; }
01424 };
01425 
01426 /// A helper ctree traversal class that maintains parent information
01427 struct ctree_parentee_t : public ctree_visitor_t
01428 {
01429   ctree_parentee_t(bool post=false)
01430     : ctree_visitor_t((post ? CV_POST : 0)|CV_PARENTS) {}
01431 
01432   /// Recalculate types of parent node.
01433   /// If a node type has been changed, the visitor must recalculate
01434   /// all parent types, otherwise the ctree becomes inconsistent.
01435   /// If during this recalculation a parent node is added/deleted,
01436   /// this function returns true. In this case it is recommended
01437   /// to restart the traversal because the information about parent nodes
01438   /// is stale.
01439   /// \return false-ok to continue the traversal, true-must stop.
01440   bool hexapi recalc_parent_types(void);
01441 };
01442 
01443 /// Class to traverse the whole function
01444 struct cfunc_parentee_t : public ctree_parentee_t
01445 {
01446   cfunc_t *func;        ///< Pointer to current function
01447   cfunc_parentee_t(cfunc_t *f, bool post=false)
01448     : ctree_parentee_t(post), func(f) {}
01449 
01450   /// Calculate rvalue type.
01451   /// This function tries to determine the type of the specified item
01452   /// based on its context. For example, if the current expression is the
01453   /// right side of an assignment operator, the type
01454   /// of its left side will be returned. This function can be used to determine the 'best'
01455   /// type of the specified expression.
01456   /// \param[in] e expression to determine the desired type
01457   /// \param[out] target 'best' type of the expression will be returned here
01458   /// \return false if failed
01459   bool hexapi calc_rvalue_type(const cexpr_t *e, typestring &target);
01460 };
01461 
01462 /// Ctree maturity level. The level will increase
01463 /// as we switch from one phase of ctree generation to the next one
01464 enum ctree_maturity_t
01465 {
01466   CMAT_ZERO,            ///< does not exist
01467   CMAT_BUILT,           ///< just generated
01468   CMAT_TRANS1,          ///< applied first wave of transformations
01469   CMAT_NICE,            ///< nicefied expressions
01470   CMAT_TRANS2,          ///< applied second wave of transformations
01471   CMAT_CPA,             ///< corrected pointer arithmetic
01472   CMAT_TRANS3,          ///< applied third wave of transformations
01473   CMAT_CASTED,          ///< added necessary casts
01474   CMAT_FINAL,           ///< ready-to-use
01475 };
01476 
01477 //--------------------------------------------------------------------------
01478 /// Comment item preciser.
01479 /// Item preciser is used to assign comments to ctree items
01480 /// A ctree item may have several comments attached to it. For example,
01481 /// an if-statement may have the following comments: <pre>
01482 ///  if ( ... )    // cmt1
01483 ///  {             // cmt2
01484 ///  }             // cmt3
01485 ///  else          // cmt4
01486 ///  {                     -- usually the else block has a separate ea
01487 ///  } </pre>
01488 /// The first 4 comments will have the same ea. In order to denote the exact
01489 /// line for the comment, we store the item_preciser along with ea.
01490 enum item_preciser_t
01491 {
01492   // inner comments (comments within an expression)
01493   ITP_EMPTY,    ///< nothing
01494   ITP_ARG1,     ///< , (64 entries are reserved for 64 call arguments)
01495   ITP_ARG64=ITP_ARG1+63, // ,
01496   ITP_BRACE1,   // (
01497   ITP_INNER_LAST=ITP_BRACE1,
01498   // outer comments
01499   ITP_ASM,      ///< __asm-line
01500   ITP_ELSE,     ///< else-line
01501   ITP_DO,       ///< do-line
01502   ITP_SEMI,     ///< semicolon
01503   ITP_CURLY1,   ///< {
01504   ITP_CURLY2,   ///< }
01505   ITP_BRACE2,   ///< )
01506   ITP_COLON,    ///< : (label)
01507   ITP_BLOCK1,   ///< opening block comment. this comment is printed before the item
01508                 ///< (other comments are indented and printed after the item)
01509   ITP_BLOCK2,   ///< closing block comment.
01510   // update get_preciser_text() if this enum changes
01511   ITP_SIGN = 0x40000000, // negative case value (if ITP_CASE)
01512   ITP_CASE = 0x80000000
01513 };
01514 /// Ctree location. Used to denote comment locations.
01515 struct treeloc_t
01516 {
01517   DEFINE_MEMORY_ALLOCATION_FUNCS()
01518   ea_t ea;
01519   item_preciser_t itp;
01520   bool operator < (const treeloc_t &r) const
01521   {
01522     return ea < r.ea
01523         || (ea == r.ea && itp < r.itp);
01524   }
01525   bool operator == (const treeloc_t &r) const
01526   {
01527     return ea == r.ea && itp == r.itp;
01528   }
01529 };
01530 
01531 /// Comment retrieval type.
01532 /// Ctree remembers what comments have already been retrieved.
01533 /// This is done because our mechanism of item_precisers is still
01534 /// not perfect and in theory some listing lines can not be told
01535 /// apart. To avoid comment duplication, we remember if a comment
01536 /// has already been used or not.
01537 enum cmt_retrieval_type_t
01538 {
01539   RETRIEVE_ONCE,        ///< Retrieve comment if it has not been used yet
01540   RETRIEVE_ALWAYS,      ///< Retrieve comment even if it has been used
01541 };
01542 
01543 /// Ctree item comment.
01544 /// For each comment we remember its body and the fact of its retrieval
01545 struct citem_cmt_t : public qstring
01546 {
01547   mutable bool used;    ///< the comment has been retrieved?
01548   citem_cmt_t(void) {}
01549   citem_cmt_t(const char *s) : qstring(s) {}
01550 };
01551 
01552 // Comments are attached to tree locations:
01553 typedef std::map<treeloc_t, citem_cmt_t> user_cmts_t;
01554 
01555 /// Generic ctree element locator. It can be used for instructions and some expression
01556 /// types. However, we need more precise locators for other items (e.g. for numbers)
01557 struct citem_locator_t
01558 {
01559   ea_t ea;              ///< citem address
01560   ctype_t op;           ///< citem operation
01561   citem_locator_t(void) {}
01562   citem_locator_t(ea_t _ea, ctype_t _op) : ea(_ea), op(_op) {}
01563   citem_locator_t(const citem_t *i);
01564   DECLARE_COMPARISONS(citem_locator_t);
01565   DEFINE_MEMORY_ALLOCATION_FUNCS()
01566 };
01567 
01568 // citem_t::iflags are attached to (ea,op) pairs
01569 typedef std::map<citem_locator_t, int32> user_iflags_t;
01570 
01571 // union field selections
01572 // they are represented as a vector of integers. each integer represents the
01573 // number of union field (0 means the first union field, etc)
01574 // the size of this vector is equal to the number of nested unions in the selection.
01575 typedef std::map<ea_t, intvec_t> user_unions_t;
01576 
01577 //--------------------------------------------------------------------------
01578 /// Basic ctree element. This is an abstract class (but we don't use virtual
01579 /// functions in ctree, so the compiler will not disallow you to create citem_t
01580 /// instances). However, elements of pure citem_t type must never be created.
01581 /// Two classes, cexpr_t and cinsn_t are derived from it.
01582 struct citem_t
01583 {
01584   ea_t ea;              ///< address that corresponds to the item
01585   ctype_t op;           ///< element type
01586   int label_num;        ///< label number. -1 means no label. items of expression
01587                         ///< types (cot_...) should not have labels at the final maturity
01588                         ///< level, but at the intermediate levels any ctree element
01589                         ///< may have a label. Labels must be unique. Usually
01590                         ///< they correspond to the basic block numbers.
01591   citem_t(void) : ea(BADADDR), op(cot_empty), label_num(-1) {}
01592   citem_t(ctype_t o) : ea(BADADDR), op(o), label_num(-1) {}
01593   /// Swap two citem_t
01594   void swap(citem_t &r)
01595   {
01596     std::swap(ea, r.ea);
01597     std::swap(op, r.op);
01598     std::swap(label_num, r.label_num);
01599   }
01600   /// Is an expression?
01601   bool is_expr(void) const { return op <= cot_last; }
01602   /// Does the item contain a label?
01603   bool hexapi contains_label(void) const;
01604   /// Find parent of the specified item.
01605   /// \param sitem Item to find the parent of. The search will be performed
01606   ///            among the children of the item pointed by \c this.
01607   /// \return NULL if not found
01608   const citem_t *hexapi find_parent_of(const citem_t *sitem) const;
01609   citem_t *find_parent_of(const citem_t *item)
01610   { return CONST_CAST(citem_t*)((CONST_CAST(const citem_t*)(this))->find_parent_of(item)); }
01611   size_t print1(char *buf, size_t bufsize, const cfunc_t *func) const;
01612   DEFINE_MEMORY_ALLOCATION_FUNCS()
01613 };
01614 
01615 /// Ctree element: expression.
01616 /// Depending on the exact expression item type, various fields of this structure are used.
01617 struct cexpr_t : public citem_t
01618 {
01619   union
01620   {
01621     cnumber_t *n;     ///< used for \ref cot_num
01622     fnumber_t *fpc;   ///< used for \ref cot_fnum
01623     struct
01624     {
01625       union
01626       {
01627         var_ref_t v;  ///< used for \ref cot_var
01628         ea_t obj_ea;  ///< used for \ref cot_obj
01629       };
01630       int refwidth;   ///< how many bytes are accessed? (-1: none)
01631     };
01632     struct
01633     {
01634       cexpr_t *x;     ///< the first operand of the expression
01635       union
01636       {
01637         cexpr_t *y;   ///< the second operand of the expression
01638         carglist_t *a;///< argument list (used for \ref cot_call)
01639         uint32 m;     ///< member offset (used for \ref cot_memptr, \ref cot_memref)
01640                       ///< for unions, the member number
01641       };
01642       union
01643       {
01644         cexpr_t *z;   ///< the third operand of the expression
01645         int ptrsize;  ///< memory access size (used for \ref cot_ptr, \ref cot_memptr)
01646       };
01647     };
01648     cinsn_t *insn;    ///< an embedded statement, they are prohibited
01649                       ///< at the final maturity stage (\ref CMAT_FINAL)
01650     char *helper;     ///< helper name (used for \ref cot_helper)
01651     char *string;     ///< string constant (used for \ref cot_str)
01652   };
01653   typestring type;    ///< expression type. must be carefully maintained
01654   int exflags;        ///< \ref EXFL_
01655 /// \defgroup EXFL_ Expression attributes
01656 /// Used in cexpr_t::exflags
01657 //@{
01658 #define EXFL_CPADONE 0x0001 ///< pointer arithmetic correction done
01659 #define EXFL_LVALUE  0x0002 ///< expression is lvalue even if it doesn't look like it
01660 #define EXFL_FPOP    0x0004 ///< floating point operation
01661 #define EXFL_ALONE   0x0008 ///< standalone helper
01662 #define EXFL_ALL     0x000F ///< all currently defined bits
01663 //@}
01664   /// Pointer arithmetic correction done for this expression?
01665   bool cpadone(void) const { return (exflags & EXFL_CPADONE) != 0; }
01666   bool is_odd_lvalue(void) const { return (exflags & EXFL_LVALUE) != 0; }
01667   bool is_fpop(void) const { return (exflags & EXFL_FPOP) != 0; }
01668 
01669 
01670   void set_cpadone(void) { exflags |= EXFL_CPADONE; }
01671 
01672   cexpr_t(void) : x(NULL), y(NULL), z(NULL), exflags(0) {}
01673   cexpr_t(ctype_t cop, cexpr_t *_x) : citem_t(cop), x(_x), y(NULL), z(NULL), exflags(0) {}
01674   cexpr_t(ctype_t cop, cexpr_t *_x, cexpr_t *_y) : citem_t(cop), x(_x), y(_y), z(NULL), exflags(0) {}
01675   cexpr_t(ctype_t cop, cexpr_t *_x, cexpr_t *_y, cexpr_t *_z) : citem_t(cop), x(_x), y(_y), z(_z), exflags(0) {}
01676   cexpr_t(mbl_array_t *mba, const lvar_t &v);
01677   cexpr_t(const cexpr_t &r) : citem_t() { *this = r; }
01678   void swap(cexpr_t &r) { qswap(*this, r); }
01679   cexpr_t &operator=(const cexpr_t &r) { return assign(r); }
01680   cexpr_t &hexapi assign(const cexpr_t &r);
01681   DECLARE_COMPARISONS(cexpr_t);
01682   ~cexpr_t(void) { cleanup(); }
01683 
01684   /// Replace the expression.
01685   /// The children of the expression are abandoned (not freed).
01686   /// The expression pointed by 'r' is moved to 'this' expression
01687   /// \param r the source expression. It is deleted after being copied
01688   void hexapi replace_by(cexpr_t *r);
01689 
01690   /// Cleanup the expression.
01691   /// This function properly deletes all children and sets the item type to cot_empty.
01692   void hexapi cleanup(void);
01693 
01694   /// Assign a number to the expression.
01695   /// \param n number value
01696   /// \param nbytes size of the number in bytes
01697   /// \param sign number sign
01698   void hexapi put_number(cfunc_t *func, uint64 v, int nbytes, type_sign_t sign=no_sign);
01699 
01700   /// Print expression into one line.
01701   /// \param buf output buffer
01702   /// \param bufsize size of the output buffer
01703   /// \param func parent function. This argument is used to find out the referenced variable names.
01704   /// \return length of the generated text.
01705   size_t hexapi print1(char *buf, size_t bufsize, const cfunc_t *func) const;
01706 
01707   /// Calculate the type of the expression.
01708   /// Use this function to calculate the expression type when a new expression is built
01709   /// \param recursive if true, types of all children expression will be calculated
01710   ///                  before calculating our type
01711   void hexapi calc_type(bool recursive);
01712 
01713   /// Compare two expressions.
01714   /// This function tries to compare two expressions in an 'intelligent' manner.
01715   /// For example, it knows about commutitive operators and can ignore useless casts.
01716   /// \param r the expression to compare against the current expression
01717   /// \return true expressions can be considered equal
01718   bool hexapi equal_effect(const cexpr_t &r) const;
01719 
01720   /// Verify if the specified item is our parent.
01721   /// \param parent possible parent item
01722   /// \return true if the specified item is our parent
01723   bool hexapi is_child_of(const citem_t *parent) const;
01724 
01725   /// Check if the expression contains the specified operator.
01726   /// \param needed_op operator code to search for
01727   /// \return true if the expression has a child with the specified opcode.
01728   bool hexapi contains_operator(ctype_t needed_op) const;
01729 
01730   /// Does the expression contain another expression?
01731   bool contains_expr(const cexpr_t *e) const;
01732   /// Does the expression contain a comma operator?
01733   bool contains_comma(void) const { return contains_operator(cot_comma); }
01734   /// Does the expression contain an embedded statement operator?
01735   bool contains_insn(void) const { return contains_operator(cot_insn); }
01736   /// Does the expression contain an embedded statement operator or a label?
01737   bool contains_insn_or_label(void) const { return contains_insn() || contains_label(); }
01738   /// Does the expression contain a comma operator or an embedded statement operator or a label?
01739   bool contains_comma_or_insn_or_label(void) const { return contains_comma() || contains_insn_or_label(); }
01740   /// Is nice expression?
01741   /// Nice expressions do not contain comma operators, embedded statements, or labels.
01742   bool is_nice_expr(void) const { return !contains_comma_or_insn_or_label(); }
01743   /// Is nice condition?.
01744   /// Nice condition is a nice expression of the boolean type.
01745   bool is_nice_cond(void) const { return is_nice_expr() && is_type_bool(type[0]); }
01746   /// Is call object?.
01747   /// \return true if our expression is the call object of the specified parent expression.
01748   bool is_call_object_of(const citem_t *parent) const { return parent != NULL && parent->op == cot_call && ((cexpr_t*)parent)->x == this; }
01749   /// Get expression sign
01750   type_sign_t get_type_sign(void) const { return ::get_type_sign(idati, type.u_str()); }
01751   /// Is expression unsigned?
01752   bool is_type_unsigned(void) const { return ::is_type_unsigned(idati, type.u_str()); }
01753   /// Is expression signed?
01754   bool is_type_signed(void) const { return ::is_type_signed(idati, type.u_str()); }
01755   /// Get number of bits that can really be used by the expression.
01756   /// For example, x % 16 uses only 4 bits
01757   int hexapi get_nbits(int pbits) const;
01758   /// Check if the expression requires an lvalue.
01759   /// \param child The function will check if this child of our expression must be an lvalue.
01760   /// \return true if child must be an lvalue.
01761   bool hexapi requires_lvalue(const cexpr_t *child) const;
01762   /// Check if the expression has side effects.
01763   /// Calls, pre/post inc/dec, and assignments have side effects.
01764   bool hexapi has_side_effects(void) const;
01765   /// Get numeric value of the expression.
01766   /// This function can be called only on cot_num expressions!
01767   uint64 numval(void) const
01768   {
01769     QASSERT(50071, op == cot_num);
01770     return n->value(type);
01771   }
01772   /// Check if the expression is a number with the specified value.
01773   bool is_const_value(uint64 v) const
01774   {
01775     return op == cot_num && numval() == v;
01776   }
01777   /// Check if the expression is a negative number.
01778   bool is_negative_const(void) const
01779   {
01780     return op == cot_num && int64(numval()) < 0;
01781   }
01782   /// Check if the expression is a non-zero number.
01783   bool is_non_zero_const(void) const
01784   {
01785     return op == cot_num && numval() != 0;
01786   }
01787   /// Check if the expression is a zero.
01788   bool is_zero_const(void) const { return is_const_value(0); }
01789   /// Get expression value.
01790   /// \param np Pointer to the variable where the expression value is returned.
01791   /// \return true if the expression is a number.
01792   bool get_const_value(uint64 *np) const
01793   {
01794     if ( op == cot_num )
01795     {
01796       if ( np != NULL )
01797         *np = numval();
01798       return true;
01799     }
01800     return false;
01801   }
01802   /// May the expression be a pointer?
01803   bool maybe_ptr(void) const
01804   {
01805     uint64 v;
01806     if ( get_const_value(&v)
01807       && (ea_t(v) != v || !isEnabled((ea_t)v)) )
01808       return false;
01809     return true;
01810   }
01811   /// Find pointer or array child.
01812   cexpr_t *get_ptr_or_array(void)
01813   {
01814     if ( x->type.is_ptr_or_array() ) return x;
01815     if ( y->type.is_ptr_or_array() ) return y;
01816     return NULL;
01817   }
01818   /// Find the child with the specified operator.
01819   const cexpr_t *find_op(ctype_t op) const
01820   {
01821     if ( x->op == op ) return x;
01822     if ( y->op == op ) return y;
01823     return NULL;
01824   }
01825         cexpr_t *find_op(ctype_t op) { return (cexpr_t *)((const cexpr_t *)this)->find_op(op); }
01826 
01827   /// Find the operand with a numeric value
01828   const cexpr_t *find_num_op(void) const { return find_op(cot_num); }
01829         cexpr_t *find_num_op(void)       { return find_op(cot_num); }
01830   /// Get the other operand.
01831   /// This function returns the other operand (not the specified one)
01832   /// for binary expressions.
01833   const cexpr_t *theother(const cexpr_t *what) const { return what == x ? y : x; }
01834         cexpr_t *theother(const cexpr_t *what)       { return what == x ? y : x; }
01835 
01836   // these are inline functions, see below
01837   bool get_1num_op(cexpr_t **o1, cexpr_t **o2);
01838   bool get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const;
01839 
01840 };//-
01841 
01842 /// Statement with an expression.
01843 /// This is a base class for various statements with expressions.
01844 struct ceinsn_t
01845 {
01846   DEFINE_MEMORY_ALLOCATION_FUNCS()
01847   cexpr_t expr;         ///< Expression of the statement
01848 };
01849 
01850 /// Should curly braces be printed?
01851 enum use_curly_t
01852 {
01853   CALC_CURLY_BRACES,    ///< print curly braces if necessary
01854   NO_CURLY_BRACES,      ///< don't print curly braces
01855   USE_CURLY_BRACES,     ///< print curly braces without any checks
01856 };
01857 
01858 /// If statement
01859 struct cif_t : public ceinsn_t
01860 {
01861   cinsn_t *ithen;       ///< Then-branch of the if-statement
01862   cinsn_t *ielse;       ///< Else-branch of the if-statement. May be NULL.
01863   cif_t(void) : ithen(NULL), ielse(NULL) {}
01864   cif_t(const cif_t &r) : ceinsn_t(), ithen(NULL), ielse(NULL) { *this = r; }
01865   cif_t &operator=(const cif_t &r) { return assign(r); }
01866   cif_t &hexapi assign(const cif_t &r);
01867   DECLARE_COMPARISONS(cif_t);
01868   ~cif_t(void) { cleanup(); }
01869   void cleanup(void);
01870 };
01871 
01872 /// Base class for loop statements
01873 struct cloop_t : public ceinsn_t
01874 {
01875   cinsn_t *body;
01876   cloop_t(void) : body(NULL) {}
01877   cloop_t(cinsn_t *b) : body(b) {}
01878   cloop_t(const cloop_t &r) : ceinsn_t(), body(NULL) { *this = r; }
01879   cloop_t &operator=(const cloop_t &r) { return assign(r); }
01880   cloop_t &hexapi assign(const cloop_t &r);
01881   ~cloop_t(void) { cleanup(); }
01882   void cleanup(void);
01883 };
01884 
01885 /// For-loop
01886 struct cfor_t : public cloop_t
01887 {
01888   cexpr_t init;                 ///< Initialization expression
01889   cexpr_t step;                 ///< Step expression
01890   DECLARE_COMPARISONS(cfor_t);
01891 };
01892 
01893 /// While-loop
01894 struct cwhile_t : public cloop_t
01895 {
01896   DECLARE_COMPARISONS(cwhile_t);
01897 };
01898 
01899 /// Do-loop
01900 struct cdo_t : public cloop_t
01901 {
01902   DECLARE_COMPARISONS(cdo_t);
01903 };
01904 
01905 /// Return statement
01906 struct creturn_t : public ceinsn_t
01907 {
01908   DECLARE_COMPARISONS(creturn_t);
01909 };
01910 
01911 /// Goto statement
01912 struct cgoto_t
01913 {
01914   int label_num;        ///< Target label number
01915   DECLARE_COMPARISONS(cgoto_t);
01916   DEFINE_MEMORY_ALLOCATION_FUNCS()
01917   void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
01918 };
01919 
01920 /// asm statement
01921 struct casm_t : public eavec_t
01922 {
01923   casm_t(ea_t ea) { push_back(ea); }
01924   casm_t(const casm_t &r) : eavec_t(eavec_t(r)) {}
01925   DECLARE_COMPARISONS(casm_t);
01926   void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
01927   bool one_insn(void) const { return size() == 1; }
01928   void genasm(ea_t ea, char *buf, size_t bufsize) const;
01929 };
01930 
01931 /// Vector of pointers to statements.
01932 typedef qvector<cinsn_t *> cinsnptrvec_t;
01933 
01934 /// Ctree element: statement.
01935 /// Depending on the exact statement type, various fields of the union are used.
01936 struct cinsn_t : public citem_t
01937 {
01938   union
01939   {
01940     cblock_t *cblock;   ///< details of block-statement
01941     cexpr_t *cexpr;     ///< details of expression-statement
01942     cif_t *cif;         ///< details of if-statement
01943     cfor_t *cfor;       ///< details of for-statement
01944     cwhile_t *cwhile;   ///< details of while-statement
01945     cdo_t *cdo;         ///< details of do-statement
01946     cswitch_t *cswitch; ///< details of switch-statement
01947     creturn_t *creturn; ///< details of return-statement
01948     cgoto_t *cgoto;     ///< details of goto-statement
01949     casm_t *casm;       ///< details of asm-statement
01950   };
01951 
01952   cinsn_t(void) : citem_t(cit_empty) {}
01953   cinsn_t(const cinsn_t &r) : citem_t(cit_empty) { *this = r; }
01954   void swap(cinsn_t &r) { citem_t::swap(r); std::swap(cblock, r.cblock); }
01955   cinsn_t &operator=(const cinsn_t &r) { return assign(r); }
01956   cinsn_t &hexapi assign(const cinsn_t &r);
01957   DECLARE_COMPARISONS(cinsn_t);
01958   ~cinsn_t(void) { cleanup(); }
01959 
01960   /// Replace the statement.
01961   /// The children of the statement are abandoned (not freed).
01962   /// The statement pointed by 'r' is moved to 'this' statement
01963   /// \param r the source statement. It is deleted after being copied
01964   void hexapi replace_by(cinsn_t *r);
01965 
01966   /// Cleanup the statement.
01967   /// This function properly deletes all children and sets the item type to cit_empty.
01968   void hexapi cleanup(void);
01969 
01970   /// Overwrite with zeroes without cleaning memory or deleting children
01971   void zero(void) { op = cit_empty; cblock=NULL; }
01972 
01973   /// Create a new statement.
01974   /// The current statement must be a block. The new statement will be appended to it.
01975   /// \param ea statement address
01976   cinsn_t &hexapi new_insn(ea_t ea);
01977 
01978   /// Create a new if-statement.
01979   /// The current statement must be a block. The new statement will be appended to it.
01980   /// \param cnd if condition. It will be deleted after being copied.
01981   cif_t &hexapi create_if(cexpr_t *cnd);
01982 
01983   /// Print the statement into many lines.
01984   /// \param indent indention (number of spaces) for the statement
01985   /// \param vp printer helper class which will receive the generated text.
01986   /// \param use_curly if the statement is a block, how should curly braces be printed.
01987   void hexapi print(int indent, vc_printer_t &vp, use_curly_t use_curly=CALC_CURLY_BRACES) const;
01988 
01989   /// Print the statement into one line.
01990   /// Currently this function is not available.
01991   /// \param buf output buffer
01992   /// \param bufsize size of output buffer
01993   /// \param func parent function. This argument is used to find out the referenced variable names.
01994   /// \return length of the generated text.
01995   size_t hexapi print1(char *buf, size_t bufsize, const cfunc_t *func) const;
01996 
01997   /// Check if the statement passes execution to the next statement.
01998   /// \return false if the statement breaks the control flow (like goto, return, etc)
01999   bool hexapi is_ordinary_flow(void) const;
02000 
02001   /// Check if the statement contains a statement of the specified type.
02002   /// \param type statement opcode to look for
02003   /// \return true if the specified opcode has been found
02004   bool hexapi contains_insn(ctype_t type) const;
02005 
02006   /// Collect free \c break statements.
02007   /// This function finds all free \c break statements within the current statement.
02008   /// A \c break statement is free if it does not have a loop or switch parent that
02009   /// that is also within the current statement.
02010   /// \param breaks pointer to the variable where the vector of all found free
02011   ///               \c break statements is returned. This argument can be NULL.
02012   /// \return true if some free \c break statements have been found
02013   bool hexapi collect_free_breaks(cinsnptrvec_t *breaks);
02014 
02015   /// Collect free \c continue statements.
02016   /// This function finds all free \c continue statements within the current statement.
02017   /// A \c continue statement is free if it does not have a loop parent that
02018   /// that is also within the current statement.
02019   /// \param continues pointer to the variable where the vector of all found free
02020   ///               \c continue statements is returned. This argument can be NULL.
02021   /// \return true if some free \c continue statements have been found
02022   bool hexapi collect_free_continues(cinsnptrvec_t *continues);
02023 
02024   /// Check if the statement has free \c break statements.
02025   bool contains_free_break(void) const { return CONST_CAST(cinsn_t*)(this)->collect_free_breaks(NULL); }
02026   /// Check if the statement has free \c continue statements.
02027   bool contains_free_continue(void) const { return CONST_CAST(cinsn_t*)(this)->collect_free_continues(NULL); }
02028 
02029 };//-
02030 
02031 /// Compound statement (curly braces)
02032 struct cblock_t : public qlist<cinsn_t> // we need list to be able to manipulate
02033 {                                       // its elements freely
02034   int remove_gotos(intseq_t &used_labels, int break_target, int continue_target, int next_num);
02035   bool use_curly_braces(void) const;
02036   iterator find(const cinsn_t *insn);
02037   DECLARE_COMPARISONS(cblock_t);
02038 };
02039 
02040 /// Function argument
02041 struct carg_t : public cexpr_t
02042 {
02043   bool is_vararg;             ///< is a vararg (matches ...)
02044   typestring formal_type;     ///< formal parameter type (if known)
02045   void consume_cexpr(cexpr_t *e)
02046   {
02047     qswap(*(cexpr_t*)this, *e);
02048     delete e;
02049   }
02050   carg_t(void) : is_vararg(false) {}
02051   DECLARE_COMPARISONS(carg_t)
02052   {
02053     return cexpr_t::compare(r);
02054   }
02055 };
02056 
02057 /// Function argument list
02058 struct carglist_t : public qvector<carg_t>
02059 {
02060   typestring functype;   ///< function object type
02061   carglist_t(void) {}
02062   carglist_t(const typestring &ftype) : functype(ftype) {}
02063   DECLARE_COMPARISONS(carglist_t);
02064   size_t print(char *buf, size_t bufsize, const cfunc_t *func) const;
02065   int print(int curpos, vc_printer_t &vp) const;
02066 };
02067 
02068 /// Switch case. Usually cinsn_t is a block
02069 struct ccase_t : public cinsn_t
02070 {
02071   qvector<uint64> values;    ///< List of case values.
02072                              ///< if empty, then 'default' case
02073   DECLARE_COMPARISONS(ccase_t);
02074   void print(const cinsn_t *parent, int indent, vc_printer_t &vp) const;
02075   bool set_insn(const cinsn_t *i);
02076   size_t size(void) const { return values.size(); }
02077   const uint64 &value(int i) const { return values[i]; }
02078 };
02079 
02080 /// Vector of switch cases
02081 struct ccases_t : public qvector<ccase_t>
02082 {
02083   DECLARE_COMPARISONS(ccases_t);
02084   void print(const cinsn_t *parent, int indent, vc_printer_t &vp) const;
02085   int find_value(uint64 v) const;
02086 };
02087 
02088 /// Switch statement
02089 struct cswitch_t : public ceinsn_t
02090 {
02091   cnumber_t mvnf;       ///< Maximal switch value and number format
02092   ccases_t cases;       ///< Switch cases: values and instructions
02093   DECLARE_COMPARISONS(cswitch_t);
02094 };
02095 
02096 //---------------------------------------------------------------------------
02097 /// Type of the cursor item.
02098 enum cursor_item_type_t
02099 {
02100   VDI_NONE, ///< undefined
02101   VDI_EXPR, ///< c-tree item
02102   VDI_LVAR, ///< declaration of local variable
02103   VDI_FUNC, ///< the function itself (the very first line with the function prototype)
02104   VDI_TAIL, ///< cursor is at (beyond) the line end (commentable line)
02105 };
02106 
02107 /// Cursor item.
02108 /// Information about the item under the cursor
02109 struct ctree_item_t
02110 {
02111   DEFINE_MEMORY_ALLOCATION_FUNCS()
02112   cursor_item_type_t citype; ///< Item type
02113   union
02114   {
02115     citem_t *it;
02116     cexpr_t *e;         ///< VDI_EXPR: Expression
02117     cinsn_t *i;         ///< VDI_EXPR: Statement
02118     lvar_t *l;          ///< VDI_LVAR: Local variable
02119     cfunc_t *f;         ///< VDI_FUNC: Function
02120     treeloc_t loc;      ///< VDI_TAIL: Line tail
02121   };
02122   void verify(const mbl_array_t *mba) const;
02123 
02124   /// Get pointer to structure member.
02125   /// If the current item is a structure field,
02126   /// this function will return pointer to its definition.
02127   /// \return NULL if failed
02128   /// \param[out] p_sptr pointer to the variable where the pointer to the
02129   ///               parent structure is returned. This parameter can be NULL.
02130 
02131   member_t *hexapi get_memptr(struc_t **p_sptr=NULL) const;
02132 
02133   /// Get pointer to local variable.
02134   /// If the current item is a local variable,
02135   /// this function will return pointer to its definition.
02136   /// \return NULL if failed
02137 
02138   lvar_t *hexapi get_lvar(void) const;
02139 
02140 
02141   /// Get address of the current item.
02142   /// Each ctree item has an address.
02143   /// \return BADADDR if failed
02144 
02145   ea_t hexapi get_ea(void) const;
02146 
02147 
02148   /// Get label number of the current item.
02149   /// \return -1 if failed or no label
02150 
02151   int hexapi get_label_num(void) const;
02152 
02153   /// Is the current item is a ctree item?
02154   bool is_citem(void) const { return citype == VDI_EXPR; }
02155 
02156   /// Does the current item has a label?
02157   bool has_label(void) const { return get_label_num() != -1; }
02158 };
02159 
02160 /// Unused label disposition.
02161 enum allow_unused_labels_t
02162 {
02163   FORBID_UNUSED_LABELS = 0,     ///< Unused labels cause interr
02164   ALLOW_UNUSED_LABELS = 1,      ///< Unused labels are permitted
02165 };
02166 
02167 typedef std::map<int, qstring> user_labels_t;
02168 
02169 /// Logically negate the specified expression.
02170 /// The specified expression will be logically negated.
02171 /// For example, "x == y" is converted into "x != y" by this function.
02172 /// \param e expression to negate. After the call, e must not be used anymore
02173 ///          because it can be changed by the function. The function return value
02174 ///          must be used to refer to the expression.
02175 /// \return logically negated expression.
02176 
02177 cexpr_t *hexapi lnot(cexpr_t *e);
02178 
02179 
02180 /// Create a new block-statement.
02181 
02182 cinsn_t *hexapi new_block(void);
02183 
02184 
02185 /// Create a helper object.
02186 /// This function creates a helper object.
02187 /// The named function is not required to exist, the decompiler will only print
02188 /// its name in the output. Helper functions are usually used to represent arbitrary
02189 /// function or macro calls in the output.
02190 /// \param standalone false:helper must be called; true:helper can be used in any expression
02191 /// \param type type of the create function object
02192 /// \param format printf-style format string that will be used to create the function name.
02193 /// \param va additional arguments for printf
02194 /// \return the created expression.
02195 
02196 AS_PRINTF(3, 0) cexpr_t *hexapi vcreate_helper(bool standalone, const typestring &type, const char *format, va_list va);
02197 
02198 /// Create a helper object..
02199 AS_PRINTF(3, 4) inline cexpr_t *create_helper(bool standalone, const typestring &type, const char *format, ...)
02200 {
02201   va_list va;
02202   va_start(va, format);
02203   cexpr_t *e = vcreate_helper(standalone, type, format, va);
02204   va_end(va);
02205   return e;
02206 }
02207 
02208 
02209 /// Create a helper call expression.
02210 /// This function creates a new expression: a call of a helper function.
02211 /// \param rettype type of the whole expression.
02212 /// \param args helper arguments. this object will be consumed by the function.
02213 ///             if there are no args, this parameter may be specified as NULL.
02214 /// \param format printf-style format string that will be used to create the function name.
02215 /// \param va additional arguments for printf
02216 /// \return the created expression.
02217 
02218 AS_PRINTF(3, 0) cexpr_t *hexapi vcall_helper(const typestring &rettype, carglist_t *args, const char *format, va_list va);
02219 
02220 /// Create a helper call.
02221 AS_PRINTF(3, 4) inline cexpr_t *call_helper(
02222         const typestring &rettype,
02223         carglist_t *args,
02224         const char *format, ...)
02225 {
02226   va_list va;
02227   va_start(va, format);
02228   cexpr_t *e = vcall_helper(rettype, args, format, va);
02229   va_end(va);
02230   return e;
02231 }
02232 
02233 
02234 /// Create a number expression
02235 /// \param n value
02236 /// \param sign number sign
02237 
02238 cexpr_t *hexapi make_num(uint64 n, int opnum=0, type_sign_t sign=no_sign);
02239 
02240 
02241 /// Create a reference.
02242 /// This function performs the following conversion: "obj" => "&obj".
02243 /// It can handle casts, annihilate "&*", and process other special cases.
02244 
02245 cexpr_t *hexapi make_ref(cexpr_t *e);
02246 
02247 
02248 /// Dereference a pointer.
02249 /// This function dereferences a pointer expression.
02250 /// It performs the following conversion: "ptr" => "*ptr"
02251 /// It can handle discrepancies in the pointer type and the access size.
02252 /// \param e expression to deference
02253 /// \param ptrsize access size
02254 /// \return dereferenced expression
02255 
02256 cexpr_t *hexapi dereference(cexpr_t *e, int ptrsize, bool is_float=false);
02257 
02258 
02259 /// Save user defined labels into the database.
02260 /// \param func_ea the entry address of the function
02261 /// \param user_labels collection of user defined labels
02262 
02263 void hexapi save_user_labels(ea_t func_ea, const user_labels_t *user_labels);
02264 
02265 
02266 /// Save user defined comments into the database.
02267 /// \param func_ea the entry address of the function
02268 /// \param user_cmts collection of user defined comments
02269 
02270 void hexapi save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts);
02271 
02272 /// Save user defined number formats into the database.
02273 /// \param func_ea the entry address of the function
02274 /// \param numforms collection of user defined comments
02275 
02276 void hexapi save_user_numforms(ea_t func_ea, const user_numforms_t *numforms);
02277 
02278 
02279 /// Save user defined citem iflags into the database.
02280 /// \param func_ea the entry address of the function
02281 /// \param iflags collection of user defined citem iflags
02282 
02283 void hexapi save_user_iflags(ea_t func_ea, const user_iflags_t *iflags);
02284 
02285 
02286 /// Save user defined union field selections into the database.
02287 /// \param func_ea the entry address of the function
02288 /// \param unions collection of union field selections
02289 
02290 void hexapi save_user_unions(ea_t func_ea, const user_unions_t *unions);
02291 
02292 
02293 /// Restore user defined labels from the database.
02294 /// \param func_ea the entry address of the function
02295 /// \return collection of user defined labels.
02296 ///         The returned object must be deleted by the caller using delete_user_labels()
02297 
02298 user_labels_t *hexapi restore_user_labels(ea_t func_ea);
02299 
02300 
02301 /// Restore user defined comments from the database.
02302 /// \param func_ea the entry address of the function
02303 /// \return collection of user defined comments.
02304 ///         The returned object must be deleted by the caller using delete_user_cmts()
02305 
02306 user_cmts_t *hexapi restore_user_cmts(ea_t func_ea);
02307 
02308 
02309 /// Restore user defined number formats from the database.
02310 /// \param func_ea the entry address of the function
02311 /// \return collection of user defined number formats.
02312 ///         The returned object must be deleted by the caller using delete_user_numforms()
02313 
02314 user_numforms_t *hexapi restore_user_numforms(ea_t func_ea);
02315 
02316 
02317 /// Restore user defined citem iflags from the database.
02318 /// \param func_ea the entry address of the function
02319 /// \return collection of user defined iflags.
02320 ///         The returned object must be deleted by the caller using delete_user_iflags()
02321 
02322 user_iflags_t *hexapi restore_user_iflags(ea_t func_ea);
02323 
02324 
02325 /// Restore user defined union field selections from the database.
02326 /// \param func_ea the entry address of the function
02327 /// \return collection of union field selections
02328 ///         The returned object must be deleted by the caller using delete_user_unions()
02329 
02330 user_unions_t *hexapi restore_user_unions(ea_t func_ea);
02331 
02332 
02333 //-------------------------------------------------------------------------
02334 /// Decompiled function. Decompilation result is kept here.
02335 struct cfunc_t
02336 {
02337   ea_t entry_ea;             ///< function entry address
02338   mbl_array_t *mba;          ///< underlying microcode
02339   cinsn_t body;              ///< function body, must be a block
02340   intseq_t &rgas;            ///< list of register arguments (indexes into vars)
02341   intseq_t &stas;            ///< list of stack arguments (indexes into vars)
02342   ctree_maturity_t maturity; ///< maturity level
02343   // The following maps must be accessed using helper functions.
02344   // Example: for user_labels_t, see functions starting with "user_labels_".
02345   user_labels_t *user_labels;///< user-defined labels.
02346   user_cmts_t *user_cmts;    ///< user-defined comments.
02347   user_numforms_t *numforms; ///< user-defined number formats.
02348   user_iflags_t *user_iflags;///< user-defined item flags \ref CIT_
02349   user_unions_t *user_unions;///< user-defined union field selections.
02350 /// \defgroup CIT_ ctree item iflags bits
02351 //@{
02352 #define CIT_COLLAPSED 0x0001 ///< display element in collapsed form
02353 //@}
02354 
02355 public:
02356   cfunc_t(mbl_array_t *mba);
02357   ~cfunc_t(void) { cleanup(); }
02358   DEFINE_MEMORY_ALLOCATION_FUNCS()
02359 
02360   /// Generate the function body.
02361   /// This function (re)generates the function body from the underlying microcode.
02362   void hexapi build_c_tree(void);
02363 
02364   /// Verify the ctree.
02365   /// This function verifies the ctree. If the ctree is malformed, an internal error
02366   /// is generated. Use it to verify the ctree after your modifications.
02367   /// \param aul Are unused labels acceptable?
02368   /// \param even_without_debugger if false and there is no debugger, the verification will be skipped
02369   void hexapi verify(allow_unused_labels_t aul, bool even_without_debugger) const;
02370 
02371   /// Print function prototype.
02372   /// \param buf output buffer
02373   /// \param bufsize size of the output buffer
02374   /// \return length of the generated text
02375   size_t hexapi print_dcl(char *buf, int bufsize) const;
02376 
02377   /// Print function text.
02378   /// \param vp printer helper class to receive the generated text.
02379   void hexapi print_func(vc_printer_t &vp) const;
02380 
02381   /// Get the function type.
02382   /// \param type variable where the function type is returned
02383   /// \param fields variable where the argument names are returned
02384   /// \return false if failure
02385   bool hexapi get_func_type(typestring &type, qtype &fields) const;
02386 
02387   /// Get vector of local variables.
02388   /// \return pointer to the vector of local variables. If you modify this vector,
02389   ///         the ctree must be regenerated in order to have correct cast operators.
02390   ///         Use build_c_tree() for that.
02391   ///         Removing lvars should be done carefully: all references in ctree
02392   ///         and microcode must be corrected after that.
02393   lvars_t *hexapi get_lvars(void);
02394 
02395 
02396   /// Find the label.
02397   /// \return pointer to the ctree item with the specified label number.
02398   citem_t *hexapi find_label(int label);
02399 
02400   /// Remove unused labels.
02401   /// This function check what labels are really used by the function and
02402   /// removes the unused ones.
02403   void hexapi remove_unused_labels(void);
02404 
02405   /// Retrieve a user defined comment.
02406   /// \param loc ctree location
02407   /// \param rt should already retrieved comments retrieved again?
02408   /// \return pointer to the comment string or NULL
02409   const char *hexapi get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const;
02410 
02411   /// Set a user defined comment.
02412   /// This function stores the specified comment in the cfunc_t structure.
02413   /// The save_user_cmts() function must be called after it.
02414   /// \param loc ctree location
02415   /// \param cmt new comment. if empty or NULL, then an existing comment is deleted.
02416   void hexapi set_user_cmt(const treeloc_t &loc, const char *cmt);
02417 
02418   /// Retrieve citem iflags.
02419   /// \param loc citem locator
02420   /// \return \ref CIT_ or 0
02421   int32 hexapi get_user_iflags(const citem_locator_t &loc) const;
02422 
02423   /// Set citem iflags.
02424   /// \param loc citem locator
02425   /// \param iflags new iflags
02426   void hexapi set_user_iflags(const citem_locator_t &loc, int32 iflags);
02427 
02428   /// Check if there are orphan comments.
02429   bool hexapi has_orphan_cmts(void) const;
02430 
02431   /// Delete all orphan comments.
02432   /// The save_user_cmts() function must be called after this call.
02433   int hexapi del_orphan_cmts(void);
02434 
02435   /// Retrieve a user defined union field selection.
02436   /// \param ea address
02437   /// \param path out: path describing the union selection.
02438   /// \return pointer to the path or NULL
02439   bool hexapi get_user_union_selection(ea_t ea, intvec_t *path);
02440 
02441   /// Set a union field selection.
02442   /// The save_user_unions() function must be called after calling this function.
02443   /// \param ea address
02444   /// \param path in: path describing the union selection.
02445   void hexapi set_user_union_selection(ea_t ea, const intvec_t &path);
02446 
02447   /// Save user-defined labels into the database
02448   void save_user_labels(void) const { ::save_user_labels(entry_ea, user_labels); }
02449   /// Save user-defined comments into the database
02450   void save_user_cmts(void) const { ::save_user_cmts(entry_ea, user_cmts); }
02451   /// Save user-defined number formats into the database
02452   void save_user_numforms(void) const { ::save_user_numforms(entry_ea, numforms); }
02453   /// Save user-defined iflags into the database
02454   void save_user_iflags(void) const { ::save_user_iflags(entry_ea, user_iflags); }
02455   /// Save user-defined union field selections into the database
02456   void save_user_unions(void) const { ::save_user_unions(entry_ea, user_unions); }
02457 
02458   /// Get ctree item for the specified cursor position.
02459   /// \return false if failed to get the current item
02460   /// \param line line of decompilation text (element of \ref sv)
02461   /// \param x x cursor coordinate in the line
02462   /// \param is_ctree_line does the line belong to statement area? (if not, it is assumed to belong to the declaration area)
02463   /// \param head ptr to the first item on the line (used to attach block comments). May be NULL
02464   /// \param item ptr to the current item. May be NULL
02465   /// \param tail ptr to the last item on the line (used to attach indented comments). May be NULL
02466   /// \sa vdui_t::get_current_item()
02467   bool hexapi get_line_item(const char *line, int x, bool is_ctree_line, ctree_item_t *head, ctree_item_t *item, ctree_item_t *tail);
02468 
02469   /// Get information about decompilation warnings.
02470   /// \return reference to the vector of warnings
02471   hexwarns_t &hexapi get_warnings(void);
02472 
02473   bool hexapi gather_derefs(int varidx, strtype_info_t *strinfo=NULL) const;
02474 private:
02475   /// Cleanup.
02476   /// Properly delete all children and free memory.
02477   void hexapi cleanup(void);
02478 };
02479 
02480 //--------------------------------------------------------------------------
02481 // Now cinsn_t class is defined, define the cleanup functions:
02482 inline void cif_t::cleanup(void)     { delete ithen; delete ielse; }
02483 inline void cloop_t::cleanup(void)   { delete body; }
02484 
02485 /// Print item into one line.
02486 /// \param buf output buffer
02487 /// \param bufsize size of the output buffer
02488 /// \param func parent function. This argument is used to find out the referenced variable names.
02489 /// \return length of the generated text.
02490 
02491 inline size_t citem_t::print1(char *buf, size_t bufsize, const cfunc_t *func) const
02492 {
02493   if ( is_expr() )
02494     return ((cexpr_t*)this)->print1(buf, bufsize, func);
02495   else
02496     return ((cinsn_t*)this)->print1(buf, bufsize, func);
02497 }
02498 
02499 /// Get pointers to operands. at last one operand should be a number
02500 /// o1 will be pointer to the number
02501 
02502 inline bool cexpr_t::get_1num_op(cexpr_t **o1, cexpr_t **o2)
02503 {
02504   if ( x->op == cot_num )
02505   {
02506     *o1 = x;
02507     *o2 = y;
02508   }
02509   else
02510   {
02511     if ( y->op != cot_num )
02512       return false;
02513     *o1 = y;
02514     *o2 = x;
02515   }
02516   return true;
02517 }
02518 
02519 inline bool cexpr_t::get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const
02520 {
02521   return CONST_CAST(cexpr_t*)(this)->get_1num_op(
02522          CONST_CAST(cexpr_t**)(o1),
02523          CONST_CAST(cexpr_t**)(o2));
02524 }
02525 
02526 inline citem_locator_t::citem_locator_t(const citem_t *i) : ea(i->ea), op(i->op)
02527 {
02528 }
02529 
02530 const char *hexapi get_ctype_name(ctype_t op);
02531 qstring hexapi create_field_name(const typestring &type, uval_t offset=BADADDR);
02532 typestring hexapi dummy_plist_for(const type_t *ptr);
02533 typestring hexapi make_dt(int n);
02534 typedef void *hexdsp_t(int code, ...);
02535 const int HEXRAYS_API_MAGIC1 = 0xC001C0DE;
02536 const int HEXRAYS_API_MAGIC2 = 0xBE37BABE; // xxNNxxxx
02537 
02538 /// Decompiler events.
02539 /// Use install_hexrays_callback() to install a handler for decompiler events.
02540 /// When the possible return value is not specified, your callback
02541 /// must return zero.
02542 enum hexrays_event_t
02543 {
02544   // When a function is decompiled, the following events occur:
02545 
02546   hxe_flowchart,        ///< Flowchart has been generated.
02547                         ///< qflow_chart_t *fc
02548 
02549   hxe_prolog,           ///< Prolog analysis has been finished.
02550                         ///< mbl_array_t *mba                                 \n
02551                         ///< qflow_chart_t *fc                                \n
02552                         ///< bitset_t *reachable_blocks
02553 
02554   hxe_preoptimized,     ///< Microcode has been preoptimized.
02555                         ///< mbl_array_t *mba
02556 
02557   hxe_locopt,           ///< Basic block level optimization has been finished.
02558                         ///< mbl_array_t *mba
02559 
02560   hxe_prealloc,         ///< Local variables: preallocation step begins.      \n
02561                         ///< mbl_array_t *mba                                 \n
02562                         ///< This event may occur several times               \n
02563                         ///< Should return: 1 if modified microcode           \n
02564                         ///< Negative values are \ref MERR_ error codes
02565 
02566   hxe_glbopt,           ///< Global optimization has been finished.
02567                         ///< mbl_array_t *mba
02568 
02569   hxe_structural,       ///< Structural analysis has been finished.
02570                         ///< control_graph_t *ct
02571 
02572   hxe_maturity,         ///< Ctree maturity level is being changed.
02573                         ///< cfunc_t *cfunc                                   \n
02574                         ///< ctree_maturity_t new_maturity
02575 
02576   hxe_interr,           ///< Internal error has occurred.
02577                         ///< int errcode
02578 
02579   hxe_combine,          ///< Trying to combine instructions of basic block.
02580                         ///< mblock_t *blk                                    \n
02581                         ///< minsn_t *insn                                    \n
02582                         ///< Should return: 1 if combined the current instruction
02583                         ///< with a preceding one
02584 
02585   hxe_print_func,       ///< Printing ctree and generating text.
02586                         ///< cfunc_t *cfunc                                   \n
02587                         ///< vc_printer_t *vp                                 \n
02588                         ///< Returns: 1 if text has been generated by the plugin
02589 
02590   // User interface related events:
02591 
02592   hxe_open_pseudocode=100,
02593                         ///< New pseudocode view has been opened.
02594                         ///< vdui_t *vu
02595 
02596   hxe_switch_pseudocode,///< Existing pseudocode view has been reloaded
02597                         ///< with a new function. Its text has not been
02598                         ///< refreshed yet, only cfunc and mba pointers are ready.\n
02599                         ///< vdui_t *vu
02600 
02601   hxe_refresh_pseudocode,///< Existing pseudocode text has been refreshed.
02602                         ///< vdui_t *vu                                       \n
02603                         ///< See also hxe_text_ready, which happens earlier
02604 
02605   hxe_close_pseudocode, ///< Pseudocode view is being closed.
02606                         ///< vdui_t *vu
02607 
02608   hxe_keyboard,         ///< Keyboard has been hit.
02609                         ///< vdui_t *vu                                       \n
02610                         ///< int key_code (VK_...)                            \n
02611                         ///< int shift_state                                  \n
02612                         ///< Should return: 1 if the event has been handled
02613 
02614   hxe_right_click,      ///< Mouse right click. We can add menu items now.
02615                         ///< vdui_t *vu
02616 
02617   hxe_double_click,     ///< Mouse double click.
02618                         ///< vdui_t *vu                                       \n
02619                         ///< int shift_state                                  \n
02620                         ///< Should return: 1 if the event has been handled
02621 
02622   hxe_curpos,           ///< Current cursor position has been changed.
02623                         ///< (for example, by left-clicking or using keyboard)\n
02624                         ///< vdui_t *vu
02625 
02626   hxe_create_hint,      ///< Create a hint for the current item.
02627                         ///< vdui_t *vu                                       \n
02628                         ///< qstring *result_hint                             \n
02629                         ///< int *implines                                    \n
02630                         ///< Possible return values:                          \n
02631                         ///<  0: the event has not been handled               \n
02632                         ///<  1: hint has been created (should set *implines to nonzero as well)\n
02633                         ///<  2: hint has been created but the standard hints must be
02634                         ///<     appended by the decompiler
02635 
02636   hxe_text_ready,       ///< Decompiled text is ready.
02637                         ///< vdui_t *vu                                       \n
02638                         ///< This event can be used to modify the output text (sv).
02639                         ///< The text uses regular color codes (see lines.hpp)
02640                         ///< COLOR_ADDR is used to store pointers to ctree elements
02641 
02642 };
02643 
02644 /// Handler of decompiler events.
02645 /// \param ud user data. the value specified at the handler installation time
02646 ///           is passed here.
02647 /// \param event decompiler event code
02648 /// \param va additional arguments
02649 /// \return as a rule the callback must return 0 unless specified otherise in the
02650 ///         event description.
02651 
02652 typedef int idaapi hexrays_cb_t(void *ud, hexrays_event_t event, va_list va);
02653 
02654 
02655 /// Install handler for decompiler events.
02656 /// \param callback handler to install
02657 /// \param ud user data. this pointer will be passed to your handler by the decompiler.
02658 /// \return false if failed
02659 
02660 bool hexapi install_hexrays_callback(hexrays_cb_t *callback, void *ud);
02661 
02662 /// Uninstall handler for decompiler events.
02663 /// \param callback handler to uninstall
02664 /// \param ud user data. if NULL, all handler corresponding to \c callback is uninstalled.
02665 ///             if not NULL, only the callback instance with the specified \c ud value is uninstalled.
02666 /// \return number of uninstalled handlers.
02667 
02668 int hexapi remove_hexrays_callback(hexrays_cb_t *callback, void *ud);
02669 
02670 
02671 
02672 //---------------------------------------------------------------------------
02673 /// \defgroup vdui User interface definitions
02674 //@{
02675 
02676 /// Type of the input device.
02677 /// How the user command has been invoked
02678 enum input_device_t
02679 {
02680   USE_KEYBOARD = 0,     ///< Keyboard
02681   USE_MOUSE = 1,        ///< Mouse
02682 };
02683 //@}
02684 
02685 //---------------------------------------------------------------------------
02686 /// Cursor position in the output text (pseudocode).
02687 struct ctext_position_t
02688 {
02689   int lnnum;            ///< Line number
02690   int x;                ///< x coordinate of the cursor within the window
02691   int y;                ///< y coordinate of the cursor within the window
02692   /// Is the cursor in the variable/type declaration area?
02693   /// \param hdrlines Number of lines of the declaration area
02694   bool in_ctree(int hdrlines) const { return lnnum >= hdrlines; }
02695   /// Comparison operators
02696   DECLARE_COMPARISONS(ctext_position_t)
02697   {
02698     if ( lnnum < r.lnnum ) return -1;
02699     if ( lnnum > r.lnnum ) return  1;
02700     if ( x < r.x ) return -1;
02701     if ( x > r.x ) return  1;
02702     return 0;
02703   }
02704 };
02705 
02706 /// Navigation history item.
02707 /// Holds information about interactive decompilation history.
02708 /// Currently this is not saved in the database.
02709 struct history_item_t : public ctext_position_t
02710 {
02711   ea_t ea;              ///< The entry address of the decompiled function
02712 };
02713 
02714 /// Navigation history.
02715 typedef qstack<history_item_t> history_t;
02716 
02717 /// Comment types
02718 typedef int cmt_type_t;
02719 const cmt_type_t
02720   CMT_NONE   = 0x0000,  ///< No comment is possible
02721   CMT_TAIL   = 0x0001,  ///< Indented comment
02722   CMT_BLOCK1 = 0x0002,  ///< Anterioir block comment
02723   CMT_BLOCK2 = 0x0004,  ///< Posterior block comment
02724   CMT_LVAR   = 0x0008,  ///< Local variable comment
02725   CMT_FUNC   = 0x0010,  ///< Function comment
02726   CMT_ALL    = 0x001F;  ///< All comments
02727 
02728 //---------------------------------------------------------------------------
02729 /// Information about pseudocode window
02730 struct vdui_t
02731 {
02732   TForm *form;          ///< attention, may point to a destroyed form
02733                         ///< check the visibility before proceeding.
02734   int flags;            ///< \ref VDUI_
02735 /// \defgroup VDUI_ Properties of pseudocode window
02736 /// Used in vdui_t::flags
02737 //@{
02738 #define VDUI_VISIBLE 0x0001     ///< is visible?
02739 #define VDUI_VALID   0x0002     ///< is valid?
02740 #define VDUI_LOCKED  0x0004     ///< is locked?
02741 //@}
02742 
02743   /// Is the pseudocode window visible?
02744   /// if not, it might be invisible or destroyed
02745   bool visible(void) const { return (flags & VDUI_VISIBLE) != 0; }
02746   /// Does the pseudocode window contain valid code?
02747   /// It can become invalid if the function type gets changed in IDA.
02748   bool valid(void) const { return (flags & VDUI_VALID) != 0; }
02749   /// Does the pseudocode window contain valid code?
02750   /// We lock windows before modifying them
02751   bool locked(void) const { return (flags & VDUI_LOCKED) != 0; }
02752   void set_visible(bool v) { setflag(flags, VDUI_VISIBLE, v); }
02753   void set_valid(bool v)   { setflag(flags, VDUI_VALID, v); }
02754   void set_locked(bool v)   { setflag(flags, VDUI_LOCKED, v); }
02755 
02756   int view_idx;         ///< pseudocode window index (0..)
02757 
02758   TCustomControl *microview; ///< unused in the current version
02759   TCustomControl *ct;   ///< pseudocode view
02760   TCustomControl *cv;   ///< codeview control
02761 
02762   mbl_array_t *mba;     ///< pointer to underlying microcode
02763   cfunc_t *cfunc;       ///< pointer to function object
02764   strvec_t sv;          ///< decompilation output: function text
02765   int hdrlines;         ///< number of lines in the declaration area
02766   int code;             ///< result of the last micro_request(). See \ref MERR_
02767 
02768   // The folloing fields are valid after get_current_item():
02769   ctext_position_t cpos;        ///< Current ctext position
02770   ctree_item_t head;            ///< First ctree item on the current line (for block comments)
02771   ctree_item_t item;            ///< Current ctree item
02772   ctree_item_t tail;            ///< Tail ctree item on the current line (for indented comments)
02773 
02774   /// Nagivation history for pseudocode window
02775   history_t history;
02776 
02777   /// Refresh pseudocode window.
02778   /// This is the highest level refresh function.
02779   /// It causes the most profound refresh possible and can lead to redecompilation
02780   /// of the current function. Please consider using refresh_ctext()
02781   /// if you need a more superficial refresh.
02782   /// \param redo_mba true means to redecompile the current function\n
02783   ///                 false means to rebuild ctree without regenerating microcode
02784   /// \sa refresh_ctext()
02785   void __fastcall hexapi refresh_view(bool redo_mba);
02786 
02787   /// Refresh pseudocode window.
02788   /// This function refreshes the pseudocode window by regenerating its text
02789   /// from cfunc_t. Use it after modifying cfunc_t from a plugin.
02790   /// \sa refresh_view()
02791   void __fastcall hexapi refresh_ctext(bool activate=true);
02792 
02793   /// Display the specified pseudocode.
02794   /// This function replaces the pseudocode window contents with the
02795   /// specified cfunc_t.
02796   /// \param f pointer to the function to display. The pointer will be stored
02797   ///          in the current vdui_t object and be destroyed when necessary.
02798   ///          The caller loses its ownership.
02799   void hexapi switch_to(cfunc_t *f);
02800 
02801   /// Is the current item a statement?
02802   //// \return false if the cursor is in the local variable/type declaration area\n
02803   ///          true if the cursor is in the statement area
02804   bool in_ctree(void) const { return cpos.in_ctree(hdrlines); }
02805 
02806   /// Get current number.
02807   /// If the current item is a number, return pointer to it.
02808   /// \return NULL if the current item is not a number
02809   cnumber_t *hexapi get_number(void) const;
02810 
02811   /// Clear the pseudocode window.
02812   /// It deletes the current function and microcode.
02813   void __fastcall hexapi clear(void);
02814 
02815   /// Refresh the current position.
02816   /// This function refreshes the \ref cpos field.
02817   /// \return false if failed
02818   /// \param idv keyboard or mouse
02819   bool __fastcall hexapi refresh_cpos(input_device_t idv);
02820 
02821   /// Get current item.
02822   /// This function refreshes the \ref cpos, \ref item, \ref tail fields.
02823   /// \return false if failed
02824   /// \param idv keyboard or mouse
02825   /// \sa cfunc_t::get_line_item()
02826   bool __fastcall hexapi get_current_item(input_device_t idv);
02827 
02828   /// Rename local variable.
02829   /// This function displays a dialog box and allows the user to rename a local variable.
02830   /// \return false if failed or cancelled
02831   /// \param v pointer to local variable
02832   bool __fastcall hexapi ui_rename_lvar(lvar_t *v);
02833 
02834   /// Rename local variable.
02835   /// This function permanently renames a local variable.
02836   /// \return false if failed
02837   /// \param v pointer to local variable
02838   /// \param name new variable name
02839   /// \param is_user_name use true to save the new name into the database
02840   bool __fastcall hexapi rename_lvar(lvar_t *v, const char *name, bool is_user_name);
02841 
02842   /// Set local variable type.
02843   /// This function displays a dialog box and allows the user to change
02844   /// the type of a local variable.
02845   /// \return false if failed or cancelled
02846   /// \param v pointer to local variable
02847   bool __fastcall hexapi ui_set_lvar_type(lvar_t *v);
02848 
02849   /// Set local variable type.
02850   /// This function permanently sets a local variable type.
02851   /// \return false if failed
02852   /// \param v pointer to local variable
02853   /// \param type new variable type
02854   bool __fastcall hexapi set_lvar_type(lvar_t *v, const typestring &type);
02855 
02856   /// Set local variable comment.
02857   /// This function displays a dialog box and allows the user to edit
02858   /// the comment of a local variable.
02859   /// \return false if failed or cancelled
02860   /// \param v pointer to local variable
02861   bool __fastcall hexapi ui_edit_lvar_cmt(lvar_t *v);
02862 
02863   /// Set local variable comment.
02864   /// This function permanently sets a variable comment.
02865   /// \return false if failed
02866   /// \param v pointer to local variable
02867   /// \param cmt new comment
02868   bool __fastcall hexapi set_lvar_cmt(lvar_t *v, const char *cmt);
02869 
02870   /// Map a local variable to another.
02871   /// This function displays a variable list and allows the user to select mapping.
02872   /// \return false if failed or cancelled
02873   /// \param v pointer to local variable
02874   bool __fastcall hexapi ui_map_lvar(lvar_t *v);
02875 
02876   /// Unmap a local variable.
02877   /// This function displays list of variables mapped to the specified variable
02878   /// and allows the user to select a variable to unmap.
02879   /// \return false if failed or cancelled
02880   /// \param v pointer to local variable
02881   bool __fastcall hexapi ui_unmap_lvar(lvar_t *v);
02882 
02883   /// Map a local variable to another.
02884   /// This function permanently maps one lvar to another.
02885   /// All occurrences of the mapped variable are replaced by the new variable
02886   /// \return false if failed
02887   /// \param from the variable being mapped
02888   /// \param to the variable to map to. if NULL, unmaps the variable
02889   bool __fastcall hexapi map_lvar(lvar_t *from, lvar_t *to);
02890 
02891   /// Set structure field type.
02892   /// This function displays a dialog box and allows the user to change
02893   /// the type of a structure field.
02894   /// \return false if failed or cancelled
02895   /// \param sptr pointer to structure
02896   /// \param mptr pointer to structure member
02897   bool __fastcall hexapi set_strmem_type(struc_t *sptr, member_t *mptr);
02898 
02899   /// Rename structure field.
02900   /// This function displays a dialog box and allows the user to rename
02901   /// a structure field.
02902   /// \return false if failed or cancelled
02903   /// \param sptr pointer to structure
02904   /// \param mptr pointer to structure member
02905   bool __fastcall hexapi rename_strmem(struc_t *sptr, member_t *mptr);
02906 
02907   /// Set global item type.
02908   /// This function displays a dialog box and allows the user to change
02909   /// the type of a global item (data or function).
02910   /// \return false if failed or cancelled
02911   /// \param ea address of the global item
02912   bool __fastcall hexapi set_global_type(ea_t ea);
02913 
02914   /// Rename global item.
02915   /// This function displays a dialog box and allows the user to rename
02916   /// a global item (data or function).
02917   /// \return false if failed or cancelled
02918   /// \param ea address of the global item
02919   bool __fastcall hexapi rename_global(ea_t ea);
02920 
02921   /// Rename a label.
02922   /// This function displays a dialog box and allows the user to rename
02923   /// a statement label.
02924   /// \return false if failed or cancelled
02925   /// \param label label number
02926   bool __fastcall hexapi rename_label(int label);
02927 
02928   /// Process the Enter key.
02929   /// This function jumps to the definition of the item under the cursor.
02930   /// If the current item is a function, it will be decompiled.
02931   /// If the current item is a global data, its disassemly text will be displayed.
02932   /// \return false if failed
02933   /// \param idv what cursor must be used, the keyboard or the mouse
02934   /// \param new_window if true, new pseudocode window will open
02935   bool __fastcall hexapi jump_enter(input_device_t idv, bool new_window);
02936 
02937   /// Jump to disassembly.
02938   /// This function jumps to the address in the disassembly window
02939   /// which corresponds to the current item. The current item is determined
02940   /// based on the current keyboard cursor position.
02941   /// \return false if failed
02942   bool __fastcall hexapi ctree_to_disasm(void);
02943 
02944   /// Push the current location into the navigation history.
02945   /// \return false if failed
02946   /// \param idv how to determine the current item
02947   bool __fastcall hexapi push_current_location(input_device_t idv);
02948 
02949   /// Pop a location from the navigation history and jump to it.
02950   /// \return false if failed
02951   bool __fastcall hexapi pop_current_location(void);
02952 
02953   /// Check if the specified line can have a comment.
02954   /// Due to the coordinate system for comments
02955   /// (http://hexblog.com/2007/08/coordinate_system_for_hexrays.html)
02956   /// some function lines can not have comments. This function checks if a comment
02957   /// can be attached to the specified line
02958   /// \return possible comment types
02959   /// \param lnnum line number (0 based)
02960   /// \param cmttype comment types to check
02961   cmt_type_t __fastcall hexapi calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const;
02962 
02963   /// Edit an indented comment.
02964   /// This function displays a dialog box and allows the user to edit
02965   /// the comment for the specified ctree location.
02966   /// \return false if failed or cancelled
02967   /// \param loc comment location
02968   bool __fastcall hexapi edit_cmt(const treeloc_t &loc);
02969 
02970   /// Edit a function comment.
02971   /// This function displays a dialog box and allows the user to edit
02972   /// the function comment.
02973   /// \return false if failed or cancelled
02974   bool __fastcall hexapi edit_func_cmt(void);
02975 
02976   /// Delete all orphan comments.
02977   /// Delete all orphan comments and refresh the screen.
02978   /// \return true
02979   bool __fastcall hexapi del_orphan_cmts(void);
02980 
02981   /// Change number base.
02982   /// This function changes the current number representation.
02983   /// \return false if failed
02984   /// \param base number radix (10 or 16)\n
02985   ///             0 means a character constant
02986   bool __fastcall hexapi set_num_radix(int base);
02987 
02988   /// Convert number to symbolic constant.
02989   /// This function displays a dialog box and allows the user to select
02990   /// a symbolic constant to represent the number.
02991   /// \return false if failed or cancelled
02992   bool __fastcall hexapi set_num_enum(void);
02993 
02994   /// Convert number to structure field offset.
02995   /// Currently not implemented.
02996   /// \return false if failed or cancelled
02997   bool __fastcall hexapi set_num_stroff(void);
02998 
02999   /// Negate a number.
03000   /// This function negates the current number.
03001   /// \return false if failed.
03002   bool __fastcall hexapi invert_sign(void);
03003 
03004   /// Collapse/uncollapse item.
03005   /// This function collapses the current item.
03006   /// \return false if failed.
03007   bool __fastcall hexapi collapse_item(bool hide);
03008 
03009   /// Split/unsplit item.
03010   /// This function splits the current assignment expression.
03011   /// \return false if failed.
03012   bool __fastcall hexapi split_item(bool split);
03013 
03014   /// Force number of argmuments of a variadic call.
03015   /// \return false if failed.
03016   /// \param ea address of the call instruction.
03017   /// \param ida_argloc points past end of arglocs used by the call.
03018   ///                   for example, 4 means that there is one stack argument.
03019   bool __fastcall hexapi set_vargloc_end(ea_t ea, argloc_t ida_argloc);
03020 
03021 };
03022 
03023 #ifndef NO_OBSOLETE_FUNCS
03024 #define number_locator_t operand_locator_t
03025 #endif
03026 
03027 
03028 //--------------------------------------------------------------------------
03029 // PUBLIC HEX-RAYS API
03030 //--------------------------------------------------------------------------
03031 
03032 /// Hex-Rays decompiler dispatcher.
03033 /// All interaction with the decompiler is carried out by the intermediary of this dispatcher.
03034 typedef void *hexdsp_t(int code, ...);
03035 
03036 /// Pointer to Hex-Rays decompiler dispatcher.
03037 /// This variable must be instantiated by the plugin. It is initialized by init_hexrays_plugin().
03038 extern hexdsp_t *hexdsp;
03039 
03040 /// API call numbers
03041 enum hexcall_t
03042 {
03043   hx_user_cmts_begin,
03044   hx_user_cmts_end,
03045   hx_user_cmts_next,
03046   hx_user_cmts_prev,
03047   hx_user_cmts_first,
03048   hx_user_cmts_second,
03049   hx_user_cmts_find,
03050   hx_user_cmts_insert,
03051   hx_user_cmts_erase,
03052   hx_user_cmts_clear,
03053   hx_user_cmts_size,
03054   hx_user_cmts_free,
03055   hx_user_numforms_begin,
03056   hx_user_numforms_end,
03057   hx_user_numforms_next,
03058   hx_user_numforms_prev,
03059   hx_user_numforms_first,
03060   hx_user_numforms_second,
03061   hx_user_numforms_find,
03062   hx_user_numforms_insert,
03063   hx_user_numforms_erase,
03064   hx_user_numforms_clear,
03065   hx_user_numforms_size,
03066   hx_user_numforms_free,
03067   hx_user_iflags_begin,
03068   hx_user_iflags_end,
03069   hx_user_iflags_next,
03070   hx_user_iflags_prev,
03071   hx_user_iflags_first,
03072   hx_user_iflags_second,
03073   hx_user_iflags_find,
03074   hx_user_iflags_insert,
03075   hx_user_iflags_erase,
03076   hx_user_iflags_clear,
03077   hx_user_iflags_size,
03078   hx_user_iflags_free,
03079   hx_user_labels_begin,
03080   hx_user_labels_end,
03081   hx_user_labels_next,
03082   hx_user_labels_prev,
03083   hx_user_labels_first,
03084   hx_user_labels_second,
03085   hx_user_labels_find,
03086   hx_user_labels_insert,
03087   hx_user_labels_erase,
03088   hx_user_labels_clear,
03089   hx_user_labels_size,
03090   hx_user_labels_free,
03091   hx_operand_locator_t_compare,
03092   hx_vd_printer_t_print,
03093   hx_qstring_printer_t_print,
03094   hx_remove_typedef,
03095   hx_is_type_correct,
03096   hx_is_type_integral,
03097   hx_is_type_small_struni,
03098   hx_partial_type_num,
03099   hx_get_float_bit,
03100   hx_typestring_print,
03101   hx_typestring_change_sign,
03102   hx_typestring_get_cc,
03103   hx_typestring_get_nth_arg,
03104   hx_get_int_type_by_width_and_sign,
03105   hx_get_unk_type,
03106   hx_get_member_type,
03107   hx_make_array,
03108   hx_make_pointer,
03109   hx_create_typedef,
03110   hx_remove_pointer,
03111   hx_cnv_array_to_ptr,
03112   hx_strtype_info_t_build_base_type,
03113   hx_strtype_info_t_build_udt_type,
03114   hx_arglocs_overlap,
03115   hx_lvar_locator_t_get_regnum,
03116   hx_lvar_locator_t_compare,
03117   hx_lvar_t_accepts_type,
03118   hx_lvar_t_set_lvar_type,
03119   hx_lvar_t_set_width,
03120   hx_lvars_t_find_stkvar,
03121   hx_lvars_t_find,
03122   hx_lvars_t_find_lvar,
03123   hx_restore_user_lvar_settings,
03124   hx_save_user_lvar_settings,
03125   hx_fnumber_t_print,
03126   hx_get_hexrays_version,
03127   hx_open_pseudocode,
03128   hx_close_pseudocode,
03129   hx_decompile,
03130   hx_decompile_many,
03131   hx_micro_err_format,
03132   hx_hexrays_failure_t_desc,
03133   hx_send_database,
03134   hx_negated_relation,
03135   hx_get_op_signness,
03136   hx_asgop,
03137   hx_asgop_revert,
03138   hx_cnumber_t_print,
03139   hx_cnumber_t_value,
03140   hx_cnumber_t_assign,
03141   hx_cnumber_t_compare,
03142   hx_var_ref_t_compare,
03143   hx_ctree_visitor_t_apply_to,
03144   hx_ctree_visitor_t_apply_to_exprs,
03145   hx_ctree_parentee_t_recalc_parent_types,
03146   hx_cfunc_parentee_t_calc_rvalue_type,
03147   hx_citem_locator_t_compare,
03148   hx_citem_t_contains_label,
03149   hx_citem_t_find_parent_of,
03150   hx_cexpr_t_assign,
03151   hx_cexpr_t_compare,
03152   hx_cexpr_t_replace_by,
03153   hx_cexpr_t_cleanup,
03154   hx_cexpr_t_put_number,
03155   hx_cexpr_t_print1,
03156   hx_cexpr_t_calc_type,
03157   hx_cexpr_t_equal_effect,
03158   hx_cexpr_t_is_child_of,
03159   hx_cexpr_t_contains_operator,
03160   hx_cexpr_t_get_nbits,
03161   hx_cexpr_t_requires_lvalue,
03162   hx_cexpr_t_has_side_effects,
03163   hx_cif_t_assign,
03164   hx_cif_t_compare,
03165   hx_cloop_t_assign,
03166   hx_cfor_t_compare,
03167   hx_cwhile_t_compare,
03168   hx_cdo_t_compare,
03169   hx_creturn_t_compare,
03170   hx_cgoto_t_compare,
03171   hx_casm_t_compare,
03172   hx_cinsn_t_assign,
03173   hx_cinsn_t_compare,
03174   hx_cinsn_t_replace_by,
03175   hx_cinsn_t_cleanup,
03176   hx_cinsn_t_new_insn,
03177   hx_cinsn_t_create_if,
03178   hx_cinsn_t_print,
03179   hx_cinsn_t_print1,
03180   hx_cinsn_t_is_ordinary_flow,
03181   hx_cinsn_t_contains_insn,
03182   hx_cinsn_t_collect_free_breaks,
03183   hx_cinsn_t_collect_free_continues,
03184   hx_cblock_t_compare,
03185   hx_carglist_t_compare,
03186   hx_ccase_t_compare,
03187   hx_ccases_t_compare,
03188   hx_cswitch_t_compare,
03189   hx_ctree_item_t_get_memptr,
03190   hx_ctree_item_t_get_lvar,
03191   hx_ctree_item_t_get_ea,
03192   hx_ctree_item_t_get_label_num,
03193   hx_lnot,
03194   hx_new_block,
03195   hx_vcreate_helper,
03196   hx_vcall_helper,
03197   hx_make_num,
03198   hx_make_ref,
03199   hx_dereference,
03200   hx_save_user_labels,
03201   hx_save_user_cmts,
03202   hx_save_user_numforms,
03203   hx_save_user_iflags,
03204   hx_restore_user_labels,
03205   hx_restore_user_cmts,
03206   hx_restore_user_numforms,
03207   hx_restore_user_iflags,
03208   hx_cfunc_t_build_c_tree,
03209   hx_cfunc_t_verify,
03210   hx_cfunc_t_print_dcl,
03211   hx_cfunc_t_print_func,
03212   hx_cfunc_t_get_func_type,
03213   hx_cfunc_t_get_lvars,
03214   hx_cfunc_t_find_label,
03215   hx_cfunc_t_remove_unused_labels,
03216   hx_cfunc_t_get_user_cmt,
03217   hx_cfunc_t_set_user_cmt,
03218   hx_cfunc_t_get_user_iflags,
03219   hx_cfunc_t_set_user_iflags,
03220   hx_cfunc_t_has_orphan_cmts,
03221   hx_cfunc_t_del_orphan_cmts,
03222   hx_cfunc_t_get_line_item,
03223   hx_cfunc_t_get_warnings,
03224   hx_cfunc_t_gather_derefs,
03225   hx_cfunc_t_cleanup,
03226   hx_get_ctype_name,
03227   hx_install_hexrays_callback,
03228   hx_remove_hexrays_callback,
03229   hx_vdui_t_refresh_view,
03230   hx_vdui_t_refresh_ctext,
03231   hx_vdui_t_switch_to,
03232   hx_vdui_t_get_number,
03233   hx_vdui_t_clear,
03234   hx_vdui_t_refresh_cpos,
03235   hx_vdui_t_get_current_item,
03236   hx_vdui_t_ui_rename_lvar,
03237   hx_vdui_t_rename_lvar,
03238   hx_vdui_t_ui_set_lvar_type,
03239   hx_vdui_t_set_lvar_type,
03240   hx_vdui_t_edit_lvar_cmt,
03241   hx_vdui_t_set_lvar_cmt,
03242   hx_vdui_t_set_strmem_type,
03243   hx_vdui_t_rename_strmem,
03244   hx_vdui_t_set_global_type,
03245   hx_vdui_t_rename_global,
03246   hx_vdui_t_rename_label,
03247   hx_vdui_t_jump_enter,
03248   hx_vdui_t_ctree_to_disasm,
03249   hx_vdui_t_push_current_location,
03250   hx_vdui_t_pop_current_location,
03251   hx_vdui_t_calc_cmt_type,
03252   hx_vdui_t_edit_cmt,
03253   hx_vdui_t_edit_func_cmt,
03254   hx_vdui_t_del_orphan_cmts,
03255   hx_vdui_t_set_num_radix,
03256   hx_vdui_t_set_num_enum,
03257   hx_vdui_t_set_num_stroff,
03258   hx_vdui_t_invert_sign,
03259   hx_vdui_t_collapse_item,
03260   hx_vdui_t_split_item,
03261   hx_vdui_t_set_vargloc_end,
03262   hx_lvar_mapping_begin,
03263   hx_lvar_mapping_end,
03264   hx_lvar_mapping_next,
03265   hx_lvar_mapping_prev,
03266   hx_lvar_mapping_first,
03267   hx_lvar_mapping_second,
03268   hx_lvar_mapping_find,
03269   hx_lvar_mapping_insert,
03270   hx_lvar_mapping_erase,
03271   hx_lvar_mapping_clear,
03272   hx_lvar_mapping_size,
03273   hx_lvar_mapping_free,
03274   hx_user_unions_begin,
03275   hx_user_unions_end,
03276   hx_user_unions_next,
03277   hx_user_unions_prev,
03278   hx_user_unions_first,
03279   hx_user_unions_second,
03280   hx_user_unions_find,
03281   hx_user_unions_insert,
03282   hx_user_unions_erase,
03283   hx_user_unions_clear,
03284   hx_user_unions_size,
03285   hx_user_unions_free,
03286   hx_strtype_info_t_create_from,
03287   hx_save_user_unions,
03288   hx_restore_user_unions,
03289   hx_cfunc_t_get_user_union_selection,
03290   hx_cfunc_t_set_user_union_selection,
03291   hx_vdui_t_ui_edit_lvar_cmt,
03292   hx_vdui_t_ui_map_lvar,
03293   hx_vdui_t_ui_unmap_lvar,
03294   hx_vdui_t_map_lvar,
03295   hx_dummy_ptrtype,
03296   hx_create_field_name,
03297   hx_dummy_plist_for,
03298   hx_make_dt,
03299 };
03300 
03301 typedef int32 iterator_word;
03302 
03303 
03304 
03305 //--------------------------------------------------------------------------
03306 /// Initialize your plugin for hex-rays decompiler.
03307 /// This function must be called before calling any other decompiler function.
03308 /// It initializes the pointer to the dispatcher.
03309 /// \param flags reserved, must be 0
03310 /// \return true if the decompiler exists and the dispatcher pointer is ready to use.
03311 inline bool init_hexrays_plugin(int flags=0)
03312 {
03313   return callui(ui_clearbreak, HEXRAYS_API_MAGIC1, HEXRAYS_API_MAGIC2, &hexdsp, flags).i == HEXRAYS_API_MAGIC1;
03314 }
03315 
03316 //--------------------------------------------------------------------------
03317 /// Terminate your plugin for hex-rays decompiler.
03318 /// Currently this function is empty but please do include it in your plugins.
03319 inline void term_hexrays_plugin(void)
03320 {
03321 }
03322 
03323 //-------------------------------------------------------------------------
03324 struct user_numforms_iterator_t
03325 {
03326   iterator_word x;
03327   bool operator==(const user_numforms_iterator_t &p) const { return x == p.x; }
03328   bool operator!=(const user_numforms_iterator_t &p) const { return x != p.x; }
03329 };
03330 
03331 //-------------------------------------------------------------------------
03332 /// Get iterator pointing to the beginning of user_numforms_t
03333 inline user_numforms_iterator_t user_numforms_begin(const user_numforms_t *map)
03334 {
03335   user_numforms_iterator_t p;
03336   hexdsp(hx_user_numforms_begin, &p, map);
03337   return p;
03338 }
03339 
03340 //-------------------------------------------------------------------------
03341 /// Get iterator pointing to the end of user_numforms_t
03342 inline user_numforms_iterator_t user_numforms_end(const user_numforms_t *map)
03343 {
03344   user_numforms_iterator_t p;
03345   hexdsp(hx_user_numforms_end, &p, map);
03346   return p;
03347 }
03348 
03349 //-------------------------------------------------------------------------
03350 /// Move to the next element
03351 inline user_numforms_iterator_t user_numforms_next(user_numforms_iterator_t p)
03352 {
03353   hexdsp(hx_user_numforms_next, &p);
03354   return p;
03355 }
03356 
03357 //-------------------------------------------------------------------------
03358 /// Move to the previous element
03359 inline user_numforms_iterator_t user_numforms_prev(user_numforms_iterator_t p)
03360 {
03361   hexdsp(hx_user_numforms_prev, &p);
03362   return p;
03363 }
03364 
03365 //-------------------------------------------------------------------------
03366 /// Get reference to the current map key
03367 inline const operand_locator_t &user_numforms_first(user_numforms_iterator_t p)
03368 {
03369   return *(operand_locator_t *)hexdsp(hx_user_numforms_first, &p);
03370 }
03371 
03372 //-------------------------------------------------------------------------
03373 /// Get reference to the current map value
03374 inline number_format_t &user_numforms_second(user_numforms_iterator_t p)
03375 {
03376   return *(number_format_t *)hexdsp(hx_user_numforms_second, &p);
03377 }
03378 
03379 //-------------------------------------------------------------------------
03380 /// Find the specified key in user_numforms_t
03381 inline user_numforms_iterator_t user_numforms_find(const user_numforms_t *map, const operand_locator_t &key)
03382 {
03383   user_numforms_iterator_t p;
03384   hexdsp(hx_user_numforms_find, &p, map, &key);
03385   return p;
03386 }
03387 
03388 //-------------------------------------------------------------------------
03389 /// Insert new (operand_locator_t, number_format_t) pair into user_numforms_t
03390 inline user_numforms_iterator_t user_numforms_insert(user_numforms_t *map, const operand_locator_t &key, const number_format_t &val)
03391 {
03392   user_numforms_iterator_t p;
03393   hexdsp(hx_user_numforms_insert, &p, map, &key, &val);
03394   return p;
03395 }
03396 
03397 //-------------------------------------------------------------------------
03398 /// Erase current element from user_numforms_t
03399 inline void user_numforms_erase(user_numforms_t *map, user_numforms_iterator_t p)
03400 {
03401   hexdsp(hx_user_numforms_erase, map, &p);
03402 }
03403 
03404 //-------------------------------------------------------------------------
03405 /// Clear user_numforms_t
03406 inline void user_numforms_clear(user_numforms_t *map)
03407 {
03408   hexdsp(hx_user_numforms_clear, map);
03409 }
03410 
03411 //-------------------------------------------------------------------------
03412 /// Get size of user_numforms_t
03413 inline size_t user_numforms_size(user_numforms_t *map)
03414 {
03415   return (size_t)hexdsp(hx_user_numforms_size, map);
03416 }
03417 
03418 //-------------------------------------------------------------------------
03419 /// Delete user_numforms_t instance
03420 inline void user_numforms_free(user_numforms_t *map)
03421 {
03422   hexdsp(hx_user_numforms_free, map);
03423 }
03424 
03425 //-------------------------------------------------------------------------
03426 struct lvar_mapping_iterator_t
03427 {
03428   iterator_word x;
03429   bool operator==(const lvar_mapping_iterator_t &p) const { return x == p.x; }
03430   bool operator!=(const lvar_mapping_iterator_t &p) const { return x != p.x; }
03431 };
03432 
03433 //-------------------------------------------------------------------------
03434 /// Get iterator pointing to the beginning of lvar_mapping_t
03435 inline lvar_mapping_iterator_t lvar_mapping_begin(const lvar_mapping_t *map)
03436 {
03437   lvar_mapping_iterator_t p;
03438   hexdsp(hx_lvar_mapping_begin, &p, map);
03439   return p;
03440 }
03441 
03442 //-------------------------------------------------------------------------
03443 /// Get iterator pointing to the end of lvar_mapping_t
03444 inline lvar_mapping_iterator_t lvar_mapping_end(const lvar_mapping_t *map)
03445 {
03446   lvar_mapping_iterator_t p;
03447   hexdsp(hx_lvar_mapping_end, &p, map);
03448   return p;
03449 }
03450 
03451 //-------------------------------------------------------------------------
03452 /// Move to the next element
03453 inline lvar_mapping_iterator_t lvar_mapping_next(lvar_mapping_iterator_t p)
03454 {
03455   hexdsp(hx_lvar_mapping_next, &p);
03456   return p;
03457 }
03458 
03459 //-------------------------------------------------------------------------
03460 /// Move to the previous element
03461 inline lvar_mapping_iterator_t lvar_mapping_prev(lvar_mapping_iterator_t p)
03462 {
03463   hexdsp(hx_lvar_mapping_prev, &p);
03464   return p;
03465 }
03466 
03467 //-------------------------------------------------------------------------
03468 /// Get reference to the current map key
03469 inline const lvar_locator_t &lvar_mapping_first(lvar_mapping_iterator_t p)
03470 {
03471   return *(lvar_locator_t *)hexdsp(hx_lvar_mapping_first, &p);
03472 }
03473 
03474 //-------------------------------------------------------------------------
03475 /// Get reference to the current map value
03476 inline lvar_locator_t &lvar_mapping_second(lvar_mapping_iterator_t p)
03477 {
03478   return *(lvar_locator_t *)hexdsp(hx_lvar_mapping_second, &p);
03479 }
03480 
03481 //-------------------------------------------------------------------------
03482 /// Find the specified key in lvar_mapping_t
03483 inline lvar_mapping_iterator_t lvar_mapping_find(const lvar_mapping_t *map, const lvar_locator_t &key)
03484 {
03485   lvar_mapping_iterator_t p;
03486   hexdsp(hx_lvar_mapping_find, &p, map, &key);
03487   return p;
03488 }
03489 
03490 //-------------------------------------------------------------------------
03491 /// Insert new (lvar_locator_t, lvar_locator_t) pair into lvar_mapping_t
03492 inline lvar_mapping_iterator_t lvar_mapping_insert(lvar_mapping_t *map, const lvar_locator_t &key, const lvar_locator_t &val)
03493 {
03494   lvar_mapping_iterator_t p;
03495   hexdsp(hx_lvar_mapping_insert, &p, map, &key, &val);
03496   return p;
03497 }
03498 
03499 //-------------------------------------------------------------------------
03500 /// Erase current element from lvar_mapping_t
03501 inline void lvar_mapping_erase(lvar_mapping_t *map, lvar_mapping_iterator_t p)
03502 {
03503   hexdsp(hx_lvar_mapping_erase, map, &p);
03504 }
03505 
03506 //-------------------------------------------------------------------------
03507 /// Clear lvar_mapping_t
03508 inline void lvar_mapping_clear(lvar_mapping_t *map)
03509 {
03510   hexdsp(hx_lvar_mapping_clear, map);
03511 }
03512 
03513 //-------------------------------------------------------------------------
03514 /// Get size of lvar_mapping_t
03515 inline size_t lvar_mapping_size(lvar_mapping_t *map)
03516 {
03517   return (size_t)hexdsp(hx_lvar_mapping_size, map);
03518 }
03519 
03520 //-------------------------------------------------------------------------
03521 /// Delete lvar_mapping_t instance
03522 inline void lvar_mapping_free(lvar_mapping_t *map)
03523 {
03524   hexdsp(hx_lvar_mapping_free, map);
03525 }
03526 
03527 //-------------------------------------------------------------------------
03528 struct user_cmts_iterator_t
03529 {
03530   iterator_word x;
03531   bool operator==(const user_cmts_iterator_t &p) const { return x == p.x; }
03532   bool operator!=(const user_cmts_iterator_t &p) const { return x != p.x; }
03533 };
03534 
03535 //-------------------------------------------------------------------------
03536 /// Get iterator pointing to the beginning of user_cmts_t
03537 inline user_cmts_iterator_t user_cmts_begin(const user_cmts_t *map)
03538 {
03539   user_cmts_iterator_t p;
03540   hexdsp(hx_user_cmts_begin, &p, map);
03541   return p;
03542 }
03543 
03544 //-------------------------------------------------------------------------
03545 /// Get iterator pointing to the end of user_cmts_t
03546 inline user_cmts_iterator_t user_cmts_end(const user_cmts_t *map)
03547 {
03548   user_cmts_iterator_t p;
03549   hexdsp(hx_user_cmts_end, &p, map);
03550   return p;
03551 }
03552 
03553 //-------------------------------------------------------------------------
03554 /// Move to the next element
03555 inline user_cmts_iterator_t user_cmts_next(user_cmts_iterator_t p)
03556 {
03557   hexdsp(hx_user_cmts_next, &p);
03558   return p;
03559 }
03560 
03561 //-------------------------------------------------------------------------
03562 /// Move to the previous element
03563 inline user_cmts_iterator_t user_cmts_prev(user_cmts_iterator_t p)
03564 {
03565   hexdsp(hx_user_cmts_prev, &p);
03566   return p;
03567 }
03568 
03569 //-------------------------------------------------------------------------
03570 /// Get reference to the current map key
03571 inline const treeloc_t &user_cmts_first(user_cmts_iterator_t p)
03572 {
03573   return *(treeloc_t *)hexdsp(hx_user_cmts_first, &p);
03574 }
03575 
03576 //-------------------------------------------------------------------------
03577 /// Get reference to the current map value
03578 inline citem_cmt_t &user_cmts_second(user_cmts_iterator_t p)
03579 {
03580   return *(citem_cmt_t *)hexdsp(hx_user_cmts_second, &p);
03581 }
03582 
03583 //-------------------------------------------------------------------------
03584 /// Find the specified key in user_cmts_t
03585 inline user_cmts_iterator_t user_cmts_find(const user_cmts_t *map, const treeloc_t &key)
03586 {
03587   user_cmts_iterator_t p;
03588   hexdsp(hx_user_cmts_find, &p, map, &key);
03589   return p;
03590 }
03591 
03592 //-------------------------------------------------------------------------
03593 /// Insert new (treeloc_t, citem_cmt_t) pair into user_cmts_t
03594 inline user_cmts_iterator_t user_cmts_insert(user_cmts_t *map, const treeloc_t &key, const citem_cmt_t &val)
03595 {
03596   user_cmts_iterator_t p;
03597   hexdsp(hx_user_cmts_insert, &p, map, &key, &val);
03598   return p;
03599 }
03600 
03601 //-------------------------------------------------------------------------
03602 /// Erase current element from user_cmts_t
03603 inline void user_cmts_erase(user_cmts_t *map, user_cmts_iterator_t p)
03604 {
03605   hexdsp(hx_user_cmts_erase, map, &p);
03606 }
03607 
03608 //-------------------------------------------------------------------------
03609 /// Clear user_cmts_t
03610 inline void user_cmts_clear(user_cmts_t *map)
03611 {
03612   hexdsp(hx_user_cmts_clear, map);
03613 }
03614 
03615 //-------------------------------------------------------------------------
03616 /// Get size of user_cmts_t
03617 inline size_t user_cmts_size(user_cmts_t *map)
03618 {
03619   return (size_t)hexdsp(hx_user_cmts_size, map);
03620 }
03621 
03622 //-------------------------------------------------------------------------
03623 /// Delete user_cmts_t instance
03624 inline void user_cmts_free(user_cmts_t *map)
03625 {
03626   hexdsp(hx_user_cmts_free, map);
03627 }
03628 
03629 //-------------------------------------------------------------------------
03630 struct user_iflags_iterator_t
03631 {
03632   iterator_word x;
03633   bool operator==(const user_iflags_iterator_t &p) const { return x == p.x; }
03634   bool operator!=(const user_iflags_iterator_t &p) const { return x != p.x; }
03635 };
03636 
03637 //-------------------------------------------------------------------------
03638 /// Get iterator pointing to the beginning of user_iflags_t
03639 inline user_iflags_iterator_t user_iflags_begin(const user_iflags_t *map)
03640 {
03641   user_iflags_iterator_t p;
03642   hexdsp(hx_user_iflags_begin, &p, map);
03643   return p;
03644 }
03645 
03646 //-------------------------------------------------------------------------
03647 /// Get iterator pointing to the end of user_iflags_t
03648 inline user_iflags_iterator_t user_iflags_end(const user_iflags_t *map)
03649 {
03650   user_iflags_iterator_t p;
03651   hexdsp(hx_user_iflags_end, &p, map);
03652   return p;
03653 }
03654 
03655 //-------------------------------------------------------------------------
03656 /// Move to the next element
03657 inline user_iflags_iterator_t user_iflags_next(user_iflags_iterator_t p)
03658 {
03659   hexdsp(hx_user_iflags_next, &p);
03660   return p;
03661 }
03662 
03663 //-------------------------------------------------------------------------
03664 /// Move to the previous element
03665 inline user_iflags_iterator_t user_iflags_prev(user_iflags_iterator_t p)
03666 {
03667   hexdsp(hx_user_iflags_prev, &p);
03668   return p;
03669 }
03670 
03671 //-------------------------------------------------------------------------
03672 /// Get reference to the current map key
03673 inline const citem_locator_t &user_iflags_first(user_iflags_iterator_t p)
03674 {
03675   return *(citem_locator_t *)hexdsp(hx_user_iflags_first, &p);
03676 }
03677 
03678 //-------------------------------------------------------------------------
03679 /// Get reference to the current map value
03680 inline int32 &user_iflags_second(user_iflags_iterator_t p)
03681 {
03682   return *(int32 *)hexdsp(hx_user_iflags_second, &p);
03683 }
03684 
03685 //-------------------------------------------------------------------------
03686 /// Find the specified key in user_iflags_t
03687 inline user_iflags_iterator_t user_iflags_find(const user_iflags_t *map, const citem_locator_t &key)
03688 {
03689   user_iflags_iterator_t p;
03690   hexdsp(hx_user_iflags_find, &p, map, &key);
03691   return p;
03692 }
03693 
03694 //-------------------------------------------------------------------------
03695 /// Insert new (citem_locator_t, int32) pair into user_iflags_t
03696 inline user_iflags_iterator_t user_iflags_insert(user_iflags_t *map, const citem_locator_t &key, const int32 &val)
03697 {
03698   user_iflags_iterator_t p;
03699   hexdsp(hx_user_iflags_insert, &p, map, &key, &val);
03700   return p;
03701 }
03702 
03703 //-------------------------------------------------------------------------
03704 /// Erase current element from user_iflags_t
03705 inline void user_iflags_erase(user_iflags_t *map, user_iflags_iterator_t p)
03706 {
03707   hexdsp(hx_user_iflags_erase, map, &p);
03708 }
03709 
03710 //-------------------------------------------------------------------------
03711 /// Clear user_iflags_t
03712 inline void user_iflags_clear(user_iflags_t *map)
03713 {
03714   hexdsp(hx_user_iflags_clear, map);
03715 }
03716 
03717 //-------------------------------------------------------------------------
03718 /// Get size of user_iflags_t
03719 inline size_t user_iflags_size(user_iflags_t *map)
03720 {
03721   return (size_t)hexdsp(hx_user_iflags_size, map);
03722 }
03723 
03724 //-------------------------------------------------------------------------
03725 /// Delete user_iflags_t instance
03726 inline void user_iflags_free(user_iflags_t *map)
03727 {
03728   hexdsp(hx_user_iflags_free, map);
03729 }
03730 
03731 //-------------------------------------------------------------------------
03732 struct user_unions_iterator_t
03733 {
03734   iterator_word x;
03735   bool operator==(const user_unions_iterator_t &p) const { return x == p.x; }
03736   bool operator!=(const user_unions_iterator_t &p) const { return x != p.x; }
03737 };
03738 
03739 //-------------------------------------------------------------------------
03740 /// Get iterator pointing to the beginning of user_unions_t
03741 inline user_unions_iterator_t user_unions_begin(const user_unions_t *map)
03742 {
03743   user_unions_iterator_t p;
03744   hexdsp(hx_user_unions_begin, &p, map);
03745   return p;
03746 }
03747 
03748 //-------------------------------------------------------------------------
03749 /// Get iterator pointing to the end of user_unions_t
03750 inline user_unions_iterator_t user_unions_end(const user_unions_t *map)
03751 {
03752   user_unions_iterator_t p;
03753   hexdsp(hx_user_unions_end, &p, map);
03754   return p;
03755 }
03756 
03757 //-------------------------------------------------------------------------
03758 /// Move to the next element
03759 inline user_unions_iterator_t user_unions_next(user_unions_iterator_t p)
03760 {
03761   hexdsp(hx_user_unions_next, &p);
03762   return p;
03763 }
03764 
03765 //-------------------------------------------------------------------------
03766 /// Move to the previous element
03767 inline user_unions_iterator_t user_unions_prev(user_unions_iterator_t p)
03768 {
03769   hexdsp(hx_user_unions_prev, &p);
03770   return p;
03771 }
03772 
03773 //-------------------------------------------------------------------------
03774 /// Get reference to the current map key
03775 inline const ea_t &user_unions_first(user_unions_iterator_t p)
03776 {
03777   return *(ea_t *)hexdsp(hx_user_unions_first, &p);
03778 }
03779 
03780 //-------------------------------------------------------------------------
03781 /// Get reference to the current map value
03782 inline intvec_t &user_unions_second(user_unions_iterator_t p)
03783 {
03784   return *(intvec_t *)hexdsp(hx_user_unions_second, &p);
03785 }
03786 
03787 //-------------------------------------------------------------------------
03788 /// Find the specified key in user_unions_t
03789 inline user_unions_iterator_t user_unions_find(const user_unions_t *map, const ea_t &key)
03790 {
03791   user_unions_iterator_t p;
03792   hexdsp(hx_user_unions_find, &p, map, &key);
03793   return p;
03794 }
03795 
03796 //-------------------------------------------------------------------------
03797 /// Insert new (ea_t, intvec_t) pair into user_unions_t
03798 inline user_unions_iterator_t user_unions_insert(user_unions_t *map, const ea_t &key, const intvec_t &val)
03799 {
03800   user_unions_iterator_t p;
03801   hexdsp(hx_user_unions_insert, &p, map, &key, &val);
03802   return p;
03803 }
03804 
03805 //-------------------------------------------------------------------------
03806 /// Erase current element from user_unions_t
03807 inline void user_unions_erase(user_unions_t *map, user_unions_iterator_t p)
03808 {
03809   hexdsp(hx_user_unions_erase, map, &p);
03810 }
03811 
03812 //-------------------------------------------------------------------------
03813 /// Clear user_unions_t
03814 inline void user_unions_clear(user_unions_t *map)
03815 {
03816   hexdsp(hx_user_unions_clear, map);
03817 }
03818 
03819 //-------------------------------------------------------------------------
03820 /// Get size of user_unions_t
03821 inline size_t user_unions_size(user_unions_t *map)
03822 {
03823   return (size_t)hexdsp(hx_user_unions_size, map);
03824 }
03825 
03826 //-------------------------------------------------------------------------
03827 /// Delete user_unions_t instance
03828 inline void user_unions_free(user_unions_t *map)
03829 {
03830   hexdsp(hx_user_unions_free, map);
03831 }
03832 
03833 //-------------------------------------------------------------------------
03834 struct user_labels_iterator_t
03835 {
03836   iterator_word x;
03837   bool operator==(const user_labels_iterator_t &p) const { return x == p.x; }
03838   bool operator!=(const user_labels_iterator_t &p) const { return x != p.x; }
03839 };
03840 
03841 //-------------------------------------------------------------------------
03842 /// Get iterator pointing to the beginning of user_labels_t
03843 inline user_labels_iterator_t user_labels_begin(const user_labels_t *map)
03844 {
03845   user_labels_iterator_t p;
03846   hexdsp(hx_user_labels_begin, &p, map);
03847   return p;
03848 }
03849 
03850 //-------------------------------------------------------------------------
03851 /// Get iterator pointing to the end of user_labels_t
03852 inline user_labels_iterator_t user_labels_end(const user_labels_t *map)
03853 {
03854   user_labels_iterator_t p;
03855   hexdsp(hx_user_labels_end, &p, map);
03856   return p;
03857 }
03858 
03859 //-------------------------------------------------------------------------
03860 /// Move to the next element
03861 inline user_labels_iterator_t user_labels_next(user_labels_iterator_t p)
03862 {
03863   hexdsp(hx_user_labels_next, &p);
03864   return p;
03865 }
03866 
03867 //-------------------------------------------------------------------------
03868 /// Move to the previous element
03869 inline user_labels_iterator_t user_labels_prev(user_labels_iterator_t p)
03870 {
03871   hexdsp(hx_user_labels_prev, &p);
03872   return p;
03873 }
03874 
03875 //-------------------------------------------------------------------------
03876 /// Get reference to the current map key
03877 inline const int &user_labels_first(user_labels_iterator_t p)
03878 {
03879   return *(int *)hexdsp(hx_user_labels_first, &p);
03880 }
03881 
03882 //-------------------------------------------------------------------------
03883 /// Get reference to the current map value
03884 inline qstring &user_labels_second(user_labels_iterator_t p)
03885 {
03886   return *(qstring *)hexdsp(hx_user_labels_second, &p);
03887 }
03888 
03889 //-------------------------------------------------------------------------
03890 /// Find the specified key in user_labels_t
03891 inline user_labels_iterator_t user_labels_find(const user_labels_t *map, const int &key)
03892 {
03893   user_labels_iterator_t p;
03894   hexdsp(hx_user_labels_find, &p, map, &key);
03895   return p;
03896 }
03897 
03898 //-------------------------------------------------------------------------
03899 /// Insert new (int, qstring) pair into user_labels_t
03900 inline user_labels_iterator_t user_labels_insert(user_labels_t *map, const int &key, const qstring &val)
03901 {
03902   user_labels_iterator_t p;
03903   hexdsp(hx_user_labels_insert, &p, map, &key, &val);
03904   return p;
03905 }
03906 
03907 //-------------------------------------------------------------------------
03908 /// Erase current element from user_labels_t
03909 inline void user_labels_erase(user_labels_t *map, user_labels_iterator_t p)
03910 {
03911   hexdsp(hx_user_labels_erase, map, &p);
03912 }
03913 
03914 //-------------------------------------------------------------------------
03915 /// Clear user_labels_t
03916 inline void user_labels_clear(user_labels_t *map)
03917 {
03918   hexdsp(hx_user_labels_clear, map);
03919 }
03920 
03921 //-------------------------------------------------------------------------
03922 /// Get size of user_labels_t
03923 inline size_t user_labels_size(user_labels_t *map)
03924 {
03925   return (size_t)hexdsp(hx_user_labels_size, map);
03926 }
03927 
03928 //-------------------------------------------------------------------------
03929 /// Delete user_labels_t instance
03930 inline void user_labels_free(user_labels_t *map)
03931 {
03932   hexdsp(hx_user_labels_free, map);
03933 }
03934 
03935 //--------------------------------------------------------------------------
03936 inline int operand_locator_t::compare(const operand_locator_t &r) const
03937 {
03938   return (int)hexdsp(hx_operand_locator_t_compare, this, &r);
03939 }
03940 
03941 //--------------------------------------------------------------------------
03942 inline AS_PRINTF(3, 4) int vd_printer_t::print(int indent, const char *format, ...)
03943 {
03944   va_list va;
03945   va_start(va, format);
03946   int retval = (int)hexdsp(hx_vd_printer_t_print, this, indent, format, va);
03947   va_end(va);
03948   return retval;
03949 }
03950 
03951 //--------------------------------------------------------------------------
03952 inline AS_PRINTF(3, 4) int qstring_printer_t::print(int indent, const char *format, ...)
03953 {
03954   va_list va;
03955   va_start(va, format);
03956   int retval = (int)hexdsp(hx_qstring_printer_t_print, this, indent, format, va);
03957   va_end(va);
03958   return retval;
03959 }
03960 
03961 //--------------------------------------------------------------------------
03962 inline const type_t *remove_typedef(const type_t *type, const p_list **fields)
03963 {
03964   return (const type_t *)hexdsp(hx_remove_typedef, type, fields);
03965 }
03966 
03967 //--------------------------------------------------------------------------
03968 inline bool is_type_correct(const type_t *ptr)
03969 {
03970   return (bool)(size_t)hexdsp(hx_is_type_correct, ptr);
03971 }
03972 
03973 //--------------------------------------------------------------------------
03974 inline bool is_type_integral(const type_t *type)
03975 {
03976   return (bool)(size_t)hexdsp(hx_is_type_integral, type);
03977 }
03978 
03979 //--------------------------------------------------------------------------
03980 inline bool is_type_small_struni(const type_t *ptr)
03981 {
03982   return (bool)(size_t)hexdsp(hx_is_type_small_struni, ptr);
03983 }
03984 
03985 //--------------------------------------------------------------------------
03986 inline int partial_type_num(const type_t *type)
03987 {
03988   return (int)hexdsp(hx_partial_type_num, type);
03989 }
03990 
03991 //--------------------------------------------------------------------------
03992 inline type_t get_float_bit(int width)
03993 {
03994   return (type_t)(size_t)hexdsp(hx_get_float_bit, width);
03995 }
03996 
03997 //--------------------------------------------------------------------------
03998 inline size_t typestring::print(char *buf, size_t bufsize) const
03999 {
04000   return (size_t)hexdsp(hx_typestring_print, this, buf, bufsize);
04001 }
04002 
04003 //--------------------------------------------------------------------------
04004 inline bool typestring::change_sign(type_sign_t sign)
04005 {
04006   return (bool)(size_t)hexdsp(hx_typestring_change_sign, this, sign);
04007 }
04008 
04009 //--------------------------------------------------------------------------
04010 inline cm_t typestring::get_cc(void) const
04011 {
04012   return (cm_t)(size_t)hexdsp(hx_typestring_get_cc, this);
04013 }
04014 
04015 //--------------------------------------------------------------------------
04016 inline typestring typestring::get_nth_arg(int n) const
04017 {
04018   typestring retval;
04019   hexdsp(hx_typestring_get_nth_arg, &retval, this, n);
04020   return retval;
04021 }
04022 
04023 //--------------------------------------------------------------------------
04024 inline typestring get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign)
04025 {
04026   typestring retval;
04027   hexdsp(hx_get_int_type_by_width_and_sign, &retval, srcwidth, sign);
04028   return retval;
04029 }
04030 
04031 //--------------------------------------------------------------------------
04032 inline typestring get_unk_type(int size)
04033 {
04034   typestring retval;
04035   hexdsp(hx_get_unk_type, &retval, size);
04036   return retval;
04037 }
04038 
04039 //--------------------------------------------------------------------------
04040 inline typestring dummy_ptrtype(int ptrsize, bool isfp)
04041 {
04042   typestring retval;
04043   hexdsp(hx_dummy_ptrtype, &retval, ptrsize, isfp);
04044   return retval;
04045 }
04046 
04047 //--------------------------------------------------------------------------
04048 inline bool get_member_type(const member_t *mptr, typestring *type, qtype *fields)
04049 {
04050   return (bool)(size_t)hexdsp(hx_get_member_type, mptr, type, fields);
04051 }
04052 
04053 //--------------------------------------------------------------------------
04054 inline typestring make_array(const type_t *type, int nelems)
04055 {
04056   typestring retval;
04057   hexdsp(hx_make_array, &retval, type, nelems);
04058   return retval;
04059 }
04060 
04061 //--------------------------------------------------------------------------
04062 inline typestring make_pointer(const typestring &type)
04063 {
04064   typestring retval;
04065   hexdsp(hx_make_pointer, &retval, &type);
04066   return retval;
04067 }
04068 
04069 //--------------------------------------------------------------------------
04070 inline typestring create_typedef(const char *name)
04071 {
04072   typestring retval;
04073   hexdsp(hx_create_typedef, &retval, name);
04074   return retval;
04075 }
04076 
04077 //--------------------------------------------------------------------------
04078 inline typestring remove_pointer(const typestring &type)
04079 {
04080   typestring retval;
04081   hexdsp(hx_remove_pointer, &retval, &type);
04082   return retval;
04083 }
04084 
04085 //--------------------------------------------------------------------------
04086 inline bool cnv_array_to_ptr(typestring &type)
04087 {
04088   return (bool)(size_t)hexdsp(hx_cnv_array_to_ptr, &type);
04089 }
04090 
04091 //--------------------------------------------------------------------------
04092 inline bool strtype_info_t::create_from(const type_t *type, const p_list *fields, bool with_gaps)
04093 {
04094   return (bool)(size_t)hexdsp(hx_strtype_info_t_create_from, this, type, fields, with_gaps);
04095 }
04096 
04097 //--------------------------------------------------------------------------
04098 inline bool strtype_info_t::build_base_type(typestring *restype) const
04099 {
04100   return (bool)(size_t)hexdsp(hx_strtype_info_t_build_base_type, this, restype);
04101 }
04102 
04103 //--------------------------------------------------------------------------
04104 inline bool strtype_info_t::build_udt_type(typestring *restype, typestring *resfields)
04105 {
04106   return (bool)(size_t)hexdsp(hx_strtype_info_t_build_udt_type, this, restype, resfields);
04107 }
04108 
04109 //--------------------------------------------------------------------------
04110 inline bool arglocs_overlap(argloc_t loc1, size_t w1, argloc_t loc2, size_t w2)
04111 {
04112   return (bool)(size_t)hexdsp(hx_arglocs_overlap, loc1, w1, loc2, w2);
04113 }
04114 
04115 //--------------------------------------------------------------------------
04116 inline sval_t lvar_locator_t::get_regnum(void) const
04117 {
04118   return (sval_t)hexdsp(hx_lvar_locator_t_get_regnum, this);
04119 }
04120 
04121 //--------------------------------------------------------------------------
04122 inline int lvar_locator_t::compare(const lvar_locator_t &r) const
04123 {
04124   return (int)hexdsp(hx_lvar_locator_t_compare, this, &r);
04125 }
04126 
04127 //--------------------------------------------------------------------------
04128 inline bool lvar_t::accepts_type(const typestring &t)
04129 {
04130   return (bool)(size_t)hexdsp(hx_lvar_t_accepts_type, this, &t);
04131 }
04132 
04133 //--------------------------------------------------------------------------
04134 inline void lvar_t::set_lvar_type(const typestring &t)
04135 {
04136   hexdsp(hx_lvar_t_set_lvar_type, this, &t);
04137 }
04138 
04139 //--------------------------------------------------------------------------
04140 inline void lvar_t::set_width(int w, bool is_float)
04141 {
04142   hexdsp(hx_lvar_t_set_width, this, w, is_float);
04143 }
04144 
04145 //--------------------------------------------------------------------------
04146 inline int lvars_t::find_stkvar(int32 spoff, int width)
04147 {
04148   return (int)hexdsp(hx_lvars_t_find_stkvar, this, spoff, width);
04149 }
04150 
04151 //--------------------------------------------------------------------------
04152 inline lvar_t *lvars_t::find(const lvar_locator_t &ll)
04153 {
04154   return (lvar_t *)hexdsp(hx_lvars_t_find, this, &ll);
04155 }
04156 
04157 //--------------------------------------------------------------------------
04158 inline int lvars_t::find_lvar(argloc_t location, int width, int defblk)
04159 {
04160   return (int)hexdsp(hx_lvars_t_find_lvar, this, location, width, defblk);
04161 }
04162 
04163 //--------------------------------------------------------------------------
04164 inline int restore_user_lvar_settings(ea_t func_ea, user_lvar_visitor_t &ulv)
04165 {
04166   return (int)hexdsp(hx_restore_user_lvar_settings, func_ea, &ulv);
04167 }
04168 
04169 //--------------------------------------------------------------------------
04170 inline void save_user_lvar_settings(ea_t func_ea, user_lvar_visitor_t &ulv)
04171 {
04172   hexdsp(hx_save_user_lvar_settings, func_ea, &ulv);
04173 }
04174 
04175 //--------------------------------------------------------------------------
04176 inline size_t fnumber_t::print(char *buf, size_t bufsize) const
04177 {
04178   return (size_t)hexdsp(hx_fnumber_t_print, this, buf, bufsize);
04179 }
04180 
04181 //--------------------------------------------------------------------------
04182 inline const char *get_hexrays_version(void)
04183 {
04184   return (const char *)hexdsp(hx_get_hexrays_version);
04185 }
04186 
04187 //--------------------------------------------------------------------------
04188 inline vdui_t *open_pseudocode(ea_t ea, int new_window)
04189 {
04190   return (vdui_t *)hexdsp(hx_open_pseudocode, ea, new_window);
04191 }
04192 
04193 //--------------------------------------------------------------------------
04194 inline bool close_pseudocode(TForm *f)
04195 {
04196   return (bool)(size_t)hexdsp(hx_close_pseudocode, f);
04197 }
04198 
04199 //--------------------------------------------------------------------------
04200 inline cfunc_t *decompile(func_t *pfn, hexrays_failure_t *hf)
04201 {
04202   return (cfunc_t *)hexdsp(hx_decompile, pfn, hf);
04203 }
04204 
04205 //--------------------------------------------------------------------------
04206 inline bool decompile_many(const char *outfile, eavec_t *funcaddrs, int vdrun_flags)
04207 {
04208   return (bool)(size_t)hexdsp(hx_decompile_many, outfile, funcaddrs, vdrun_flags);
04209 }
04210 
04211 //--------------------------------------------------------------------------
04212 inline const char *micro_err_format(int code)
04213 {
04214   return (const char *)hexdsp(hx_micro_err_format, code);
04215 }
04216 
04217 //--------------------------------------------------------------------------
04218 inline qstring hexrays_failure_t::desc(void) const
04219 {
04220   qstring retval;
04221   hexdsp(hx_hexrays_failure_t_desc, &retval, this);
04222   return retval;
04223 }
04224 
04225 //--------------------------------------------------------------------------
04226 inline void send_database(const hexrays_failure_t &err, bool silent)
04227 {
04228   hexdsp(hx_send_database, &err, silent);
04229 }
04230 
04231 //--------------------------------------------------------------------------
04232 inline ctype_t negated_relation(ctype_t op)
04233 {
04234   return (ctype_t)(size_t)hexdsp(hx_negated_relation, op);
04235 }
04236 
04237 //--------------------------------------------------------------------------
04238 inline type_sign_t get_op_signness(ctype_t op)
04239 {
04240   return (type_sign_t)hexdsp(hx_get_op_signness, op);
04241 }
04242 
04243 //--------------------------------------------------------------------------
04244 inline ctype_t asgop(ctype_t cop)
04245 {
04246   return (ctype_t)(size_t)hexdsp(hx_asgop, cop);
04247 }
04248 
04249 //--------------------------------------------------------------------------
04250 inline ctype_t asgop_revert(ctype_t cop)
04251 {
04252   return (ctype_t)(size_t)hexdsp(hx_asgop_revert, cop);
04253 }
04254 
04255 //--------------------------------------------------------------------------
04256 inline size_t cnumber_t::print(char *buf, size_t bufsize, const type_t *type) const
04257 {
04258   return (size_t)hexdsp(hx_cnumber_t_print, this, buf, bufsize, type);
04259 }
04260 
04261 //--------------------------------------------------------------------------
04262 inline uint64 cnumber_t::value(const typestring &type) const
04263 {
04264   uint64 retval;
04265   hexdsp(hx_cnumber_t_value, &retval, this, &type);
04266   return retval;
04267 }
04268 
04269 //--------------------------------------------------------------------------
04270 inline void cnumber_t::assign(uint64 v, int nbytes, type_sign_t sign)
04271 {
04272   hexdsp(hx_cnumber_t_assign, this, &v, nbytes, sign);
04273 }
04274 
04275 //--------------------------------------------------------------------------
04276 inline int cnumber_t::compare(const cnumber_t &r) const
04277 {
04278   return (int)hexdsp(hx_cnumber_t_compare, this, &r);
04279 }
04280 
04281 //--------------------------------------------------------------------------
04282 inline int var_ref_t::compare(const var_ref_t &r) const
04283 {
04284   return (int)hexdsp(hx_var_ref_t_compare, this, &r);
04285 }
04286 
04287 //--------------------------------------------------------------------------
04288 inline int ctree_visitor_t::apply_to(citem_t *item, citem_t *parent)
04289 {
04290   return (int)hexdsp(hx_ctree_visitor_t_apply_to, this, item, parent);
04291 }
04292 
04293 //--------------------------------------------------------------------------
04294 inline int ctree_visitor_t::apply_to_exprs(citem_t *item, citem_t *parent)
04295 {
04296   return (int)hexdsp(hx_ctree_visitor_t_apply_to_exprs, this, item, parent);
04297 }
04298 
04299 //--------------------------------------------------------------------------
04300 inline bool ctree_parentee_t::recalc_parent_types(void)
04301 {
04302   return (bool)(size_t)hexdsp(hx_ctree_parentee_t_recalc_parent_types, this);
04303 }
04304 
04305 //--------------------------------------------------------------------------
04306 inline bool cfunc_parentee_t::calc_rvalue_type(const cexpr_t *e, typestring &target)
04307 {
04308   return (bool)(size_t)hexdsp(hx_cfunc_parentee_t_calc_rvalue_type, this, e, &target);
04309 }
04310 
04311 //--------------------------------------------------------------------------
04312 inline int citem_locator_t::compare(const citem_locator_t &r) const
04313 {
04314   return (int)hexdsp(hx_citem_locator_t_compare, this, &r);
04315 }
04316 
04317 //--------------------------------------------------------------------------
04318 inline bool citem_t::contains_label(void) const
04319 {
04320   return (bool)(size_t)hexdsp(hx_citem_t_contains_label, this);
04321 }
04322 
04323 //--------------------------------------------------------------------------
04324 inline const citem_t *citem_t::find_parent_of(const citem_t *sitem) const
04325 {
04326   return (const citem_t *)hexdsp(hx_citem_t_find_parent_of, this, sitem);
04327 }
04328 
04329 //--------------------------------------------------------------------------
04330 inline cexpr_t &cexpr_t::assign(const cexpr_t &r)
04331 {
04332   return *(cexpr_t *)hexdsp(hx_cexpr_t_assign, this, &r);
04333 }
04334 
04335 //--------------------------------------------------------------------------
04336 inline int cexpr_t::compare(const cexpr_t &r) const
04337 {
04338   return (int)hexdsp(hx_cexpr_t_compare, this, &r);
04339 }
04340 
04341 //--------------------------------------------------------------------------
04342 inline void cexpr_t::replace_by(cexpr_t *r)
04343 {
04344   hexdsp(hx_cexpr_t_replace_by, this, r);
04345 }
04346 
04347 //--------------------------------------------------------------------------
04348 inline void cexpr_t::cleanup(void)
04349 {
04350   hexdsp(hx_cexpr_t_cleanup, this);
04351 }
04352 
04353 //--------------------------------------------------------------------------
04354 inline void cexpr_t::put_number(cfunc_t *func, uint64 v, int nbytes, type_sign_t sign)
04355 {
04356   hexdsp(hx_cexpr_t_put_number, this, func, &v, nbytes, sign);
04357 }
04358 
04359 //--------------------------------------------------------------------------
04360 inline size_t cexpr_t::print1(char *buf, size_t bufsize, const cfunc_t *func) const
04361 {
04362   return (size_t)hexdsp(hx_cexpr_t_print1, this, buf, bufsize, func);
04363 }
04364 
04365 //--------------------------------------------------------------------------
04366 inline void cexpr_t::calc_type(bool recursive)
04367 {
04368   hexdsp(hx_cexpr_t_calc_type, this, recursive);
04369 }
04370 
04371 //--------------------------------------------------------------------------
04372 inline bool cexpr_t::equal_effect(const cexpr_t &r) const
04373 {
04374   return (bool)(size_t)hexdsp(hx_cexpr_t_equal_effect, this, &r);
04375 }
04376 
04377 //--------------------------------------------------------------------------
04378 inline bool cexpr_t::is_child_of(const citem_t *parent) const
04379 {
04380   return (bool)(size_t)hexdsp(hx_cexpr_t_is_child_of, this, parent);
04381 }
04382 
04383 //--------------------------------------------------------------------------
04384 inline bool cexpr_t::contains_operator(ctype_t needed_op) const
04385 {
04386   return (bool)(size_t)hexdsp(hx_cexpr_t_contains_operator, this, needed_op);
04387 }
04388 
04389 //--------------------------------------------------------------------------
04390 inline int cexpr_t::get_nbits(int pbits) const
04391 {
04392   return (int)hexdsp(hx_cexpr_t_get_nbits, this, pbits);
04393 }
04394 
04395 //--------------------------------------------------------------------------
04396 inline bool cexpr_t::requires_lvalue(const cexpr_t *child) const
04397 {
04398   return (bool)(size_t)hexdsp(hx_cexpr_t_requires_lvalue, this, child);
04399 }
04400 
04401 //--------------------------------------------------------------------------
04402 inline bool cexpr_t::has_side_effects(void) const
04403 {
04404   return (bool)(size_t)hexdsp(hx_cexpr_t_has_side_effects, this);
04405 }
04406 
04407 //--------------------------------------------------------------------------
04408 inline cif_t &cif_t::assign(const cif_t &r)
04409 {
04410   return *(cif_t *)hexdsp(hx_cif_t_assign, this, &r);
04411 }
04412 
04413 //--------------------------------------------------------------------------
04414 inline int cif_t::compare(const cif_t &r) const
04415 {
04416   return (int)hexdsp(hx_cif_t_compare, this, &r);
04417 }
04418 
04419 //--------------------------------------------------------------------------
04420 inline cloop_t &cloop_t::assign(const cloop_t &r)
04421 {
04422   return *(cloop_t *)hexdsp(hx_cloop_t_assign, this, &r);
04423 }
04424 
04425 //--------------------------------------------------------------------------
04426 inline int cfor_t::compare(const cfor_t &r) const
04427 {
04428   return (int)hexdsp(hx_cfor_t_compare, this, &r);
04429 }
04430 
04431 //--------------------------------------------------------------------------
04432 inline int cwhile_t::compare(const cwhile_t &r) const
04433 {
04434   return (int)hexdsp(hx_cwhile_t_compare, this, &r);
04435 }
04436 
04437 //--------------------------------------------------------------------------
04438 inline int cdo_t::compare(const cdo_t &r) const
04439 {
04440   return (int)hexdsp(hx_cdo_t_compare, this, &r);
04441 }
04442 
04443 //--------------------------------------------------------------------------
04444 inline int creturn_t::compare(const creturn_t &r) const
04445 {
04446   return (int)hexdsp(hx_creturn_t_compare, this, &r);
04447 }
04448 
04449 //--------------------------------------------------------------------------
04450 inline int cgoto_t::compare(const cgoto_t &r) const
04451 {
04452   return (int)hexdsp(hx_cgoto_t_compare, this, &r);
04453 }
04454 
04455 //--------------------------------------------------------------------------
04456 inline int casm_t::compare(const casm_t &r) const
04457 {
04458   return (int)hexdsp(hx_casm_t_compare, this, &r);
04459 }
04460 
04461 //--------------------------------------------------------------------------
04462 inline cinsn_t &cinsn_t::assign(const cinsn_t &r)
04463 {
04464   return *(cinsn_t *)hexdsp(hx_cinsn_t_assign, this, &r);
04465 }
04466 
04467 //--------------------------------------------------------------------------
04468 inline int cinsn_t::compare(const cinsn_t &r) const
04469 {
04470   return (int)hexdsp(hx_cinsn_t_compare, this, &r);
04471 }
04472 
04473 //--------------------------------------------------------------------------
04474 inline void cinsn_t::replace_by(cinsn_t *r)
04475 {
04476   hexdsp(hx_cinsn_t_replace_by, this, r);
04477 }
04478 
04479 //--------------------------------------------------------------------------
04480 inline void cinsn_t::cleanup(void)
04481 {
04482   hexdsp(hx_cinsn_t_cleanup, this);
04483 }
04484 
04485 //--------------------------------------------------------------------------
04486 inline cinsn_t &cinsn_t::new_insn(ea_t ea)
04487 {
04488   return *(cinsn_t *)hexdsp(hx_cinsn_t_new_insn, this, ea);
04489 }
04490 
04491 //--------------------------------------------------------------------------
04492 inline cif_t &cinsn_t::create_if(cexpr_t *cnd)
04493 {
04494   return *(cif_t *)hexdsp(hx_cinsn_t_create_if, this, cnd);
04495 }
04496 
04497 //--------------------------------------------------------------------------
04498 inline void cinsn_t::print(int indent, vc_printer_t &vp, use_curly_t use_curly) const
04499 {
04500   hexdsp(hx_cinsn_t_print, this, indent, &vp, use_curly);
04501 }
04502 
04503 //--------------------------------------------------------------------------
04504 inline size_t cinsn_t::print1(char *buf, size_t bufsize, const cfunc_t *func) const
04505 {
04506   return (size_t)hexdsp(hx_cinsn_t_print1, this, buf, bufsize, func);
04507 }
04508 
04509 //--------------------------------------------------------------------------
04510 inline bool cinsn_t::is_ordinary_flow(void) const
04511 {
04512   return (bool)(size_t)hexdsp(hx_cinsn_t_is_ordinary_flow, this);
04513 }
04514 
04515 //--------------------------------------------------------------------------
04516 inline bool cinsn_t::contains_insn(ctype_t type) const
04517 {
04518   return (bool)(size_t)hexdsp(hx_cinsn_t_contains_insn, this, type);
04519 }
04520 
04521 //--------------------------------------------------------------------------
04522 inline bool cinsn_t::collect_free_breaks(cinsnptrvec_t *breaks)
04523 {
04524   return (bool)(size_t)hexdsp(hx_cinsn_t_collect_free_breaks, this, breaks);
04525 }
04526 
04527 //--------------------------------------------------------------------------
04528 inline bool cinsn_t::collect_free_continues(cinsnptrvec_t *continues)
04529 {
04530   return (bool)(size_t)hexdsp(hx_cinsn_t_collect_free_continues, this, continues);
04531 }
04532 
04533 //--------------------------------------------------------------------------
04534 inline int cblock_t::compare(const cblock_t &r) const
04535 {
04536   return (int)hexdsp(hx_cblock_t_compare, this, &r);
04537 }
04538 
04539 //--------------------------------------------------------------------------
04540 inline int carglist_t::compare(const carglist_t &r) const
04541 {
04542   return (int)hexdsp(hx_carglist_t_compare, this, &r);
04543 }
04544 
04545 //--------------------------------------------------------------------------
04546 inline int ccase_t::compare(const ccase_t &r) const
04547 {
04548   return (int)hexdsp(hx_ccase_t_compare, this, &r);
04549 }
04550 
04551 //--------------------------------------------------------------------------
04552 inline int ccases_t::compare(const ccases_t &r) const
04553 {
04554   return (int)hexdsp(hx_ccases_t_compare, this, &r);
04555 }
04556 
04557 //--------------------------------------------------------------------------
04558 inline int cswitch_t::compare(const cswitch_t &r) const
04559 {
04560   return (int)hexdsp(hx_cswitch_t_compare, this, &r);
04561 }
04562 
04563 //--------------------------------------------------------------------------
04564 inline member_t *ctree_item_t::get_memptr(struc_t **p_sptr) const
04565 {
04566   return (member_t *)hexdsp(hx_ctree_item_t_get_memptr, this, p_sptr);
04567 }
04568 
04569 //--------------------------------------------------------------------------
04570 inline lvar_t *ctree_item_t::get_lvar(void) const
04571 {
04572   return (lvar_t *)hexdsp(hx_ctree_item_t_get_lvar, this);
04573 }
04574 
04575 //--------------------------------------------------------------------------
04576 inline ea_t ctree_item_t::get_ea(void) const
04577 {
04578   return (ea_t)hexdsp(hx_ctree_item_t_get_ea, this);
04579 }
04580 
04581 //--------------------------------------------------------------------------
04582 inline int ctree_item_t::get_label_num(void) const
04583 {
04584   return (int)hexdsp(hx_ctree_item_t_get_label_num, this);
04585 }
04586 
04587 //--------------------------------------------------------------------------
04588 inline cexpr_t *lnot(cexpr_t *e)
04589 {
04590   return (cexpr_t *)hexdsp(hx_lnot, e);
04591 }
04592 
04593 //--------------------------------------------------------------------------
04594 inline cinsn_t *new_block(void)
04595 {
04596   return (cinsn_t *)hexdsp(hx_new_block);
04597 }
04598 
04599 //--------------------------------------------------------------------------
04600 inline AS_PRINTF(3, 0) cexpr_t *vcreate_helper(bool standalone, const typestring &type, const char *format, va_list va)
04601 {
04602   return (cexpr_t *)hexdsp(hx_vcreate_helper, standalone, &type, format, va);
04603 }
04604 
04605 //--------------------------------------------------------------------------
04606 inline AS_PRINTF(3, 0) cexpr_t *vcall_helper(const typestring &rettype, carglist_t *args, const char *format, va_list va)
04607 {
04608   return (cexpr_t *)hexdsp(hx_vcall_helper, &rettype, args, format, va);
04609 }
04610 
04611 //--------------------------------------------------------------------------
04612 inline cexpr_t *make_num(uint64 n, int opnum, type_sign_t sign)
04613 {
04614   return (cexpr_t *)hexdsp(hx_make_num, &n, opnum, sign);
04615 }
04616 
04617 //--------------------------------------------------------------------------
04618 inline cexpr_t *make_ref(cexpr_t *e)
04619 {
04620   return (cexpr_t *)hexdsp(hx_make_ref, e);
04621 }
04622 
04623 //--------------------------------------------------------------------------
04624 inline cexpr_t *dereference(cexpr_t *e, int ptrsize, bool is_float)
04625 {
04626   return (cexpr_t *)hexdsp(hx_dereference, e, ptrsize, is_float);
04627 }
04628 
04629 //--------------------------------------------------------------------------
04630 inline void save_user_labels(ea_t func_ea, const user_labels_t *user_labels)
04631 {
04632   hexdsp(hx_save_user_labels, func_ea, user_labels);
04633 }
04634 
04635 //--------------------------------------------------------------------------
04636 inline void save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts)
04637 {
04638   hexdsp(hx_save_user_cmts, func_ea, user_cmts);
04639 }
04640 
04641 //--------------------------------------------------------------------------
04642 inline void save_user_numforms(ea_t func_ea, const user_numforms_t *numforms)
04643 {
04644   hexdsp(hx_save_user_numforms, func_ea, numforms);
04645 }
04646 
04647 //--------------------------------------------------------------------------
04648 inline void save_user_iflags(ea_t func_ea, const user_iflags_t *iflags)
04649 {
04650   hexdsp(hx_save_user_iflags, func_ea, iflags);
04651 }
04652 
04653 //--------------------------------------------------------------------------
04654 inline void save_user_unions(ea_t func_ea, const user_unions_t *unions)
04655 {
04656   hexdsp(hx_save_user_unions, func_ea, unions);
04657 }
04658 
04659 //--------------------------------------------------------------------------
04660 inline user_labels_t *restore_user_labels(ea_t func_ea)
04661 {
04662   return (user_labels_t *)hexdsp(hx_restore_user_labels, func_ea);
04663 }
04664 
04665 //--------------------------------------------------------------------------
04666 inline user_cmts_t *restore_user_cmts(ea_t func_ea)
04667 {
04668   return (user_cmts_t *)hexdsp(hx_restore_user_cmts, func_ea);
04669 }
04670 
04671 //--------------------------------------------------------------------------
04672 inline user_numforms_t *restore_user_numforms(ea_t func_ea)
04673 {
04674   return (user_numforms_t *)hexdsp(hx_restore_user_numforms, func_ea);
04675 }
04676 
04677 //--------------------------------------------------------------------------
04678 inline user_iflags_t *restore_user_iflags(ea_t func_ea)
04679 {
04680   return (user_iflags_t *)hexdsp(hx_restore_user_iflags, func_ea);
04681 }
04682 
04683 //--------------------------------------------------------------------------
04684 inline user_unions_t *restore_user_unions(ea_t func_ea)
04685 {
04686   return (user_unions_t *)hexdsp(hx_restore_user_unions, func_ea);
04687 }
04688 
04689 //--------------------------------------------------------------------------
04690 inline void cfunc_t::build_c_tree(void)
04691 {
04692   hexdsp(hx_cfunc_t_build_c_tree, this);
04693 }
04694 
04695 //--------------------------------------------------------------------------
04696 inline void cfunc_t::verify(allow_unused_labels_t aul, bool even_without_debugger) const
04697 {
04698   hexdsp(hx_cfunc_t_verify, this, aul, even_without_debugger);
04699 }
04700 
04701 //--------------------------------------------------------------------------
04702 inline size_t cfunc_t::print_dcl(char *buf, int bufsize) const
04703 {
04704   return (size_t)hexdsp(hx_cfunc_t_print_dcl, this, buf, bufsize);
04705 }
04706 
04707 //--------------------------------------------------------------------------
04708 inline void cfunc_t::print_func(vc_printer_t &vp) const
04709 {
04710   hexdsp(hx_cfunc_t_print_func, this, &vp);
04711 }
04712 
04713 //--------------------------------------------------------------------------
04714 inline bool cfunc_t::get_func_type(typestring &type, qtype &fields) const
04715 {
04716   return (bool)(size_t)hexdsp(hx_cfunc_t_get_func_type, this, &type, &fields);
04717 }
04718 
04719 //--------------------------------------------------------------------------
04720 inline lvars_t *cfunc_t::get_lvars(void)
04721 {
04722   return (lvars_t *)hexdsp(hx_cfunc_t_get_lvars, this);
04723 }
04724 
04725 //--------------------------------------------------------------------------
04726 inline citem_t *cfunc_t::find_label(int label)
04727 {
04728   return (citem_t *)hexdsp(hx_cfunc_t_find_label, this, label);
04729 }
04730 
04731 //--------------------------------------------------------------------------
04732 inline void cfunc_t::remove_unused_labels(void)
04733 {
04734   hexdsp(hx_cfunc_t_remove_unused_labels, this);
04735 }
04736 
04737 //--------------------------------------------------------------------------
04738 inline const char *cfunc_t::get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const
04739 {
04740   return (const char *)hexdsp(hx_cfunc_t_get_user_cmt, this, &loc, rt);
04741 }
04742 
04743 //--------------------------------------------------------------------------
04744 inline void cfunc_t::set_user_cmt(const treeloc_t &loc, const char *cmt)
04745 {
04746   hexdsp(hx_cfunc_t_set_user_cmt, this, &loc, cmt);
04747 }
04748 
04749 //--------------------------------------------------------------------------
04750 inline int32 cfunc_t::get_user_iflags(const citem_locator_t &loc) const
04751 {
04752   return (int32)hexdsp(hx_cfunc_t_get_user_iflags, this, &loc);
04753 }
04754 
04755 //--------------------------------------------------------------------------
04756 inline void cfunc_t::set_user_iflags(const citem_locator_t &loc, int32 iflags)
04757 {
04758   hexdsp(hx_cfunc_t_set_user_iflags, this, &loc, iflags);
04759 }
04760 
04761 //--------------------------------------------------------------------------
04762 inline bool cfunc_t::has_orphan_cmts(void) const
04763 {
04764   return (bool)(size_t)hexdsp(hx_cfunc_t_has_orphan_cmts, this);
04765 }
04766 
04767 //--------------------------------------------------------------------------
04768 inline int cfunc_t::del_orphan_cmts(void)
04769 {
04770   return (int)hexdsp(hx_cfunc_t_del_orphan_cmts, this);
04771 }
04772 
04773 //--------------------------------------------------------------------------
04774 inline bool cfunc_t::get_user_union_selection(ea_t ea, intvec_t *path)
04775 {
04776   return (bool)(size_t)hexdsp(hx_cfunc_t_get_user_union_selection, this, ea, path);
04777 }
04778 
04779 //--------------------------------------------------------------------------
04780 inline void cfunc_t::set_user_union_selection(ea_t ea, const intvec_t &path)
04781 {
04782   hexdsp(hx_cfunc_t_set_user_union_selection, this, ea, &path);
04783 }
04784 
04785 //--------------------------------------------------------------------------
04786 inline bool cfunc_t::get_line_item(const char *line, int x, bool is_ctree_line, ctree_item_t *head, ctree_item_t *item, ctree_item_t *tail)
04787 {
04788   return (bool)(size_t)hexdsp(hx_cfunc_t_get_line_item, this, line, x, is_ctree_line, head, item, tail);
04789 }
04790 
04791 //--------------------------------------------------------------------------
04792 inline hexwarns_t &cfunc_t::get_warnings(void)
04793 {
04794   return *(hexwarns_t *)hexdsp(hx_cfunc_t_get_warnings, this);
04795 }
04796 
04797 //--------------------------------------------------------------------------
04798 inline bool cfunc_t::gather_derefs(int varidx, strtype_info_t *strinfo) const
04799 {
04800   return (bool)(size_t)hexdsp(hx_cfunc_t_gather_derefs, this, varidx, strinfo);
04801 }
04802 
04803 //--------------------------------------------------------------------------
04804 inline void cfunc_t::cleanup(void)
04805 {
04806   hexdsp(hx_cfunc_t_cleanup, this);
04807 }
04808 
04809 //--------------------------------------------------------------------------
04810 inline const char *get_ctype_name(ctype_t op)
04811 {
04812   return (const char *)hexdsp(hx_get_ctype_name, op);
04813 }
04814 
04815 //--------------------------------------------------------------------------
04816 inline qstring create_field_name(const typestring &type, uval_t offset)
04817 {
04818   qstring retval;
04819   hexdsp(hx_create_field_name, &retval, &type, offset);
04820   return retval;
04821 }
04822 
04823 //--------------------------------------------------------------------------
04824 inline typestring dummy_plist_for(const type_t *ptr)
04825 {
04826   typestring retval;
04827   hexdsp(hx_dummy_plist_for, &retval, ptr);
04828   return retval;
04829 }
04830 
04831 //--------------------------------------------------------------------------
04832 inline typestring make_dt(int n)
04833 {
04834   typestring retval;
04835   hexdsp(hx_make_dt, &retval, n);
04836   return retval;
04837 }
04838 
04839 //--------------------------------------------------------------------------
04840 inline bool install_hexrays_callback(hexrays_cb_t *callback, void *ud)
04841 {
04842   return (bool)(size_t)hexdsp(hx_install_hexrays_callback, callback, ud);
04843 }
04844 
04845 //--------------------------------------------------------------------------
04846 inline int remove_hexrays_callback(hexrays_cb_t *callback, void *ud)
04847 {
04848   return (int)hexdsp(hx_remove_hexrays_callback, callback, ud);
04849 }
04850 
04851 //--------------------------------------------------------------------------
04852 inline void __fastcall vdui_t::refresh_view(bool redo_mba)
04853 {
04854   hexdsp(hx_vdui_t_refresh_view, this, redo_mba);
04855 }
04856 
04857 //--------------------------------------------------------------------------
04858 inline void __fastcall vdui_t::refresh_ctext(bool activate)
04859 {
04860   hexdsp(hx_vdui_t_refresh_ctext, this, activate);
04861 }
04862 
04863 //--------------------------------------------------------------------------
04864 inline void vdui_t::switch_to(cfunc_t *f)
04865 {
04866   hexdsp(hx_vdui_t_switch_to, this, f);
04867 }
04868 
04869 //--------------------------------------------------------------------------
04870 inline cnumber_t *vdui_t::get_number(void) const
04871 {
04872   return (cnumber_t *)hexdsp(hx_vdui_t_get_number, this);
04873 }
04874 
04875 //--------------------------------------------------------------------------
04876 inline void __fastcall vdui_t::clear(void)
04877 {
04878   hexdsp(hx_vdui_t_clear, this);
04879 }
04880 
04881 //--------------------------------------------------------------------------
04882 inline bool __fastcall vdui_t::refresh_cpos(input_device_t idv)
04883 {
04884   return (bool)(size_t)hexdsp(hx_vdui_t_refresh_cpos, this, idv);
04885 }
04886 
04887 //--------------------------------------------------------------------------
04888 inline bool __fastcall vdui_t::get_current_item(input_device_t idv)
04889 {
04890   return (bool)(size_t)hexdsp(hx_vdui_t_get_current_item, this, idv);
04891 }
04892 
04893 //--------------------------------------------------------------------------
04894 inline bool __fastcall vdui_t::ui_rename_lvar(lvar_t *v)
04895 {
04896   return (bool)(size_t)hexdsp(hx_vdui_t_ui_rename_lvar, this, v);
04897 }
04898 
04899 //--------------------------------------------------------------------------
04900 inline bool __fastcall vdui_t::rename_lvar(lvar_t *v, const char *name, bool is_user_name)
04901 {
04902   return (bool)(size_t)hexdsp(hx_vdui_t_rename_lvar, this, v, name, is_user_name);
04903 }
04904 
04905 //--------------------------------------------------------------------------
04906 inline bool __fastcall vdui_t::ui_set_lvar_type(lvar_t *v)
04907 {
04908   return (bool)(size_t)hexdsp(hx_vdui_t_ui_set_lvar_type, this, v);
04909 }
04910 
04911 //--------------------------------------------------------------------------
04912 inline bool __fastcall vdui_t::set_lvar_type(lvar_t *v, const typestring &type)
04913 {
04914   return (bool)(size_t)hexdsp(hx_vdui_t_set_lvar_type, this, v, &type);
04915 }
04916 
04917 //--------------------------------------------------------------------------
04918 inline bool __fastcall vdui_t::ui_edit_lvar_cmt(lvar_t *v)
04919 {
04920   return (bool)(size_t)hexdsp(hx_vdui_t_ui_edit_lvar_cmt, this, v);
04921 }
04922 
04923 //--------------------------------------------------------------------------
04924 inline bool __fastcall vdui_t::set_lvar_cmt(lvar_t *v, const char *cmt)
04925 {
04926   return (bool)(size_t)hexdsp(hx_vdui_t_set_lvar_cmt, this, v, cmt);
04927 }
04928 
04929 //--------------------------------------------------------------------------
04930 inline bool __fastcall vdui_t::ui_map_lvar(lvar_t *v)
04931 {
04932   return (bool)(size_t)hexdsp(hx_vdui_t_ui_map_lvar, this, v);
04933 }
04934 
04935 //--------------------------------------------------------------------------
04936 inline bool __fastcall vdui_t::ui_unmap_lvar(lvar_t *v)
04937 {
04938   return (bool)(size_t)hexdsp(hx_vdui_t_ui_unmap_lvar, this, v);
04939 }
04940 
04941 //--------------------------------------------------------------------------
04942 inline bool __fastcall vdui_t::map_lvar(lvar_t *from, lvar_t *to)
04943 {
04944   return (bool)(size_t)hexdsp(hx_vdui_t_map_lvar, this, from, to);
04945 }
04946 
04947 //--------------------------------------------------------------------------
04948 inline bool __fastcall vdui_t::set_strmem_type(struc_t *sptr, member_t *mptr)
04949 {
04950   return (bool)(size_t)hexdsp(hx_vdui_t_set_strmem_type, this, sptr, mptr);
04951 }
04952 
04953 //--------------------------------------------------------------------------
04954 inline bool __fastcall vdui_t::rename_strmem(struc_t *sptr, member_t *mptr)
04955 {
04956   return (bool)(size_t)hexdsp(hx_vdui_t_rename_strmem, this, sptr, mptr);
04957 }
04958 
04959 //--------------------------------------------------------------------------
04960 inline bool __fastcall vdui_t::set_global_type(ea_t ea)
04961 {
04962   return (bool)(size_t)hexdsp(hx_vdui_t_set_global_type, this, ea);
04963 }
04964 
04965 //--------------------------------------------------------------------------
04966 inline bool __fastcall vdui_t::rename_global(ea_t ea)
04967 {
04968   return (bool)(size_t)hexdsp(hx_vdui_t_rename_global, this, ea);
04969 }
04970 
04971 //--------------------------------------------------------------------------
04972 inline bool __fastcall vdui_t::rename_label(int label)
04973 {
04974   return (bool)(size_t)hexdsp(hx_vdui_t_rename_label, this, label);
04975 }
04976 
04977 //--------------------------------------------------------------------------
04978 inline bool __fastcall vdui_t::jump_enter(input_device_t idv, bool new_window)
04979 {
04980   return (bool)(size_t)hexdsp(hx_vdui_t_jump_enter, this, idv, new_window);
04981 }
04982 
04983 //--------------------------------------------------------------------------
04984 inline bool __fastcall vdui_t::ctree_to_disasm(void)
04985 {
04986   return (bool)(size_t)hexdsp(hx_vdui_t_ctree_to_disasm, this);
04987 }
04988 
04989 //--------------------------------------------------------------------------
04990 inline bool __fastcall vdui_t::push_current_location(input_device_t idv)
04991 {
04992   return (bool)(size_t)hexdsp(hx_vdui_t_push_current_location, this, idv);
04993 }
04994 
04995 //--------------------------------------------------------------------------
04996 inline bool __fastcall vdui_t::pop_current_location(void)
04997 {
04998   return (bool)(size_t)hexdsp(hx_vdui_t_pop_current_location, this);
04999 }
05000 
05001 //--------------------------------------------------------------------------
05002 inline cmt_type_t __fastcall vdui_t::calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const
05003 {
05004   return (cmt_type_t)hexdsp(hx_vdui_t_calc_cmt_type, this, lnnum, cmttype);
05005 }
05006 
05007 //--------------------------------------------------------------------------
05008 inline bool __fastcall vdui_t::edit_cmt(const treeloc_t &loc)
05009 {
05010   return (bool)(size_t)hexdsp(hx_vdui_t_edit_cmt, this, &loc);
05011 }
05012 
05013 //--------------------------------------------------------------------------
05014 inline bool __fastcall vdui_t::edit_func_cmt(void)
05015 {
05016   return (bool)(size_t)hexdsp(hx_vdui_t_edit_func_cmt, this);
05017 }
05018 
05019 //--------------------------------------------------------------------------
05020 inline bool __fastcall vdui_t::del_orphan_cmts(void)
05021 {
05022   return (bool)(size_t)hexdsp(hx_vdui_t_del_orphan_cmts, this);
05023 }
05024 
05025 //--------------------------------------------------------------------------
05026 inline bool __fastcall vdui_t::set_num_radix(int base)
05027 {
05028   return (bool)(size_t)hexdsp(hx_vdui_t_set_num_radix, this, base);
05029 }
05030 
05031 //--------------------------------------------------------------------------
05032 inline bool __fastcall vdui_t::set_num_enum(void)
05033 {
05034   return (bool)(size_t)hexdsp(hx_vdui_t_set_num_enum, this);
05035 }
05036 
05037 //--------------------------------------------------------------------------
05038 inline bool __fastcall vdui_t::set_num_stroff(void)
05039 {
05040   return (bool)(size_t)hexdsp(hx_vdui_t_set_num_stroff, this);
05041 }
05042 
05043 //--------------------------------------------------------------------------
05044 inline bool __fastcall vdui_t::invert_sign(void)
05045 {
05046   return (bool)(size_t)hexdsp(hx_vdui_t_invert_sign, this);
05047 }
05048 
05049 //--------------------------------------------------------------------------
05050 inline bool __fastcall vdui_t::collapse_item(bool hide)
05051 {
05052   return (bool)(size_t)hexdsp(hx_vdui_t_collapse_item, this, hide);
05053 }
05054 
05055 //--------------------------------------------------------------------------
05056 inline bool __fastcall vdui_t::split_item(bool split)
05057 {
05058   return (bool)(size_t)hexdsp(hx_vdui_t_split_item, this, split);
05059 }
05060 
05061 //--------------------------------------------------------------------------
05062 inline bool __fastcall vdui_t::set_vargloc_end(ea_t ea, argloc_t ida_argloc)
05063 {
05064   return (bool)(size_t)hexdsp(hx_vdui_t_set_vargloc_end, this, ea, ida_argloc);
05065 }
05066 
05067 #ifdef __VC__
05068 #pragma warning(pop)
05069 #endif
05070 #pragma pack(pop)
05071 #endif
  • Home
  • Products
  • Forum
  • Blog
  • News
  • About us
  • Contact
  • Site Map
Copyright (c) 2011 Hex-Rays SA. Contact us at info@hex-rays.com Monday, 07-May-2012 08:01:23 EDT