hexrays.hpp
Go to the documentation of this file.
1 /*
2  * Hex-Rays Decompiler project
3  * Copyright (c) 1990-2015 Hex-Rays
4  * ALL RIGHTS RESERVED.
5  */
6 
7 #ifndef __HEXRAYS_HPP
8 #define __HEXRAYS_HPP
9 
10 #define CHECKED_BUILD
11 #include <pro.h>
12 #include <fpro.h>
13 #include <ida.hpp>
14 #include <idp.hpp>
15 #include <ieee.h>
16 #include <loader.hpp>
17 #include <kernwin.hpp>
18 #include <typeinf.hpp>
19 #include <set>
20 #include <map>
21 #include <deque>
22 #include <queue>
23 #include <algorithm>
24 
25 #ifdef __VC__
26 #pragma warning(push)
27 #pragma warning(disable:4062) // enumerator 'x' in switch of enum 'y' is not handled
28 #pragma warning(disable:4265) // virtual functions without virtual destructor
29 #endif
30 
31 #define hexapi ///< Public functions are marked with this keyword
32 
33 class intseq_t;
34 class mbl_array_t;
35 class mblock_t;
36 class codegen_t;
37 struct vdui_t;
38 struct hexrays_failure_t;
39 struct mba_stats_t;
40 struct mlist_t;
41 typedef int mreg_t; ///< Micro register
42 
43 struct cfunc_t;
44 struct citem_t;
45 struct cexpr_t;
46 struct cinsn_t;
47 struct cblock_t;
48 struct cswitch_t;
49 struct carg_t;
50 struct carglist_t;
51 
52 //-------------------------------------------------------------------------
53 /// Macro to declare standard inline comparison operators
54 #define DECLARE_COMPARISON_OPERATORS(type) \
55  bool operator==(const type &r) const { return compare(r) == 0; } \
56  bool operator!=(const type &r) const { return compare(r) != 0; } \
57  bool operator< (const type &r) const { return compare(r) < 0; } \
58  bool operator> (const type &r) const { return compare(r) > 0; } \
59  bool operator<=(const type &r) const { return compare(r) <= 0; } \
60  bool operator>=(const type &r) const { return compare(r) >= 0; }
61 
62 /// Macro to declare comparisons for our classes
63 /// All comparison operators call the compare() function which returns -1/0/1
64 #define DECLARE_COMPARISONS(type) \
65  DECLARE_COMPARISON_OPERATORS(type) \
66  friend int compare(const type &a, const type &b) { return a.compare(b); } \
67  int compare(const type &r) const
68 
69 /// Operand locator.
71 {
72 private:
73  //forbid the default constructor
74  operand_locator_t(void) {}
75 public:
76  ea_t ea; ///< address of the original instruction
77  int opnum; ///< operand number in the instruction
78  operand_locator_t(ea_t _ea, int _opnum) : ea(_ea), opnum(_opnum) {}
79  DECLARE_COMPARISONS(operand_locator_t);
80  DEFINE_MEMORY_ALLOCATION_FUNCS()
81 };
82 
83 //-------------------------------------------------------------------------
84 /// Number represenation.
85 /// This structure holds information about number format.
87 {
88  DEFINE_MEMORY_ALLOCATION_FUNCS()
89  flags_t flags; ///< ida flags, which describe number radix, enum, etc
90  char opnum; ///< operand number: 0..UA_MAXOP
91  char props; ///< properties: combination of NF_ bits (\ref NF_)
92 /// \defgroup NF_ Number format property bits
93 /// Used in number_format_t::props
94 //@{
95 #define NF_FIXED 0x01 ///< number format has been defined by the user
96 #define NF_NEGDONE 0x02 ///< temporary internal bit: negation has been performed
97 #define NF_BINVDONE 0x04 ///< temporary internal bit: inverting bits is done
98 #define NF_NEGATE 0x08 ///< The user asked to negate the constant
99 #define NF_BITNOT 0x10 ///< The user asked to invert bits of the constant
100 #define NF_STROFF 0x20 ///< internal bit: used as stroff, valid iff is_stroff()
101 //@}
102  uchar serial; ///< for enums: constant serial number
103  char org_nbytes; ///< original number size in bytes
104  qstring type_name; ///< for stroffs: structure for offsetof()\n
105  ///< for enums: enum name
106  /// Contructor
107  number_format_t(int _opnum=0)
108  : flags(0), opnum(char(_opnum)), props(0), serial(0), org_nbytes(0) {}
109  /// Get number radix
110  /// \return 2,8,10, or 16
111  int get_radix(void) const { return ::get_radix(flags, opnum); }
112  /// Is number representation fixed?
113  /// Fixed representation can not be modified by the decompiler
114  bool is_fixed(void) const { return props != 0; }
115  /// Is a hexadecimal number?
116  bool is_hex(void) const { return ::is_numop(flags, opnum) && get_radix() == 16; }
117  /// Is a decimal number?
118  bool is_dec(void) const { return ::is_numop(flags, opnum) && get_radix() == 10; }
119  /// Is a octal number?
120  bool is_oct(void) const { return ::is_numop(flags, opnum) && get_radix() == 8; }
121  /// Is a symbolic constant?
122  bool is_enum(void) const { return ::is_enum(flags, opnum); }
123  /// Is a character constant?
124  bool is_char(void) const { return ::is_char(flags, opnum); }
125  /// Is a structure field offset?
126  bool is_stroff(void) const { return ::is_stroff(flags, opnum); }
127  /// Is a number?
128  bool is_numop(void) const { return !is_enum() && !is_char() && !is_stroff(); }
129  /// Does the number need to be negated or bitwise negated?
130  /// Returns true if the user requested a negation but it is not done yet
131  bool needs_to_be_inverted(void) const
132  {
133  return (props & (NF_NEGATE|NF_BITNOT)) != 0 // the user requested it
134  && (props & (NF_NEGDONE|NF_BINVDONE)) == 0; // not done yet
135  }
136 };
137 
138 // Number formats are attached to (ea,opnum) pairs
139 typedef std::map<operand_locator_t, number_format_t> user_numforms_t;
140 
141 //-------------------------------------------------------------------------
142 /// Base helper class to convert binary data structures into text.
143 /// Other classes are derived from this class.
145 {
146  qstring tmpbuf;
147  int hdrlines; ///< number of header lines (prototype+typedef+lvars)
148  ///< valid at the end of print process
149  /// Print.
150  /// This function is called to generate a portion of the output text.
151  /// The output text may contain color codes.
152  /// \return the number of printed characters
153  /// \param indent number of spaces to generate as prefix
154  /// \param format printf-style format specifier
155  AS_PRINTF(3, 4) virtual int hexapi print(int indent, const char *format,...);
156  AS_PRINTF(3, 0) int vprint(int indent, const char *format, va_list);
157  DEFINE_MEMORY_ALLOCATION_FUNCS()
158 };
159 
160 /// Helper class to convert cfunc_t into text.
161 struct vc_printer_t : public vd_printer_t
162 {
163  const cfunc_t *func; ///< cfunc_t to generate text for
164  char lastchar; ///< internal: last printed character
165  /// Constructor
166  vc_printer_t(const cfunc_t *f) : func(f), lastchar(0) {}
167  /// Are we generating one-line text representation?
168  /// \return \c true if the output will occupy one line without line breaks
169  virtual bool idaapi oneliner(void) const { return false; }
170 };
171 
172 /// Helper class to convert binary data structures into text and put into a file.
174 {
175  FILE *fp; ///< Output file pointer
176  /// Print.
177  /// This function is called to generate a portion of the output text.
178  /// The output text may contain color codes.
179  /// \return the number of printed characters
180  /// \param indent number of spaces to generate as prefix
181  /// \param format printf-style format specifier
182  AS_PRINTF(3, 4) int print(int indent, const char *format, ...);
183  /// Constructor
184  file_printer_t(FILE *_fp) : fp(_fp) {}
185 };
186 
187 /// Helper class to convert cfunc_t into a text string
189 {
190  bool with_tags; ///< Generate output with color tags
191  qstring &s; ///< Reference to the output string
192  /// Constructor
193  qstring_printer_t(const cfunc_t *f, qstring &_s, bool tags)
194  : vc_printer_t(f), with_tags(tags), s(_s) {}
195  /// Print.
196  /// This function is called to generate a portion of the output text.
197  /// The output text may contain color codes.
198  /// \return the number of printed characters
199  /// \param indent number of spaces to generate as prefix
200  /// \param format printf-style format specifier
201  AS_PRINTF(3, 4) int hexapi print(int indent, const char *format, ...);
202  AS_PRINTF(3, 0) int vprint(int indent, const char *format, va_list);
203 };
204 
205 //-------------------------------------------------------------------------
206 /// \defgroup type Type string related declarations
207 /// Type related functions and class.
208 //@{
209 
210 /// Verify a type string.
211 /// \return true if type string is correct
212 
213 bool hexapi is_type_correct(const type_t *ptr);
214 
215 
216 /// Is a small structure or union?
217 /// \return true if the type is a small UDT (user defined type).
218 /// Small UDTs fit into a register (or pair or registers) as a rule.
219 
220 bool hexapi is_small_struni(const tinfo_t &tif);
221 
222 
223 /// Is definitely a non-boolean type?
224 /// \return true if the type is a non-boolean type (non bool and well defined)
225 
226 bool hexapi is_nonbool_type(const tinfo_t &type);
227 
228 
229 /// Is a boolean type?
230 /// \return true if the type is a boolean type
231 
232 bool hexapi is_bool_type(const tinfo_t &type);
233 
234 
235 /// Is a pointer or array type?
236 inline bool is_ptr_or_array(type_t t)
237 {
238  return is_type_ptr(t) || is_type_array(t);
239 }
240 
241 /// Is a pointer, array, or function type?
242 inline bool is_paf(type_t t)
243 {
244  return is_ptr_or_array(t) || is_type_func(t);
245 }
246 
247 /// Is struct/union/enum definition (not declaration)?
248 inline bool is_inplace_def(const tinfo_t &type)
249 {
250  return type.is_decl_complex() && !type.is_typeref();
251 }
252 
253 /// Calculate number of partial subtypes.
254 /// \return number of partial subtypes. The bigger is this number, the uglier is the type.
255 
256 int hexapi partial_type_num(const tinfo_t &type);
257 
258 
259 /// Get a type of a floating point value with the specified width
260 /// \returns type info object
261 /// \param width width of the desired type
262 
263 tinfo_t hexapi get_float_type(int width);
264 
265 
266 /// Create a type info by width and sign.
267 /// Returns a simple type (examples: int, short) with the given width and sign.
268 /// \param srcwidth size of the type in bytes
269 /// \param sign sign of the type
270 
271 tinfo_t hexapi get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign);
272 
273 
274 /// Create a partial type info by width.
275 /// Returns a partially defined type (examples: _DWORD, _BYTE) with the given width.
276 /// \param size size of the type in bytes
277 
278 tinfo_t hexapi get_unk_type(int size);
279 
280 
281 /// Generate a dummy pointer type
282 /// \param ptrsize size of pointed object
283 /// \param isfp is floating point object?
284 
285 tinfo_t hexapi dummy_ptrtype(int ptrsize, bool isfp);
286 
287 
288 /// Get type of a structure field.
289 /// This function performs validity checks of the field type. Wrong types are rejected.
290 /// \param mptr structure field
291 /// \param type pointer to the variable where the type is returned. This parameter can be NULL.
292 /// \return false if failed
293 
294 bool hexapi get_member_type(const member_t *mptr, tinfo_t *type);
295 
296 
297 /// Create a pointer type.
298 /// This function performs the following conversion: "type" -> "type*"
299 /// \param type object type.
300 /// \return "type*". for example, if 'char' is passed as the argument,
301 // the function will return 'char *'
302 
303 tinfo_t hexapi make_pointer(const tinfo_t &type);
304 
305 
306 /// Create a reference to a named type.
307 /// \param name type name
308 /// \return type which refers to the specified name. For example, if name is "DWORD",
309 /// the type info which refers to "DWORD" is created.
310 
311 tinfo_t hexapi create_typedef(const char *name);
312 
313 
314 /// Create a reference to an ordinal type.
315 /// \param n ordinal number of the type
316 /// \return type which refers to the specified ordianl. For example, if n is 1,
317 /// the type info which refers to ordinal type 1 is created.
318 
319 inline tinfo_t create_typedef(int n)
320 {
321  tinfo_t tif;
322  tif.create_typedef(NULL, n);
323  return tif;
324 }
325 
326 /// Type source (where the type information comes from)
328 {
329  GUESSED_NONE, // not guessed, specified by the user
330  GUESSED_WEAK, // not guessed, comes from idb
331  GUESSED_FUNC, // guessed as a function
332  GUESSED_DATA, // guessed as a data item
333  TS_NOELL = 0x8000000, // can be used in set_type() to avoid merging into ellipsis
334  TS_SHRINK = 0x4000000, // can be used in set_type() to prefer smaller arguments
335  TS_MASK = 0xC000000, // all high bits
336 };
337 
338 inline int compare_typsrc(type_source_t s1, type_source_t s2)
339 {
340  if ( s1 > GUESSED_WEAK && s2 > GUESSED_WEAK )
341  return 0; // both guessed, consider equal
342  return compare(s1, s2);
343 }
344 
345 
346 /// Get a global type.
347 /// Global types are types of addressable objects and struct/union/enum types
348 /// \param id address or id of the object
349 /// \param tif buffer for the answer
350 /// \param guess what kind of types to consider
351 /// \return success
352 
353 bool hexapi get_type(uval_t id, tinfo_t *tif, type_source_t guess);
354 
355 
356 /// Set a global type.
357 /// \param id address or id of the object
358 /// \param tif new type info
359 /// \param source where the type comes from
360 /// \param force true means to set the type as is, false means to merge the
361 /// new type with the possibly existing old type info.
362 /// \return success
363 
364 bool hexapi set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force=false);
365 
366 //@}
367 
368 //-------------------------------------------------------------------------
369 // We use our own class to store argument and variable locations.
370 // The main differences between vdloc and argloc_t:
371 // VLOC_REG1: the offset is always 0, so it is not used. the register number
372 // uses the whole ~VLOC_MASK field.
373 // VLOCK_STKOFF: stack offsets are always positive because they are based on
374 // the lowest value of sp in the function.
375 class vdloc_t : public argloc_t
376 {
377  int regoff(void); // inaccessible & undefined: regoff() should not be used
378 public:
379  // use all available bits for register number for VLOC_REG1
380  int reg1(void) const { return atype() == ALOC_REG2 ? argloc_t::reg1() : get_reginfo(); }
381  void _set_reg1(int r1) { argloc_t::_set_reg1(r1, r1>>16); } // it works fine
382  void set_reg1(int r1) { cleanup_argloc(this); _set_reg1(r1); }
383  inline bool is_fpu_mreg() const;
384 };
385 
386 size_t hexapi print_vdloc(char *buf, size_t bufsize, const vdloc_t &loc, int w);
387 //-------------------------------------------------------------------------
388 /// Do two arglocs overlap?
389 bool hexapi arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2);
390 
391 /// Local variable locator. Local variables are located using: definition ea, location
393 {
394  vdloc_t location; ///< Variable location.
395  ea_t defea; ///< Definition address. The address of an instruction
396  ///< that initializes the variable. This value is
397  ///< assigned to each lvar by lvar allocator.
398  ///< BADADDR for function arguments
399  lvar_locator_t(void) : defea(BADADDR) {}
400  lvar_locator_t(const vdloc_t &loc, ea_t ea) : location(loc), defea(ea) {}
401  /// Calculate the variable location (only for continuous variables)
402  /// \return if the variable is register-hosted, the register number
403  /// otherwise, return the virtual stack register number that
404  /// corresponds to the stack location
405  sval_t hexapi get_regnum(void) const;
406  /// Is variable located on one register?
407  bool is_reg1(void) const { return location.is_reg1(); }
408  /// Is variable located on two registers?
409  bool is_reg2(void) const { return location.is_reg2(); }
410  /// Is variable located on register(s)?
411  bool is_reg_var(void) const { return location.is_reg(); }
412  /// Is variable located on the stack?
413  bool is_stk_var(void) const { return location.is_stkoff(); }
414  /// Is variable scattered?
415  bool is_scattered(void) const { return location.is_scattered(); }
416  /// Get number of the register for the variable
417  mreg_t get_reg1(void) const { return location.reg1(); }
418  /// Get number of the second register (only for tworeg lvars)
419  mreg_t get_reg2(void) const { return location.reg2(); }
420  /// Get information about scattered variable
421  const scattered_aloc_t &get_scattered(void) const { return location.scattered(); }
422  scattered_aloc_t &get_scattered(void) { return location.scattered(); }
424  DEFINE_MEMORY_ALLOCATION_FUNCS()
425 };
426 
427 /// Definition of a local variable (register or stack) #var #lvar
428 class lvar_t : public lvar_locator_t
429 {
430  friend class mbl_array_t;
431  int flags; ///< \ref CVAR_
432 /// \defgroup CVAR_ Local variable property bits
433 /// Used in lvar_t::flags
434 //@{
435 #define CVAR_USED 0x0001 ///< is used in the code?
436 #define CVAR_TYPE 0x0002 ///< the type is defined?
437 #define CVAR_NAME 0x0004 ///< has nice name?
438 #define CVAR_MREG 0x0008 ///< corresponding mregs were replaced?
439 #define CVAR_NOWD 0x0010 ///< width is unknown
440 #define CVAR_UNAME 0x0020 ///< user-defined name
441 #define CVAR_UTYPE 0x0040 ///< user-defined type
442 #define CVAR_RESULT 0x0080 ///< function result variable
443 #define CVAR_ARG 0x0100 ///< function argument
444 #define CVAR_FAKE 0x0200 ///< fake return variable
445 #define CVAR_OVER 0x0400 ///< overlapping variable
446 #define CVAR_FLOAT 0x0800 ///< used in a fpu insn
447 #define CVAR_SPOILED 0x1000 ///< internal flag, do not use: spoiled var
448 #define CVAR_MAPDST 0x2000 ///< other variables are mapped to this var
449 #define CVAR_PARTIAL 0x4000 ///< variable type is partialy defined
450 //@}
451 
452 public:
453  qstring name; ///< variable name.
454  ///< use mbl_array_t::set_nice_lvar_name() and
455  ///< mbl_array_t::set_user_lvar_name() to modify it
456  qstring cmt; ///< variable comment string
457  tinfo_t tif; ///< variable type
458  int width; ///< variable size in bytes
459  int defblk; ///< first block defining the variable.
460  ///< 0 for args, -1 if unknown
461  uint64 divisor; ///< max known divisor of the variable
462 
463  lvar_t(void) : flags(CVAR_USED), width(0), defblk(-1), divisor(0) {}
464  lvar_t(const qstring &n, const vdloc_t &l, ea_t e, const tinfo_t &t, int w, int db)
465  : lvar_locator_t(l, e), flags(CVAR_USED), name(n), tif(t), width(w),
466  defblk(db), divisor(0) {}
467  lvar_t(mreg_t reg, int width, const tinfo_t &type, int nblock, ea_t defea);
468 
469  /// Is the variable used in the code?
470  bool used(void) const { return (flags & CVAR_USED) != 0; }
471  /// Has the variable a type?
472  bool typed(void) const { return (flags & CVAR_TYPE) != 0; }
473  /// Have corresponding microregs been replaced by references to this variable?
474  bool mreg_done(void) const { return (flags & CVAR_MREG) != 0; }
475  /// Does the variable have a nice name?
476  bool has_nice_name(void) const { return (flags & CVAR_NAME) != 0; }
477  /// Do we know the width of the variable?
478  bool is_unknown_width(void) const { return (flags & CVAR_NOWD) != 0; }
479  /// Has any user-defined information?
480  bool has_user_info(void) const { return (flags & (CVAR_UNAME|CVAR_UTYPE)) != 0 || !cmt.empty(); }
481  /// Has user-defined name?
482  bool has_user_name(void) const { return (flags & CVAR_UNAME) != 0; }
483  /// Has user-defined type?
484  bool has_user_type(void) const { return (flags & CVAR_UTYPE) != 0; }
485  /// Is the function result?
486  bool is_result_var(void) const { return (flags & CVAR_RESULT) != 0; }
487  /// Is the function argument?
488  bool is_arg_var(void) const { return (flags & CVAR_ARG) != 0; }
489  /// Is the promoted function argument?
490  bool is_promoted_arg(void) const;
491  /// Is fake return variable?
492  bool is_fake_var(void) const { return (flags & CVAR_FAKE) != 0; }
493  /// Is overlapped variable?
494  bool is_overlapped_var(void) const { return (flags & CVAR_OVER) != 0; }
495  /// Used by a fpu insn?
496  bool is_floating_var(void) const { return (flags & CVAR_FLOAT) != 0; }
497  /// Is spoiled var? (meaningful only during lvar allocation)
498  bool is_spoiled_var(void) const { return (flags & CVAR_SPOILED) != 0; }
499  /// Other variable(s) map to this var?
500  bool is_partialy_typed(void) const { return (flags & CVAR_PARTIAL) != 0; }
501  /// Other variable(s) map to this var?
502  bool is_mapdst_var(void) const { return (flags & CVAR_MAPDST) != 0; }
503  void set_used(void) { flags |= CVAR_USED; }
504  void clear_used(void) { flags &= ~CVAR_USED; }
505  void set_typed(void) { flags |= CVAR_TYPE; }
506  void set_non_typed(void) { flags &= ~CVAR_TYPE; }
507  void clr_user_info(void) { flags &= ~(CVAR_UNAME|CVAR_UTYPE); }
508  void set_user_name(void) { flags |= CVAR_NAME|CVAR_UNAME; }
509  void set_user_type(void) { flags |= CVAR_TYPE|CVAR_UTYPE; }
510  void clr_user_type(void) { flags &= ~CVAR_UTYPE; }
511  void clr_user_name(void) { flags &= ~CVAR_UNAME; }
512  void set_mreg_done(void) { flags |= CVAR_MREG; }
513  void clr_mreg_done(void) { flags &= ~CVAR_MREG; }
514  void set_unknown_width(void) { flags |= CVAR_NOWD; }
515  void clr_unknown_width(void) { flags &= ~CVAR_NOWD; }
516  void set_arg_var(void) { flags |= CVAR_ARG; }
517  void clr_arg_var(void) { flags &= ~CVAR_ARG; }
518  void set_fake_var(void) { flags |= CVAR_FAKE; }
519  void clr_fake_var(void) { flags &= ~CVAR_FAKE; }
520  void set_overlapped_var(void) { flags |= CVAR_OVER; }
521  void clr_overlapped_var(void) { flags &= ~CVAR_OVER; }
522  void set_floating_var(void) { flags |= CVAR_FLOAT; }
523  void clr_floating_var(void) { flags &= ~CVAR_FLOAT; }
524  void set_spoiled_var(void) { flags |= CVAR_SPOILED; }
525  void clr_spoiled_var(void) { flags &= ~CVAR_SPOILED; }
526  void set_mapdst_var(void) { flags |= CVAR_MAPDST; }
527  void clr_mapdst_var(void) { flags &= ~CVAR_MAPDST; }
528  void set_partialy_typed(void) { flags |= CVAR_PARTIAL; }
529  void clr_partialy_typed(void) { flags &= ~CVAR_PARTIAL; }
530 
531  void set_reg_name(const char *n)
532  {
533  name = n; // do not verify uniqueness
534  flags &= ~CVAR_USED; // do not display the declaration
535  flags |= CVAR_NAME; // do not autorename
536  }
537  /// Do variables overlap?
538  bool has_common(const lvar_t &v) const
539  {
540  return arglocs_overlap(location, width, v.location, v.width);
541  }
542  /// Does the variable overlap with the specified location?
543  bool has_common_bit(const vdloc_t &loc, asize_t width2) const
544  {
545  return arglocs_overlap(location, width, loc, width2);
546  }
547  /// Get variable type
548  const tinfo_t &type(void) const { return tif; }
549  tinfo_t &type(void) { return tif; }
550 
551  /// Check if the variable accept the specified type.
552  /// Some types are forbidden (void, function types, wrong arrays, etc)
553  bool hexapi accepts_type(const tinfo_t &t);
554 
555  /// Set variable type without any validation.
556  void force_lvar_type(const tinfo_t &t);
557 
558  /// Set variable type
559  /// \param t new type
560  /// \param may_fail if false and type is bad, interr
561  /// \return success
562  bool hexapi set_lvar_type(const tinfo_t &t, bool may_fail=false);
563 
564  /// Set final variable type.
565  void set_final_lvar_type(const tinfo_t &t)
566  {
567  set_lvar_type(t);
568  set_typed();
569  }
570 
571  /// Change the variable width. This function also changes
572  /// the variable type.
573  /// \param w new width
574  /// \param svw_flags combination of SVW_... bits
575  /// \return success
576  bool hexapi set_width(int w, int svw_flags=0);
577 #define SVW_INT 0x00 // integer value
578 #define SVW_FLOAT 0x01 // floating point value
579 #define SVW_SOFT 0x02 // may fail and return false;
580  // if this bit is not set and the type is bad, interr
581 
582 };
583 DECLARE_TYPE_AS_MOVABLE(lvar_t);
584 
585 /// Set of local variables
586 struct lvars_t : public qvector<lvar_t>
587 {
588  /// Find input variable at the specified location.
589  /// \param argloc variable location
590  /// \param _size variable size
591  /// \return -1 if failed, otherwise the index into the variables vector.
592  int find_input_lvar(const vdloc_t &argloc, int _size) { return find_lvar(argloc, _size, 0); }
593 
594  /// Find stack variable at the specified location.
595  /// \param spoff offset from the minimal sp
596  /// \param width variable size
597  /// \return -1 if failed, otherwise the index into the variables vector.
598  int hexapi find_stkvar(int32 spoff, int width);
599 
600  /// Find variable at the specified location.
601  /// \param ll variable location
602  /// \return pointer to variable or NULL
603  lvar_t *hexapi find(const lvar_locator_t &ll);
604 
605 
606  /// Find variable at the specified location.
607  /// \param location variable location
608  /// \param width variable size
609  /// \param defblk definition block of the lvar. -1 means any block
610  /// \return -1 if failed, otherwise the index into the variables vector.
611  int hexapi find_lvar(const vdloc_t &location, int width, int defblk=-1);
612 };
613 
614 /// Saved user settings for local variables: name, type, comment
616 {
617  lvar_locator_t ll;
618  qstring name;
619  tinfo_t type;
620  qstring cmt;
621  ssize_t size; ///< type size (if not initialized then -1)
622  int flags; ///< \ref LVINF_
623 /// \defgroup LVINF_ saved user lvar info property bits
624 /// Used in lvar_saved_info_t::flags
625 //@{
626 #define LVINF_KEEP 0x0001 ///< keep saved user settings regardless of vars
627 //@}
628  lvar_saved_info_t(void) : size(BADSIZE), flags(0) {}
629  bool has_info(void) const { return !name.empty() || !type.empty() || !cmt.empty(); }
630  bool operator==(const lvar_saved_info_t &r) const
631  {
632  return name == r.name
633  && cmt == r.cmt
634  && ll == r.ll
635  && type == r.type;
636  }
637  bool operator!=(const lvar_saved_info_t &r) const { return !(*this == r); }
638  bool is_kept(void) const { return (flags & LVINF_KEEP) != 0; }
639  void clear_keep(void) { flags &= ~LVINF_KEEP; }
640  void set_keep(void) { flags |= LVINF_KEEP; }
641 };
642 DECLARE_TYPE_AS_MOVABLE(lvar_saved_info_t);
643 typedef qvector<lvar_saved_info_t> lvar_saved_infos_t;
644 
645 /// Local variable mapping (is used to merge variables)
646 typedef std::map<lvar_locator_t, lvar_locator_t> lvar_mapping_t;
647 
648 /// All user-defined information about local variables
650 {
651  /// User-specified names, types, comments for lvars. Variables without
652  /// user-specified info are not present in this vector.
653  lvar_saved_infos_t lvvec;
654 
655  /// Local variable mapping (used for merging variables)
656  lvar_mapping_t lmaps;
657 
658  /// Delta to add to IDA stack offset to calculate Hex-Rays stack offsets.
659  /// Should be set by the caller before calling save_user_lvar_settings();
660  uval_t stkoff_delta;
661 
662  /// Various flags. Possible values are from \ref ULV_
664 /// \defgroup ULV_ lvar_uservec_t property bits
665 /// Used in lvar_uservec_t::ulv_flags
666 //@{
667 #define ULV_PRECISE_DEFEA 0x0001 ///< Use precise defea's for lvar locations
668 //@}
669 
670  lvar_uservec_t(void) : stkoff_delta(0), ulv_flags(ULV_PRECISE_DEFEA) {}
671  void swap(lvar_uservec_t &r)
672  {
673  lvvec.swap(r.lvvec);
674  lmaps.swap(r.lmaps);
675  std::swap(stkoff_delta, r.stkoff_delta);
676  std::swap(ulv_flags, r.ulv_flags);
677  }
678 
679  /// find saved user settings for given var
681  {
682  for ( lvar_saved_infos_t::iterator p=lvvec.begin(); p != lvvec.end(); ++p )
683  {
684  if ( p->ll == vloc )
685  return p;
686  }
687  return NULL;
688  }
689 
690  /// keep user settings for given var
691  void keep_info(const lvar_t &v)
692  {
693  lvar_saved_info_t *p = find_info(v);
694  if ( p != NULL )
695  p->set_keep();
696  }
697 };
698 
699 /// Restore user defined local variable settings in the database.
700 /// \param func_ea entry address of the function
701 /// \param lvinf ptr to output buffer
702 /// \return success
703 
704 bool hexapi restore_user_lvar_settings(lvar_uservec_t *lvinf, ea_t func_ea);
705 
706 
707 /// Save user defined local variable settings into the database.
708 /// \param func_ea entry address of the function
709 /// \param lvinf user-specified info about local variables
710 
711 void hexapi save_user_lvar_settings(ea_t func_ea, const lvar_uservec_t &lvinf);
712 
713 
714 /// Helper class to modify saved local variable settings.
716 {
717  /// Modify lvar settings.
718  /// Returns: true-modified
719  virtual bool idaapi modify_lvars(lvar_uservec_t *lvinf) = 0;
720 };
721 
722 /// Modify saved local variable settings.
723 /// \param entry_ea function start address
724 /// \param mlv local variable modifier
725 /// \return true if modified variables
726 
727 bool hexapi modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv);
728 
729 
730 //-------------------------------------------------------------------------
731 /// User-defined function calls
732 struct udcall_t
733 {
734  qstring name; // name of the function
735  tinfo_t tif; // function prototype
736 };
737 
738 // All user-defined function calls (map address -> udcall)
739 typedef std::map<ea_t, udcall_t> udcall_map_t;
740 
741 /// Restore user defined function calls from the database.
742 /// \param udcalls ptr to output buffer
743 /// \param func_ea entry address of the function
744 /// \return success
745 
746 bool hexapi restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea);
747 
748 /// Save user defined local function calls into the database.
749 /// \param func_ea entry address of the function
750 /// \param udcalls user-specified info about user defined function calls
751 
752 void hexapi save_user_defined_calls(ea_t func_ea, const udcall_map_t &udcalls);
753 
754 /// Convert function type declaration into internal structure
755 /// \param udc - pointer to output structure
756 /// \param decl - function type declaration
757 /// \param silent - if TRUE: do not show warning in case of incorrect type
758 /// \return success
759 bool hexapi parse_user_call(udcall_t *udc, const char *decl, bool silent);
760 
761 /// try to generate user-defined call for an instruction
762 /// \return MERR_... code:
763 /// MERR_OK - user-defined call generated
764 /// else - error (MERR_INSN == inacceptable udc.tif)
765 int hexapi convert_to_user_call(const udcall_t &udc, codegen_t &cdg);
766 
767 //-------------------------------------------------------------------------
768 /// Generic microcode generator class.
769 /// An instance of a derived class can be registered to be used for
770 /// non-standard microcode generation. Before microcode generation for an
771 /// instruction all registered object will be visited by the following way:
772 /// if ( filter->match(cdg) )
773 /// code = filter->apply(cdg);
774 /// if ( code == MERR_OK )
775 /// continue; // filter generated microcode, go to the next instruction
777 {
778  /// check if the filter object is to be appied
779  /// \return success
780  virtual bool match(codegen_t &cdg) = 0;
781  /// generate microcode for an instruction
782  /// \return MERR_... code:
783  /// MERR_OK - user-defined call generated, go to the next instruction
784  /// MERR_INSN - not generated - the caller should try the standard way
785  /// else - error
786  virtual int apply(codegen_t &cdg) = 0;
787 };
788 
789 /// register/unregister non-standard microcode generator
790 /// \param filter - microcode generator object
791 /// \param install - TRUE - register the object, FALSE - unregister
792 void hexapi install_microcode_filter(microcode_filter_t *filter, bool install=true);
793 
794 //-------------------------------------------------------------------------
795 /// Abstract class: User-defined call generator
796 /// derived classes should implement method 'match'
798 {
799  udcall_t udc;
800 
801 public:
802  /// return true if the filter object should be appied to given instruction
803  virtual bool match(codegen_t &cdg) = 0;
804 
805  bool hexapi init(const char *decl);
806  virtual int hexapi apply(codegen_t &cdg);
807 };
808 
809 //-------------------------------------------------------------------------
810 struct fnumber_t /// Floating point constant.
811  /// For more details, please see the ieee.h file from IDA SDK.
812 {
813  uint16 fnum[6]; ///< Internal representation of the number
814  int nbytes; ///< Original size of the constant in bytes
815  operator uint16 *(void) { return fnum; }
816  operator const uint16 *(void) const { return fnum; }
817  size_t hexapi print(char *buf, size_t bufsize) const;
818  DEFINE_MEMORY_ALLOCATION_FUNCS()
820  {
821  return ecmp(fnum, r.fnum);
822  }
823 };
824 
825 //-------------------------------------------------------------------------
826 // Warning ids
827 enum warnid_t
828 {
829  WARN_VARARG_REGS, // 0 can not handle register arguments in vararg function, discarded them
830  WARN_ILL_PURGED, // 1 odd caller purged bytes %d, correcting
831  WARN_ILL_FUNCTYPE, // 2 invalid function type has been ignored
832  WARN_VARARG_TCAL, // 3 can not handle tail call to vararg
833  WARN_VARARG_NOSTK, // 4 call vararg without local stack
834  WARN_VARARG_MANY, // 5 too many varargs, some ignored
835  WARN_ADDR_OUTARGS, // 6 can not handle address arithmetics in outgoing argument area of stack frame -- unused
836  WARN_DEP_UNK_CALLS, // 7 found interdependent unknown calls
837  WARN_ILL_ELLIPSIS, // 8 erroneously detected ellipsis type has been ignored
838  WARN_GUESSED_TYPE, // 9 using guessed type %s;
839  WARN_EXP_LINVAR, // 10 failed to expand a linear variable
840  WARN_WIDEN_CHAINS, // 11 failed to widen chains
841  WARN_BAD_PURGED, // 12 inconsistent function type and number of purged bytes
842  WARN_CBUILD_LOOPS, // 13 too many cbuild loops
843  WARN_NO_SAVE_REST, // 14 could not find valid save-restore pair for %s
844  WARN_ODD_INPUT_REG, // 15 odd input register %s
845  WARN_ODD_ADDR_USE, // 16 odd use of a variable address
846  WARN_MUST_RET_FP, // 17 function return type is incorrect (must be floating point)
847  WARN_ILL_FPU_STACK, // 18 inconsistent fpu stack
848  WARN_SELFREF_PROP, // 19 self-referencing variable has been detected
849  WARN_WOULD_OVERLAP, // 20 variables would overlap: %s
850  WARN_ARRAY_INARG, // 21 array has been used for an input argument
851  WARN_MAX_ARGS, // 22 too many input arguments, some ignored
852  WARN_BAD_FIELD_TYPE,// 23 incorrect structure member type for %s::%s, ignored
853  WARN_WRITE_CONST, // 24 write access to const memory at %a has been detected
854  WARN_BAD_RETVAR, // 25 wrong return variable
855  WARN_FRAG_LVAR, // 26 fragmented variable at %s may be wrong
856  WARN_HUGE_STKOFF, // 27 exceedingly huge offset into the stack frame
857  WARN_UNINITED_REG, // 28 reference to an uninitialized register has been removed: %s
858  WARN_FIXED_MACRO, // 29 fixed broken macro-insn
859  WARN_WRONG_VA_OFF, // 30 wrong offset of va_list variable
860  WARN_CR_NOFIELD, // 31 CONTAINING_RECORD: no field '%s' in struct '%s' at %d
861  WARN_CR_BADOFF, // 32 CONTAINING_RECORD: too small offset %d for struct '%s'
862  WARN_BAD_STROFF, // 33 user specified stroff has not been processed: %s
863  WARN_BAD_VARSIZE, // 34 inconsistent variable size for '%s'
864  WARN_UNSUPP_REG, // 35 unsupported processor register '%s'
865  WARN_UNALIGNED_ARG, // 36 unaligned function argument '%s'
866  WARN_BAD_STD_TYPE, // 37 corrupted or unexisting local type '%s'
867 
868  WARN_MAX,
869 };
870 
871 // Warnings
872 struct hexwarn_t
873 {
874  ea_t ea;
875  warnid_t id;
876  qstring text;
878  {
879  if ( ea < r.ea )
880  return -1;
881  if ( ea > r.ea )
882  return 1;
883  if ( id < r.id )
884  return -1;
885  if ( id > r.id )
886  return 1;
887  return strcmp(text.c_str(), r.text.c_str());
888  }
889 };
890 DECLARE_TYPE_AS_MOVABLE(hexwarn_t);
891 typedef qvector<hexwarn_t> hexwarns_t;
892 
893 //-------------------------------------------------------------------------
894 // helper class to generate the initial microcode
896 {
897 public:
898  mbl_array_t *mba;
899  mblock_t *mb;
900  insn_t insn;
901  char ignore_micro;
902 
904  : mba(m), mb(NULL), ignore_micro(IM_NONE) {}
905  virtual ~codegen_t(void)
906  {
907  }
908 
909  // Analyze prolog/epilog of the function to decompile
910  // If found, allocate and fill 'mba->pi' structure.
911  virtual int idaapi analyze_prolog(
912  const class qflow_chart_t &fc,
913  const class bitset_t &reachable) = 0;
914 
915  // Generate microcode for one instruction
916  virtual int idaapi gen_micro() = 0;
917 
918  // Generate microcode to load one operand
919  virtual mreg_t idaapi load_operand(int opnum) = 0;
920 }; //-
921 
922 //-------------------------------------------------------------------------
923 /// Get decompiler version.
924 /// The returned string is of the form <major>.<minor>.<revision>.<build-date>
925 /// \return pointer to version string. For example: "2.0.0.140605"
926 
927 const char *hexapi get_hexrays_version(void);
928 
929 
930 /// Open pseudocode window.
931 /// The specified function is decompiled and the pseudocode window is opened.
932 /// \param ea function to decompile
933 /// \param new_window 0:reuse existing window; 1:open new window;
934 /// -1: reuse existing window if the current view is pseudocode
935 /// \return false if failed
936 
937 vdui_t *hexapi open_pseudocode(ea_t ea, int new_window);
938 
939 
940 /// Close pseudocode window.
941 /// \param f pointer to window
942 /// \return false if failed
943 
945 
946 
947 /// Get the vdui_t instance associated to the TWidget
948 /// \param f pointer to window
949 /// \return a vdui_t *, or NULL
950 
952 
953 
954 /// \defgroup VDRUN_ Batch decompilation bits
955 //@{
956 #define VDRUN_NEWFILE 0x0000 ///< Create a new file or overwrite existing file
957 #define VDRUN_APPEND 0x0001 ///< Create a new file or append to existing file
958 #define VDRUN_ONLYNEW 0x0002 ///< Fail if output file already exists
959 #define VDRUN_SILENT 0x0004 ///< Silent decompilation
960 #define VDRUN_SENDIDB 0x0008 ///< Send problematic databases to hex-rays.com
961 #define VDRUN_MAYSTOP 0x0010 ///< the user can cancel decompilation
962 #define VDRUN_CMDLINE 0x0020 ///< called from ida's command line
963 #define VDRUN_STATS 0x0040 ///< print statistics into vd_stats.txt
964 //@}
965 
966 /// Batch decompilation.
967 /// Decompile all or the specified functions
968 /// \return true if no internal error occured and the user has not cancelled decompilation
969 /// \param outfile name of the output file
970 /// \param funcaddrs list of functions to decompile.
971 /// If NULL or empty, then decompile all nonlib functions
972 /// \param flags \ref VDRUN_
973 
974 bool hexapi decompile_many(const char *outfile, eavec_t *funcaddrs, int flags);
975 
976 
977 /// Get textual description of an error code
978 /// \return pointer to static error description string
979 /// \param code \ref MERR_
980 
981 const char *hexapi micro_err_format(int code);
982 
983 /// \defgroup MERR_ Microcode error codes
984 //@{
985 #define MERR_OK 0 ///< ok
986 #define MERR_BLOCK 1 ///< no error, switch to new block
987 #define MERR_INTERR (-1) ///< internal error
988 #define MERR_INSN (-2) ///< can not convert to microcode
989 #define MERR_MEM (-3) ///< not enough memory
990 #define MERR_BADBLK (-4) ///< bad block found
991 #define MERR_BADSP (-5) ///< positive sp value has been found
992 #define MERR_PROLOG (-6) ///< prolog analysis failed
993 #define MERR_SWITCH (-7) ///< wrong switch idiom
994 #define MERR_EXCEPTION (-8) ///< exception analysis failed
995 #define MERR_HUGESTACK (-9) ///< stack frame is too big
996 #define MERR_LVARS (-10) ///< local variable allocation failed
997 #define MERR_BITNESS (-11) ///< only 32/16bit functions can be decompiled
998 #define MERR_BADCALL (-12) ///< could not determine call arguments
999 #define MERR_BADFRAME (-13) ///< function frame is wrong
1000 #define MERR_UNKTYPE (-14) ///< undefined type %s (currently unused error code)
1001 #define MERR_BADIDB (-15) ///< inconsistent database information
1002 #define MERR_SIZEOF (-16) ///< wrong basic type sizes in compiler settings
1003 #define MERR_REDO (-17) ///< redecompilation has been requested
1004 #define MERR_CANCELED (-18) ///< decompilation has been cancelled
1005 #define MERR_RECDEPTH (-19) ///< max recursion depth reached during lvar allocation
1006 #define MERR_OVERLAP (-20) ///< variables would overlap: %s
1007 #define MERR_PARTINIT (-21) ///< partially initialized variable %s
1008 #define MERR_COMPLEX (-22) ///< too complex function
1009 #define MERR_LICENSE (-23) ///< no license available
1010 #define MERR_ONLY32 (-24) ///< only 32-bit functions can be decompiled for the current database
1011 #define MERR_ONLY64 (-25) ///< only 64-bit functions can be decompiled for the current database
1012 #define MERR_BUSY (-26) ///< already decompiling a function
1013 #define MERR_FARPTR (-27) ///< far memory model is supported only for pc
1014 #define MERR_EXTERN (-28) ///< special segments can not be decompiled
1015 #define MERR_FUNCSIZE (-29) ///< too big function
1016 #define MERR_MAX_ERR 29
1017 #define MERR_LOOP (-30) ///< internal code: redo last loop (never reported)
1018 //@}
1019 
1020 /// Exception object: decompiler failure information
1022 {
1023  int code; ///< \ref MERR_
1024  ea_t errea; ///< associated address
1025  qstring str; ///< string information
1026  hexrays_failure_t(void) : code(MERR_OK), errea(BADADDR) {}
1027  hexrays_failure_t(int c, ea_t ea, const char *buf=NULL) : code(c), errea(ea), str(buf) {}
1028  hexrays_failure_t(int c, ea_t ea, const qstring &buf) : code(c), errea(ea), str(buf) {}
1029  qstring hexapi desc(void) const;
1030  DEFINE_MEMORY_ALLOCATION_FUNCS()
1031 };
1032 
1033 /// Exception object: decompiler exception
1034 struct vd_failure_t : public std::exception
1035 {
1036  hexrays_failure_t hf;
1037  vd_failure_t(void) {}
1038  vd_failure_t(int code, ea_t ea, const char *buf=NULL) : hf(code, ea, buf) {}
1039  vd_failure_t(int code, ea_t ea, const qstring &buf) : hf(code, ea, buf) {}
1040  vd_failure_t(const hexrays_failure_t &_hf) : hf(_hf) {}
1041  qstring desc(void) const { return hf.desc(); }
1042 #ifdef __GNUC__
1043  ~vd_failure_t(void) throw() {}
1044 #endif
1045  DEFINE_MEMORY_ALLOCATION_FUNCS()
1046 };
1047 
1048 /// Exception object: decompiler internal error
1049 struct vd_interr_t : public vd_failure_t
1050 {
1051  vd_interr_t(ea_t ea, const qstring &buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
1052  vd_interr_t(ea_t ea, const char *buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
1053 };
1054 
1055 /// Send the database to Hex-Rays.
1056 /// This function sends the current database to the hex-rays server.
1057 /// The database is sent in the compressed form over an encrypted (SSL) connection.
1058 /// \param err failure description object. Empty hexrays_failure_t object can be used if error information is not available.
1059 /// \param silent if false, a dialog box will be displayed before sending the database.
1060 
1061 void hexapi send_database(const hexrays_failure_t &err, bool silent);
1062 
1063 //-------------------------------------------------------------------------
1064 /// Ctree element type. At the beginning of this list there are expression
1065 /// elements (cot_...), followed by statement elements (cit_...).
1067 {
1068  cot_empty = 0,
1069  cot_comma = 1, ///< x, y
1070  cot_asg = 2, ///< x = y
1071  cot_asgbor = 3, ///< x |= y
1072  cot_asgxor = 4, ///< x ^= y
1073  cot_asgband = 5, ///< x &= y
1074  cot_asgadd = 6, ///< x += y
1075  cot_asgsub = 7, ///< x -= y
1076  cot_asgmul = 8, ///< x *= y
1077  cot_asgsshr = 9, ///< x >>= y signed
1078  cot_asgushr = 10, ///< x >>= y unsigned
1079  cot_asgshl = 11, ///< x <<= y
1080  cot_asgsdiv = 12, ///< x /= y signed
1081  cot_asgudiv = 13, ///< x /= y unsigned
1082  cot_asgsmod = 14, ///< x %= y signed
1083  cot_asgumod = 15, ///< x %= y unsigned
1084  cot_tern = 16, ///< x ? y : z
1085  cot_lor = 17, ///< x || y
1086  cot_land = 18, ///< x && y
1087  cot_bor = 19, ///< x | y
1088  cot_xor = 20, ///< x ^ y
1089  cot_band = 21, ///< x & y
1090  cot_eq = 22, ///< x == y int or fpu (see EXFL_FPOP)
1091  cot_ne = 23, ///< x != y int or fpu (see EXFL_FPOP)
1092  cot_sge = 24, ///< x >= y signed or fpu (see EXFL_FPOP)
1093  cot_uge = 25, ///< x >= y unsigned
1094  cot_sle = 26, ///< x <= y signed or fpu (see EXFL_FPOP)
1095  cot_ule = 27, ///< x <= y unsigned
1096  cot_sgt = 28, ///< x > y signed or fpu (see EXFL_FPOP)
1097  cot_ugt = 29, ///< x > y unsigned
1098  cot_slt = 30, ///< x < y signed or fpu (see EXFL_FPOP)
1099  cot_ult = 31, ///< x < y unsigned
1100  cot_sshr = 32, ///< x >> y signed
1101  cot_ushr = 33, ///< x >> y unsigned
1102  cot_shl = 34, ///< x << y
1103  cot_add = 35, ///< x + y
1104  cot_sub = 36, ///< x - y
1105  cot_mul = 37, ///< x * y
1106  cot_sdiv = 38, ///< x / y signed
1107  cot_udiv = 39, ///< x / y unsigned
1108  cot_smod = 40, ///< x % y signed
1109  cot_umod = 41, ///< x % y unsigned
1110  cot_fadd = 42, ///< x + y fp
1111  cot_fsub = 43, ///< x - y fp
1112  cot_fmul = 44, ///< x * y fp
1113  cot_fdiv = 45, ///< x / y fp
1114  cot_fneg = 46, ///< -x fp
1115  cot_neg = 47, ///< -x
1116  cot_cast = 48, ///< (type)x
1117  cot_lnot = 49, ///< !x
1118  cot_bnot = 50, ///< ~x
1119  cot_ptr = 51, ///< *x, access size in 'ptrsize'
1120  cot_ref = 52, ///< &x
1121  cot_postinc = 53, ///< x++
1122  cot_postdec = 54, ///< x--
1123  cot_preinc = 55, ///< ++x
1124  cot_predec = 56, ///< --x
1125  cot_call = 57, ///< x(...)
1126  cot_idx = 58, ///< x[y]
1127  cot_memref = 59, ///< x.m
1128  cot_memptr = 60, ///< x->m, access size in 'ptrsize'
1129  cot_num = 61, ///< n
1130  cot_fnum = 62, ///< fpc
1131  cot_str = 63, ///< string constant
1132  cot_obj = 64, ///< obj_ea
1133  cot_var = 65, ///< v
1134  cot_insn = 66, ///< instruction in expression, internal representation only
1135  cot_sizeof = 67, ///< sizeof(x)
1136  cot_helper = 68, ///< arbitrary name
1137  cot_type = 69, ///< arbitrary type
1138  cot_last = cot_type,
1139  cit_empty = 70, ///< instruction types start here
1140  cit_block = 71, ///< block-statement: { ... }
1141  cit_expr = 72, ///< expression-statement: expr;
1142  cit_if = 73, ///< if-statement
1143  cit_for = 74, ///< for-statement
1144  cit_while = 75, ///< while-statement
1145  cit_do = 76, ///< do-statement
1146  cit_switch = 77, ///< switch-statement
1147  cit_break = 78, ///< break-statement
1148  cit_continue = 79, ///< continue-statement
1149  cit_return = 80, ///< return-statement
1150  cit_goto = 81, ///< goto-statement
1151  cit_asm = 82, ///< asm-statement
1152  cit_end
1153 };
1154 
1155 /// \defgroup fixtype_t C operator writing styles
1156 /// Used in operator_info_t::fixtype
1157 //@{
1158 const uchar
1159  FX_NONE = 0, ///< not applicable
1160  FX_INFIX = 1, ///< infix: a + b
1161  FX_PREFIX = 2, ///< prefix: *a
1162  FX_POSTFIX = 3, ///< postfix: a++
1163  FX_TERNARY = 4; ///< ternary: a ? b : c
1164 //@}
1165 
1166 /// \defgroup opattrs_t C operator attributes
1167 /// Used in operator_info_t::flags
1168 //@{
1169 const uchar
1170  COI_RL = 0x00, ///< right to left
1171  COI_LR = 0x01, ///< left to right
1172  COI_INT = 0x02, ///< requires integer operands
1173  COI_FP = 0x04, ///< requires floating point operands
1174  COI_SH = 0x08, ///< is shift operation?
1175  COI_SGN = 0x10, ///< sign sensitive?
1176  COI_SBN = 0x20; ///< is simple binary?
1177 //@}
1178 
1179 /// Information about C operator
1181 {
1182  DEFINE_MEMORY_ALLOCATION_FUNCS()
1183  const char *text; ///< Text representation
1184  uchar precedence; ///< Operator precedence (lower: more priority)
1185  uchar valency; ///< Number of operator arguments
1186  uchar fixtype; ///< \ref fixtype_t
1187  uchar flags; ///< \ref opattrs_t
1188 };
1189 
1190 
1191 
1192 /// Negate a comparison operator. For example, \ref cot_sge becomes \ref cot_slt
1194 /// Get operator sign. Meaningful for sign-dependent operators, like \ref cot_sdiv
1195 type_sign_t hexapi get_op_signness(ctype_t op);
1196 /// Convert plain operator into assignment operator. For example, \ref cot_add returns \ref cot_asgadd
1198 /// Convert assignment operator into plain operator. For example, \ref cot_asgadd returns \ref cot_add
1199 /// \return cot_empty is the input operator is not an assignment operator.
1201 /// Does operator use the 'x' field of cexpr_t?
1202 inline bool op_uses_x(ctype_t op) { return op >= cot_comma && op <= cot_memptr; }
1203 /// Does operator use the 'y' field of cexpr_t?
1204 inline bool op_uses_y(ctype_t op) { return (op >= cot_comma && op <= cot_fdiv) || op == cot_idx; }
1205 /// Does operator use the 'z' field of cexpr_t?
1206 inline bool op_uses_z(ctype_t op) { return op == cot_tern; }
1207 /// Is binary operator?
1208 inline bool is_binary(ctype_t op) { return op_uses_y(op) && op != cot_tern; } // x,y
1209 /// Is unary operator?
1210 inline bool is_unary(ctype_t op) { return op >= cot_fneg && op <= cot_predec; }
1211 /// Is comparison operator?
1212 inline bool is_relational(ctype_t op) { return op >= cot_eq && op <= cot_ult; }
1213 /// Is assignment operator?
1214 inline bool is_assignment(ctype_t op) { return op >= cot_asg && op <= cot_asgumod; }
1215 // Can operate on UDTs?
1216 inline bool accepts_udts(ctype_t op) { return op == cot_asg || op == cot_comma || op > cot_last; }
1217 /// Is pre/post increment/decrement operator?
1218 inline bool is_prepost(ctype_t op) { return op >= cot_postinc && op <= cot_predec; }
1219 /// Is commutative operator?
1220 inline bool is_commutative(ctype_t op)
1221 {
1222  return op == cot_bor
1223  || op == cot_xor
1224  || op == cot_band
1225  || op == cot_add
1226  || op == cot_mul
1227  || op == cot_fadd
1228  || op == cot_fmul
1229  || op == cot_ne
1230  || op == cot_eq;
1231 }
1232 /// Is additive operator?
1233 inline bool is_additive(ctype_t op)
1234 {
1235  return op == cot_add
1236  || op == cot_sub
1237  || op == cot_fadd
1238  || op == cot_fsub;
1239 }
1240 /// Is multiplicative operator?
1242 {
1243  return op == cot_mul
1244  || op == cot_sdiv
1245  || op == cot_udiv
1246  || op == cot_fmul
1247  || op == cot_fdiv;
1248 }
1249 
1250 /// Is bit related operator?
1251 inline bool is_bitop(ctype_t op)
1252 {
1253  return op == cot_bor
1254  || op == cot_xor
1255  || op == cot_band
1256  || op == cot_bnot;
1257 }
1258 
1259 /// Is logical operator?
1260 inline bool is_logical(ctype_t op)
1261 {
1262  return op == cot_lor
1263  || op == cot_land
1264  || op == cot_lnot;
1265 }
1266 
1267 /// Is loop statement code?
1268 inline bool is_loop(ctype_t op)
1269 {
1270  return op == cit_for
1271  || op == cit_while
1272  || op == cit_do;
1273 }
1274 /// Does a break statement influence the specified statement code?
1276 {
1277  return is_loop(op) || op == cit_switch;
1278 }
1279 
1280 /// Is Lvalue operator?
1281 inline bool is_lvalue(ctype_t op)
1282 {
1283  return op == cot_ptr // *x
1284  || op == cot_idx // x[y]
1285  || op == cot_memref // x.m
1286  || op == cot_memptr // x->m
1287  || op == cot_obj // v
1288  || op == cot_var; // l
1289 }
1290 
1291 /// Is the operator allowed on small struni (structure/union)?
1293 {
1294  return op == cit_return
1295  || op == cot_asg
1296  || op == cot_eq
1297  || op == cot_ne
1298  || op == cot_comma
1299  || op == cot_tern
1300  || (op > cot_last && op < cit_end); // any insn
1301 }
1302 
1303 /// An immediate number
1305 {
1306  uint64 _value; ///< its value
1307  number_format_t nf; ///< how to represent it
1308  cnumber_t(int _opnum=0) : _value(0), nf(_opnum) {}
1309 
1310  /// Get text representation
1311  /// \param buf output buffer
1312  /// \param bufsize size of output buffer
1313  /// \param type number type
1314  /// \param parent parent expression
1315  /// \param nice_stroff out: printed as stroff expression
1316  size_t hexapi print(char *buf, size_t bufsize, const tinfo_t &type, const citem_t *parent=NULL, bool *nice_stroff=NULL) const;
1317 
1318  /// Get value.
1319  /// This function will properly extend the number sign to 64bits
1320  /// depending on the type sign.
1321  uint64 hexapi value(const tinfo_t &type) const;
1322 
1323  /// Assign new value
1324  /// \param v new value
1325  /// \param nbytes size of the new value in bytes
1326  /// \param sign sign of the value
1327  void hexapi assign(uint64 v, int nbytes, type_sign_t sign);
1328 
1330 };
1331 
1332 /// Reference to a local variable
1334 {
1335  mbl_array_t *mba; ///< pointer to the underlying micro array
1336  int idx; ///< index into lvars_t
1337  DEFINE_MEMORY_ALLOCATION_FUNCS()
1338  DECLARE_COMPARISONS(var_ref_t);
1339 };
1340 
1341 /// Vector of parents
1342 typedef qvector<citem_t *> ctree_items_t;
1343 typedef ctree_items_t parents_t;
1344 
1345 /// A generic helper class that is used for ctree traversal
1347 {
1348  DEFINE_MEMORY_ALLOCATION_FUNCS()
1349  int cv_flags; ///< \ref CV_
1350 /// \defgroup CV_ Ctree visitor property bits
1351 /// Used in ctree_visitor_t::cv_flags
1352 //@{
1353 #define CV_FAST 0x0000 ///< do not maintain parent information
1354 #define CV_PRUNE 0x0001 ///< this bit is set by visit...() to prune the walk
1355 #define CV_PARENTS 0x0002 ///< maintain parent information
1356 #define CV_POST 0x0004 ///< call the leave...() functions
1357 #define CV_RESTART 0x0008 ///< restart enumeration at the top expr (apply_to_exprs)
1358 #define CV_INSNS 0x0010 ///< visit only statements, prune all expressions
1359  ///< do not use before the final ctree maturity because
1360  ///< expressions may contain statements at intermediate
1361  ///< stages (see cot_insn). Otherwise you risk missing
1362  ///< statements embedded into expressions.
1363 //@}
1364  /// Should the parent information by maintained?
1365  bool maintain_parents(void) const { return (cv_flags & CV_PARENTS) != 0; }
1366  /// Should the traversal skip the children of the current item?
1367  bool must_prune(void) const { return (cv_flags & CV_PRUNE) != 0; }
1368  /// Should the traversal restart?
1369  bool must_restart(void) const { return (cv_flags & CV_RESTART) != 0; }
1370  /// Should the leave...() functions be called?
1371  bool is_postorder(void) const { return (cv_flags & CV_POST) != 0; }
1372  /// Should all expressions be automatically pruned?
1373  bool only_insns(void) const { return (cv_flags & CV_INSNS) != 0; }
1374  /// Prune children.
1375  /// This function may be called by a visitor() to skip all children of the current item.
1376  void prune_now(void) { cv_flags |= CV_PRUNE; }
1377  /// Do not prune children. This is an internal function, no need to call it.
1378  void clr_prune(void) { cv_flags &= ~CV_PRUNE; }
1379  /// Restart the travesal. Meaningful only in apply_to_exprs()
1380  void set_restart(void) { cv_flags |= CV_RESTART; }
1381  /// Do not restart. This is an internal function, no need to call it.
1382  void clr_restart(void) { cv_flags &= ~CV_RESTART; }
1383 
1384  parents_t parents; ///< Vector of parents of the current item
1385 
1386  /// Constructor.
1387  /// This constructor can be used with CV_FAST, CV_PARENTS
1388  /// combined with CV_POST, CV_ONLYINS
1389  ctree_visitor_t(int _flags) : cv_flags(_flags) {}
1390 
1391  DEFINE_VIRTUAL_DTOR(ctree_visitor_t);
1392  /// Traverse ctree.
1393  /// The traversal will start at the specified item and continue until
1394  /// of one the visit_...() functions return a non-zero value.
1395  /// \param item root of the ctree to traverse
1396  /// \param parent parent of the specified item. can be specified as NULL.
1397  /// \return 0 or a non-zero value returned by a visit_...() function
1398  int hexapi apply_to(citem_t *item, citem_t *parent);
1399 
1400  /// Traverse only expressions.
1401  /// The traversal will start at the specified item and continue until
1402  /// of one the visit_...() functions return a non-zero value.
1403  /// \param item root of the ctree to traverse
1404  /// \param parent parent of the specified item. can be specified as NULL.
1405  /// \return 0 or a non-zero value returned by a visit_...() function
1406  int hexapi apply_to_exprs(citem_t *item, citem_t *parent);
1407 
1408  /// Get parent of the current item as an expression
1409  cexpr_t *parent_expr(void) { return (cexpr_t *)parents.back(); }
1410  /// Get parent of the current item as a statement
1411  cinsn_t *parent_insn(void) { return (cinsn_t *)parents.back(); }
1412 
1413  // the following functions are redefined by the derived class
1414  // in order to perform the desired actions during the traversal
1415 
1416  /// Visit a statement.
1417  /// This is a visitor function which should be overridden by a derived
1418  /// class to do some useful work.
1419  /// This visitor performs pre-order traserval, i.e. an item is visited before
1420  /// its children.
1421  /// \return 0 to continue the traversal, nonzero to stop.
1422  virtual int idaapi visit_insn(cinsn_t *) { return 0; }
1423 
1424  /// Visit an expression.
1425  /// This is a visitor function which should be overridden by a derived
1426  /// class to do some useful work.
1427  /// This visitor performs pre-order traserval, i.e. an item is visited before
1428  /// its children.
1429  /// \return 0 to continue the traversal, nonzero to stop.
1430  virtual int idaapi visit_expr(cexpr_t *) { return 0; }
1431 
1432  /// Visit a statement after having visited its children
1433  /// This is a visitor function which should be overridden by a derived
1434  /// class to do some useful work.
1435  /// This visitor performs post-order traserval, i.e. an item is visited after
1436  /// its children.
1437  /// \return 0 to continue the traversal, nonzero to stop.
1438  virtual int idaapi leave_insn(cinsn_t *) { return 0; }
1439 
1440  /// Visit an expression after having visited its children
1441  /// This is a visitor function which should be overridden by a derived
1442  /// class to do some useful work.
1443  /// This visitor performs post-order traserval, i.e. an item is visited after
1444  /// its children.
1445  /// \return 0 to continue the traversal, nonzero to stop.
1446  virtual int idaapi leave_expr(cexpr_t *) { return 0; }
1447 };
1448 
1449 /// A helper ctree traversal class that maintains parent information
1451 {
1452  ctree_parentee_t(bool post=false)
1453  : ctree_visitor_t((post ? CV_POST : 0)|CV_PARENTS) {}
1454 
1455  /// Recalculate types of parent node.
1456  /// If a node type has been changed, the visitor must recalculate
1457  /// all parent types, otherwise the ctree becomes inconsistent.
1458  /// If during this recalculation a parent node is added/deleted,
1459  /// this function returns true. In this case it is recommended
1460  /// to restart the traversal because the information about parent nodes
1461  /// is stale.
1462  /// \return false-ok to continue the traversal, true-must stop.
1463  bool hexapi recalc_parent_types(void);
1464 };
1465 
1466 /// Class to traverse the whole function
1468 {
1469  cfunc_t *func; ///< Pointer to current function
1470  cfunc_parentee_t(cfunc_t *f, bool post=false)
1471  : ctree_parentee_t(post), func(f) {}
1472 
1473  /// Calculate rvalue type.
1474  /// This function tries to determine the type of the specified item
1475  /// based on its context. For example, if the current expression is the
1476  /// right side of an assignment operator, the type
1477  /// of its left side will be returned. This function can be used to determine the 'best'
1478  /// type of the specified expression.
1479  /// \param[in] e expression to determine the desired type
1480  /// \param[out] target 'best' type of the expression will be returned here
1481  /// \return false if failed
1482  bool hexapi calc_rvalue_type(tinfo_t *target, const cexpr_t *e);
1483 };
1484 
1485 /// Ctree maturity level. The level will increase
1486 /// as we switch from one phase of ctree generation to the next one
1488 {
1489  CMAT_ZERO, ///< does not exist
1490  CMAT_BUILT, ///< just generated
1491  CMAT_TRANS1, ///< applied first wave of transformations
1492  CMAT_NICE, ///< nicefied expressions
1493  CMAT_TRANS2, ///< applied second wave of transformations
1494  CMAT_CPA, ///< corrected pointer arithmetic
1495  CMAT_TRANS3, ///< applied third wave of transformations
1496  CMAT_CASTED, ///< added necessary casts
1497  CMAT_FINAL, ///< ready-to-use
1498 };
1499 
1500 //--------------------------------------------------------------------------
1501 /// Comment item preciser.
1502 /// Item preciser is used to assign comments to ctree items
1503 /// A ctree item may have several comments attached to it. For example,
1504 /// an if-statement may have the following comments: <pre>
1505 /// if ( ... ) // cmt1
1506 /// { // cmt2
1507 /// } // cmt3
1508 /// else // cmt4
1509 /// { -- usually the else block has a separate ea
1510 /// } </pre>
1511 /// The first 4 comments will have the same ea. In order to denote the exact
1512 /// line for the comment, we store the item_preciser along with ea.
1514 {
1515  // inner comments (comments within an expression)
1516  ITP_EMPTY, ///< nothing
1517  ITP_ARG1, ///< , (64 entries are reserved for 64 call arguments)
1518  ITP_ARG64 = ITP_ARG1+63, // ,
1519  ITP_BRACE1, // (
1520  ITP_INNER_LAST = ITP_BRACE1,
1521  // outer comments
1522  ITP_ASM, ///< __asm-line
1523  ITP_ELSE, ///< else-line
1524  ITP_DO, ///< do-line
1525  ITP_SEMI, ///< semicolon
1526  ITP_CURLY1, ///< {
1527  ITP_CURLY2, ///< }
1528  ITP_BRACE2, ///< )
1529  ITP_COLON, ///< : (label)
1530  ITP_BLOCK1, ///< opening block comment. this comment is printed before the item
1531  ///< (other comments are indented and printed after the item)
1532  ITP_BLOCK2, ///< closing block comment.
1533  ITP_CASE = 0x40000000, ///< bit for switch cases
1534  ITP_SIGN = 0x20000000, ///< if this bit is set too, then we have a negative case value
1535  // this is a hack, we better introduce special indexes for case values
1536  // case value >= ITP_CASE will be processed incorrectly
1537 };
1538 /// Ctree location. Used to denote comment locations.
1540 {
1541  DEFINE_MEMORY_ALLOCATION_FUNCS()
1542  ea_t ea;
1543  item_preciser_t itp;
1544  bool operator < (const treeloc_t &r) const
1545  {
1546  return ea < r.ea
1547  || (ea == r.ea && itp < r.itp);
1548  }
1549  bool operator == (const treeloc_t &r) const
1550  {
1551  return ea == r.ea && itp == r.itp;
1552  }
1553 };
1554 
1555 /// Comment retrieval type.
1556 /// Ctree remembers what comments have already been retrieved.
1557 /// This is done because our mechanism of item_precisers is still
1558 /// not perfect and in theory some listing lines can not be told
1559 /// apart. To avoid comment duplication, we remember if a comment
1560 /// has already been used or not.
1562 {
1563  RETRIEVE_ONCE, ///< Retrieve comment if it has not been used yet
1564  RETRIEVE_ALWAYS, ///< Retrieve comment even if it has been used
1565 };
1566 
1567 /// Ctree item comment.
1568 /// For each comment we remember its body and the fact of its retrieval
1569 struct citem_cmt_t : public qstring
1570 {
1571  mutable bool used; ///< the comment has been retrieved?
1572  citem_cmt_t(void) : used(false) {}
1573  citem_cmt_t(const char *s) : qstring(s), used(false) {}
1574 };
1575 
1576 // Comments are attached to tree locations:
1577 typedef std::map<treeloc_t, citem_cmt_t> user_cmts_t;
1578 
1579 /// Generic ctree element locator. It can be used for instructions and some expression
1580 /// types. However, we need more precise locators for other items (e.g. for numbers)
1582 {
1583  ea_t ea; ///< citem address
1584  ctype_t op; ///< citem operation
1585 private:
1586  //forbid the default constructor
1587  citem_locator_t(void) {}
1588 public:
1589  citem_locator_t(ea_t _ea, ctype_t _op) : ea(_ea), op(_op) {}
1590  citem_locator_t(const citem_t *i);
1592  DEFINE_MEMORY_ALLOCATION_FUNCS()
1593 };
1594 
1595 // citem_t::iflags are attached to (ea,op) pairs
1596 typedef std::map<citem_locator_t, int32> user_iflags_t;
1597 
1598 // union field selections
1599 // they are represented as a vector of integers. each integer represents the
1600 // number of union field (0 means the first union field, etc)
1601 // the size of this vector is equal to the number of nested unions in the selection.
1602 typedef std::map<ea_t, intvec_t> user_unions_t;
1603 
1604 //--------------------------------------------------------------------------
1605 /// Basic ctree element. This is an abstract class (but we don't use virtual
1606 /// functions in ctree, so the compiler will not disallow you to create citem_t
1607 /// instances). However, elements of pure citem_t type must never be created.
1608 /// Two classes, cexpr_t and cinsn_t are derived from it.
1609 struct citem_t
1610 {
1611  ea_t ea; ///< address that corresponds to the item
1612  ctype_t op; ///< element type
1613  int label_num; ///< label number. -1 means no label. items of expression
1614  ///< types (cot_...) should not have labels at the final maturity
1615  ///< level, but at the intermediate levels any ctree element
1616  ///< may have a label. Labels must be unique. Usually
1617  ///< they correspond to the basic block numbers.
1618  mutable int index; ///< item index. meaningful only after print_func()
1619  citem_t(void) : ea(BADADDR), op(cot_empty), label_num(-1), index(-1) {}
1620  citem_t(ctype_t o) : ea(BADADDR), op(o), label_num(-1), index(-1) {}
1621  /// Swap two citem_t
1622  void swap(citem_t &r)
1623  {
1624  std::swap(ea, r.ea);
1625  std::swap(op, r.op);
1626  std::swap(label_num, r.label_num);
1627  }
1628  /// Is an expression?
1629  bool is_expr(void) const { return op <= cot_last; }
1630  /// Does the item contain a label?
1631  bool hexapi contains_label(void) const;
1632  /// Find parent of the specified item.
1633  /// \param sitem Item to find the parent of. The search will be performed
1634  /// among the children of the item pointed by \c this.
1635  /// \return NULL if not found
1636  const citem_t *hexapi find_parent_of(const citem_t *sitem) const;
1637  citem_t *find_parent_of(const citem_t *item)
1638  { return CONST_CAST(citem_t*)((CONST_CAST(const citem_t*)(this))->find_parent_of(item)); }
1639  size_t print1(char *buf, size_t bufsize, const cfunc_t *func) const;
1640  DEFINE_MEMORY_ALLOCATION_FUNCS()
1641 };
1642 
1643 /// Ctree element: expression.
1644 /// Depending on the exact expression item type, various fields of this structure are used.
1645 struct cexpr_t : public citem_t
1646 {
1647  union
1648  {
1649  cnumber_t *n; ///< used for \ref cot_num
1650  fnumber_t *fpc; ///< used for \ref cot_fnum
1651  struct
1652  {
1653  union
1654  {
1655  var_ref_t v; ///< used for \ref cot_var
1656  ea_t obj_ea; ///< used for \ref cot_obj
1657  };
1658  int refwidth; ///< how many bytes are accessed? (-1: none)
1659  };
1660  struct
1661  {
1662  cexpr_t *x; ///< the first operand of the expression
1663  union
1664  {
1665  cexpr_t *y; ///< the second operand of the expression
1666  carglist_t *a;///< argument list (used for \ref cot_call)
1667  uint32 m; ///< member offset (used for \ref cot_memptr, \ref cot_memref)
1668  ///< for unions, the member number
1669  };
1670  union
1671  {
1672  cexpr_t *z; ///< the third operand of the expression
1673  int ptrsize; ///< memory access size (used for \ref cot_ptr, \ref cot_memptr)
1674  };
1675  };
1676  cinsn_t *insn; ///< an embedded statement, they are prohibited
1677  ///< at the final maturity stage (\ref CMAT_FINAL)
1678  char *helper; ///< helper name (used for \ref cot_helper)
1679  char *string; ///< string constant (used for \ref cot_str)
1680  };
1681  tinfo_t type; ///< expression type. must be carefully maintained
1682  int exflags; ///< \ref EXFL_
1683 /// \defgroup EXFL_ Expression attributes
1684 /// Used in cexpr_t::exflags
1685 //@{
1686 #define EXFL_CPADONE 0x0001 ///< pointer arithmetic correction done
1687 #define EXFL_LVALUE 0x0002 ///< expression is lvalue even if it doesn't look like it
1688 #define EXFL_FPOP 0x0004 ///< floating point operation
1689 #define EXFL_ALONE 0x0008 ///< standalone helper
1690 #define EXFL_CSTR 0x0010 ///< string literal
1691 #define EXFL_PARTIAL 0x0020 ///< type of the expression is considered partial
1692 #define EXFL_ALL 0x003F ///< all currently defined bits
1693 //@}
1694  /// Pointer arithmetic correction done for this expression?
1695  bool cpadone(void) const { return (exflags & EXFL_CPADONE) != 0; }
1696  bool is_odd_lvalue(void) const { return (exflags & EXFL_LVALUE) != 0; }
1697  bool is_fpop(void) const { return (exflags & EXFL_FPOP) != 0; }
1698  bool is_cstr(void) const { return (exflags & EXFL_CSTR) != 0; }
1699  bool is_type_partial(void) const { return (exflags & EXFL_PARTIAL) != 0; }
1700 
1701 
1702  void set_cpadone(void) { exflags |= EXFL_CPADONE; }
1703  void set_type_partial(void) { exflags |= EXFL_PARTIAL; }
1704 
1705  cexpr_t(void) : x(NULL), y(NULL), z(NULL), exflags(0) {}
1706  cexpr_t(ctype_t cop, cexpr_t *_x) : citem_t(cop), x(_x), y(NULL), z(NULL), exflags(0) {}
1707  cexpr_t(ctype_t cop, cexpr_t *_x, cexpr_t *_y) : citem_t(cop), x(_x), y(_y), z(NULL), exflags(0) {}
1708  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) {}
1709  cexpr_t(mbl_array_t *mba, const lvar_t &v);
1710  cexpr_t(const cexpr_t &r) : citem_t() { *this = r; }
1711  void swap(cexpr_t &r) { qswap(*this, r); }
1712  cexpr_t &operator=(const cexpr_t &r) { return assign(r); }
1713  cexpr_t &hexapi assign(const cexpr_t &r);
1715  ~cexpr_t(void) { cleanup(); }
1716 
1717  /// Replace the expression.
1718  /// The children of the expression are abandoned (not freed).
1719  /// The expression pointed by 'r' is moved to 'this' expression
1720  /// \param r the source expression. It is deleted after being copied
1721  void hexapi replace_by(cexpr_t *r);
1722 
1723  /// Cleanup the expression.
1724  /// This function properly deletes all children and sets the item type to cot_empty.
1725  void hexapi cleanup(void);
1726 
1727  /// Assign a number to the expression.
1728  /// \param func current function
1729  /// \param value number value
1730  /// \param nbytes size of the number in bytes
1731  /// \param sign number sign
1732  void hexapi put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign=no_sign);
1733 
1734  /// Print expression into one line.
1735  /// \param buf output buffer
1736  /// \param bufsize size of the output buffer
1737  /// \param func parent function. This argument is used to find out the referenced variable names.
1738  /// \return length of the generated text.
1739  size_t hexapi print1(char *buf, size_t bufsize, const cfunc_t *func) const;
1740 
1741  /// Calculate the type of the expression.
1742  /// Use this function to calculate the expression type when a new expression is built
1743  /// \param recursive if true, types of all children expression will be calculated
1744  /// before calculating our type
1745  void hexapi calc_type(bool recursive);
1746 
1747  /// Compare two expressions.
1748  /// This function tries to compare two expressions in an 'intelligent' manner.
1749  /// For example, it knows about commutitive operators and can ignore useless casts.
1750  /// \param r the expression to compare against the current expression
1751  /// \return true expressions can be considered equal
1752  bool hexapi equal_effect(const cexpr_t &r) const;
1753 
1754  /// Verify if the specified item is our parent.
1755  /// \param parent possible parent item
1756  /// \return true if the specified item is our parent
1757  bool hexapi is_child_of(const citem_t *parent) const;
1758 
1759  /// Check if the expression contains the specified operator.
1760  /// \param needed_op operator code to search for
1761  /// \param times how many times the operator code should be present
1762  /// \return true if the expression has at least TIMES children with NEEDED_OP
1763  bool hexapi contains_operator(ctype_t needed_op, int times=1) const;
1764 
1765  /// Does the expression contain another expression?
1766  bool contains_expr(const cexpr_t *e) const;
1767  /// Does the expression contain a comma operator?
1768  bool contains_comma(int times=1) const { return contains_operator(cot_comma, times); }
1769  /// Does the expression contain an embedded statement operator?
1770  bool contains_insn(int times=1) const { return contains_operator(cot_insn, times); }
1771  /// Does the expression contain an embedded statement operator or a label?
1772  bool contains_insn_or_label(void) const { return contains_insn() || contains_label(); }
1773  /// Does the expression contain a comma operator or an embedded statement operator or a label?
1774  bool contains_comma_or_insn_or_label(int maxcommas=1) const { return contains_comma(maxcommas) || contains_insn_or_label(); }
1775  /// Is nice expression?
1776  /// Nice expressions do not contain comma operators, embedded statements, or labels.
1777  bool is_nice_expr(void) const { return !contains_comma_or_insn_or_label(); }
1778  /// Is nice condition?.
1779  /// Nice condition is a nice expression of the boolean type.
1780  bool is_nice_cond(void) const { return is_nice_expr() && type.is_bool(); }
1781  /// Is call object?
1782  /// \return true if our expression is the call object of the specified parent expression.
1783  bool is_call_object_of(const citem_t *parent) const { return parent != NULL && parent->op == cot_call && ((cexpr_t*)parent)->x == this; }
1784  /// Is call argument?
1785  /// \return true if our expression is a call argument of the specified parent expression.
1786  bool is_call_arg_of(const citem_t *parent) const { return parent != NULL && parent->op == cot_call && ((cexpr_t*)parent)->x != this; }
1787  /// Get expression sign
1788  type_sign_t get_type_sign(void) const { return type.get_sign(); }
1789  /// Is expression unsigned?
1790  bool is_type_unsigned(void) const { return type.is_unsigned(); }
1791  /// Is expression signed?
1792  bool is_type_signed(void) const { return type.is_signed(); }
1793  /// Get max number of bits that can really be used by the expression.
1794  /// For example, x % 16 can yield only 4 non-zero bits
1795  int hexapi get_high_nbit_bound(int pbits, type_sign_t psign, bool *p_maybe_negative=NULL) const;
1796  /// Get min number of bits that are always present in the expression.
1797  /// For example, 16 always uses 5 bits.
1798  int hexapi get_low_nbit_bound(type_sign_t psign, bool *p_maybe_negative=NULL) const;
1799  /// Check if the expression requires an lvalue.
1800  /// \param child The function will check if this child of our expression must be an lvalue.
1801  /// \return true if child must be an lvalue.
1802  bool hexapi requires_lvalue(const cexpr_t *child) const;
1803  /// Check if the expression has side effects.
1804  /// Calls, pre/post inc/dec, and assignments have side effects.
1805  bool hexapi has_side_effects(void) const;
1806  /// Check if the expression if aliasable.
1807  /// Simple registers and non-aliasble stack slots return false.
1808  bool is_aliasable(void) const;
1809  /// Get numeric value of the expression.
1810  /// This function can be called only on cot_num expressions!
1811  uint64 numval(void) const
1812  {
1813  QASSERT(50071, op == cot_num);
1814  return n->value(type);
1815  }
1816  /// Check if the expression is a number with the specified value.
1817  bool is_const_value(uint64 _v) const
1818  {
1819  return op == cot_num && numval() == _v;
1820  }
1821  /// Check if the expression is a negative number.
1822  bool is_negative_const(void) const
1823  {
1824  return op == cot_num && int64(numval()) < 0;
1825  }
1826  /// Check if the expression is a non-zero number.
1827  bool is_non_zero_const(void) const
1828  {
1829  return op == cot_num && numval() != 0;
1830  }
1831  /// Check if the expression is a zero.
1832  bool is_zero_const(void) const { return is_const_value(0); }
1833  /// Get expression value.
1834  /// \param out Pointer to the variable where the expression value is returned.
1835  /// \return true if the expression is a number.
1836  bool get_const_value(uint64 *out) const
1837  {
1838  if ( op == cot_num )
1839  {
1840  if ( out != NULL )
1841  *out = numval();
1842  return true;
1843  }
1844  return false;
1845  }
1846  /// May the expression be a pointer?
1847  bool maybe_ptr(void) const
1848  {
1849  uint64 val;
1850  if ( get_const_value(&val)
1851  && (ea_t(val) != val || !is_mapped((ea_t)val)) )
1852  {
1853  return false;
1854  }
1855  return true;
1856  }
1857  /// Find pointer or array child.
1859  {
1860  if ( x->type.is_ptr_or_array() )
1861  return x;
1862  if ( y->type.is_ptr_or_array() )
1863  return y;
1864  return NULL;
1865  }
1866  /// Find the child with the specified operator.
1867  const cexpr_t *find_op(ctype_t _op) const
1868  {
1869  if ( x->op == _op )
1870  return x;
1871  if ( y->op == _op )
1872  return y;
1873  return NULL;
1874  }
1875  cexpr_t *find_op(ctype_t _op)
1876  {
1877  return (cexpr_t *)((const cexpr_t *)this)->find_op(_op);
1878  }
1879 
1880  /// Find the operand with a numeric value
1881  const cexpr_t *find_num_op(void) const { return find_op(cot_num); }
1882  cexpr_t *find_num_op(void) { return find_op(cot_num); }
1883  /// Find the pointer operand.
1884  /// This function returns the pointer operand for binary expressions.
1885  const cexpr_t *find_ptr_or_array(bool remove_eqsize_casts) const;
1886  /// Get the other operand.
1887  /// This function returns the other operand (not the specified one)
1888  /// for binary expressions.
1889  const cexpr_t *theother(const cexpr_t *what) const { return what == x ? y : x; }
1890  cexpr_t *theother(const cexpr_t *what) { return what == x ? y : x; }
1891 
1892  // these are inline functions, see below
1893  bool get_1num_op(cexpr_t **o1, cexpr_t **o2);
1894  bool get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const;
1895 
1896 };//-
1897 
1898 /// Statement with an expression.
1899 /// This is a base class for various statements with expressions.
1900 struct ceinsn_t
1901 {
1902  DEFINE_MEMORY_ALLOCATION_FUNCS()
1903  cexpr_t expr; ///< Expression of the statement
1904 };
1905 
1906 /// Should curly braces be printed?
1908 {
1909  CALC_CURLY_BRACES, ///< print curly braces if necessary
1910  NO_CURLY_BRACES, ///< don't print curly braces
1911  USE_CURLY_BRACES, ///< print curly braces without any checks
1912 };
1913 
1914 /// If statement
1915 struct cif_t : public ceinsn_t
1916 {
1917  cinsn_t *ithen; ///< Then-branch of the if-statement
1918  cinsn_t *ielse; ///< Else-branch of the if-statement. May be NULL.
1919  cif_t(void) : ithen(NULL), ielse(NULL) {}
1920  cif_t(const cif_t &r) : ceinsn_t(), ithen(NULL), ielse(NULL) { *this = r; }
1921  cif_t &operator=(const cif_t &r) { return assign(r); }
1922  cif_t &hexapi assign(const cif_t &r);
1924  ~cif_t(void) { cleanup(); }
1925  void cleanup(void);
1926 };
1927 
1928 /// Base class for loop statements
1929 struct cloop_t : public ceinsn_t
1930 {
1931  cinsn_t *body;
1932  cloop_t(void) : body(NULL) {}
1933  cloop_t(cinsn_t *b) : body(b) {}
1934  cloop_t(const cloop_t &r) : ceinsn_t(), body(NULL) { *this = r; }
1935  cloop_t &operator=(const cloop_t &r) { return assign(r); }
1936  cloop_t &hexapi assign(const cloop_t &r);
1937  ~cloop_t(void) { cleanup(); }
1938  void cleanup(void);
1939 };
1940 
1941 /// For-loop
1942 struct cfor_t : public cloop_t
1943 {
1944  cexpr_t init; ///< Initialization expression
1945  cexpr_t step; ///< Step expression
1947 };
1948 
1949 /// While-loop
1950 struct cwhile_t : public cloop_t
1951 {
1953 };
1954 
1955 /// Do-loop
1956 struct cdo_t : public cloop_t
1957 {
1959 };
1960 
1961 /// Return statement
1962 struct creturn_t : public ceinsn_t
1963 {
1965 };
1966 
1967 /// Goto statement
1968 struct cgoto_t
1969 {
1970  int label_num; ///< Target label number
1972  DEFINE_MEMORY_ALLOCATION_FUNCS()
1973  void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
1974 };
1975 
1976 /// asm statement
1977 struct casm_t : public eavec_t
1978 {
1979  casm_t(ea_t ea) { push_back(ea); }
1980  casm_t(const casm_t &r) : eavec_t(eavec_t(r)) {}
1982  void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
1983  bool one_insn(void) const { return size() == 1; }
1984  void genasm(qstring *buf, ea_t ea) const;
1985 };
1986 
1987 /// Vector of pointers to statements.
1988 typedef qvector<cinsn_t *> cinsnptrvec_t;
1989 
1990 /// Ctree element: statement.
1991 /// Depending on the exact statement type, various fields of the union are used.
1992 struct cinsn_t : public citem_t
1993 {
1994  union
1995  {
1996  cblock_t *cblock; ///< details of block-statement
1997  cexpr_t *cexpr; ///< details of expression-statement
1998  cif_t *cif; ///< details of if-statement
1999  cfor_t *cfor; ///< details of for-statement
2000  cwhile_t *cwhile; ///< details of while-statement
2001  cdo_t *cdo; ///< details of do-statement
2002  cswitch_t *cswitch; ///< details of switch-statement
2003  creturn_t *creturn; ///< details of return-statement
2004  cgoto_t *cgoto; ///< details of goto-statement
2005  casm_t *casm; ///< details of asm-statement
2006  };
2007 
2008  cinsn_t(void) : citem_t(cit_empty) {}
2009  cinsn_t(const cinsn_t &r) : citem_t(cit_empty) { *this = r; }
2010  void swap(cinsn_t &r) { citem_t::swap(r); std::swap(cblock, r.cblock); }
2011  cinsn_t &operator=(const cinsn_t &r) { return assign(r); }
2012  cinsn_t &hexapi assign(const cinsn_t &r);
2014  ~cinsn_t(void) { cleanup(); }
2015 
2016  /// Replace the statement.
2017  /// The children of the statement are abandoned (not freed).
2018  /// The statement pointed by 'r' is moved to 'this' statement
2019  /// \param r the source statement. It is deleted after being copied
2020  void hexapi replace_by(cinsn_t *r);
2021 
2022  /// Cleanup the statement.
2023  /// This function properly deletes all children and sets the item type to cit_empty.
2024  void hexapi cleanup(void);
2025 
2026  /// Overwrite with zeroes without cleaning memory or deleting children
2027  void zero(void) { op = cit_empty; cblock = NULL; }
2028 
2029  /// Create a new statement.
2030  /// The current statement must be a block. The new statement will be appended to it.
2031  /// \param insn_ea statement address
2032  cinsn_t &hexapi new_insn(ea_t insn_ea);
2033 
2034  /// Create a new if-statement.
2035  /// The current statement must be a block. The new statement will be appended to it.
2036  /// \param cnd if condition. It will be deleted after being copied.
2037  cif_t &hexapi create_if(cexpr_t *cnd);
2038 
2039  /// Print the statement into many lines.
2040  /// \param indent indention (number of spaces) for the statement
2041  /// \param vp printer helper class which will receive the generated text.
2042  /// \param use_curly if the statement is a block, how should curly braces be printed.
2043  void hexapi print(int indent, vc_printer_t &vp, use_curly_t use_curly=CALC_CURLY_BRACES) const;
2044 
2045  /// Print the statement into one line.
2046  /// Currently this function is not available.
2047  /// \param buf output buffer
2048  /// \param bufsize size of output buffer
2049  /// \param func parent function. This argument is used to find out the referenced variable names.
2050  /// \return length of the generated text.
2051  size_t hexapi print1(char *buf, size_t bufsize, const cfunc_t *func) const;
2052 
2053  /// Check if the statement passes execution to the next statement.
2054  /// \return false if the statement breaks the control flow (like goto, return, etc)
2055  bool hexapi is_ordinary_flow(void) const;
2056 
2057  /// Check if the statement contains a statement of the specified type.
2058  /// \param type statement opcode to look for
2059  /// \param times how many times TYPE should be present
2060  /// \return true if the statement has at least TIMES children with opcode == TYPE
2061  bool hexapi contains_insn(ctype_t type, int times=1) const;
2062 
2063  /// Collect free \c break statements.
2064  /// This function finds all free \c break statements within the current statement.
2065  /// A \c break statement is free if it does not have a loop or switch parent that
2066  /// that is also within the current statement.
2067  /// \param breaks pointer to the variable where the vector of all found free
2068  /// \c break statements is returned. This argument can be NULL.
2069  /// \return true if some free \c break statements have been found
2070  bool hexapi collect_free_breaks(cinsnptrvec_t *breaks);
2071 
2072  /// Collect free \c continue statements.
2073  /// This function finds all free \c continue statements within the current statement.
2074  /// A \c continue statement is free if it does not have a loop parent that
2075  /// that is also within the current statement.
2076  /// \param continues pointer to the variable where the vector of all found free
2077  /// \c continue statements is returned. This argument can be NULL.
2078  /// \return true if some free \c continue statements have been found
2079  bool hexapi collect_free_continues(cinsnptrvec_t *continues);
2080 
2081  /// Check if the statement has free \c break statements.
2082  bool contains_free_break(void) const { return CONST_CAST(cinsn_t*)(this)->collect_free_breaks(NULL); }
2083  /// Check if the statement has free \c continue statements.
2084  bool contains_free_continue(void) const { return CONST_CAST(cinsn_t*)(this)->collect_free_continues(NULL); }
2085 
2086 };//-
2087 
2088 /// Compound statement (curly braces)
2089 struct cblock_t : public qlist<cinsn_t> // we need list to be able to manipulate
2090 { // its elements freely
2092 };
2093 
2094 /// Function argument
2095 struct carg_t : public cexpr_t
2096 {
2097  bool is_vararg; ///< is a vararg (matches ...)
2098  tinfo_t formal_type; ///< formal parameter type (if known)
2099  void consume_cexpr(cexpr_t *e)
2100  {
2101  qswap(*(cexpr_t*)this, *e);
2102  delete e;
2103  }
2104  carg_t(void) : is_vararg(false) {}
2106  {
2107  return cexpr_t::compare(r);
2108  }
2109 };
2110 DECLARE_TYPE_AS_MOVABLE(carg_t);
2111 
2112 /// Function argument list
2113 struct carglist_t : public qvector<carg_t>
2114 {
2115  tinfo_t functype; ///< function object type
2116  carglist_t(void) {}
2117  carglist_t(const tinfo_t &ftype) : functype(ftype) {}
2119  size_t print(char *buf, size_t bufsize, const cfunc_t *func) const;
2120  int print(int curpos, vc_printer_t &vp) const;
2121 };
2122 
2123 /// Switch case. Usually cinsn_t is a block
2124 struct ccase_t : public cinsn_t
2125 {
2126  qvector<uint64> values; ///< List of case values.
2127  ///< if empty, then 'default' case
2129  void print(const cinsn_t *parent, int indent, vc_printer_t &vp) const;
2130  void set_insn(cinsn_t *i); // deletes 'i'
2131  size_t size(void) const { return values.size(); }
2132  const uint64 &value(int i) const { return values[i]; }
2133 };
2134 DECLARE_TYPE_AS_MOVABLE(ccase_t);
2135 
2136 /// Vector of switch cases
2137 struct ccases_t : public qvector<ccase_t>
2138 {
2140  void print(const cinsn_t *parent, int indent, vc_printer_t &vp) const;
2141  int find_value(uint64 v) const;
2142 };
2143 
2144 /// Switch statement
2145 struct cswitch_t : public ceinsn_t
2146 {
2147  cnumber_t mvnf; ///< Maximal switch value and number format
2148  ccases_t cases; ///< Switch cases: values and instructions
2150 };
2151 
2152 //---------------------------------------------------------------------------
2153 /// Invisible COLOR_ADDR tags in the output text are used to refer to ctree items and variables
2155 {
2156  uval_t value;
2157 #define ANCHOR_INDEX 0x1FFFFFFF
2158 #define ANCHOR_MASK 0xC0000000
2159 #define ANCHOR_CITEM 0x00000000 ///< c-tree item
2160 #define ANCHOR_LVAR 0x40000000 ///< declaration of local variable
2161 #define ANCHOR_ITP 0x80000000 ///< item type preciser
2162 #define ANCHOR_BLKCMT 0x20000000 ///< block comment (for ctree items)
2163  ctree_anchor_t(void) : value(BADADDR) {}
2164  int get_index(void) const { return value & ANCHOR_INDEX; }
2165  item_preciser_t get_itp(void) const { return item_preciser_t(value & ~ANCHOR_ITP); }
2166  bool is_valid_anchor(void) const { return value != BADADDR; }
2167  bool is_citem_anchor(void) const { return (value & ANCHOR_MASK) == ANCHOR_CITEM; }
2168  bool is_lvar_anchor(void) const { return (value & ANCHOR_MASK) == ANCHOR_LVAR; }
2169  bool is_itp_anchor(void) const { return (value & ANCHOR_ITP) != 0; }
2170  bool is_blkcmt_anchor(void) const { return (value & ANCHOR_BLKCMT) != 0; }
2171 };
2172 
2173 /// Type of the cursor item.
2175 {
2176  VDI_NONE, ///< undefined
2177  VDI_EXPR, ///< c-tree item
2178  VDI_LVAR, ///< declaration of local variable
2179  VDI_FUNC, ///< the function itself (the very first line with the function prototype)
2180  VDI_TAIL, ///< cursor is at (beyond) the line end (commentable line)
2181 };
2182 
2183 /// Cursor item.
2184 /// Information about the item under the cursor
2186 {
2187  DEFINE_MEMORY_ALLOCATION_FUNCS()
2188  cursor_item_type_t citype; ///< Item type
2189  union
2190  {
2191  citem_t *it;
2192  cexpr_t *e; ///< VDI_EXPR: Expression
2193  cinsn_t *i; ///< VDI_EXPR: Statement
2194  lvar_t *l; ///< VDI_LVAR: Local variable
2195  cfunc_t *f; ///< VDI_FUNC: Function
2196  treeloc_t loc; ///< VDI_TAIL: Line tail
2197  };
2198  void verify(const mbl_array_t *mba) const;
2199 
2200  /// Get pointer to structure member.
2201  /// If the current item is a structure field,
2202  /// this function will return pointer to its definition.
2203  /// \return NULL if failed
2204  /// \param[out] p_sptr pointer to the variable where the pointer to the
2205  /// parent structure is returned. This parameter can be NULL.
2206 
2207  member_t *hexapi get_memptr(struc_t **p_sptr=NULL) const;
2208 
2209  /// Get pointer to local variable.
2210  /// If the current item is a local variable,
2211  /// this function will return pointer to its definition.
2212  /// \return NULL if failed
2213 
2214  lvar_t *hexapi get_lvar(void) const;
2215 
2216 
2217  /// Get address of the current item.
2218  /// Each ctree item has an address.
2219  /// \return BADADDR if failed
2220 
2221  ea_t hexapi get_ea(void) const;
2222 
2223 
2224  /// Get label number of the current item.
2225  /// \param[in] gln_flags Combination of \ref GLN_ bits
2226  /// \return -1 if failed or no label
2227 
2228  int hexapi get_label_num(int gln_flags) const;
2229 /// \defgroup GLN_ get_label_num control
2230 //@{
2231 #define GLN_CURRENT 0x01 ///< get label of the current item
2232 #define GLN_GOTO_TARGET 0x02 ///< get goto target
2233 #define GLN_ALL 0x03 ///< get both
2234 //@}
2235 
2236  /// Is the current item is a ctree item?
2237  bool is_citem(void) const { return citype == VDI_EXPR; }
2238 
2239 };
2240 
2241 /// Unused label disposition.
2243 {
2244  FORBID_UNUSED_LABELS = 0, ///< Unused labels cause interr
2245  ALLOW_UNUSED_LABELS = 1, ///< Unused labels are permitted
2246 };
2247 
2248 typedef std::map<int, qstring> user_labels_t;
2249 
2250 /// Logically negate the specified expression.
2251 /// The specified expression will be logically negated.
2252 /// For example, "x == y" is converted into "x != y" by this function.
2253 /// \param e expression to negate. After the call, e must not be used anymore
2254 /// because it can be changed by the function. The function return value
2255 /// must be used to refer to the expression.
2256 /// \return logically negated expression.
2257 
2258 cexpr_t *hexapi lnot(cexpr_t *e);
2259 
2260 
2261 /// Create a new block-statement.
2262 
2263 cinsn_t *hexapi new_block(void);
2264 
2265 
2266 /// Create a helper object.
2267 /// This function creates a helper object.
2268 /// The named function is not required to exist, the decompiler will only print
2269 /// its name in the output. Helper functions are usually used to represent arbitrary
2270 /// function or macro calls in the output.
2271 /// \param standalone false:helper must be called; true:helper can be used in any expression
2272 /// \param type type of the create function object
2273 /// \param format printf-style format string that will be used to create the function name.
2274 /// \param va additional arguments for printf
2275 /// \return the created expression.
2276 
2277 AS_PRINTF(3, 0) cexpr_t *hexapi vcreate_helper(bool standalone, const tinfo_t &type, const char *format, va_list va);
2278 
2279 /// Create a helper object..
2280 AS_PRINTF(3, 4) inline cexpr_t *create_helper(bool standalone, const tinfo_t &type, const char *format, ...)
2281 {
2282  va_list va;
2283  va_start(va, format);
2284  cexpr_t *e = vcreate_helper(standalone, type, format, va);
2285  va_end(va);
2286  return e;
2287 }
2288 
2289 
2290 /// Create a helper call expression.
2291 /// This function creates a new expression: a call of a helper function.
2292 /// \param rettype type of the whole expression.
2293 /// \param args helper arguments. this object will be consumed by the function.
2294 /// if there are no args, this parameter may be specified as NULL.
2295 /// \param format printf-style format string that will be used to create the function name.
2296 /// \param va additional arguments for printf
2297 /// \return the created expression.
2298 
2299 AS_PRINTF(3, 0) cexpr_t *hexapi vcall_helper(const tinfo_t &rettype, carglist_t *args, const char *format, va_list va);
2300 
2301 /// Create a helper call.
2302 AS_PRINTF(3, 4) inline cexpr_t *call_helper(
2303  const tinfo_t &rettype,
2304  carglist_t *args,
2305  const char *format, ...)
2306 {
2307  va_list va;
2308  va_start(va, format);
2309  cexpr_t *e = vcall_helper(rettype, args, format, va);
2310  va_end(va);
2311  return e;
2312 }
2313 
2314 
2315 /// Create a number expression
2316 /// \param n value
2317 /// \param func current function
2318 /// \param ea definition address of the number
2319 /// \param opnum operand number of the number (in the disassembly listing)
2320 /// \param sign number sign
2321 /// \param size size of number in bytes
2322 
2323 cexpr_t *hexapi make_num(uint64 n, cfunc_t *func=NULL, ea_t ea=BADADDR, int opnum=0, type_sign_t sign=no_sign, int size=0);
2324 
2325 
2326 /// Create a reference.
2327 /// This function performs the following conversion: "obj" => "&obj".
2328 /// It can handle casts, annihilate "&*", and process other special cases.
2329 
2331 
2332 
2333 /// Dereference a pointer.
2334 /// This function dereferences a pointer expression.
2335 /// It performs the following conversion: "ptr" => "*ptr"
2336 /// It can handle discrepancies in the pointer type and the access size.
2337 /// \param e expression to deference
2338 /// \param ptrsize access size
2339 /// \param is_flt dereferencing for floating point access?
2340 /// \return dereferenced expression
2341 
2342 cexpr_t *hexapi dereference(cexpr_t *e, int ptrsize, bool is_flt=false);
2343 
2344 
2345 /// Save user defined labels into the database.
2346 /// \param func_ea the entry address of the function
2347 /// \param user_labels collection of user defined labels
2348 
2349 void hexapi save_user_labels(ea_t func_ea, const user_labels_t *user_labels);
2350 
2351 
2352 /// Save user defined comments into the database.
2353 /// \param func_ea the entry address of the function
2354 /// \param user_cmts collection of user defined comments
2355 
2356 void hexapi save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts);
2357 
2358 /// Save user defined number formats into the database.
2359 /// \param func_ea the entry address of the function
2360 /// \param numforms collection of user defined comments
2361 
2362 void hexapi save_user_numforms(ea_t func_ea, const user_numforms_t *numforms);
2363 
2364 
2365 /// Save user defined citem iflags into the database.
2366 /// \param func_ea the entry address of the function
2367 /// \param iflags collection of user defined citem iflags
2368 
2369 void hexapi save_user_iflags(ea_t func_ea, const user_iflags_t *iflags);
2370 
2371 
2372 /// Save user defined union field selections into the database.
2373 /// \param func_ea the entry address of the function
2374 /// \param unions collection of union field selections
2375 
2376 void hexapi save_user_unions(ea_t func_ea, const user_unions_t *unions);
2377 
2378 
2379 /// Restore user defined labels from the database.
2380 /// \param func_ea the entry address of the function
2381 /// \return collection of user defined labels.
2382 /// The returned object must be deleted by the caller using delete_user_labels()
2383 
2384 user_labels_t *hexapi restore_user_labels(ea_t func_ea);
2385 
2386 
2387 /// Restore user defined comments from the database.
2388 /// \param func_ea the entry address of the function
2389 /// \return collection of user defined comments.
2390 /// The returned object must be deleted by the caller using delete_user_cmts()
2391 
2392 user_cmts_t *hexapi restore_user_cmts(ea_t func_ea);
2393 
2394 
2395 /// Restore user defined number formats from the database.
2396 /// \param func_ea the entry address of the function
2397 /// \return collection of user defined number formats.
2398 /// The returned object must be deleted by the caller using delete_user_numforms()
2399 
2400 user_numforms_t *hexapi restore_user_numforms(ea_t func_ea);
2401 
2402 
2403 /// Restore user defined citem iflags from the database.
2404 /// \param func_ea the entry address of the function
2405 /// \return collection of user defined iflags.
2406 /// The returned object must be deleted by the caller using delete_user_iflags()
2407 
2408 user_iflags_t *hexapi restore_user_iflags(ea_t func_ea);
2409 
2410 
2411 /// Restore user defined union field selections from the database.
2412 /// \param func_ea the entry address of the function
2413 /// \return collection of union field selections
2414 /// The returned object must be deleted by the caller using delete_user_unions()
2415 
2416 user_unions_t *hexapi restore_user_unions(ea_t func_ea);
2417 
2418 
2419 typedef std::map<ea_t, cinsnptrvec_t> eamap_t;
2420 // map of instruction boundaries. may contain INS_EPILOG for the epilog instructions
2421 typedef std::map<cinsn_t *, rangeset_t> boundaries_t;
2422 #define INS_EPILOG ((cinsn_t *)1)
2423 // Tags to find this location quickly: #cfunc_t #func_t
2424 //-------------------------------------------------------------------------
2425 /// Decompiled function. Decompilation result is kept here.
2426 struct cfunc_t
2427 {
2428  ea_t entry_ea; ///< function entry address
2429  mbl_array_t *mba; ///< underlying microcode
2430  cinsn_t body; ///< function body, must be a block
2431  intseq_t &argidx; ///< list of arguments (indexes into vars)
2432  ctree_maturity_t maturity; ///< maturity level
2433  // The following maps must be accessed using helper functions.
2434  // Example: for user_labels_t, see functions starting with "user_labels_".
2435  user_labels_t *user_labels;///< user-defined labels.
2436  user_cmts_t *user_cmts; ///< user-defined comments.
2437  user_numforms_t *numforms; ///< user-defined number formats.
2438  user_iflags_t *user_iflags;///< user-defined item flags \ref CIT_
2439  user_unions_t *user_unions;///< user-defined union field selections.
2440 /// \defgroup CIT_ ctree item iflags bits
2441 //@{
2442 #define CIT_COLLAPSED 0x0001 ///< display element in collapsed form
2443 //@}
2444  int refcnt; ///< reference count to this object. use cfuncptr_t
2445  int statebits; ///< current cfunc_t state. see \ref CFS_
2446 /// \defgroup CFS_ cfunc state bits
2447 #define CFS_BOUNDS 0x0001 ///< 'eamap' and 'boundaries' are ready
2448 #define CFS_TEXT 0x0002 ///< 'sv' is ready (and hdrlines)
2449 #define CFS_LVARS_HIDDEN 0x0004 ///< local variable definitions are collapsed
2450  eamap_t *eamap; ///< ea->insn map. use \ref get_eamap
2451  boundaries_t *boundaries; ///< map of instruction boundaries. use \ref get_boundaries
2452  strvec_t sv; ///< decompilation output: function text. use \ref get_pseudocode
2453  int hdrlines; ///< number of lines in the declaration area
2454  mutable ctree_items_t treeitems; ///< vector of ctree items
2455 
2456 public:
2457  cfunc_t(mbl_array_t *mba);
2458  ~cfunc_t(void) { cleanup(); }
2459  void release(void) { delete this; }
2460  DEFINE_MEMORY_ALLOCATION_FUNCS()
2461 
2462  /// Generate the function body.
2463  /// This function (re)generates the function body from the underlying microcode.
2464  void hexapi build_c_tree(void);
2465 
2466  /// Verify the ctree.
2467  /// This function verifies the ctree. If the ctree is malformed, an internal error
2468  /// is generated. Use it to verify the ctree after your modifications.
2469  /// \param aul Are unused labels acceptable?
2470  /// \param even_without_debugger if false and there is no debugger, the verification will be skipped
2471  void hexapi verify(allow_unused_labels_t aul, bool even_without_debugger) const;
2472 
2473  /// Print function prototype.
2474  /// \param buf output buffer
2475  /// \param bufsize size of the output buffer
2476  /// \return length of the generated text
2477  size_t hexapi print_dcl(char *buf, int bufsize) const;
2478  size_t hexapi print_dcl2(qstring *out) const;
2479 
2480  /// Print function text.
2481  /// \param vp printer helper class to receive the generated text.
2482  void hexapi print_func(vc_printer_t &vp) const;
2483 
2484  /// Get the function type.
2485  /// \param type variable where the function type is returned
2486  /// \return false if failure
2487  bool hexapi get_func_type(tinfo_t *type) const;
2488 
2489  /// Get vector of local variables.
2490  /// \return pointer to the vector of local variables. If you modify this vector,
2491  /// the ctree must be regenerated in order to have correct cast operators.
2492  /// Use build_c_tree() for that.
2493  /// Removing lvars should be done carefully: all references in ctree
2494  /// and microcode must be corrected after that.
2495  lvars_t *hexapi get_lvars(void);
2496 
2497  /// Get stack offset delta.
2498  /// The local variable stack offsets retreived by v.location.stkoff()
2499  /// should be adjusted before being used as stack frame offsets in IDA.
2500  /// \return the delta to apply.
2501  /// example: ida_stkoff = v.location.stkoff() - f->get_stkoff_delta()
2502  sval_t hexapi get_stkoff_delta(void);
2503 
2504  /// Find the label.
2505  /// \return pointer to the ctree item with the specified label number.
2506  citem_t *hexapi find_label(int label);
2507 
2508  /// Remove unused labels.
2509  /// This function check what labels are really used by the function and
2510  /// removes the unused ones.
2511  void hexapi remove_unused_labels(void);
2512 
2513  /// Retrieve a user defined comment.
2514  /// \param loc ctree location
2515  /// \param rt should already retrieved comments retrieved again?
2516  /// \return pointer to the comment string or NULL
2517  const char *hexapi get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const;
2518 
2519  /// Set a user defined comment.
2520  /// This function stores the specified comment in the cfunc_t structure.
2521  /// The save_user_cmts() function must be called after it.
2522  /// \param loc ctree location
2523  /// \param cmt new comment. if empty or NULL, then an existing comment is deleted.
2524  void hexapi set_user_cmt(const treeloc_t &loc, const char *cmt);
2525 
2526  /// Retrieve citem iflags.
2527  /// \param loc citem locator
2528  /// \return \ref CIT_ or 0
2529  int32 hexapi get_user_iflags(const citem_locator_t &loc) const;
2530 
2531  /// Set citem iflags.
2532  /// \param loc citem locator
2533  /// \param iflags new iflags
2534  void hexapi set_user_iflags(const citem_locator_t &loc, int32 iflags);
2535 
2536  /// Check if there are orphan comments.
2537  bool hexapi has_orphan_cmts(void) const;
2538 
2539  /// Delete all orphan comments.
2540  /// The save_user_cmts() function must be called after this call.
2541  int hexapi del_orphan_cmts(void);
2542 
2543  /// Retrieve a user defined union field selection.
2544  /// \param ea address
2545  /// \param path out: path describing the union selection.
2546  /// \return pointer to the path or NULL
2547  bool hexapi get_user_union_selection(ea_t ea, intvec_t *path);
2548 
2549  /// Set a union field selection.
2550  /// The save_user_unions() function must be called after calling this function.
2551  /// \param ea address
2552  /// \param path in: path describing the union selection.
2553  void hexapi set_user_union_selection(ea_t ea, const intvec_t &path);
2554 
2555  /// Save user-defined labels into the database
2556  void save_user_labels(void) const { ::save_user_labels(entry_ea, user_labels); }
2557  /// Save user-defined comments into the database
2558  void save_user_cmts(void) const { ::save_user_cmts(entry_ea, user_cmts); }
2559  /// Save user-defined number formats into the database
2560  void save_user_numforms(void) const { ::save_user_numforms(entry_ea, numforms); }
2561  /// Save user-defined iflags into the database
2562  void save_user_iflags(void) const { ::save_user_iflags(entry_ea, user_iflags); }
2563  /// Save user-defined union field selections into the database
2564  void save_user_unions(void) const { ::save_user_unions(entry_ea, user_unions); }
2565 
2566  /// Get ctree item for the specified cursor position.
2567  /// \return false if failed to get the current item
2568  /// \param line line of decompilation text (element of \ref sv)
2569  /// \param x x cursor coordinate in the line
2570  /// \param is_ctree_line does the line belong to statement area? (if not, it is assumed to belong to the declaration area)
2571  /// \param phead ptr to the first item on the line (used to attach block comments). May be NULL
2572  /// \param pitem ptr to the current item. May be NULL
2573  /// \param ptail ptr to the last item on the line (used to attach indented comments). May be NULL
2574  /// \sa vdui_t::get_current_item()
2575  bool hexapi get_line_item(const char *line, int x, bool is_ctree_line, ctree_item_t *phead, ctree_item_t *pitem, ctree_item_t *ptail);
2576 
2577  /// Get information about decompilation warnings.
2578  /// \return reference to the vector of warnings
2579  hexwarns_t &hexapi get_warnings(void);
2580 
2581  /// Get pointer to ea->insn map.
2582  /// This function initializes eamap if not done yet.
2583  eamap_t &hexapi get_eamap(void);
2584 
2585  /// Get pointer to map of instruction boundaries.
2586  /// This function initializes the boundary map if not done yet.
2587  boundaries_t &hexapi get_boundaries(void);
2588 
2589  /// Get pointer to decompilation output: the pseudocode.
2590  /// This function generates pseudocode if not done yet.
2591  strvec_t &hexapi get_pseudocode(void);
2592 
2593  bool hexapi gather_derefs(const ctree_item_t &ci, udt_type_data_t *udm=NULL) const;
2594 private:
2595  /// Cleanup.
2596  /// Properly delete all children and free memory.
2597  void hexapi cleanup(void);
2598  DECLARE_UNCOPYABLE(cfunc_t)
2599 };
2600 typedef qrefcnt_t<cfunc_t> cfuncptr_t;
2601 
2602 
2603 /// Decompile a function.
2604 /// Multiple decompilations of the same function return the same object.
2605 /// \param pfn pointer to function to decompile
2606 /// \param hf extended error information (if failed)
2607 /// \return pointer to the decompilation result (a reference counted pointer).
2608 /// NULL if failed.
2609 
2610 cfuncptr_t hexapi decompile(func_t *pfn, hexrays_failure_t *hf);
2611 
2612 
2613 /// Flush the cached decompilation results.
2614 /// Erases a cache entry for the specified function.
2615 /// \param ea function to erase from the cache
2616 /// \return if a cache entry existed.
2617 
2618 bool hexapi mark_cfunc_dirty(ea_t ea);
2619 
2620 
2621 /// Flush all cached decompilation results.
2622 
2623 void hexapi clear_cached_cfuncs(void);
2624 
2625 
2626 /// Do we have a cached decompilation result for 'ea'?
2627 
2628 bool hexapi has_cached_cfunc(ea_t ea);
2629 
2630 //--------------------------------------------------------------------------
2631 // Now cinsn_t class is defined, define the cleanup functions:
2632 inline void cif_t::cleanup(void) { delete ithen; delete ielse; }
2633 inline void cloop_t::cleanup(void) { delete body; }
2634 
2635 /// Print item into one line.
2636 /// \param buf output buffer
2637 /// \param bufsize size of the output buffer
2638 /// \param func parent function. This argument is used to find out the referenced variable names.
2639 /// \return length of the generated text.
2640 
2641 inline size_t citem_t::print1(char *buf, size_t bufsize, const cfunc_t *func) const
2642 {
2643  if ( is_expr() )
2644  return ((cexpr_t*)this)->print1(buf, bufsize, func);
2645  else
2646  return ((cinsn_t*)this)->print1(buf, bufsize, func);
2647 }
2648 
2649 /// Get pointers to operands. at last one operand should be a number
2650 /// o1 will be pointer to the number
2651 
2652 inline bool cexpr_t::get_1num_op(cexpr_t **o1, cexpr_t **o2)
2653 {
2654  if ( x->op == cot_num )
2655  {
2656  *o1 = x;
2657  *o2 = y;
2658  }
2659  else
2660  {
2661  if ( y->op != cot_num )
2662  return false;
2663  *o1 = y;
2664  *o2 = x;
2665  }
2666  return true;
2667 }
2668 
2669 inline bool cexpr_t::get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const
2670 {
2671  return CONST_CAST(cexpr_t*)(this)->get_1num_op(
2672  CONST_CAST(cexpr_t**)(o1),
2673  CONST_CAST(cexpr_t**)(o2));
2674 }
2675 
2676 inline citem_locator_t::citem_locator_t(const citem_t *i) : ea(i->ea), op(i->op)
2677 {
2678 }
2679 
2680 const char *hexapi get_ctype_name(ctype_t op);
2681 qstring hexapi create_field_name(const tinfo_t &type, uval_t offset=BADADDR);
2682 typedef void *hexdsp_t(int code, ...);
2683 const int64 HEXRAYS_API_MAGIC = 0x00DEC0DE00000001LL;
2684 
2685 /// Decompiler events.
2686 /// Use install_hexrays_callback() to install a handler for decompiler events.
2687 /// When the possible return value is not specified, your callback
2688 /// must return zero.
2690 {
2691  // When a function is decompiled, the following events occur:
2692 
2693  hxe_flowchart, ///< Flowchart has been generated.
2694  ///< qflow_chart_t *fc
2695 
2696  hxe_prolog, ///< Prolog analysis has been finished.
2697  ///< mbl_array_t *mba \n
2698  ///< qflow_chart_t *fc \n
2699  ///< bitset_t *reachable_blocks
2700 
2701  hxe_preoptimized, ///< Microcode has been preoptimized.
2702  ///< mbl_array_t *mba
2703 
2704  hxe_locopt, ///< Basic block level optimization has been finished.
2705  ///< mbl_array_t *mba
2706 
2707  hxe_prealloc, ///< Local variables: preallocation step begins. \n
2708  ///< mbl_array_t *mba \n
2709  ///< This event may occur several times \n
2710  ///< Should return: 1 if modified microcode \n
2711  ///< Negative values are \ref MERR_ error codes
2712 
2713  hxe_glbopt, ///< Global optimization has been finished.
2714  ///< mbl_array_t *mba
2715 
2716  hxe_structural, ///< Structural analysis has been finished.
2717  ///< control_graph_t *ct
2718 
2719  hxe_maturity, ///< Ctree maturity level is being changed.
2720  ///< cfunc_t *cfunc \n
2721  ///< ctree_maturity_t new_maturity
2722 
2723  hxe_interr, ///< Internal error has occurred.
2724  ///< int errcode
2725 
2726  hxe_combine, ///< Trying to combine instructions of basic block.
2727  ///< mblock_t *blk \n
2728  ///< minsn_t *insn \n
2729  ///< Should return: 1 if combined the current instruction
2730  ///< with a preceding one
2731 
2732  hxe_print_func, ///< Printing ctree and generating text.
2733  ///< cfunc_t *cfunc \n
2734  ///< vc_printer_t *vp \n
2735  ///< Returns: 1 if text has been generated by the plugin
2736 
2737  hxe_func_printed, ///< Function text has been generated. Plugins may
2738  ///< modify the text in \ref cfunc_t::sv.
2739  ///< cfunc_t *cfunc
2740 
2741  hxe_resolve_stkaddrs, ///< The optimizer is about to resolve stack addresses.
2742  ///< mbl_array_t *mba
2743 
2744  // User interface related events:
2745 
2747  ///< New pseudocode view has been opened.
2748  ///< vdui_t *vu
2749 
2750  hxe_switch_pseudocode,///< Existing pseudocode view has been reloaded
2751  ///< with a new function. Its text has not been
2752  ///< refreshed yet, only cfunc and mba pointers are ready.\n
2753  ///< vdui_t *vu
2754 
2755  hxe_refresh_pseudocode,///< Existing pseudocode text has been refreshed.
2756  ///< Adding/removing pseudocode lines is forbidden in this event.
2757  ///< This event is obsolete, please use \ref hxe_func_printed.
2758  ///< vdui_t *vu \n
2759  ///< See also hxe_text_ready, which happens earlier
2760 
2761  hxe_close_pseudocode, ///< Pseudocode view is being closed.
2762  ///< vdui_t *vu
2763 
2764  hxe_keyboard, ///< Keyboard has been hit.
2765  ///< vdui_t *vu \n
2766  ///< int key_code (VK_...) \n
2767  ///< int shift_state \n
2768  ///< Should return: 1 if the event has been handled
2769 
2770  hxe_right_click, ///< Mouse right click.
2771  ///< Use hxe_populating_popup instead, in case you
2772  ///< want to add items in the popup menu.
2773  ///< vdui_t *vu
2774 
2775  hxe_double_click, ///< Mouse double click.
2776  ///< vdui_t *vu \n
2777  ///< int shift_state \n
2778  ///< Should return: 1 if the event has been handled
2779 
2780  hxe_curpos, ///< Current cursor position has been changed.
2781  ///< (for example, by left-clicking or using keyboard)\n
2782  ///< vdui_t *vu
2783 
2784  hxe_create_hint, ///< Create a hint for the current item.
2785  ///< vdui_t *vu \n
2786  ///< qstring *result_hint \n
2787  ///< int *implines \n
2788  ///< Possible return values: \n
2789  ///< 0: the event has not been handled \n
2790  ///< 1: hint has been created (should set *implines to nonzero as well)\n
2791  ///< 2: hint has been created but the standard hints must be
2792  ///< appended by the decompiler
2793 
2794  hxe_text_ready, ///< Decompiled text is ready.
2795  ///< vdui_t *vu \n
2796  ///< This event can be used to modify the output text (sv).
2797  ///< The text uses regular color codes (see lines.hpp)
2798  ///< COLOR_ADDR is used to store pointers to ctree elements
2799 
2800  hxe_populating_popup, ///< Populating popup menu. We can add menu items now.
2801  ///< TWidget *widget
2802  ///< TPopupMenu *popup_handle
2803  ///< vdui_t *vu
2804 };
2805 
2806 /// Handler of decompiler events.
2807 /// \param ud user data. the value specified at the handler installation time
2808 /// is passed here.
2809 /// \param event decompiler event code
2810 /// \param va additional arguments
2811 /// \return as a rule the callback must return 0 unless specified otherise in the
2812 /// event description.
2813 
2814 typedef int idaapi hexrays_cb_t(void *ud, hexrays_event_t event, va_list va);
2815 
2816 
2817 /// Install handler for decompiler events.
2818 /// \param callback handler to install
2819 /// \param ud user data. this pointer will be passed to your handler by the decompiler.
2820 /// \return false if failed
2821 
2822 bool hexapi install_hexrays_callback(hexrays_cb_t *callback, void *ud);
2823 
2824 /// Uninstall handler for decompiler events.
2825 /// \param callback handler to uninstall
2826 /// \param ud user data. if NULL, all handler corresponding to \c callback is uninstalled.
2827 /// if not NULL, only the callback instance with the specified \c ud value is uninstalled.
2828 /// \return number of uninstalled handlers.
2829 
2830 int hexapi remove_hexrays_callback(hexrays_cb_t *callback, void *ud);
2831 
2832 
2833 
2834 //---------------------------------------------------------------------------
2835 /// \defgroup vdui User interface definitions
2836 //@{
2837 
2838 /// Type of the input device.
2839 /// How the user command has been invoked
2841 {
2842  USE_KEYBOARD = 0, ///< Keyboard
2843  USE_MOUSE = 1, ///< Mouse
2844 };
2845 //@}
2846 
2847 //---------------------------------------------------------------------------
2848 /// Cursor position in the output text (pseudocode).
2850 {
2851  int lnnum; ///< Line number
2852  int x; ///< x coordinate of the cursor within the window
2853  int y; ///< y coordinate of the cursor within the window
2854  /// Is the cursor in the variable/type declaration area?
2855  /// \param hdrlines Number of lines of the declaration area
2856  bool in_ctree(int hdrlines) const { return lnnum >= hdrlines; }
2857  /// Comparison operators
2859  {
2860  if ( lnnum < r.lnnum ) return -1;
2861  if ( lnnum > r.lnnum ) return 1;
2862  if ( x < r.x ) return -1;
2863  if ( x > r.x ) return 1;
2864  return 0;
2865  }
2866 };
2867 
2868 /// Navigation history item.
2869 /// Holds information about interactive decompilation history.
2870 /// Currently this is not saved in the database.
2872 {
2873  ea_t ea; ///< The entry address of the decompiled function
2874 };
2875 
2876 /// Navigation history.
2877 typedef qstack<history_item_t> history_t;
2878 
2879 /// Comment types
2880 typedef int cmt_type_t;
2881 const cmt_type_t
2882  CMT_NONE = 0x0000, ///< No comment is possible
2883  CMT_TAIL = 0x0001, ///< Indented comment
2884  CMT_BLOCK1 = 0x0002, ///< Anterioir block comment
2885  CMT_BLOCK2 = 0x0004, ///< Posterior block comment
2886  CMT_LVAR = 0x0008, ///< Local variable comment
2887  CMT_FUNC = 0x0010, ///< Function comment
2888  CMT_ALL = 0x001F; ///< All comments
2889 
2890 //---------------------------------------------------------------------------
2891 /// Information about pseudocode window
2892 struct vdui_t
2893 {
2894  int flags; ///< \ref VDUI_
2895 /// \defgroup VDUI_ Properties of pseudocode window
2896 /// Used in vdui_t::flags
2897 //@{
2898 #define VDUI_VISIBLE 0x0001 ///< is visible?
2899 #define VDUI_VALID 0x0002 ///< is valid?
2900 #define VDUI_LOCKED 0x0004 ///< is locked?
2901 //@}
2902 
2903  /// Is the pseudocode window visible?
2904  /// if not, it might be invisible or destroyed
2905  bool visible(void) const { return (flags & VDUI_VISIBLE) != 0; }
2906  /// Does the pseudocode window contain valid code?
2907  /// It can become invalid if the function type gets changed in IDA.
2908  bool valid(void) const { return (flags & VDUI_VALID) != 0; }
2909  /// Does the pseudocode window contain valid code?
2910  /// We lock windows before modifying them
2911  bool locked(void) const { return (flags & VDUI_LOCKED) != 0; }
2912  void set_visible(bool v) { setflag(flags, VDUI_VISIBLE, v); }
2913  void set_valid(bool v) { setflag(flags, VDUI_VALID, v); }
2914  void set_locked(bool v) { setflag(flags, VDUI_LOCKED, v); }
2915 
2916  int view_idx; ///< pseudocode window index (0..)
2917  TWidget *ct; ///< pseudocode view
2918  TWidget *toplevel;
2919 
2920  mbl_array_t *mba; ///< pointer to underlying microcode
2921  cfuncptr_t cfunc; ///< pointer to function object
2922  int last_code; ///< result of the last micro_request(). See \ref MERR_
2923 
2924  // The folloing fields are valid after get_current_item():
2925  ctext_position_t cpos; ///< Current ctext position
2926  ctree_item_t head; ///< First ctree item on the current line (for block comments)
2927  ctree_item_t item; ///< Current ctree item
2928  ctree_item_t tail; ///< Tail ctree item on the current line (for indented comments)
2929 
2930  vdui_t(void); // do not create your own vdui_t objects
2931 
2932  /// Refresh pseudocode window.
2933  /// This is the highest level refresh function.
2934  /// It causes the most profound refresh possible and can lead to redecompilation
2935  /// of the current function. Please consider using refresh_ctext()
2936  /// if you need a more superficial refresh.
2937  /// \param redo_mba true means to redecompile the current function\n
2938  /// false means to rebuild ctree without regenerating microcode
2939  /// \sa refresh_ctext()
2940  void __fastcall hexapi refresh_view(bool redo_mba);
2941 
2942  /// Refresh pseudocode window.
2943  /// This function refreshes the pseudocode window by regenerating its text
2944  /// from cfunc_t. Use it after modifying cfunc_t from a plugin.
2945  /// \sa refresh_view()
2946  void __fastcall hexapi refresh_ctext(bool activate=true);
2947 
2948  /// Display the specified pseudocode.
2949  /// This function replaces the pseudocode window contents with the
2950  /// specified cfunc_t.
2951  /// \param f pointer to the function to display.
2952  /// \param activate should the pseudocode window get focus?
2953  void hexapi switch_to(cfuncptr_t f, bool activate);
2954 
2955  /// Is the current item a statement?
2956  //// \return false if the cursor is in the local variable/type declaration area\n
2957  /// true if the cursor is in the statement area
2958  bool in_ctree(void) const { return cpos.in_ctree(cfunc->hdrlines); }
2959 
2960  /// Get current number.
2961  /// If the current item is a number, return pointer to it.
2962  /// \return NULL if the current item is not a number
2963  cnumber_t *__fastcall hexapi get_number(void);
2964 
2965  /// Get current label.
2966  /// If there is a label under the cursor, return its number.
2967  /// \return -1 if there is no label under the cursor.
2968  /// prereq: get_current_item() has been called
2969  int __fastcall hexapi get_current_label(void);
2970 
2971  /// Clear the pseudocode window.
2972  /// It deletes the current function and microcode.
2973  void __fastcall hexapi clear(void);
2974 
2975  /// Refresh the current position.
2976  /// This function refreshes the \ref cpos field.
2977  /// \return false if failed
2978  /// \param idv keyboard or mouse
2979  bool __fastcall hexapi refresh_cpos(input_device_t idv);
2980 
2981  /// Get current item.
2982  /// This function refreshes the \ref cpos, \ref item, \ref tail fields.
2983  /// \return false if failed
2984  /// \param idv keyboard or mouse
2985  /// \sa cfunc_t::get_line_item()
2986  bool __fastcall hexapi get_current_item(input_device_t idv);
2987 
2988  /// Rename local variable.
2989  /// This function displays a dialog box and allows the user to rename a local variable.
2990  /// \return false if failed or cancelled
2991  /// \param v pointer to local variable
2992  bool __fastcall hexapi ui_rename_lvar(lvar_t *v);
2993 
2994  /// Rename local variable.
2995  /// This function permanently renames a local variable.
2996  /// \return false if failed
2997  /// \param v pointer to local variable
2998  /// \param name new variable name
2999  /// \param is_user_name use true to save the new name into the database
3000  bool __fastcall hexapi rename_lvar(lvar_t *v, const char *name, bool is_user_name);
3001 
3002  /// Set local variable type.
3003  /// This function displays a dialog box and allows the user to change
3004  /// the type of a local variable.
3005  /// \return false if failed or cancelled
3006  /// \param v pointer to local variable
3007  bool __fastcall hexapi ui_set_lvar_type(lvar_t *v);
3008 
3009  /// Set local variable type.
3010  /// This function permanently sets a local variable type.
3011  /// \return false if failed
3012  /// \param v pointer to local variable
3013  /// \param type new variable type
3014  bool __fastcall hexapi set_lvar_type(lvar_t *v, const tinfo_t &type);
3015 
3016  /// Set local variable comment.
3017  /// This function displays a dialog box and allows the user to edit
3018  /// the comment of a local variable.
3019  /// \return false if failed or cancelled
3020  /// \param v pointer to local variable
3021  bool __fastcall hexapi ui_edit_lvar_cmt(lvar_t *v);
3022 
3023  /// Set local variable comment.
3024  /// This function permanently sets a variable comment.
3025  /// \return false if failed
3026  /// \param v pointer to local variable
3027  /// \param cmt new comment
3028  bool __fastcall hexapi set_lvar_cmt(lvar_t *v, const char *cmt);
3029 
3030  /// Map a local variable to another.
3031  /// This function displays a variable list and allows the user to select mapping.
3032  /// \return false if failed or cancelled
3033  /// \param v pointer to local variable
3034  bool __fastcall hexapi ui_map_lvar(lvar_t *v);
3035 
3036  /// Unmap a local variable.
3037  /// This function displays list of variables mapped to the specified variable
3038  /// and allows the user to select a variable to unmap.
3039  /// \return false if failed or cancelled
3040  /// \param v pointer to local variable
3041  bool __fastcall hexapi ui_unmap_lvar(lvar_t *v);
3042 
3043  /// Map a local variable to another.
3044  /// This function permanently maps one lvar to another.
3045  /// All occurrences of the mapped variable are replaced by the new variable
3046  /// \return false if failed
3047  /// \param from the variable being mapped
3048  /// \param to the variable to map to. if NULL, unmaps the variable
3049  bool __fastcall hexapi map_lvar(lvar_t *from, lvar_t *to);
3050 
3051  /// Set structure field type.
3052  /// This function displays a dialog box and allows the user to change
3053  /// the type of a structure field.
3054  /// \return false if failed or cancelled
3055  /// \param sptr pointer to structure
3056  /// \param mptr pointer to structure member
3057  bool __fastcall hexapi set_strmem_type(struc_t *sptr, member_t *mptr);
3058 
3059  /// Rename structure field.
3060  /// This function displays a dialog box and allows the user to rename
3061  /// a structure field.
3062  /// \return false if failed or cancelled
3063  /// \param sptr pointer to structure
3064  /// \param mptr pointer to structure member
3065  bool __fastcall hexapi rename_strmem(struc_t *sptr, member_t *mptr);
3066 
3067  /// Set global item type.
3068  /// This function displays a dialog box and allows the user to change
3069  /// the type of a global item (data or function).
3070  /// \return false if failed or cancelled
3071  /// \param ea address of the global item
3072  bool __fastcall hexapi set_global_type(ea_t ea);
3073 
3074  /// Rename global item.
3075  /// This function displays a dialog box and allows the user to rename
3076  /// a global item (data or function).
3077  /// \return false if failed or cancelled
3078  /// \param ea address of the global item
3079  bool __fastcall hexapi rename_global(ea_t ea);
3080 
3081  /// Rename a label.
3082  /// This function displays a dialog box and allows the user to rename
3083  /// a statement label.
3084  /// \return false if failed or cancelled
3085  /// \param label label number
3086  bool __fastcall hexapi rename_label(int label);
3087 
3088  /// Process the Enter key.
3089  /// This function jumps to the definition of the item under the cursor.
3090  /// If the current item is a function, it will be decompiled.
3091  /// If the current item is a global data, its disassemly text will be displayed.
3092  /// \return false if failed
3093  /// \param idv what cursor must be used, the keyboard or the mouse
3094  /// \param omflags OM_NEWWIN: new pseudocode window will open, 0: reuse the existing window
3095  bool __fastcall hexapi jump_enter(input_device_t idv, int omflags);
3096 
3097  /// Jump to disassembly.
3098  /// This function jumps to the address in the disassembly window
3099  /// which corresponds to the current item. The current item is determined
3100  /// based on the current keyboard cursor position.
3101  /// \return false if failed
3102  bool __fastcall hexapi ctree_to_disasm(void);
3103 
3104  /// Check if the specified line can have a comment.
3105  /// Due to the coordinate system for comments
3106  /// (http://hexblog.com/2007/08/coordinate_system_for_hexrays.html)
3107  /// some function lines can not have comments. This function checks if a comment
3108  /// can be attached to the specified line
3109  /// \return possible comment types
3110  /// \param lnnum line number (0 based)
3111  /// \param cmttype comment types to check
3112  cmt_type_t __fastcall hexapi calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const;
3113 
3114  /// Edit an indented comment.
3115  /// This function displays a dialog box and allows the user to edit
3116  /// the comment for the specified ctree location.
3117  /// \return false if failed or cancelled
3118  /// \param loc comment location
3119  bool __fastcall hexapi edit_cmt(const treeloc_t &loc);
3120 
3121  /// Edit a function comment.
3122  /// This function displays a dialog box and allows the user to edit
3123  /// the function comment.
3124  /// \return false if failed or cancelled
3125  bool __fastcall hexapi edit_func_cmt(void);
3126 
3127  /// Delete all orphan comments.
3128  /// Delete all orphan comments and refresh the screen.
3129  /// \return true
3130  bool __fastcall hexapi del_orphan_cmts(void);
3131 
3132  /// Change number base.
3133  /// This function changes the current number representation.
3134  /// \return false if failed
3135  /// \param base number radix (10 or 16)\n
3136  /// 0 means a character constant
3137  bool __fastcall hexapi set_num_radix(int base);
3138 
3139  /// Convert number to symbolic constant.
3140  /// This function displays a dialog box and allows the user to select
3141  /// a symbolic constant to represent the number.
3142  /// \return false if failed or cancelled
3143  bool __fastcall hexapi set_num_enum(void);
3144 
3145  /// Convert number to structure field offset.
3146  /// Currently not implemented.
3147  /// \return false if failed or cancelled
3148  bool __fastcall hexapi set_num_stroff(void);
3149 
3150  /// Negate a number.
3151  /// This function negates the current number.
3152  /// \return false if failed.
3153  bool __fastcall hexapi invert_sign(void);
3154 
3155  /// Bitwise negate a number.
3156  /// This function inverts all bits of the current number.
3157  /// \return false if failed.
3158  bool __fastcall hexapi invert_bits(void);
3159 
3160  /// Collapse/uncollapse item.
3161  /// This function collapses the current item.
3162  /// \return false if failed.
3163  bool __fastcall hexapi collapse_item(bool hide);
3164 
3165  /// Collapse/uncollapse local variable declarations.
3166  /// \return false if failed.
3167  bool __fastcall hexapi collapse_lvars(bool hide);
3168 
3169  /// Split/unsplit item.
3170  /// This function splits the current assignment expression.
3171  /// \return false if failed.
3172  bool __fastcall hexapi split_item(bool split);
3173 
3174 };
3175 
3176 
3177 
3178 //--------------------------------------------------------------------------
3179 // PUBLIC HEX-RAYS API
3180 //--------------------------------------------------------------------------
3181 
3182 /// Hex-Rays decompiler dispatcher.
3183 /// All interaction with the decompiler is carried out by the intermediary of this dispatcher.
3184 typedef void *hexdsp_t(int code, ...);
3185 
3186 /// Pointer to Hex-Rays decompiler dispatcher.
3187 /// This variable must be instantiated by the plugin. It is initialized by init_hexrays_plugin().
3188 extern hexdsp_t *hexdsp;
3189 
3190 /// API call numbers
3192 {
3193  hx_user_cmts_begin,
3194  hx_user_cmts_end,
3195  hx_user_cmts_next,
3196  hx_user_cmts_prev,
3197  hx_user_cmts_first,
3198  hx_user_cmts_second,
3199  hx_user_cmts_find,
3200  hx_user_cmts_insert,
3201  hx_user_cmts_erase,
3202  hx_user_cmts_clear,
3203  hx_user_cmts_size,
3204  hx_user_cmts_free,
3205  hx_user_numforms_begin,
3206  hx_user_numforms_end,
3207  hx_user_numforms_next,
3208  hx_user_numforms_prev,
3209  hx_user_numforms_first,
3210  hx_user_numforms_second,
3211  hx_user_numforms_find,
3212  hx_user_numforms_insert,
3213  hx_user_numforms_erase,
3214  hx_user_numforms_clear,
3215  hx_user_numforms_size,
3216  hx_user_numforms_free,
3217  hx_user_iflags_begin,
3218  hx_user_iflags_end,
3219  hx_user_iflags_next,
3220  hx_user_iflags_prev,
3221  hx_user_iflags_first,
3222  hx_user_iflags_second,
3223  hx_user_iflags_find,
3224  hx_user_iflags_insert,
3225  hx_user_iflags_erase,
3226  hx_user_iflags_clear,
3227  hx_user_iflags_size,
3228  hx_user_iflags_free,
3229  hx_user_labels_begin,
3230  hx_user_labels_end,
3231  hx_user_labels_next,
3232  hx_user_labels_prev,
3233  hx_user_labels_first,
3234  hx_user_labels_second,
3235  hx_user_labels_find,
3236  hx_user_labels_insert,
3237  hx_user_labels_erase,
3238  hx_user_labels_clear,
3239  hx_user_labels_size,
3240  hx_user_labels_free,
3241  hx_operand_locator_t_compare,
3242  hx_vd_printer_t_print,
3243  hx_qstring_printer_t_print,
3244  hx_remove_typedef,
3245  hx_is_type_correct,
3246  hx_is_type_integral,
3247  hx_is_type_small_struni,
3248  hx_partial_type_num,
3249  hx_get_float_bit,
3250  hx_typestring_print,
3251  hx_typestring_change_sign,
3252  hx_typestring_get_cc,
3253  hx_typestring_get_nth_arg,
3254  hx_get_int_type_by_width_and_sign,
3255  hx_get_unk_type,
3256  hx_get_member_type,
3257  hx_make_array,
3258  hx_make_pointer,
3259  hx_create_typedef,
3260  hx_remove_pointer,
3261  hx_cnv_array_to_ptr,
3262  hx_strtype_info_t_build_base_type,
3263  hx_strtype_info_t_build_udt_type,
3264  hx_arglocs_overlap,
3265  hx_lvar_locator_t_get_regnum,
3266  hx_lvar_locator_t_compare,
3267  hx_lvar_t_accepts_type,
3268  hx_lvar_t_set_lvar_type,
3269  hx_lvar_t_set_width,
3270  hx_lvars_t_find_stkvar,
3271  hx_lvars_t_find,
3272  hx_lvars_t_find_lvar,
3273  hx_restore_user_lvar_settings,
3274  hx_save_user_lvar_settings,
3275  hx_fnumber_t_print,
3276  hx_get_hexrays_version,
3277  hx_open_pseudocode,
3278  hx_close_pseudocode,
3279  hx_decompile,
3280  hx_decompile_many,
3281  hx_micro_err_format,
3282  hx_hexrays_failure_t_desc,
3283  hx_send_database,
3284  hx_negated_relation,
3285  hx_get_op_signness,
3286  hx_asgop,
3287  hx_asgop_revert,
3288  hx_cnumber_t_print,
3289  hx_cnumber_t_value,
3290  hx_cnumber_t_assign,
3291  hx_cnumber_t_compare,
3292  hx_var_ref_t_compare,
3293  hx_ctree_visitor_t_apply_to,
3294  hx_ctree_visitor_t_apply_to_exprs,
3295  hx_ctree_parentee_t_recalc_parent_types,
3296  hx_cfunc_parentee_t_calc_rvalue_type,
3297  hx_citem_locator_t_compare,
3298  hx_citem_t_contains_label,
3299  hx_citem_t_find_parent_of,
3300  hx_cexpr_t_assign,
3301  hx_cexpr_t_compare,
3302  hx_cexpr_t_replace_by,
3303  hx_cexpr_t_cleanup,
3304  hx_cexpr_t_put_number,
3305  hx_cexpr_t_print1,
3306  hx_cexpr_t_calc_type,
3307  hx_cexpr_t_equal_effect,
3308  hx_cexpr_t_is_child_of,
3309  hx_cexpr_t_contains_operator,
3310  hx_cexpr_t_get_high_nbit_bound,
3311  hx_cexpr_t_requires_lvalue,
3312  hx_cexpr_t_has_side_effects,
3313  hx_cif_t_assign,
3314  hx_cif_t_compare,
3315  hx_cloop_t_assign,
3316  hx_cfor_t_compare,
3317  hx_cwhile_t_compare,
3318  hx_cdo_t_compare,
3319  hx_creturn_t_compare,
3320  hx_cgoto_t_compare,
3321  hx_casm_t_compare,
3322  hx_cinsn_t_assign,
3323  hx_cinsn_t_compare,
3324  hx_cinsn_t_replace_by,
3325  hx_cinsn_t_cleanup,
3326  hx_cinsn_t_new_insn,
3327  hx_cinsn_t_create_if,
3328  hx_cinsn_t_print,
3329  hx_cinsn_t_print1,
3330  hx_cinsn_t_is_ordinary_flow,
3331  hx_cinsn_t_contains_insn,
3332  hx_cinsn_t_collect_free_breaks,
3333  hx_cinsn_t_collect_free_continues,
3334  hx_cblock_t_compare,
3335  hx_carglist_t_compare,
3336  hx_ccase_t_compare,
3337  hx_ccases_t_compare,
3338  hx_cswitch_t_compare,
3339  hx_ctree_item_t_get_memptr,
3340  hx_ctree_item_t_get_lvar,
3341  hx_ctree_item_t_get_ea,
3342  hx_ctree_item_t_get_label_num,
3343  hx_lnot,
3344  hx_new_block,
3345  hx_vcreate_helper,
3346  hx_vcall_helper,
3347  hx_make_num,
3348  hx_make_ref,
3349  hx_dereference,
3350  hx_save_user_labels,
3351  hx_save_user_cmts,
3352  hx_save_user_numforms,
3353  hx_save_user_iflags,
3354  hx_restore_user_labels,
3355  hx_restore_user_cmts,
3356  hx_restore_user_numforms,
3357  hx_restore_user_iflags,
3358  hx_cfunc_t_build_c_tree,
3359  hx_cfunc_t_verify,
3360  hx_cfunc_t_print_dcl,
3361  hx_cfunc_t_print_func,
3362  hx_cfunc_t_get_func_type,
3363  hx_cfunc_t_get_lvars,
3364  hx_cfunc_t_find_label,
3365  hx_cfunc_t_remove_unused_labels,
3366  hx_cfunc_t_get_user_cmt,
3367  hx_cfunc_t_set_user_cmt,
3368  hx_cfunc_t_get_user_iflags,
3369  hx_cfunc_t_set_user_iflags,
3370  hx_cfunc_t_has_orphan_cmts,
3371  hx_cfunc_t_del_orphan_cmts,
3372  hx_cfunc_t_get_line_item,
3373  hx_cfunc_t_get_warnings,
3374  hx_cfunc_t_gather_derefs,
3375  hx_cfunc_t_cleanup,
3376  hx_get_ctype_name,
3377  hx_install_hexrays_callback,
3378  hx_remove_hexrays_callback,
3379  hx_vdui_t_refresh_view,
3380  hx_vdui_t_refresh_ctext,
3381  hx_vdui_t_switch_to,
3382  hx_vdui_t_get_number,
3383  hx_vdui_t_clear,
3384  hx_vdui_t_refresh_cpos,
3385  hx_vdui_t_get_current_item,
3386  hx_vdui_t_ui_rename_lvar,
3387  hx_vdui_t_rename_lvar,
3388  hx_vdui_t_ui_set_lvar_type,
3389  hx_vdui_t_set_lvar_type,
3390  hx_vdui_t_edit_lvar_cmt,
3391  hx_vdui_t_set_lvar_cmt,
3392  hx_vdui_t_set_strmem_type,
3393  hx_vdui_t_rename_strmem,
3394  hx_vdui_t_set_global_type,
3395  hx_vdui_t_rename_global,
3396  hx_vdui_t_rename_label,
3397  hx_vdui_t_jump_enter,
3398  hx_vdui_t_ctree_to_disasm,
3399  hx_vdui_t_push_current_location,
3400  hx_vdui_t_pop_current_location,
3401  hx_vdui_t_calc_cmt_type,
3402  hx_vdui_t_edit_cmt,
3403  hx_vdui_t_edit_func_cmt,
3404  hx_vdui_t_del_orphan_cmts,
3405  hx_vdui_t_set_num_radix,
3406  hx_vdui_t_set_num_enum,
3407  hx_vdui_t_set_num_stroff,
3408  hx_vdui_t_invert_sign,
3409  hx_vdui_t_collapse_item,
3410  hx_vdui_t_split_item,
3411  hx_vdui_t_set_vargloc_end,
3412  hx_lvar_mapping_begin,
3413  hx_lvar_mapping_end,
3414  hx_lvar_mapping_next,
3415  hx_lvar_mapping_prev,
3416  hx_lvar_mapping_first,
3417  hx_lvar_mapping_second,
3418  hx_lvar_mapping_find,
3419  hx_lvar_mapping_insert,
3420  hx_lvar_mapping_erase,
3421  hx_lvar_mapping_clear,
3422  hx_lvar_mapping_size,
3423  hx_lvar_mapping_free,
3424  hx_user_unions_begin,
3425  hx_user_unions_end,
3426  hx_user_unions_next,
3427  hx_user_unions_prev,
3428  hx_user_unions_first,
3429  hx_user_unions_second,
3430  hx_user_unions_find,
3431  hx_user_unions_insert,
3432  hx_user_unions_erase,
3433  hx_user_unions_clear,
3434  hx_user_unions_size,
3435  hx_user_unions_free,
3436  hx_strtype_info_t_create_from,
3437  hx_save_user_unions,
3438  hx_restore_user_unions,
3439  hx_cfunc_t_get_user_union_selection,
3440  hx_cfunc_t_set_user_union_selection,
3441  hx_vdui_t_ui_edit_lvar_cmt,
3442  hx_vdui_t_ui_map_lvar,
3443  hx_vdui_t_ui_unmap_lvar,
3444  hx_vdui_t_map_lvar,
3445  hx_dummy_ptrtype,
3446  hx_create_field_name,
3447  hx_dummy_plist_for,
3448  hx_make_dt,
3449  hx_cexpr_t_get_low_nbit_bound,
3450  hx_eamap_begin,
3451  hx_eamap_end,
3452  hx_eamap_next,
3453  hx_eamap_prev,
3454  hx_eamap_first,
3455  hx_eamap_second,
3456  hx_eamap_find,
3457  hx_eamap_insert,
3458  hx_eamap_erase,
3459  hx_eamap_clear,
3460  hx_eamap_size,
3461  hx_eamap_free,
3462  hx_boundaries_begin,
3463  hx_boundaries_end,
3464  hx_boundaries_next,
3465  hx_boundaries_prev,
3466  hx_boundaries_first,
3467  hx_boundaries_second,
3468  hx_boundaries_find,
3469  hx_boundaries_insert,
3470  hx_boundaries_erase,
3471  hx_boundaries_clear,
3472  hx_boundaries_size,
3473  hx_boundaries_free,
3474  hx_mark_cfunc_dirty,
3475  hx_clear_cached_cfuncs,
3476  hx_has_cached_cfunc,
3477  hx_cfunc_t_get_eamap,
3478  hx_cfunc_t_get_boundaries,
3479  hx_cfunc_t_get_pseudocode,
3480  hx_vdui_t_collapse_lvars,
3481  hx_vdui_t_invert_bits,
3482  hx_print_vdloc,
3483  hx_is_small_struni,
3484  hx_is_nonbool_type,
3485  hx_is_bool_type,
3486  hx_get_type,
3487  hx_set_type,
3488  hx_vdloc_t_compare,
3489  hx_get_float_type,
3490  hx_vdui_t_get_current_label,
3491  hx_get_widget_vdui,
3492  hx_cfunc_t_print_dcl2,
3493  hx_modify_user_lvars,
3494  hx_user_numforms_new,
3495  hx_lvar_mapping_new,
3496  hx_user_cmts_new,
3497  hx_user_iflags_new,
3498  hx_user_unions_new,
3499  hx_user_labels_new,
3500  hx_eamap_new,
3501  hx_boundaries_new,
3502  hx_restore_user_defined_calls,
3503  hx_save_user_defined_calls,
3504  hx_udcall_map_begin,
3505  hx_udcall_map_end,
3506  hx_udcall_map_next,
3507  hx_udcall_map_prev,
3508  hx_udcall_map_first,
3509  hx_udcall_map_second,
3510  hx_udcall_map_find,
3511  hx_udcall_map_insert,
3512  hx_udcall_map_erase,
3513  hx_udcall_map_clear,
3514  hx_udcall_map_size,
3515  hx_udcall_map_free,
3516  hx_udcall_map_new,
3517  hx_parse_user_call,
3518  hx_convert_to_user_call,
3519  hx_install_microcode_filter,
3520  hx_microcode_filter_t_match,
3521  hx_microcode_filter_t_apply,
3522  hx_udc_filter_t_apply,
3523  hx_udc_filter_t_match,
3524  hx_udc_filter_t_init,
3525  hx_cfunc_t_get_stkoff_delta,
3526 };
3527 
3528 typedef size_t iterator_word;
3529 
3530 //--------------------------------------------------------------------------
3531 /// Initialize your plugin for hex-rays decompiler.
3532 /// This function must be called before calling any other decompiler function.
3533 /// It initializes the pointer to the dispatcher.
3534 /// \param flags reserved, must be 0
3535 /// \return true if the decompiler exists and the dispatcher pointer is ready to use.
3536 inline bool init_hexrays_plugin(int flags=0)
3537 {
3538  return callui(ui_broadcast, HEXRAYS_API_MAGIC, &hexdsp, flags).i == (HEXRAYS_API_MAGIC >> 32);
3539 }
3540 
3541 //--------------------------------------------------------------------------
3542 /// Terminate your plugin for hex-rays decompiler.
3543 /// Currently this function is empty but please do include it in your plugins.
3544 inline void term_hexrays_plugin(void)
3545 {
3546 }
3547 
3548 //-------------------------------------------------------------------------
3550 {
3551  iterator_word x;
3552  bool operator==(const user_numforms_iterator_t &p) const { return x == p.x; }
3553  bool operator!=(const user_numforms_iterator_t &p) const { return x != p.x; }
3554 };
3555 
3556 //-------------------------------------------------------------------------
3557 /// Get iterator pointing to the beginning of user_numforms_t
3558 inline user_numforms_iterator_t user_numforms_begin(const user_numforms_t *map)
3559 {
3561  hexdsp(hx_user_numforms_begin, &p, map);
3562  return p;
3563 }
3564 
3565 //-------------------------------------------------------------------------
3566 /// Get iterator pointing to the end of user_numforms_t
3567 inline user_numforms_iterator_t user_numforms_end(const user_numforms_t *map)
3568 {
3570  hexdsp(hx_user_numforms_end, &p, map);
3571  return p;
3572 }
3573 
3574 //-------------------------------------------------------------------------
3575 /// Move to the next element
3577 {
3578  hexdsp(hx_user_numforms_next, &p);
3579  return p;
3580 }
3581 
3582 //-------------------------------------------------------------------------
3583 /// Move to the previous element
3585 {
3586  hexdsp(hx_user_numforms_prev, &p);
3587  return p;
3588 }
3589 
3590 //-------------------------------------------------------------------------
3591 /// Get reference to the current map key
3593 {
3594  return *(operand_locator_t *)hexdsp(hx_user_numforms_first, &p);
3595 }
3596 
3597 //-------------------------------------------------------------------------
3598 /// Get reference to the current map value
3600 {
3601  return *(number_format_t *)hexdsp(hx_user_numforms_second, &p);
3602 }
3603 
3604 //-------------------------------------------------------------------------
3605 /// Find the specified key in user_numforms_t
3606 inline user_numforms_iterator_t user_numforms_find(const user_numforms_t *map, const operand_locator_t &key)
3607 {
3609  hexdsp(hx_user_numforms_find, &p, map, &key);
3610  return p;
3611 }
3612 
3613 //-------------------------------------------------------------------------
3614 /// Insert new (operand_locator_t, number_format_t) pair into user_numforms_t
3615 inline user_numforms_iterator_t user_numforms_insert(user_numforms_t *map, const operand_locator_t &key, const number_format_t &val)
3616 {
3618  hexdsp(hx_user_numforms_insert, &p, map, &key, &val);
3619  return p;
3620 }
3621 
3622 //-------------------------------------------------------------------------
3623 /// Erase current element from user_numforms_t
3624 inline void user_numforms_erase(user_numforms_t *map, user_numforms_iterator_t p)
3625 {
3626  hexdsp(hx_user_numforms_erase, map, &p);
3627 }
3628 
3629 //-------------------------------------------------------------------------
3630 /// Clear user_numforms_t
3631 inline void user_numforms_clear(user_numforms_t *map)
3632 {
3633  hexdsp(hx_user_numforms_clear, map);
3634 }
3635 
3636 //-------------------------------------------------------------------------
3637 /// Get size of user_numforms_t
3638 inline size_t user_numforms_size(user_numforms_t *map)
3639 {
3640  return (size_t)hexdsp(hx_user_numforms_size, map);
3641 }
3642 
3643 //-------------------------------------------------------------------------
3644 /// Delete user_numforms_t instance
3645 inline void user_numforms_free(user_numforms_t *map)
3646 {
3647  hexdsp(hx_user_numforms_free, map);
3648 }
3649 
3650 //-------------------------------------------------------------------------
3651 /// Create a new user_numforms_t instance
3652 inline user_numforms_t *user_numforms_new(void)
3653 {
3654  return (user_numforms_t *)hexdsp(hx_user_numforms_new);
3655 }
3656 
3657 //-------------------------------------------------------------------------
3659 {
3660  iterator_word x;
3661  bool operator==(const lvar_mapping_iterator_t &p) const { return x == p.x; }
3662  bool operator!=(const lvar_mapping_iterator_t &p) const { return x != p.x; }
3663 };
3664 
3665 //-------------------------------------------------------------------------
3666 /// Get iterator pointing to the beginning of lvar_mapping_t
3667 inline lvar_mapping_iterator_t lvar_mapping_begin(const lvar_mapping_t *map)
3668 {
3670  hexdsp(hx_lvar_mapping_begin, &p, map);
3671  return p;
3672 }
3673 
3674 //-------------------------------------------------------------------------
3675 /// Get iterator pointing to the end of lvar_mapping_t
3676 inline lvar_mapping_iterator_t lvar_mapping_end(const lvar_mapping_t *map)
3677 {
3679  hexdsp(hx_lvar_mapping_end, &p, map);
3680  return p;
3681 }
3682 
3683 //-------------------------------------------------------------------------
3684 /// Move to the next element
3686 {
3687  hexdsp(hx_lvar_mapping_next, &p);
3688  return p;
3689 }
3690 
3691 //-------------------------------------------------------------------------
3692 /// Move to the previous element
3694 {
3695  hexdsp(hx_lvar_mapping_prev, &p);
3696  return p;
3697 }
3698 
3699 //-------------------------------------------------------------------------
3700 /// Get reference to the current map key
3702 {
3703  return *(lvar_locator_t *)hexdsp(hx_lvar_mapping_first, &p);
3704 }
3705 
3706 //-------------------------------------------------------------------------
3707 /// Get reference to the current map value
3709 {
3710  return *(lvar_locator_t *)hexdsp(hx_lvar_mapping_second, &p);
3711 }
3712 
3713 //-------------------------------------------------------------------------
3714 /// Find the specified key in lvar_mapping_t
3715 inline lvar_mapping_iterator_t lvar_mapping_find(const lvar_mapping_t *map, const lvar_locator_t &key)
3716 {
3718  hexdsp(hx_lvar_mapping_find, &p, map, &key);
3719  return p;
3720 }
3721 
3722 //-------------------------------------------------------------------------
3723 /// Insert new (lvar_locator_t, lvar_locator_t) pair into lvar_mapping_t
3724 inline lvar_mapping_iterator_t lvar_mapping_insert(lvar_mapping_t *map, const lvar_locator_t &key, const lvar_locator_t &val)
3725 {
3727  hexdsp(hx_lvar_mapping_insert, &p, map, &key, &val);
3728  return p;
3729 }
3730 
3731 //-------------------------------------------------------------------------
3732 /// Erase current element from lvar_mapping_t
3733 inline void lvar_mapping_erase(lvar_mapping_t *map, lvar_mapping_iterator_t p)
3734 {
3735  hexdsp(hx_lvar_mapping_erase, map, &p);
3736 }
3737 
3738 //-------------------------------------------------------------------------
3739 /// Clear lvar_mapping_t
3740 inline void lvar_mapping_clear(lvar_mapping_t *map)
3741 {
3742  hexdsp(hx_lvar_mapping_clear, map);
3743 }
3744 
3745 //-------------------------------------------------------------------------
3746 /// Get size of lvar_mapping_t
3747 inline size_t lvar_mapping_size(lvar_mapping_t *map)
3748 {
3749  return (size_t)hexdsp(hx_lvar_mapping_size, map);
3750 }
3751 
3752 //-------------------------------------------------------------------------
3753 /// Delete lvar_mapping_t instance
3754 inline void lvar_mapping_free(lvar_mapping_t *map)
3755 {
3756  hexdsp(hx_lvar_mapping_free, map);
3757 }
3758 
3759 //-------------------------------------------------------------------------
3760 /// Create a new lvar_mapping_t instance
3761 inline lvar_mapping_t *lvar_mapping_new(void)
3762 {
3763  return (lvar_mapping_t *)hexdsp(hx_lvar_mapping_new);
3764 }
3765 
3766 //-------------------------------------------------------------------------
3768 {
3769  iterator_word x;
3770  bool operator==(const udcall_map_iterator_t &p) const { return x == p.x; }
3771  bool operator!=(const udcall_map_iterator_t &p) const { return x != p.x; }
3772 };
3773 
3774 //-------------------------------------------------------------------------
3775 /// Get iterator pointing to the beginning of udcall_map_t
3776 inline udcall_map_iterator_t udcall_map_begin(const udcall_map_t *map)
3777 {
3779  hexdsp(hx_udcall_map_begin, &p, map);
3780  return p;
3781 }
3782 
3783 //-------------------------------------------------------------------------
3784 /// Get iterator pointing to the end of udcall_map_t
3785 inline udcall_map_iterator_t udcall_map_end(const udcall_map_t *map)
3786 {
3788  hexdsp(hx_udcall_map_end, &p, map);
3789  return p;
3790 }
3791 
3792 //-------------------------------------------------------------------------
3793 /// Move to the next element
3795 {
3796  hexdsp(hx_udcall_map_next, &p);
3797  return p;
3798 }
3799 
3800 //-------------------------------------------------------------------------
3801 /// Move to the previous element
3803 {
3804  hexdsp(hx_udcall_map_prev, &p);
3805  return p;
3806 }
3807 
3808 //-------------------------------------------------------------------------
3809 /// Get reference to the current map key
3811 {
3812  return *(ea_t *)hexdsp(hx_udcall_map_first, &p);
3813 }
3814 
3815 //-------------------------------------------------------------------------
3816 /// Get reference to the current map value
3818 {
3819  return *(udcall_t *)hexdsp(hx_udcall_map_second, &p);
3820 }
3821 
3822 //-------------------------------------------------------------------------
3823 /// Find the specified key in udcall_map_t
3824 inline udcall_map_iterator_t udcall_map_find(const udcall_map_t *map, const ea_t &key)
3825 {
3827  hexdsp(hx_udcall_map_find, &p, map, &key);
3828  return p;
3829 }
3830 
3831 //-------------------------------------------------------------------------
3832 /// Insert new (ea_t, udcall_t) pair into udcall_map_t
3833 inline udcall_map_iterator_t udcall_map_insert(udcall_map_t *map, const ea_t &key, const udcall_t &val)
3834 {
3836  hexdsp(hx_udcall_map_insert, &p, map, &key, &val);
3837  return p;
3838 }
3839 
3840 //-------------------------------------------------------------------------
3841 /// Erase current element from udcall_map_t
3842 inline void udcall_map_erase(udcall_map_t *map, udcall_map_iterator_t p)
3843 {
3844  hexdsp(hx_udcall_map_erase, map, &p);
3845 }
3846 
3847 //-------------------------------------------------------------------------
3848 /// Clear udcall_map_t
3849 inline void udcall_map_clear(udcall_map_t *map)
3850 {
3851  hexdsp(hx_udcall_map_clear, map);
3852 }
3853 
3854 //-------------------------------------------------------------------------
3855 /// Get size of udcall_map_t
3856 inline size_t udcall_map_size(udcall_map_t *map)
3857 {
3858  return (size_t)hexdsp(hx_udcall_map_size, map);
3859 }
3860 
3861 //-------------------------------------------------------------------------
3862 /// Delete udcall_map_t instance
3863 inline void udcall_map_free(udcall_map_t *map)
3864 {
3865  hexdsp(hx_udcall_map_free, map);
3866 }
3867 
3868 //-------------------------------------------------------------------------
3869 /// Create a new udcall_map_t instance
3870 inline udcall_map_t *udcall_map_new(void)
3871 {
3872  return (udcall_map_t *)hexdsp(hx_udcall_map_new);
3873 }
3874 
3875 //-------------------------------------------------------------------------
3876 struct user_cmts_iterator_t
3877 {
3878  iterator_word x;
3879  bool operator==(const user_cmts_iterator_t &p) const { return x == p.x; }
3880  bool operator!=(const user_cmts_iterator_t &p) const { return x != p.x; }
3881 };
3882 
3883 //-------------------------------------------------------------------------
3884 /// Get iterator pointing to the beginning of user_cmts_t
3885 inline user_cmts_iterator_t user_cmts_begin(const user_cmts_t *map)
3886 {
3888  hexdsp(hx_user_cmts_begin, &p, map);
3889  return p;
3890 }
3891 
3892 //-------------------------------------------------------------------------
3893 /// Get iterator pointing to the end of user_cmts_t
3894 inline user_cmts_iterator_t user_cmts_end(const user_cmts_t *map)
3895 {
3897  hexdsp(hx_user_cmts_end, &p, map);
3898  return p;
3899 }
3900 
3901 //-------------------------------------------------------------------------
3902 /// Move to the next element
3904 {
3905  hexdsp(hx_user_cmts_next, &p);
3906  return p;
3907 }
3908 
3909 //-------------------------------------------------------------------------
3910 /// Move to the previous element
3912 {
3913  hexdsp(hx_user_cmts_prev, &p);
3914  return p;
3915 }
3916 
3917 //-------------------------------------------------------------------------
3918 /// Get reference to the current map key
3920 {
3921  return *(treeloc_t *)hexdsp(hx_user_cmts_first, &p);
3922 }
3923 
3924 //-------------------------------------------------------------------------
3925 /// Get reference to the current map value
3927 {
3928  return *(citem_cmt_t *)hexdsp(hx_user_cmts_second, &p);
3929 }
3930 
3931 //-------------------------------------------------------------------------
3932 /// Find the specified key in user_cmts_t
3933 inline user_cmts_iterator_t user_cmts_find(const user_cmts_t *map, const treeloc_t &key)
3934 {
3936  hexdsp(hx_user_cmts_find, &p, map, &key);
3937  return p;
3938 }
3939 
3940 //-------------------------------------------------------------------------
3941 /// Insert new (treeloc_t, citem_cmt_t) pair into user_cmts_t
3942 inline user_cmts_iterator_t user_cmts_insert(user_cmts_t *map, const treeloc_t &key, const citem_cmt_t &val)
3943 {
3945  hexdsp(hx_user_cmts_insert, &p, map, &key, &val);
3946  return p;
3947 }
3948 
3949 //-------------------------------------------------------------------------
3950 /// Erase current element from user_cmts_t
3951 inline void user_cmts_erase(user_cmts_t *map, user_cmts_iterator_t p)
3952 {
3953  hexdsp(hx_user_cmts_erase, map, &p);
3954 }
3955 
3956 //-------------------------------------------------------------------------
3957 /// Clear user_cmts_t
3958 inline void user_cmts_clear(user_cmts_t *map)
3959 {
3960  hexdsp(hx_user_cmts_clear, map);
3961 }
3962 
3963 //-------------------------------------------------------------------------
3964 /// Get size of user_cmts_t
3965 inline size_t user_cmts_size(user_cmts_t *map)
3966 {
3967  return (size_t)hexdsp(hx_user_cmts_size, map);
3968 }
3969 
3970 //-------------------------------------------------------------------------
3971 /// Delete user_cmts_t instance
3972 inline void user_cmts_free(user_cmts_t *map)
3973 {
3974  hexdsp(hx_user_cmts_free, map);
3975 }
3976 
3977 //-------------------------------------------------------------------------
3978 /// Create a new user_cmts_t instance
3979 inline user_cmts_t *user_cmts_new(void)
3980 {
3981  return (user_cmts_t *)hexdsp(hx_user_cmts_new);
3982 }
3983 
3984 //-------------------------------------------------------------------------
3986 {
3987  iterator_word x;
3988  bool operator==(const user_iflags_iterator_t &p) const { return x == p.x; }
3989  bool operator!=(const user_iflags_iterator_t &p) const { return x != p.x; }
3990 };
3991 
3992 //-------------------------------------------------------------------------
3993 /// Get iterator pointing to the beginning of user_iflags_t
3994 inline user_iflags_iterator_t user_iflags_begin(const user_iflags_t *map)
3995 {
3997  hexdsp(hx_user_iflags_begin, &p, map);
3998  return p;
3999 }
4000 
4001 //-------------------------------------------------------------------------
4002 /// Get iterator pointing to the end of user_iflags_t
4003 inline user_iflags_iterator_t user_iflags_end(const user_iflags_t *map)
4004 {
4006  hexdsp(hx_user_iflags_end, &p, map);
4007  return p;
4008 }
4009 
4010 //-------------------------------------------------------------------------
4011 /// Move to the next element
4013 {
4014  hexdsp(hx_user_iflags_next, &p);
4015  return p;
4016 }
4017 
4018 //-------------------------------------------------------------------------
4019 /// Move to the previous element
4021 {
4022  hexdsp(hx_user_iflags_prev, &p);
4023  return p;
4024 }
4025 
4026 //-------------------------------------------------------------------------
4027 /// Get reference to the current map key
4029 {
4030  return *(citem_locator_t *)hexdsp(hx_user_iflags_first, &p);
4031 }
4032 
4033 //-------------------------------------------------------------------------
4034 /// Get reference to the current map value
4036 {
4037  return *(int32 *)hexdsp(hx_user_iflags_second, &p);
4038 }
4039 
4040 //-------------------------------------------------------------------------
4041 /// Find the specified key in user_iflags_t
4042 inline user_iflags_iterator_t user_iflags_find(const user_iflags_t *map, const citem_locator_t &key)
4043 {
4045  hexdsp(hx_user_iflags_find, &p, map, &key);
4046  return p;
4047 }
4048 
4049 //-------------------------------------------------------------------------
4050 /// Insert new (citem_locator_t, int32) pair into user_iflags_t
4051 inline user_iflags_iterator_t user_iflags_insert(user_iflags_t *map, const citem_locator_t &key, const int32 &val)
4052 {
4054  hexdsp(hx_user_iflags_insert, &p, map, &key, &val);
4055  return p;
4056 }
4057 
4058 //-------------------------------------------------------------------------
4059 /// Erase current element from user_iflags_t
4060 inline void user_iflags_erase(user_iflags_t *map, user_iflags_iterator_t p)
4061 {
4062  hexdsp(hx_user_iflags_erase, map, &p);
4063 }
4064 
4065 //-------------------------------------------------------------------------
4066 /// Clear user_iflags_t
4067 inline void user_iflags_clear(user_iflags_t *map)
4068 {
4069  hexdsp(hx_user_iflags_clear, map);
4070 }
4071 
4072 //-------------------------------------------------------------------------
4073 /// Get size of user_iflags_t
4074 inline size_t user_iflags_size(user_iflags_t *map)
4075 {
4076  return (size_t)hexdsp(hx_user_iflags_size, map);
4077 }
4078 
4079 //-------------------------------------------------------------------------
4080 /// Delete user_iflags_t instance
4081 inline void user_iflags_free(user_iflags_t *map)
4082 {
4083  hexdsp(hx_user_iflags_free, map);
4084 }
4085 
4086 //-------------------------------------------------------------------------
4087 /// Create a new user_iflags_t instance
4088 inline user_iflags_t *user_iflags_new(void)
4089 {
4090  return (user_iflags_t *)hexdsp(hx_user_iflags_new);
4091 }
4092 
4093 //-------------------------------------------------------------------------
4095 {
4096  iterator_word x;
4097  bool operator==(const user_unions_iterator_t &p) const { return x == p.x; }
4098  bool operator!=(const user_unions_iterator_t &p) const { return x != p.x; }
4099 };
4100 
4101 //-------------------------------------------------------------------------
4102 /// Get iterator pointing to the beginning of user_unions_t
4103 inline user_unions_iterator_t user_unions_begin(const user_unions_t *map)
4104 {
4106  hexdsp(hx_user_unions_begin, &p, map);
4107  return p;
4108 }
4109 
4110 //-------------------------------------------------------------------------
4111 /// Get iterator pointing to the end of user_unions_t
4112 inline user_unions_iterator_t user_unions_end(const user_unions_t *map)
4113 {
4115  hexdsp(hx_user_unions_end, &p, map);
4116  return p;
4117 }
4118 
4119 //-------------------------------------------------------------------------
4120 /// Move to the next element
4122 {
4123  hexdsp(hx_user_unions_next, &p);
4124  return p;
4125 }
4126 
4127 //-------------------------------------------------------------------------
4128 /// Move to the previous element
4130 {
4131  hexdsp(hx_user_unions_prev, &p);
4132  return p;
4133 }
4134 
4135 //-------------------------------------------------------------------------
4136 /// Get reference to the current map key
4138 {
4139  return *(ea_t *)hexdsp(hx_user_unions_first, &p);
4140 }
4141 
4142 //-------------------------------------------------------------------------
4143 /// Get reference to the current map value
4145 {
4146  return *(intvec_t *)hexdsp(hx_user_unions_second, &p);
4147 }
4148 
4149 //-------------------------------------------------------------------------
4150 /// Find the specified key in user_unions_t
4151 inline user_unions_iterator_t user_unions_find(const user_unions_t *map, const ea_t &key)
4152 {
4154  hexdsp(hx_user_unions_find, &p, map, &key);
4155  return p;
4156 }
4157 
4158 //-------------------------------------------------------------------------
4159 /// Insert new (ea_t, intvec_t) pair into user_unions_t
4160 inline user_unions_iterator_t user_unions_insert(user_unions_t *map, const ea_t &key, const intvec_t &val)
4161 {
4163  hexdsp(hx_user_unions_insert, &p, map, &key, &val);
4164  return p;
4165 }
4166 
4167 //-------------------------------------------------------------------------
4168 /// Erase current element from user_unions_t
4169 inline void user_unions_erase(user_unions_t *map, user_unions_iterator_t p)
4170 {
4171  hexdsp(hx_user_unions_erase, map, &p);
4172 }
4173 
4174 //-------------------------------------------------------------------------
4175 /// Clear user_unions_t
4176 inline void user_unions_clear(user_unions_t *map)
4177 {
4178  hexdsp(hx_user_unions_clear, map);
4179 }
4180 
4181 //-------------------------------------------------------------------------
4182 /// Get size of user_unions_t
4183 inline size_t user_unions_size(user_unions_t *map)
4184 {
4185  return (size_t)hexdsp(hx_user_unions_size, map);
4186 }
4187 
4188 //-------------------------------------------------------------------------
4189 /// Delete user_unions_t instance
4190 inline void user_unions_free(user_unions_t *map)
4191 {
4192  hexdsp(hx_user_unions_free, map);
4193 }
4194 
4195 //-------------------------------------------------------------------------
4196 /// Create a new user_unions_t instance
4197 inline user_unions_t *user_unions_new(void)
4198 {
4199  return (user_unions_t *)hexdsp(hx_user_unions_new);
4200 }
4201 
4202 //-------------------------------------------------------------------------
4204 {
4205  iterator_word x;
4206  bool operator==(const user_labels_iterator_t &p) const { return x == p.x; }
4207  bool operator!=(const user_labels_iterator_t &p) const { return x != p.x; }
4208 };
4209 
4210 //-------------------------------------------------------------------------
4211 /// Get iterator pointing to the beginning of user_labels_t
4212 inline user_labels_iterator_t user_labels_begin(const user_labels_t *map)
4213 {
4215  hexdsp(hx_user_labels_begin, &p, map);
4216  return p;
4217 }
4218 
4219 //-------------------------------------------------------------------------
4220 /// Get iterator pointing to the end of user_labels_t
4221 inline user_labels_iterator_t user_labels_end(const user_labels_t *map)
4222 {
4224  hexdsp(hx_user_labels_end, &p, map);
4225  return p;
4226 }
4227 
4228 //-------------------------------------------------------------------------
4229 /// Move to the next element
4231 {
4232  hexdsp(hx_user_labels_next, &p);
4233  return p;
4234 }
4235 
4236 //-------------------------------------------------------------------------
4237 /// Move to the previous element
4239 {
4240  hexdsp(hx_user_labels_prev, &p);
4241  return p;
4242 }
4243 
4244 //-------------------------------------------------------------------------
4245 /// Get reference to the current map key
4247 {
4248  return *(int *)hexdsp(hx_user_labels_first, &p);
4249 }
4250 
4251 //-------------------------------------------------------------------------
4252 /// Get reference to the current map value
4254 {
4255  return *(qstring *)hexdsp(hx_user_labels_second, &p);
4256 }
4257 
4258 //-------------------------------------------------------------------------
4259 /// Find the specified key in user_labels_t
4260 inline user_labels_iterator_t user_labels_find(const user_labels_t *map, const int &key)
4261 {
4263  hexdsp(hx_user_labels_find, &p, map, &key);
4264  return p;
4265 }
4266 
4267 //-------------------------------------------------------------------------
4268 /// Insert new (int, qstring) pair into user_labels_t
4269 inline user_labels_iterator_t user_labels_insert(user_labels_t *map, const int &key, const qstring &val)
4270 {
4272  hexdsp(hx_user_labels_insert, &p, map, &key, &val);
4273  return p;
4274 }
4275 
4276 //-------------------------------------------------------------------------
4277 /// Erase current element from user_labels_t
4278 inline void user_labels_erase(user_labels_t *map, user_labels_iterator_t p)
4279 {
4280  hexdsp(hx_user_labels_erase, map, &p);
4281 }
4282 
4283 //-------------------------------------------------------------------------
4284 /// Clear user_labels_t
4285 inline void user_labels_clear(user_labels_t *map)
4286 {
4287  hexdsp(hx_user_labels_clear, map);
4288 }
4289 
4290 //-------------------------------------------------------------------------
4291 /// Get size of user_labels_t
4292 inline size_t user_labels_size(user_labels_t *map)
4293 {
4294  return (size_t)hexdsp(hx_user_labels_size, map);
4295 }
4296 
4297 //-------------------------------------------------------------------------
4298 /// Delete user_labels_t instance
4299 inline void user_labels_free(user_labels_t *map)
4300 {
4301  hexdsp(hx_user_labels_free, map);
4302 }
4303 
4304 //-------------------------------------------------------------------------
4305 /// Create a new user_labels_t instance
4306 inline user_labels_t *user_labels_new(void)
4307 {
4308  return (user_labels_t *)hexdsp(hx_user_labels_new);
4309 }
4310 
4311 //-------------------------------------------------------------------------
4313 {
4314  iterator_word x;
4315  bool operator==(const eamap_iterator_t &p) const { return x == p.x; }
4316  bool operator!=(const eamap_iterator_t &p) const { return x != p.x; }
4317 };
4318 
4319 //-------------------------------------------------------------------------
4320 /// Get iterator pointing to the beginning of eamap_t
4321 inline eamap_iterator_t eamap_begin(const eamap_t *map)
4322 {
4323  eamap_iterator_t p;
4324  hexdsp(hx_eamap_begin, &p, map);
4325  return p;
4326 }
4327 
4328 //-------------------------------------------------------------------------
4329 /// Get iterator pointing to the end of eamap_t
4330 inline eamap_iterator_t eamap_end(const eamap_t *map)
4331 {
4332  eamap_iterator_t p;
4333  hexdsp(hx_eamap_end, &p, map);
4334  return p;
4335 }
4336 
4337 //-------------------------------------------------------------------------
4338 /// Move to the next element
4340 {
4341  hexdsp(hx_eamap_next, &p);
4342  return p;
4343 }
4344 
4345 //-------------------------------------------------------------------------
4346 /// Move to the previous element
4348 {
4349  hexdsp(hx_eamap_prev, &p);
4350  return p;
4351 }
4352 
4353 //-------------------------------------------------------------------------
4354 /// Get reference to the current map key
4355 inline ea_t const &eamap_first(eamap_iterator_t p)
4356 {
4357  return *(ea_t *)hexdsp(hx_eamap_first, &p);
4358 }
4359 
4360 //-------------------------------------------------------------------------
4361 /// Get reference to the current map value
4362 inline cinsnptrvec_t &eamap_second(eamap_iterator_t p)
4363 {
4364  return *(cinsnptrvec_t *)hexdsp(hx_eamap_second, &p);
4365 }
4366 
4367 //-------------------------------------------------------------------------
4368 /// Find the specified key in eamap_t
4369 inline eamap_iterator_t eamap_find(const eamap_t *map, const ea_t &key)
4370 {
4371  eamap_iterator_t p;
4372  hexdsp(hx_eamap_find, &p, map, &key);
4373  return p;
4374 }
4375 
4376 //-------------------------------------------------------------------------
4377 /// Insert new (ea_t, cinsnptrvec_t) pair into eamap_t
4378 inline eamap_iterator_t eamap_insert(eamap_t *map, const ea_t &key, const cinsnptrvec_t &val)
4379 {
4380  eamap_iterator_t p;
4381  hexdsp(hx_eamap_insert, &p, map, &key, &val);
4382  return p;
4383 }
4384 
4385 //-------------------------------------------------------------------------
4386 /// Erase current element from eamap_t
4387 inline void eamap_erase(eamap_t *map, eamap_iterator_t p)
4388 {
4389  hexdsp(hx_eamap_erase, map, &p);
4390 }
4391 
4392 //-------------------------------------------------------------------------
4393 /// Clear eamap_t
4394 inline void eamap_clear(eamap_t *map)
4395 {
4396  hexdsp(hx_eamap_clear, map);
4397 }
4398 
4399 //-------------------------------------------------------------------------
4400 /// Get size of eamap_t
4401 inline size_t eamap_size(eamap_t *map)
4402 {
4403  return (size_t)hexdsp(hx_eamap_size, map);
4404 }
4405 
4406 //-------------------------------------------------------------------------
4407 /// Delete eamap_t instance
4408 inline void eamap_free(eamap_t *map)
4409 {
4410  hexdsp(hx_eamap_free, map);
4411 }
4412 
4413 //-------------------------------------------------------------------------
4414 /// Create a new eamap_t instance
4415 inline eamap_t *eamap_new(void)
4416 {
4417  return (eamap_t *)hexdsp(hx_eamap_new);
4418 }
4419 
4420 //-------------------------------------------------------------------------
4422 {
4423  iterator_word x;
4424  bool operator==(const boundaries_iterator_t &p) const { return x == p.x; }
4425  bool operator!=(const boundaries_iterator_t &p) const { return x != p.x; }
4426 };
4427 
4428 //-------------------------------------------------------------------------
4429 /// Get iterator pointing to the beginning of boundaries_t
4430 inline boundaries_iterator_t boundaries_begin(const boundaries_t *map)
4431 {
4433  hexdsp(hx_boundaries_begin, &p, map);
4434  return p;
4435 }
4436 
4437 //-------------------------------------------------------------------------
4438 /// Get iterator pointing to the end of boundaries_t
4439 inline boundaries_iterator_t boundaries_end(const boundaries_t *map)
4440 {
4442  hexdsp(hx_boundaries_end, &p, map);
4443  return p;
4444 }
4445 
4446 //-------------------------------------------------------------------------
4447 /// Move to the next element
4449 {
4450  hexdsp(hx_boundaries_next, &p);
4451  return p;
4452 }
4453 
4454 //-------------------------------------------------------------------------
4455 /// Move to the previous element
4457 {
4458  hexdsp(hx_boundaries_prev, &p);
4459  return p;
4460 }
4461 
4462 //-------------------------------------------------------------------------
4463 /// Get reference to the current map key
4465 {
4466  return *(cinsn_t * *)hexdsp(hx_boundaries_first, &p);
4467 }
4468 
4469 //-------------------------------------------------------------------------
4470 /// Get reference to the current map value
4472 {
4473  return *(rangeset_t *)hexdsp(hx_boundaries_second, &p);
4474 }
4475 
4476 //-------------------------------------------------------------------------
4477 /// Find the specified key in boundaries_t
4478 inline boundaries_iterator_t boundaries_find(const boundaries_t *map, const cinsn_t * &key)
4479 {
4481  hexdsp(hx_boundaries_find, &p, map, &key);
4482  return p;
4483 }
4484 
4485 //-------------------------------------------------------------------------
4486 /// Insert new (cinsn_t *, rangeset_t) pair into boundaries_t
4487 inline boundaries_iterator_t boundaries_insert(boundaries_t *map, const cinsn_t * &key, const rangeset_t &val)
4488 {
4490  hexdsp(hx_boundaries_insert, &p, map, &key, &val);
4491  return p;
4492 }
4493 
4494 //-------------------------------------------------------------------------
4495 /// Erase current element from boundaries_t
4496 inline void boundaries_erase(boundaries_t *map, boundaries_iterator_t p)
4497 {
4498  hexdsp(hx_boundaries_erase, map, &p);
4499 }
4500 
4501 //-------------------------------------------------------------------------
4502 /// Clear boundaries_t
4503 inline void boundaries_clear(boundaries_t *map)
4504 {
4505  hexdsp(hx_boundaries_clear, map);
4506 }
4507 
4508 //-------------------------------------------------------------------------
4509 /// Get size of boundaries_t
4510 inline size_t boundaries_size(boundaries_t *map)
4511 {
4512  return (size_t)hexdsp(hx_boundaries_size, map);
4513 }
4514 
4515 //-------------------------------------------------------------------------
4516 /// Delete boundaries_t instance
4517 inline void boundaries_free(boundaries_t *map)
4518 {
4519  hexdsp(hx_boundaries_free, map);
4520 }
4521 
4522 //-------------------------------------------------------------------------
4523 /// Create a new boundaries_t instance
4524 inline boundaries_t *boundaries_new(void)
4525 {
4526  return (boundaries_t *)hexdsp(hx_boundaries_new);
4527 }
4528 
4529 //--------------------------------------------------------------------------
4530 inline int operand_locator_t::compare(const operand_locator_t &r) const
4531 {
4532  return (int)(size_t)hexdsp(hx_operand_locator_t_compare, this, &r);
4533 }
4534 
4535 //--------------------------------------------------------------------------
4536 inline AS_PRINTF(3, 4) int vd_printer_t::print(int indent, const char *format, ...)
4537 {
4538  va_list va;
4539  va_start(va, format);
4540  int retval = (int)(size_t)hexdsp(hx_vd_printer_t_print, this, indent, format, va);
4541  va_end(va);
4542  return retval;
4543 }
4544 
4545 //--------------------------------------------------------------------------
4546 inline AS_PRINTF(3, 4) int qstring_printer_t::print(int indent, const char *format, ...)
4547 {
4548  va_list va;
4549  va_start(va, format);
4550  int retval = (int)(size_t)hexdsp(hx_qstring_printer_t_print, this, indent, format, va);
4551  va_end(va);
4552  return retval;
4553 }
4554 
4555 //--------------------------------------------------------------------------
4556 inline bool is_type_correct(const type_t *ptr)
4557 {
4558  return (uchar)(size_t)hexdsp(hx_is_type_correct, ptr) != 0;
4559 }
4560 
4561 //--------------------------------------------------------------------------
4562 inline bool is_small_struni(const tinfo_t &tif)
4563 {
4564  return (uchar)(size_t)hexdsp(hx_is_small_struni, &tif) != 0;
4565 }
4566 
4567 //--------------------------------------------------------------------------
4568 inline bool is_nonbool_type(const tinfo_t &type)
4569 {
4570  return (uchar)(size_t)hexdsp(hx_is_nonbool_type, &type) != 0;
4571 }
4572 
4573 //--------------------------------------------------------------------------
4574 inline bool is_bool_type(const tinfo_t &type)
4575 {
4576  return (uchar)(size_t)hexdsp(hx_is_bool_type, &type) != 0;
4577 }
4578 
4579 //--------------------------------------------------------------------------
4580 inline int partial_type_num(const tinfo_t &type)
4581 {
4582  return (int)(size_t)hexdsp(hx_partial_type_num, &type);
4583 }
4584 
4585 //--------------------------------------------------------------------------
4586 inline tinfo_t get_float_type(int width)
4587 {
4588  tinfo_t retval;
4589  hexdsp(hx_get_float_type, &retval, width);
4590  return retval;
4591 }
4592 
4593 //--------------------------------------------------------------------------
4594 inline tinfo_t get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign)
4595 {
4596  tinfo_t retval;
4597  hexdsp(hx_get_int_type_by_width_and_sign, &retval, srcwidth, sign);
4598  return retval;
4599 }
4600 
4601 //--------------------------------------------------------------------------
4602 inline tinfo_t get_unk_type(int size)
4603 {
4604  tinfo_t retval;
4605  hexdsp(hx_get_unk_type, &retval, size);
4606  return retval;
4607 }
4608 
4609 //--------------------------------------------------------------------------
4610 inline tinfo_t dummy_ptrtype(int ptrsize, bool isfp)
4611 {
4612  tinfo_t retval;
4613  hexdsp(hx_dummy_ptrtype, &retval, ptrsize, isfp);
4614  return retval;
4615 }
4616 
4617 //--------------------------------------------------------------------------
4618 inline bool get_member_type(const member_t *mptr, tinfo_t *type)
4619 {
4620  return (uchar)(size_t)hexdsp(hx_get_member_type, mptr, type) != 0;
4621 }
4622 
4623 //--------------------------------------------------------------------------
4624 inline tinfo_t make_pointer(const tinfo_t &type)
4625 {
4626  tinfo_t retval;
4627  hexdsp(hx_make_pointer, &retval, &type);
4628  return retval;
4629 }
4630 
4631 //--------------------------------------------------------------------------
4632 inline tinfo_t create_typedef(const char *name)
4633 {
4634  tinfo_t retval;
4635  hexdsp(hx_create_typedef, &retval, name);
4636  return retval;
4637 }
4638 
4639 //--------------------------------------------------------------------------
4640 inline bool get_type(uval_t id, tinfo_t *tif, type_source_t guess)
4641 {
4642  return (uchar)(size_t)hexdsp(hx_get_type, &id, tif, guess) != 0;
4643 }
4644 
4645 //--------------------------------------------------------------------------
4646 inline bool set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force)
4647 {
4648  return (uchar)(size_t)hexdsp(hx_set_type, &id, &tif, source, force) != 0;
4649 }
4650 
4651 //--------------------------------------------------------------------------
4652 inline size_t print_vdloc(char *buf, size_t bufsize, const vdloc_t &loc, int w)
4653 {
4654  return (size_t)hexdsp(hx_print_vdloc, buf, bufsize, &loc, w);
4655 }
4656 
4657 //--------------------------------------------------------------------------
4658 inline bool arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2)
4659 {
4660  return (uchar)(size_t)hexdsp(hx_arglocs_overlap, &loc1, w1, &loc2, w2) != 0;
4661 }
4662 
4663 //--------------------------------------------------------------------------
4664 inline sval_t lvar_locator_t::get_regnum(void) const
4665 {
4666  sval_t retval;
4667  hexdsp(hx_lvar_locator_t_get_regnum, &retval, this);
4668  return retval;
4669 }
4670 
4671 //--------------------------------------------------------------------------
4672 inline int lvar_locator_t::compare(const lvar_locator_t &r) const
4673 {
4674  return (int)(size_t)hexdsp(hx_lvar_locator_t_compare, this, &r);
4675 }
4676 
4677 //--------------------------------------------------------------------------
4678 inline bool lvar_t::accepts_type(const tinfo_t &t)
4679 {
4680  return (uchar)(size_t)hexdsp(hx_lvar_t_accepts_type, this, &t) != 0;
4681 }
4682 
4683 //--------------------------------------------------------------------------
4684 inline bool lvar_t::set_lvar_type(const tinfo_t &t, bool may_fail)
4685 {
4686  return (uchar)(size_t)hexdsp(hx_lvar_t_set_lvar_type, this, &t, may_fail) != 0;
4687 }
4688 
4689 //--------------------------------------------------------------------------
4690 inline bool lvar_t::set_width(int w, int svw_flags)
4691 {
4692  return (uchar)(size_t)hexdsp(hx_lvar_t_set_width, this, w, svw_flags) != 0;
4693 }
4694 
4695 //--------------------------------------------------------------------------
4696 inline int lvars_t::find_stkvar(int32 spoff, int width)
4697 {
4698  return (int)(size_t)hexdsp(hx_lvars_t_find_stkvar, this, spoff, width);
4699 }
4700 
4701 //--------------------------------------------------------------------------
4703 {
4704  return (lvar_t *)hexdsp(hx_lvars_t_find, this, &ll);
4705 }
4706 
4707 //--------------------------------------------------------------------------
4708 inline int lvars_t::find_lvar(const vdloc_t &location, int width, int defblk)
4709 {
4710  return (int)(size_t)hexdsp(hx_lvars_t_find_lvar, this, &location, width, defblk);
4711 }
4712 
4713 //--------------------------------------------------------------------------
4714 inline bool restore_user_lvar_settings(lvar_uservec_t *lvinf, ea_t func_ea)
4715 {
4716  return (uchar)(size_t)hexdsp(hx_restore_user_lvar_settings, lvinf, &func_ea) != 0;
4717 }
4718 
4719 //--------------------------------------------------------------------------
4720 inline void save_user_lvar_settings(ea_t func_ea, const lvar_uservec_t &lvinf)
4721 {
4722  hexdsp(hx_save_user_lvar_settings, &func_ea, &lvinf);
4723 }
4724 
4725 //--------------------------------------------------------------------------
4726 inline bool modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv)
4727 {
4728  return (uchar)(size_t)hexdsp(hx_modify_user_lvars, &entry_ea, &mlv) != 0;
4729 }
4730 
4731 //--------------------------------------------------------------------------
4732 inline bool restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea)
4733 {
4734  return (uchar)(size_t)hexdsp(hx_restore_user_defined_calls, udcalls, &func_ea) != 0;
4735 }
4736 
4737 //--------------------------------------------------------------------------
4738 inline void save_user_defined_calls(ea_t func_ea, const udcall_map_t &udcalls)
4739 {
4740  hexdsp(hx_save_user_defined_calls, &func_ea, &udcalls);
4741 }
4742 
4743 //--------------------------------------------------------------------------
4744 inline bool parse_user_call(udcall_t *udc, const char *decl, bool silent)
4745 {
4746  return (uchar)(size_t)hexdsp(hx_parse_user_call, udc, decl, silent) != 0;
4747 }
4748 
4749 //--------------------------------------------------------------------------
4750 inline int convert_to_user_call(const udcall_t &udc, codegen_t &cdg)
4751 {
4752  return (int)(size_t)hexdsp(hx_convert_to_user_call, &udc, &cdg);
4753 }
4754 
4755 //--------------------------------------------------------------------------
4756 inline void install_microcode_filter(microcode_filter_t *filter, bool install)
4757 {
4758  hexdsp(hx_install_microcode_filter, filter, install);
4759 }
4760 
4761 //--------------------------------------------------------------------------
4762 inline bool udc_filter_t::init(const char *decl)
4763 {
4764  return (uchar)(size_t)hexdsp(hx_udc_filter_t_init, this, decl) != 0;
4765 }
4766 
4767 //--------------------------------------------------------------------------
4769 {
4770  return (int)(size_t)hexdsp(hx_udc_filter_t_apply, this, &cdg);
4771 }
4772 
4773 //--------------------------------------------------------------------------
4774 inline size_t fnumber_t::print(char *buf, size_t bufsize) const
4775 {
4776  return (size_t)hexdsp(hx_fnumber_t_print, this, buf, bufsize);
4777 }
4778 
4779 //--------------------------------------------------------------------------
4780 inline const char *get_hexrays_version(void)
4781 {
4782  return (const char *)hexdsp(hx_get_hexrays_version);
4783 }
4784 
4785 //--------------------------------------------------------------------------
4786 inline vdui_t *open_pseudocode(ea_t ea, int new_window)
4787 {
4788  return (vdui_t *)hexdsp(hx_open_pseudocode, &ea, new_window);
4789 }
4790 
4791 //--------------------------------------------------------------------------
4792 inline bool close_pseudocode(TWidget *f)
4793 {
4794  return (uchar)(size_t)hexdsp(hx_close_pseudocode, f) != 0;
4795 }
4796 
4797 //--------------------------------------------------------------------------
4799 {
4800  return (vdui_t *)hexdsp(hx_get_widget_vdui, f);
4801 }
4802 
4803 //--------------------------------------------------------------------------
4804 inline bool decompile_many(const char *outfile, eavec_t *funcaddrs, int flags)
4805 {
4806  return (uchar)(size_t)hexdsp(hx_decompile_many, outfile, funcaddrs, flags) != 0;
4807 }
4808 
4809 //--------------------------------------------------------------------------
4810 inline const char *micro_err_format(int code)
4811 {
4812  return (const char *)hexdsp(hx_micro_err_format, code);
4813 }
4814 
4815 //--------------------------------------------------------------------------
4816 inline qstring hexrays_failure_t::desc(void) const
4817 {
4818  qstring retval;
4819  hexdsp(hx_hexrays_failure_t_desc, &retval, this);
4820  return retval;
4821 }
4822 
4823 //--------------------------------------------------------------------------
4824 inline void send_database(const hexrays_failure_t &err, bool silent)
4825 {
4826  hexdsp(hx_send_database, &err, silent);
4827 }
4828 
4829 //--------------------------------------------------------------------------
4831 {
4832  return (ctype_t)(size_t)hexdsp(hx_negated_relation, op);
4833 }
4834 
4835 //--------------------------------------------------------------------------
4836 inline type_sign_t get_op_signness(ctype_t op)
4837 {
4838  return (type_sign_t)(size_t)hexdsp(hx_get_op_signness, op);
4839 }
4840 
4841 //--------------------------------------------------------------------------
4842 inline ctype_t asgop(ctype_t cop)
4843 {
4844  return (ctype_t)(size_t)hexdsp(hx_asgop, cop);
4845 }
4846 
4847 //--------------------------------------------------------------------------
4849 {
4850  return (ctype_t)(size_t)hexdsp(hx_asgop_revert, cop);
4851 }
4852 
4853 //--------------------------------------------------------------------------
4854 inline size_t cnumber_t::print(char *buf, size_t bufsize, const tinfo_t &type, const citem_t *parent, bool *nice_stroff) const
4855 {
4856  return (size_t)hexdsp(hx_cnumber_t_print, this, buf, bufsize, &type, parent, nice_stroff);
4857 }
4858 
4859 //--------------------------------------------------------------------------
4860 inline uint64 cnumber_t::value(const tinfo_t &type) const
4861 {
4862  uint64 retval;
4863  hexdsp(hx_cnumber_t_value, &retval, this, &type);
4864  return retval;
4865 }
4866 
4867 //--------------------------------------------------------------------------
4868 inline void cnumber_t::assign(uint64 v, int nbytes, type_sign_t sign)
4869 {
4870  hexdsp(hx_cnumber_t_assign, this, &v, nbytes, sign);
4871 }
4872 
4873 //--------------------------------------------------------------------------
4874 inline int cnumber_t::compare(const cnumber_t &r) const
4875 {
4876  return (int)(size_t)hexdsp(hx_cnumber_t_compare, this, &r);
4877 }
4878 
4879 //--------------------------------------------------------------------------
4880 inline int var_ref_t::compare(const var_ref_t &r) const
4881 {
4882  return (int)(size_t)hexdsp(hx_var_ref_t_compare, this, &r);
4883 }
4884 
4885 //--------------------------------------------------------------------------
4886 inline int ctree_visitor_t::apply_to(citem_t *item, citem_t *parent)
4887 {
4888  return (int)(size_t)hexdsp(hx_ctree_visitor_t_apply_to, this, item, parent);
4889 }
4890 
4891 //--------------------------------------------------------------------------
4893 {
4894  return (int)(size_t)hexdsp(hx_ctree_visitor_t_apply_to_exprs, this, item, parent);
4895 }
4896 
4897 //--------------------------------------------------------------------------
4899 {
4900  return (uchar)(size_t)hexdsp(hx_ctree_parentee_t_recalc_parent_types, this) != 0;
4901 }
4902 
4903 //--------------------------------------------------------------------------
4904 inline bool cfunc_parentee_t::calc_rvalue_type(tinfo_t *target, const cexpr_t *e)
4905 {
4906  return (uchar)(size_t)hexdsp(hx_cfunc_parentee_t_calc_rvalue_type, this, target, e) != 0;
4907 }
4908 
4909 //--------------------------------------------------------------------------
4910 inline int citem_locator_t::compare(const citem_locator_t &r) const
4911 {
4912  return (int)(size_t)hexdsp(hx_citem_locator_t_compare, this, &r);
4913 }
4914 
4915 //--------------------------------------------------------------------------
4916 inline bool citem_t::contains_label(void) const
4917 {
4918  return (uchar)(size_t)hexdsp(hx_citem_t_contains_label, this) != 0;
4919 }
4920 
4921 //--------------------------------------------------------------------------
4922 inline const citem_t *citem_t::find_parent_of(const citem_t *sitem) const
4923 {
4924  return (const citem_t *)hexdsp(hx_citem_t_find_parent_of, this, sitem);
4925 }
4926 
4927 //--------------------------------------------------------------------------
4928 inline cexpr_t &cexpr_t::assign(const cexpr_t &r)
4929 {
4930  return *(cexpr_t *)hexdsp(hx_cexpr_t_assign, this, &r);
4931 }
4932 
4933 //--------------------------------------------------------------------------
4934 inline int cexpr_t::compare(const cexpr_t &r) const
4935 {
4936  return (int)(size_t)hexdsp(hx_cexpr_t_compare, this, &r);
4937 }
4938 
4939 //--------------------------------------------------------------------------
4941 {
4942  hexdsp(hx_cexpr_t_replace_by, this, r);
4943 }
4944 
4945 //--------------------------------------------------------------------------
4946 inline void cexpr_t::cleanup(void)
4947 {
4948  hexdsp(hx_cexpr_t_cleanup, this);
4949 }
4950 
4951 //--------------------------------------------------------------------------
4952 inline void cexpr_t::put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign)
4953 {
4954  hexdsp(hx_cexpr_t_put_number, this, func, &value, nbytes, sign);
4955 }
4956 
4957 //--------------------------------------------------------------------------
4958 inline size_t cexpr_t::print1(char *buf, size_t bufsize, const cfunc_t *func) const
4959 {
4960  return (size_t)hexdsp(hx_cexpr_t_print1, this, buf, bufsize, func);
4961 }
4962 
4963 //--------------------------------------------------------------------------
4964 inline void cexpr_t::calc_type(bool recursive)
4965 {
4966  hexdsp(hx_cexpr_t_calc_type, this, recursive);
4967 }
4968 
4969 //--------------------------------------------------------------------------
4970 inline bool cexpr_t::equal_effect(const cexpr_t &r) const
4971 {
4972  return (uchar)(size_t)hexdsp(hx_cexpr_t_equal_effect, this, &r) != 0;
4973 }
4974 
4975 //--------------------------------------------------------------------------
4976 inline bool cexpr_t::is_child_of(const citem_t *parent) const
4977 {
4978  return (uchar)(size_t)hexdsp(hx_cexpr_t_is_child_of, this, parent) != 0;
4979 }
4980 
4981 //--------------------------------------------------------------------------
4982 inline bool cexpr_t::contains_operator(ctype_t needed_op, int times) const
4983 {
4984  return (uchar)(size_t)hexdsp(hx_cexpr_t_contains_operator, this, needed_op, times) != 0;
4985 }
4986 
4987 //--------------------------------------------------------------------------
4988 inline int cexpr_t::get_high_nbit_bound(int pbits, type_sign_t psign, bool *p_maybe_negative) const
4989 {
4990  return (int)(size_t)hexdsp(hx_cexpr_t_get_high_nbit_bound, this, pbits, psign, p_maybe_negative);
4991 }
4992 
4993 //--------------------------------------------------------------------------
4994 inline int cexpr_t::get_low_nbit_bound(type_sign_t psign, bool *p_maybe_negative) const
4995 {
4996  return (int)(size_t)hexdsp(hx_cexpr_t_get_low_nbit_bound, this, psign, p_maybe_negative);
4997 }
4998 
4999 //--------------------------------------------------------------------------
5000 inline bool cexpr_t::requires_lvalue(const cexpr_t *child) const
5001 {
5002  return (uchar)(size_t)hexdsp(hx_cexpr_t_requires_lvalue, this, child) != 0;
5003 }
5004 
5005 //--------------------------------------------------------------------------
5006 inline bool cexpr_t::has_side_effects(void) const
5007 {
5008  return (uchar)(size_t)hexdsp(hx_cexpr_t_has_side_effects, this) != 0;
5009 }
5010 
5011 //--------------------------------------------------------------------------
5012 inline cif_t &cif_t::assign(const cif_t &r)
5013 {
5014  return *(cif_t *)hexdsp(hx_cif_t_assign, this, &r);
5015 }
5016 
5017 //--------------------------------------------------------------------------
5018 inline int cif_t::compare(const cif_t &r) const
5019 {
5020  return (int)(size_t)hexdsp(hx_cif_t_compare, this, &r);
5021 }
5022 
5023 //--------------------------------------------------------------------------
5024 inline cloop_t &cloop_t::assign(const cloop_t &r)
5025 {
5026  return *(cloop_t *)hexdsp(hx_cloop_t_assign, this, &r);
5027 }
5028 
5029 //--------------------------------------------------------------------------
5030 inline int cfor_t::compare(const cfor_t &r) const
5031 {
5032  return (int)(size_t)hexdsp(hx_cfor_t_compare, this, &r);
5033 }
5034 
5035 //--------------------------------------------------------------------------
5036 inline int cwhile_t::compare(const cwhile_t &r) const
5037 {
5038  return (int)(size_t)hexdsp(hx_cwhile_t_compare, this, &r);
5039 }
5040 
5041 //--------------------------------------------------------------------------
5042 inline int cdo_t::compare(const cdo_t &r) const
5043 {
5044  return (int)(size_t)hexdsp(hx_cdo_t_compare, this, &r);
5045 }
5046 
5047 //--------------------------------------------------------------------------
5048 inline int creturn_t::compare(const creturn_t &r) const
5049 {
5050  return (int)(size_t)hexdsp(hx_creturn_t_compare, this, &r);
5051 }
5052 
5053 //--------------------------------------------------------------------------
5054 inline int cgoto_t::compare(const cgoto_t &r) const
5055 {
5056  return (int)(size_t)hexdsp(hx_cgoto_t_compare, this, &r);
5057 }
5058 
5059 //--------------------------------------------------------------------------
5060 inline int casm_t::compare(const casm_t &r) const
5061 {
5062  return (int)(size_t)hexdsp(hx_casm_t_compare, this, &r);
5063 }
5064 
5065 //--------------------------------------------------------------------------
5066 inline cinsn_t &cinsn_t::assign(const cinsn_t &r)
5067 {
5068  return *(cinsn_t *)hexdsp(hx_cinsn_t_assign, this, &r);
5069 }
5070 
5071 //--------------------------------------------------------------------------
5072 inline int cinsn_t::compare(const cinsn_t &r) const
5073 {
5074  return (int)(size_t)hexdsp(hx_cinsn_t_compare, this, &r);
5075 }
5076 
5077 //--------------------------------------------------------------------------
5079 {
5080  hexdsp(hx_cinsn_t_replace_by, this, r);
5081 }
5082 
5083 //--------------------------------------------------------------------------
5084 inline void cinsn_t::cleanup(void)
5085 {
5086  hexdsp(hx_cinsn_t_cleanup, this);
5087 }
5088 
5089 //--------------------------------------------------------------------------
5090 inline cinsn_t &cinsn_t::new_insn(ea_t insn_ea)
5091 {
5092  return *(cinsn_t *)hexdsp(hx_cinsn_t_new_insn, this, &insn_ea);
5093 }
5094 
5095 //--------------------------------------------------------------------------
5097 {
5098  return *(cif_t *)hexdsp(hx_cinsn_t_create_if, this, cnd);
5099 }
5100 
5101 //--------------------------------------------------------------------------
5102 inline void cinsn_t::print(int indent, vc_printer_t &vp, use_curly_t use_curly) const
5103 {
5104  hexdsp(hx_cinsn_t_print, this, indent, &vp, use_curly);
5105 }
5106 
5107 //--------------------------------------------------------------------------
5108 inline size_t cinsn_t::print1(char *buf, size_t bufsize, const cfunc_t *func) const
5109 {
5110  return (size_t)hexdsp(hx_cinsn_t_print1, this, buf, bufsize, func);
5111 }
5112 
5113 //--------------------------------------------------------------------------
5114 inline bool cinsn_t::is_ordinary_flow(void) const
5115 {
5116  return (uchar)(size_t)hexdsp(hx_cinsn_t_is_ordinary_flow, this) != 0;
5117 }
5118 
5119 //--------------------------------------------------------------------------
5120 inline bool cinsn_t::contains_insn(ctype_t type, int times) const
5121 {
5122  return (uchar)(size_t)hexdsp(hx_cinsn_t_contains_insn, this, type, times) != 0;
5123 }
5124 
5125 //--------------------------------------------------------------------------
5126 inline bool cinsn_t::collect_free_breaks(cinsnptrvec_t *breaks)
5127 {
5128  return (uchar)(size_t)hexdsp(hx_cinsn_t_collect_free_breaks, this, breaks) != 0;
5129 }
5130 
5131 //--------------------------------------------------------------------------
5132 inline bool cinsn_t::collect_free_continues(cinsnptrvec_t *continues)
5133 {
5134  return (uchar)(size_t)hexdsp(hx_cinsn_t_collect_free_continues, this, continues) != 0;
5135 }
5136 
5137 //--------------------------------------------------------------------------
5138 inline int cblock_t::compare(const cblock_t &r) const
5139 {
5140  return (int)(size_t)hexdsp(hx_cblock_t_compare, this, &r);
5141 }
5142 
5143 //--------------------------------------------------------------------------
5144 inline int carglist_t::compare(const carglist_t &r) const
5145 {
5146  return (int)(size_t)hexdsp(hx_carglist_t_compare, this, &r);
5147 }
5148 
5149 //--------------------------------------------------------------------------
5150 inline int ccase_t::compare(const ccase_t &r) const
5151 {
5152  return (int)(size_t)hexdsp(hx_ccase_t_compare, this, &r);
5153 }
5154 
5155 //--------------------------------------------------------------------------
5156 inline int ccases_t::compare(const ccases_t &r) const
5157 {
5158  return (int)(size_t)hexdsp(hx_ccases_t_compare, this, &r);
5159 }
5160 
5161 //--------------------------------------------------------------------------
5162 inline int cswitch_t::compare(const cswitch_t &r) const
5163 {
5164  return (int)(size_t)hexdsp(hx_cswitch_t_compare, this, &r);
5165 }
5166 
5167 //--------------------------------------------------------------------------
5168 inline member_t *ctree_item_t::get_memptr(struc_t **p_sptr) const
5169 {
5170  return (member_t *)hexdsp(hx_ctree_item_t_get_memptr, this, p_sptr);
5171 }
5172 
5173 //--------------------------------------------------------------------------
5174 inline lvar_t *ctree_item_t::get_lvar(void) const
5175 {
5176  return (lvar_t *)hexdsp(hx_ctree_item_t_get_lvar, this);
5177 }
5178 
5179 //--------------------------------------------------------------------------
5180 inline ea_t ctree_item_t::get_ea(void) const
5181 {
5182  ea_t retval;
5183  hexdsp(hx_ctree_item_t_get_ea, &retval, this);
5184  return retval;
5185 }
5186 
5187 //--------------------------------------------------------------------------
5188 inline int ctree_item_t::get_label_num(int gln_flags) const
5189 {
5190  return (int)(size_t)hexdsp(hx_ctree_item_t_get_label_num, this, gln_flags);
5191 }
5192 
5193 //--------------------------------------------------------------------------
5194 inline cexpr_t *lnot(cexpr_t *e)
5195 {
5196  return (cexpr_t *)hexdsp(hx_lnot, e);
5197 }
5198 
5199 //--------------------------------------------------------------------------
5200 inline cinsn_t *new_block(void)
5201 {
5202  return (cinsn_t *)hexdsp(hx_new_block);
5203 }
5204 
5205 //--------------------------------------------------------------------------
5206 inline AS_PRINTF(3, 0) cexpr_t *vcreate_helper(bool standalone, const tinfo_t &type, const char *format, va_list va)
5207 {
5208  return (cexpr_t *)hexdsp(hx_vcreate_helper, standalone, &type, format, va);
5209 }
5210 
5211 //--------------------------------------------------------------------------
5212 inline AS_PRINTF(3, 0) cexpr_t *vcall_helper(const tinfo_t &rettype, carglist_t *args, const char *format, va_list va)
5213 {
5214  return (cexpr_t *)hexdsp(hx_vcall_helper, &rettype, args, format, va);
5215 }
5216 
5217 //--------------------------------------------------------------------------
5218 inline cexpr_t *make_num(uint64 n, cfunc_t *func, ea_t ea, int opnum, type_sign_t sign, int size)
5219 {
5220  return (cexpr_t *)hexdsp(hx_make_num, &n, func, &ea, opnum, sign, size);
5221 }
5222 
5223 //--------------------------------------------------------------------------
5225 {
5226  return (cexpr_t *)hexdsp(hx_make_ref, e);
5227 }
5228 
5229 //--------------------------------------------------------------------------
5230 inline cexpr_t *dereference(cexpr_t *e, int ptrsize, bool is_flt)
5231 {
5232  return (cexpr_t *)hexdsp(hx_dereference, e, ptrsize, is_flt);
5233 }
5234 
5235 //--------------------------------------------------------------------------
5236 inline void save_user_labels(ea_t func_ea, const user_labels_t *user_labels)
5237 {
5238  hexdsp(hx_save_user_labels, &func_ea, user_labels);
5239 }
5240 
5241 //--------------------------------------------------------------------------
5242 inline void save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts)
5243 {
5244  hexdsp(hx_save_user_cmts, &func_ea, user_cmts);
5245 }
5246 
5247 //--------------------------------------------------------------------------
5248 inline void save_user_numforms(ea_t func_ea, const user_numforms_t *numforms)
5249 {
5250  hexdsp(hx_save_user_numforms, &func_ea, numforms);
5251 }
5252 
5253 //--------------------------------------------------------------------------
5254 inline void save_user_iflags(ea_t func_ea, const user_iflags_t *iflags)
5255 {
5256  hexdsp(hx_save_user_iflags, &func_ea, iflags);
5257 }
5258 
5259 //--------------------------------------------------------------------------
5260 inline void save_user_unions(ea_t func_ea, const user_unions_t *unions)
5261 {
5262  hexdsp(hx_save_user_unions, &func_ea, unions);
5263 }
5264 
5265 //--------------------------------------------------------------------------
5266 inline user_labels_t *restore_user_labels(ea_t func_ea)
5267 {
5268  return (user_labels_t *)hexdsp(hx_restore_user_labels, &func_ea);
5269 }
5270 
5271 //--------------------------------------------------------------------------
5272 inline user_cmts_t *restore_user_cmts(ea_t func_ea)
5273 {
5274  return (user_cmts_t *)hexdsp(hx_restore_user_cmts, &func_ea);
5275 }
5276 
5277 //--------------------------------------------------------------------------
5278 inline user_numforms_t *restore_user_numforms(ea_t func_ea)
5279 {
5280  return (user_numforms_t *)hexdsp(hx_restore_user_numforms, &func_ea);
5281 }
5282 
5283 //--------------------------------------------------------------------------
5284 inline user_iflags_t *restore_user_iflags(ea_t func_ea)
5285 {
5286  return (user_iflags_t *)