struct value * value_nsstring (struct gdbarch *gdbarch, char *ptr, int len) { struct type *char_type = builtin_type (gdbarch)->builtin_char; struct value *stringValue[3]; struct value *function, *nsstringValue; struct symbol *sym; struct type *type; if (!target_has_execution) return 0; /* Can't call into inferior to create NSString. */ stringValue[2] = value_string(ptr, len, char_type); stringValue[2] = value_coerce_array(stringValue[2]); /* _NSNewStringFromCString replaces "istr" after Lantern2A. */ if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym) { function = find_function_in_inferior("_NSNewStringFromCString", NULL); nsstringValue = call_function_by_hand(function, 1, &stringValue[2]); } else if (lookup_minimal_symbol("istr", 0, 0).minsym) { function = find_function_in_inferior("istr", NULL); nsstringValue = call_function_by_hand(function, 1, &stringValue[2]); } else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym) { function = find_function_in_inferior("+[NSString stringWithCString:]", NULL); type = builtin_type (gdbarch)->builtin_long; stringValue[0] = value_from_longest (type, lookup_objc_class (gdbarch, "NSString")); stringValue[1] = value_from_longest (type, lookup_child_selector (gdbarch, "stringWithCString:")); nsstringValue = call_function_by_hand(function, 3, &stringValue[0]); } else error (_("NSString: internal error -- no way to create new NSString")); sym = lookup_struct_typedef("NSString", 0, 1); if (sym == NULL) sym = lookup_struct_typedef("NXString", 0, 1); if (sym == NULL) type = builtin_type (gdbarch)->builtin_data_ptr; else type = lookup_pointer_type(SYMBOL_TYPE (sym)); deprecated_set_value_type (nsstringValue, type); return nsstringValue; }
CORE_ADDR lookup_child_selector (struct gdbarch *gdbarch, char *selname) { struct type *char_type = builtin_type (gdbarch)->builtin_char; struct value * function, *selstring; if (! target_has_execution) { /* Can't call into inferior to lookup selector. */ return 0; } if (lookup_minimal_symbol("sel_getUid", 0, 0).minsym) function = find_function_in_inferior("sel_getUid", NULL); else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0).minsym) function = find_function_in_inferior("sel_get_any_uid", NULL); else { complaint (&symfile_complaints, _("no way to lookup Objective-C selectors")); return 0; } selstring = value_coerce_array (value_string (selname, strlen (selname) + 1, char_type)); return value_as_long (call_function_by_hand (function, 1, &selstring)); }
CORE_ADDR lookup_objc_class (struct gdbarch *gdbarch, char *classname) { struct type *char_type = builtin_type (gdbarch)->builtin_char; struct value * function, *classval; if (! target_has_execution) { /* Can't call into inferior to lookup class. */ return 0; } if (lookup_minimal_symbol("objc_lookUpClass", 0, 0).minsym) function = find_function_in_inferior("objc_lookUpClass", NULL); else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0).minsym) function = find_function_in_inferior("objc_lookup_class", NULL); else { complaint (&symfile_complaints, _("no way to lookup Objective-C classes")); return 0; } classval = value_string (classname, strlen (classname) + 1, char_type); classval = value_coerce_array (classval); return (CORE_ADDR) value_as_long (call_function_by_hand (function, 1, &classval)); }
/* macosx_check_malloc_is_unsafe calls into LibC to see if the malloc lock * is taken by any thread. It returns 1 if malloc is locked, 0 if malloc * is unlocked, and -1 if LibC does not support the malloc lock check * function: */ static int macosx_check_malloc_is_unsafe(void) { static struct cached_value *malloc_check_fn = NULL; struct cleanup *scheduler_cleanup; struct value *volatile tmp_value = (struct value *volatile)NULL; struct gdb_exception e; int success; if (malloc_unsafe_flag != -1) return malloc_unsafe_flag; if (malloc_check_fn == NULL) { if (lookup_minimal_symbol("malloc_gdb_po_unsafe", 0, 0)) { struct type *func_type; func_type = builtin_type_int; func_type = lookup_function_type(func_type); func_type = lookup_pointer_type(func_type); malloc_check_fn = create_cached_function("malloc_gdb_po_unsafe", func_type); } else return -1; } if (debug_handcall_setup) printf_unfiltered("Overriding debugger mode to call malloc check function.\n"); scheduler_cleanup = make_cleanup_set_restore_scheduler_locking_mode(scheduler_locking_on); /* Suppress the objc runtime mode checking here: */ make_cleanup_set_restore_debugger_mode(NULL, 0); make_cleanup_set_restore_unwind_on_signal(1); TRY_CATCH(e, RETURN_MASK_ALL) { tmp_value = call_function_by_hand(lookup_cached_function(malloc_check_fn), 0, NULL); }
static bfd_vma call_target_sbrk (int sbrk_arg) { struct objfile *sbrk_objf; struct gdbarch *gdbarch; bfd_vma top_of_heap; struct value *target_sbrk_arg; struct value *sbrk_fn, *ret; bfd_vma tmp; if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) { sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf); if (sbrk_fn == NULL) return (bfd_vma) 0; } else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) { sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf); if (sbrk_fn == NULL) return (bfd_vma) 0; } else return (bfd_vma) 0; gdbarch = get_objfile_arch (sbrk_objf); target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, sbrk_arg); gdb_assert (target_sbrk_arg); ret = call_function_by_hand (sbrk_fn, 1, &target_sbrk_arg); if (ret == NULL) return (bfd_vma) 0; tmp = value_as_long (ret); if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff) return (bfd_vma) 0; top_of_heap = tmp; return top_of_heap; }
static int derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) { bfd_vma top_of_data_memory = 0; bfd_vma top_of_heap = 0; bfd_size_type sec_size; struct value *zero, *sbrk; bfd_vma sec_vaddr; asection *sec; gdb_assert (bottom); gdb_assert (top); /* This function depends on being able to call a function in the inferior. */ if (!target_has_execution) return 0; /* The following code assumes that the link map is arranged as follows (low to high addresses): --------------------------------- | text sections | --------------------------------- | data sections (including bss) | --------------------------------- | heap | --------------------------------- */ for (sec = abfd->sections; sec; sec = sec->next) { if (bfd_get_section_flags (abfd, sec) & SEC_DATA || strcmp (".bss", bfd_section_name (abfd, sec)) == 0) { sec_vaddr = bfd_get_section_vma (abfd, sec); sec_size = bfd_get_section_size (sec); if (sec_vaddr + sec_size > top_of_data_memory) top_of_data_memory = sec_vaddr + sec_size; } } /* Now get the top-of-heap by calling sbrk in the inferior. */ if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) { sbrk = find_function_in_inferior ("sbrk"); if (sbrk == NULL) return 0; } else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) { sbrk = find_function_in_inferior ("_sbrk"); if (sbrk == NULL) return 0; } else return 0; zero = value_from_longest (builtin_type_int, 0); gdb_assert (zero); sbrk = call_function_by_hand (sbrk, 1, &zero); if (sbrk == NULL) return 0; top_of_heap = value_as_long (sbrk); /* Return results. */ if (top_of_heap > top_of_data_memory) { *bottom = top_of_data_memory; *top = top_of_heap; return 1; } /* No additional heap space needs to be saved. */ return 0; }
static int ada_val_print_1 (struct type *type, char *valaddr0, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int len; int i; struct type *elttype; unsigned int eltlen; LONGEST val; char *valaddr = valaddr0 + embedded_offset; CHECK_TYPEDEF (type); if (ada_is_array_descriptor_type (type) || ada_is_packed_array_type (type)) { int retn; struct value *mark = value_mark (); struct value *val; val = value_from_contents_and_address (type, valaddr, address); val = ada_coerce_to_simple_array_ptr (val); if (val == NULL) { fprintf_filtered (stream, "(null)"); retn = 0; } else retn = ada_val_print_1 (VALUE_TYPE (val), VALUE_CONTENTS (val), 0, VALUE_ADDRESS (val), stream, format, deref_ref, recurse, pretty); value_free_to_mark (mark); return retn; } valaddr = ada_aligned_value_addr (type, valaddr); embedded_offset -= valaddr - valaddr0 - embedded_offset; type = printable_val_type (type, valaddr); switch (TYPE_CODE (type)) { default: return c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); case TYPE_CODE_PTR: { int ret = c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); if (ada_is_tag_type (type)) { struct value *val = value_from_contents_and_address (type, valaddr, address); const char *name = ada_tag_name (val); if (name != NULL) fprintf_filtered (stream, " (%s)", name); return 0; } return ret; } case TYPE_CODE_INT: case TYPE_CODE_RANGE: if (ada_is_fixed_point_type (type)) { LONGEST v = unpack_long (type, valaddr); int len = TYPE_LENGTH (type); fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g", (double) ada_fixed_to_float (type, v)); return 0; } else if (ada_is_vax_floating_type (type)) { struct value *val = value_from_contents_and_address (type, valaddr, address); struct value *func = ada_vax_float_print_function (type); if (func != 0) { static struct type *parray_of_char = NULL; struct value *printable_val; if (parray_of_char == NULL) parray_of_char = make_pointer_type (create_array_type (NULL, builtin_type_char, create_range_type (NULL, builtin_type_int, 0, 32)), NULL); printable_val = value_ind (value_cast (parray_of_char, call_function_by_hand (func, 1, &val))); fprintf_filtered (stream, "%s", VALUE_CONTENTS (printable_val)); return 0; } /* No special printing function. Do as best we can. */ } else if (TYPE_CODE (type) == TYPE_CODE_RANGE) { struct type *target_type = TYPE_TARGET_TYPE (type); if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type)) { /* Obscure case of range type that has different length from its base type. Perform a conversion, or we will get a nonsense value. Actually, we could use the same code regardless of lengths; I'm just avoiding a cast. */ struct value *v = value_cast (target_type, value_from_contents_and_address (type, valaddr, 0)); return ada_val_print_1 (target_type, VALUE_CONTENTS (v), 0, 0, stream, format, 0, recurse + 1, pretty); } else return ada_val_print_1 (TYPE_TARGET_TYPE (type), valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); } else { format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); } else if (ada_is_system_address_type (type)) { /* FIXME: We want to print System.Address variables using the same format as for any access type. But for some reason GNAT encodes the System.Address type as an int, so we have to work-around this deficiency by handling System.Address values as a special case. */ fprintf_filtered (stream, "("); type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); print_address_numeric (extract_typed_address (valaddr, builtin_type_void_data_ptr), 1, stream); } else { val_print_type_code_int (type, valaddr, stream); if (ada_is_character_type (type)) { fputs_filtered (" ", stream); ada_printchar ((unsigned char) unpack_long (type, valaddr), stream); } } return 0; } case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i)); if (name[0] == '\'') fprintf_filtered (stream, "%ld %s", (long) val, name); else fputs_filtered (name, stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FLT: if (format) return c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); else ada_print_floating (valaddr0 + embedded_offset, type, stream); break; case TYPE_CODE_UNION: case TYPE_CODE_STRUCT: if (ada_is_bogus_array_descriptor (type)) { fprintf_filtered (stream, "(...?)"); return 0; } else { print_record (type, valaddr, stream, format, recurse, pretty); return 0; } case TYPE_CODE_ARRAY: elttype = TYPE_TARGET_TYPE (type); if (elttype == NULL) eltlen = 0; else eltlen = TYPE_LENGTH (elttype); /* FIXME: This doesn't deal with non-empty arrays of 0-length items (not a typical case!) */ if (eltlen == 0) len = 0; else len = TYPE_LENGTH (type) / eltlen; /* For an array of chars, print with string syntax. */ if (ada_is_string_type (type) && (format == 0 || format == 's')) { if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* If requested, look for the first null char and only print elements up to it. */ if (stop_print_at_null) { int temp_len; /* Look for a NULL char. */ for (temp_len = 0; temp_len < len && temp_len < print_max && char_at (valaddr, temp_len, eltlen) != 0; temp_len += 1); len = temp_len; } printstr (stream, valaddr, len, 0, eltlen); } else { len = 0; fprintf_filtered (stream, "("); print_optional_low_bound (stream, type); if (TYPE_FIELD_BITSIZE (type, 0) > 0) val_print_packed_array_elements (type, valaddr, 0, stream, format, recurse, pretty); else val_print_array_elements (type, valaddr, address, stream, format, deref_ref, recurse, pretty, 0); fprintf_filtered (stream, ")"); } gdb_flush (stream); return len; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); /* De-reference the reference */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { LONGEST deref_val_int = (LONGEST) unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); if (deref_val_int != 0) { struct value *deref_val = ada_value_ind (value_from_longest (lookup_pointer_type (elttype), deref_val_int)); val_print (VALUE_TYPE (deref_val), VALUE_CONTENTS (deref_val), 0, VALUE_ADDRESS (deref_val), stream, format, deref_ref, recurse + 1, pretty); } else fputs_filtered ("(null)", stream); } else fputs_filtered ("???", stream); } break; } gdb_flush (stream); return 0; }
struct value * value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) { struct gdbarch *gdbarch = get_type_arch (value_type (arg1)); struct value **argvec; char *ptr, *mangle_ptr; char tstr[13], mangle_tstr[13]; int static_memfuncp, nargs; arg1 = coerce_ref (arg1); /* now we know that what we have to do is construct our arg vector and find the right function to call it with. */ if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT) error (_("Can't do that unary op on that type")); /* FIXME be explicit */ argvec = (struct value **) alloca (sizeof (struct value *) * 4); argvec[1] = value_addr (arg1); argvec[2] = 0; nargs = 1; /* Make the right function name up. */ strcpy (tstr, "operator__"); ptr = tstr + 8; strcpy (mangle_tstr, "__"); mangle_ptr = mangle_tstr + 2; switch (op) { case UNOP_PREINCREMENT: strcpy (ptr, "++"); break; case UNOP_PREDECREMENT: strcpy (ptr, "--"); break; case UNOP_POSTINCREMENT: strcpy (ptr, "++"); argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); argvec[3] = 0; nargs ++; break; case UNOP_POSTDECREMENT: strcpy (ptr, "--"); argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); argvec[3] = 0; nargs ++; break; case UNOP_LOGICAL_NOT: strcpy (ptr, "!"); break; case UNOP_COMPLEMENT: strcpy (ptr, "~"); break; case UNOP_NEG: strcpy (ptr, "-"); break; case UNOP_PLUS: strcpy (ptr, "+"); break; case UNOP_IND: strcpy (ptr, "*"); break; case STRUCTOP_PTR: strcpy (ptr, "->"); break; default: error (_("Invalid unary operation specified.")); } argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr, &static_memfuncp, nargs); if (argvec[0]) { if (static_memfuncp) { argvec[1] = argvec[0]; nargs --; argvec++; } if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *return_type; return_type = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); return value_zero (return_type, VALUE_LVAL (arg1)); } return call_function_by_hand (argvec[0], nargs, argvec + 1); } throw_error (NOT_FOUND_ERROR, _("member function %s not found"), tstr); return 0; /* For lint -- never reached */ }
struct value * value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, enum exp_opcode otherop, enum noside noside) { struct value **argvec; char *ptr; char tstr[13]; int static_memfuncp; arg1 = coerce_ref (arg1); arg2 = coerce_ref (arg2); /* now we know that what we have to do is construct our arg vector and find the right function to call it with. */ if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT) error (_("Can't do that binary op on that type")); /* FIXME be explicit */ argvec = (struct value **) alloca (sizeof (struct value *) * 4); argvec[1] = value_addr (arg1); argvec[2] = arg2; argvec[3] = 0; /* Make the right function name up. */ strcpy (tstr, "operator__"); ptr = tstr + 8; switch (op) { case BINOP_ADD: strcpy (ptr, "+"); break; case BINOP_SUB: strcpy (ptr, "-"); break; case BINOP_MUL: strcpy (ptr, "*"); break; case BINOP_DIV: strcpy (ptr, "/"); break; case BINOP_REM: strcpy (ptr, "%"); break; case BINOP_LSH: strcpy (ptr, "<<"); break; case BINOP_RSH: strcpy (ptr, ">>"); break; case BINOP_BITWISE_AND: strcpy (ptr, "&"); break; case BINOP_BITWISE_IOR: strcpy (ptr, "|"); break; case BINOP_BITWISE_XOR: strcpy (ptr, "^"); break; case BINOP_LOGICAL_AND: strcpy (ptr, "&&"); break; case BINOP_LOGICAL_OR: strcpy (ptr, "||"); break; case BINOP_MIN: strcpy (ptr, "<?"); break; case BINOP_MAX: strcpy (ptr, ">?"); break; case BINOP_ASSIGN: strcpy (ptr, "="); break; case BINOP_ASSIGN_MODIFY: switch (otherop) { case BINOP_ADD: strcpy (ptr, "+="); break; case BINOP_SUB: strcpy (ptr, "-="); break; case BINOP_MUL: strcpy (ptr, "*="); break; case BINOP_DIV: strcpy (ptr, "/="); break; case BINOP_REM: strcpy (ptr, "%="); break; case BINOP_BITWISE_AND: strcpy (ptr, "&="); break; case BINOP_BITWISE_IOR: strcpy (ptr, "|="); break; case BINOP_BITWISE_XOR: strcpy (ptr, "^="); break; case BINOP_MOD: /* invalid */ default: error (_("Invalid binary operation specified.")); } break; case BINOP_SUBSCRIPT: strcpy (ptr, "[]"); break; case BINOP_EQUAL: strcpy (ptr, "=="); break; case BINOP_NOTEQUAL: strcpy (ptr, "!="); break; case BINOP_LESS: strcpy (ptr, "<"); break; case BINOP_GTR: strcpy (ptr, ">"); break; case BINOP_GEQ: strcpy (ptr, ">="); break; case BINOP_LEQ: strcpy (ptr, "<="); break; case BINOP_MOD: /* invalid */ default: error (_("Invalid binary operation specified.")); } argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr, &static_memfuncp, 2); if (argvec[0]) { if (static_memfuncp) { argvec[1] = argvec[0]; argvec++; } if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *return_type; return_type = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); return value_zero (return_type, VALUE_LVAL (arg1)); } return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); } throw_error (NOT_FOUND_ERROR, _("member function %s not found"), tstr); #ifdef lint return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); #endif }
struct value * value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) { struct gdbarch *gdbarch = get_type_arch (value_type (arg1)); char *ptr; char tstr[13], mangle_tstr[13]; int static_memfuncp, nargs; arg1 = coerce_ref (arg1); /* now we know that what we have to do is construct our arg vector and find the right function to call it with. */ if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT) error (_("Can't do that unary op on that type")); /* FIXME be explicit */ value *argvec_storage[3]; gdb::array_view<value *> argvec = argvec_storage; argvec[1] = value_addr (arg1); argvec[2] = 0; nargs = 1; /* Make the right function name up. */ strcpy (tstr, "operator__"); ptr = tstr + 8; strcpy (mangle_tstr, "__"); switch (op) { case UNOP_PREINCREMENT: strcpy (ptr, "++"); break; case UNOP_PREDECREMENT: strcpy (ptr, "--"); break; case UNOP_POSTINCREMENT: strcpy (ptr, "++"); argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); nargs ++; break; case UNOP_POSTDECREMENT: strcpy (ptr, "--"); argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); nargs ++; break; case UNOP_LOGICAL_NOT: strcpy (ptr, "!"); break; case UNOP_COMPLEMENT: strcpy (ptr, "~"); break; case UNOP_NEG: strcpy (ptr, "-"); break; case UNOP_PLUS: strcpy (ptr, "+"); break; case UNOP_IND: strcpy (ptr, "*"); break; case STRUCTOP_PTR: strcpy (ptr, "->"); break; default: error (_("Invalid unary operation specified.")); } argvec[0] = value_user_defined_op (&arg1, argvec.slice (1, nargs), tstr, &static_memfuncp, noside); if (argvec[0]) { if (static_memfuncp) { argvec[1] = argvec[0]; argvec = argvec.slice (1); } if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD) { /* Static xmethods are not supported yet. */ gdb_assert (static_memfuncp == 0); if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *return_type = result_type_of_xmethod (argvec[0], argvec[1]); if (return_type == NULL) error (_("Xmethod is missing return type.")); return value_zero (return_type, VALUE_LVAL (arg1)); } return call_xmethod (argvec[0], argvec[1]); } if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *return_type; return_type = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); return value_zero (return_type, VALUE_LVAL (arg1)); } return call_function_by_hand (argvec[0], NULL, argvec.slice (1, nargs)); } throw_error (NOT_FOUND_ERROR, _("member function %s not found"), tstr); }
struct value * value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, enum exp_opcode otherop, enum noside noside) { char *ptr; char tstr[13]; int static_memfuncp; arg1 = coerce_ref (arg1); arg2 = coerce_ref (arg2); /* now we know that what we have to do is construct our arg vector and find the right function to call it with. */ if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT) error (_("Can't do that binary op on that type")); /* FIXME be explicit */ value *argvec_storage[3]; gdb::array_view<value *> argvec = argvec_storage; argvec[1] = value_addr (arg1); argvec[2] = arg2; /* Make the right function name up. */ strcpy (tstr, "operator__"); ptr = tstr + 8; switch (op) { case BINOP_ADD: strcpy (ptr, "+"); break; case BINOP_SUB: strcpy (ptr, "-"); break; case BINOP_MUL: strcpy (ptr, "*"); break; case BINOP_DIV: strcpy (ptr, "/"); break; case BINOP_REM: strcpy (ptr, "%"); break; case BINOP_LSH: strcpy (ptr, "<<"); break; case BINOP_RSH: strcpy (ptr, ">>"); break; case BINOP_BITWISE_AND: strcpy (ptr, "&"); break; case BINOP_BITWISE_IOR: strcpy (ptr, "|"); break; case BINOP_BITWISE_XOR: strcpy (ptr, "^"); break; case BINOP_LOGICAL_AND: strcpy (ptr, "&&"); break; case BINOP_LOGICAL_OR: strcpy (ptr, "||"); break; case BINOP_MIN: strcpy (ptr, "<?"); break; case BINOP_MAX: strcpy (ptr, ">?"); break; case BINOP_ASSIGN: strcpy (ptr, "="); break; case BINOP_ASSIGN_MODIFY: switch (otherop) { case BINOP_ADD: strcpy (ptr, "+="); break; case BINOP_SUB: strcpy (ptr, "-="); break; case BINOP_MUL: strcpy (ptr, "*="); break; case BINOP_DIV: strcpy (ptr, "/="); break; case BINOP_REM: strcpy (ptr, "%="); break; case BINOP_BITWISE_AND: strcpy (ptr, "&="); break; case BINOP_BITWISE_IOR: strcpy (ptr, "|="); break; case BINOP_BITWISE_XOR: strcpy (ptr, "^="); break; case BINOP_MOD: /* invalid */ default: error (_("Invalid binary operation specified.")); } break; case BINOP_SUBSCRIPT: strcpy (ptr, "[]"); break; case BINOP_EQUAL: strcpy (ptr, "=="); break; case BINOP_NOTEQUAL: strcpy (ptr, "!="); break; case BINOP_LESS: strcpy (ptr, "<"); break; case BINOP_GTR: strcpy (ptr, ">"); break; case BINOP_GEQ: strcpy (ptr, ">="); break; case BINOP_LEQ: strcpy (ptr, "<="); break; case BINOP_MOD: /* invalid */ default: error (_("Invalid binary operation specified.")); } argvec[0] = value_user_defined_op (&arg1, argvec.slice (1), tstr, &static_memfuncp, noside); if (argvec[0]) { if (static_memfuncp) { argvec[1] = argvec[0]; argvec = argvec.slice (1); } if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD) { /* Static xmethods are not supported yet. */ gdb_assert (static_memfuncp == 0); if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *return_type = result_type_of_xmethod (argvec[0], argvec.slice (1)); if (return_type == NULL) error (_("Xmethod is missing return type.")); return value_zero (return_type, VALUE_LVAL (arg1)); } return call_xmethod (argvec[0], argvec.slice (1)); } if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *return_type; return_type = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); return value_zero (return_type, VALUE_LVAL (arg1)); } return call_function_by_hand (argvec[0], NULL, argvec.slice (1, 2 - static_memfuncp)); } throw_error (NOT_FOUND_ERROR, _("member function %s not found"), tstr); }