15796c8dcSSimon Schubert /* Support for printing C values for GDB, the GNU debugger. 25796c8dcSSimon Schubert 35796c8dcSSimon Schubert Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 4*c50c785cSJohn Marino 1998, 1999, 2000, 2001, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 55796c8dcSSimon Schubert Free Software Foundation, Inc. 65796c8dcSSimon Schubert 75796c8dcSSimon Schubert This file is part of GDB. 85796c8dcSSimon Schubert 95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 125796c8dcSSimon Schubert (at your option) any later version. 135796c8dcSSimon Schubert 145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 175796c8dcSSimon Schubert GNU General Public License for more details. 185796c8dcSSimon Schubert 195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 205796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 215796c8dcSSimon Schubert 225796c8dcSSimon Schubert #include "defs.h" 235796c8dcSSimon Schubert #include "gdb_string.h" 245796c8dcSSimon Schubert #include "symtab.h" 255796c8dcSSimon Schubert #include "gdbtypes.h" 265796c8dcSSimon Schubert #include "expression.h" 275796c8dcSSimon Schubert #include "value.h" 285796c8dcSSimon Schubert #include "valprint.h" 295796c8dcSSimon Schubert #include "language.h" 305796c8dcSSimon Schubert #include "c-lang.h" 315796c8dcSSimon Schubert #include "cp-abi.h" 325796c8dcSSimon Schubert #include "target.h" 335796c8dcSSimon Schubert 345796c8dcSSimon Schubert 355796c8dcSSimon Schubert /* Print function pointer with inferior address ADDRESS onto stdio 365796c8dcSSimon Schubert stream STREAM. */ 375796c8dcSSimon Schubert 385796c8dcSSimon Schubert static void 39*c50c785cSJohn Marino print_function_pointer_address (struct gdbarch *gdbarch, 40*c50c785cSJohn Marino CORE_ADDR address, 41*c50c785cSJohn Marino struct ui_file *stream, 42*c50c785cSJohn Marino int addressprint) 435796c8dcSSimon Schubert { 44*c50c785cSJohn Marino CORE_ADDR func_addr 45*c50c785cSJohn Marino = gdbarch_convert_from_func_ptr_addr (gdbarch, address, 465796c8dcSSimon Schubert ¤t_target); 475796c8dcSSimon Schubert 48*c50c785cSJohn Marino /* If the function pointer is represented by a description, print 49*c50c785cSJohn Marino the address of the description. */ 505796c8dcSSimon Schubert if (addressprint && func_addr != address) 515796c8dcSSimon Schubert { 525796c8dcSSimon Schubert fputs_filtered ("@", stream); 535796c8dcSSimon Schubert fputs_filtered (paddress (gdbarch, address), stream); 545796c8dcSSimon Schubert fputs_filtered (": ", stream); 555796c8dcSSimon Schubert } 565796c8dcSSimon Schubert print_address_demangle (gdbarch, func_addr, stream, demangle); 575796c8dcSSimon Schubert } 585796c8dcSSimon Schubert 595796c8dcSSimon Schubert 60cf7f2e2dSJohn Marino /* A helper for c_textual_element_type. This checks the name of the 615796c8dcSSimon Schubert typedef. This is bogus but it isn't apparent that the compiler 625796c8dcSSimon Schubert provides us the help we may need. */ 635796c8dcSSimon Schubert 645796c8dcSSimon Schubert static int 655796c8dcSSimon Schubert textual_name (const char *name) 665796c8dcSSimon Schubert { 675796c8dcSSimon Schubert return (!strcmp (name, "wchar_t") 685796c8dcSSimon Schubert || !strcmp (name, "char16_t") 695796c8dcSSimon Schubert || !strcmp (name, "char32_t")); 705796c8dcSSimon Schubert } 715796c8dcSSimon Schubert 725796c8dcSSimon Schubert /* Apply a heuristic to decide whether an array of TYPE or a pointer 735796c8dcSSimon Schubert to TYPE should be printed as a textual string. Return non-zero if 745796c8dcSSimon Schubert it should, or zero if it should be treated as an array of integers 75*c50c785cSJohn Marino or pointer to integers. FORMAT is the current format letter, or 0 76*c50c785cSJohn Marino if none. 775796c8dcSSimon Schubert 785796c8dcSSimon Schubert We guess that "char" is a character. Explicitly signed and 795796c8dcSSimon Schubert unsigned character types are also characters. Integer data from 805796c8dcSSimon Schubert vector types is not. The user can override this by using the /s 815796c8dcSSimon Schubert format letter. */ 825796c8dcSSimon Schubert 83cf7f2e2dSJohn Marino int 84cf7f2e2dSJohn Marino c_textual_element_type (struct type *type, char format) 855796c8dcSSimon Schubert { 865796c8dcSSimon Schubert struct type *true_type, *iter_type; 875796c8dcSSimon Schubert 885796c8dcSSimon Schubert if (format != 0 && format != 's') 895796c8dcSSimon Schubert return 0; 905796c8dcSSimon Schubert 915796c8dcSSimon Schubert /* We also rely on this for its side effect of setting up all the 925796c8dcSSimon Schubert typedef pointers. */ 935796c8dcSSimon Schubert true_type = check_typedef (type); 945796c8dcSSimon Schubert 955796c8dcSSimon Schubert /* TYPE_CODE_CHAR is always textual. */ 965796c8dcSSimon Schubert if (TYPE_CODE (true_type) == TYPE_CODE_CHAR) 975796c8dcSSimon Schubert return 1; 985796c8dcSSimon Schubert 995796c8dcSSimon Schubert /* Any other character-like types must be integral. */ 1005796c8dcSSimon Schubert if (TYPE_CODE (true_type) != TYPE_CODE_INT) 1015796c8dcSSimon Schubert return 0; 1025796c8dcSSimon Schubert 1035796c8dcSSimon Schubert /* We peel typedefs one by one, looking for a match. */ 1045796c8dcSSimon Schubert iter_type = type; 1055796c8dcSSimon Schubert while (iter_type) 1065796c8dcSSimon Schubert { 1075796c8dcSSimon Schubert /* Check the name of the type. */ 1085796c8dcSSimon Schubert if (TYPE_NAME (iter_type) && textual_name (TYPE_NAME (iter_type))) 1095796c8dcSSimon Schubert return 1; 1105796c8dcSSimon Schubert 1115796c8dcSSimon Schubert if (TYPE_CODE (iter_type) != TYPE_CODE_TYPEDEF) 1125796c8dcSSimon Schubert break; 1135796c8dcSSimon Schubert 1145796c8dcSSimon Schubert /* Peel a single typedef. If the typedef doesn't have a target 1155796c8dcSSimon Schubert type, we use check_typedef and hope the result is ok -- it 1165796c8dcSSimon Schubert might be for C++, where wchar_t is a built-in type. */ 1175796c8dcSSimon Schubert if (TYPE_TARGET_TYPE (iter_type)) 1185796c8dcSSimon Schubert iter_type = TYPE_TARGET_TYPE (iter_type); 1195796c8dcSSimon Schubert else 1205796c8dcSSimon Schubert iter_type = check_typedef (iter_type); 1215796c8dcSSimon Schubert } 1225796c8dcSSimon Schubert 1235796c8dcSSimon Schubert if (format == 's') 1245796c8dcSSimon Schubert { 125*c50c785cSJohn Marino /* Print this as a string if we can manage it. For now, no wide 126*c50c785cSJohn Marino character support. */ 1275796c8dcSSimon Schubert if (TYPE_CODE (true_type) == TYPE_CODE_INT 1285796c8dcSSimon Schubert && TYPE_LENGTH (true_type) == 1) 1295796c8dcSSimon Schubert return 1; 1305796c8dcSSimon Schubert } 1315796c8dcSSimon Schubert else 1325796c8dcSSimon Schubert { 1335796c8dcSSimon Schubert /* If a one-byte TYPE_CODE_INT is missing the not-a-character 1345796c8dcSSimon Schubert flag, then we treat it as text; otherwise, we assume it's 1355796c8dcSSimon Schubert being used as data. */ 1365796c8dcSSimon Schubert if (TYPE_CODE (true_type) == TYPE_CODE_INT 1375796c8dcSSimon Schubert && TYPE_LENGTH (true_type) == 1 1385796c8dcSSimon Schubert && !TYPE_NOTTEXT (true_type)) 1395796c8dcSSimon Schubert return 1; 1405796c8dcSSimon Schubert } 1415796c8dcSSimon Schubert 1425796c8dcSSimon Schubert return 0; 1435796c8dcSSimon Schubert } 1445796c8dcSSimon Schubert 145*c50c785cSJohn Marino /* See val_print for a description of the various parameters of this 146*c50c785cSJohn Marino function; they are identical. The semantics of the return value is 147*c50c785cSJohn Marino also identical to val_print. */ 1485796c8dcSSimon Schubert 1495796c8dcSSimon Schubert int 150*c50c785cSJohn Marino c_val_print (struct type *type, const gdb_byte *valaddr, 151*c50c785cSJohn Marino int embedded_offset, CORE_ADDR address, 152*c50c785cSJohn Marino struct ui_file *stream, int recurse, 153cf7f2e2dSJohn Marino const struct value *original_value, 1545796c8dcSSimon Schubert const struct value_print_options *options) 1555796c8dcSSimon Schubert { 1565796c8dcSSimon Schubert struct gdbarch *gdbarch = get_type_arch (type); 1575796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 158*c50c785cSJohn Marino unsigned int i = 0; /* Number of characters printed. */ 1595796c8dcSSimon Schubert unsigned len; 1605796c8dcSSimon Schubert struct type *elttype, *unresolved_elttype; 1615796c8dcSSimon Schubert struct type *unresolved_type = type; 1625796c8dcSSimon Schubert unsigned eltlen; 1635796c8dcSSimon Schubert LONGEST val; 1645796c8dcSSimon Schubert CORE_ADDR addr; 1655796c8dcSSimon Schubert 1665796c8dcSSimon Schubert CHECK_TYPEDEF (type); 1675796c8dcSSimon Schubert switch (TYPE_CODE (type)) 1685796c8dcSSimon Schubert { 1695796c8dcSSimon Schubert case TYPE_CODE_ARRAY: 1705796c8dcSSimon Schubert unresolved_elttype = TYPE_TARGET_TYPE (type); 1715796c8dcSSimon Schubert elttype = check_typedef (unresolved_elttype); 1725796c8dcSSimon Schubert if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) 1735796c8dcSSimon Schubert { 174*c50c785cSJohn Marino LONGEST low_bound, high_bound; 175*c50c785cSJohn Marino 176*c50c785cSJohn Marino if (!get_array_bounds (type, &low_bound, &high_bound)) 177*c50c785cSJohn Marino error (_("Could not determine the array high bound")); 178*c50c785cSJohn Marino 1795796c8dcSSimon Schubert eltlen = TYPE_LENGTH (elttype); 180*c50c785cSJohn Marino len = high_bound - low_bound + 1; 1815796c8dcSSimon Schubert if (options->prettyprint_arrays) 1825796c8dcSSimon Schubert { 1835796c8dcSSimon Schubert print_spaces_filtered (2 + 2 * recurse, stream); 1845796c8dcSSimon Schubert } 1855796c8dcSSimon Schubert 186cf7f2e2dSJohn Marino /* Print arrays of textual chars with a string syntax, as 187cf7f2e2dSJohn Marino long as the entire array is valid. */ 188*c50c785cSJohn Marino if (c_textual_element_type (unresolved_elttype, 189*c50c785cSJohn Marino options->format) 190*c50c785cSJohn Marino && value_bytes_available (original_value, embedded_offset, 191*c50c785cSJohn Marino TYPE_LENGTH (type)) 192cf7f2e2dSJohn Marino && value_bits_valid (original_value, 193cf7f2e2dSJohn Marino TARGET_CHAR_BIT * embedded_offset, 194cf7f2e2dSJohn Marino TARGET_CHAR_BIT * TYPE_LENGTH (type))) 1955796c8dcSSimon Schubert { 196*c50c785cSJohn Marino /* If requested, look for the first null char and only 197*c50c785cSJohn Marino print elements up to it. */ 1985796c8dcSSimon Schubert if (options->stop_print_at_null) 1995796c8dcSSimon Schubert { 2005796c8dcSSimon Schubert unsigned int temp_len; 2015796c8dcSSimon Schubert 2025796c8dcSSimon Schubert for (temp_len = 0; 2035796c8dcSSimon Schubert (temp_len < len 2045796c8dcSSimon Schubert && temp_len < options->print_max 2055796c8dcSSimon Schubert && extract_unsigned_integer (valaddr + embedded_offset 2065796c8dcSSimon Schubert + temp_len * eltlen, 207cf7f2e2dSJohn Marino eltlen, byte_order) != 0); 2085796c8dcSSimon Schubert ++temp_len) 2095796c8dcSSimon Schubert ; 2105796c8dcSSimon Schubert len = temp_len; 2115796c8dcSSimon Schubert } 2125796c8dcSSimon Schubert 2135796c8dcSSimon Schubert LA_PRINT_STRING (stream, unresolved_elttype, 214cf7f2e2dSJohn Marino valaddr + embedded_offset, len, 215cf7f2e2dSJohn Marino NULL, 0, options); 2165796c8dcSSimon Schubert i = len; 2175796c8dcSSimon Schubert } 2185796c8dcSSimon Schubert else 2195796c8dcSSimon Schubert { 2205796c8dcSSimon Schubert fprintf_filtered (stream, "{"); 2215796c8dcSSimon Schubert /* If this is a virtual function table, print the 0th 222*c50c785cSJohn Marino entry specially, and the rest of the members 223*c50c785cSJohn Marino normally. */ 2245796c8dcSSimon Schubert if (cp_is_vtbl_ptr_type (elttype)) 2255796c8dcSSimon Schubert { 2265796c8dcSSimon Schubert i = 1; 227*c50c785cSJohn Marino fprintf_filtered (stream, _("%d vtable entries"), 228*c50c785cSJohn Marino len - 1); 2295796c8dcSSimon Schubert } 2305796c8dcSSimon Schubert else 2315796c8dcSSimon Schubert { 2325796c8dcSSimon Schubert i = 0; 2335796c8dcSSimon Schubert } 234*c50c785cSJohn Marino val_print_array_elements (type, valaddr, embedded_offset, 235*c50c785cSJohn Marino address, stream, 236cf7f2e2dSJohn Marino recurse, original_value, options, i); 2375796c8dcSSimon Schubert fprintf_filtered (stream, "}"); 2385796c8dcSSimon Schubert } 2395796c8dcSSimon Schubert break; 2405796c8dcSSimon Schubert } 241*c50c785cSJohn Marino /* Array of unspecified length: treat like pointer to first 242*c50c785cSJohn Marino elt. */ 243*c50c785cSJohn Marino addr = address + embedded_offset; 2445796c8dcSSimon Schubert goto print_unpacked_pointer; 2455796c8dcSSimon Schubert 2465796c8dcSSimon Schubert case TYPE_CODE_MEMBERPTR: 2475796c8dcSSimon Schubert if (options->format) 2485796c8dcSSimon Schubert { 249*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 250*c50c785cSJohn Marino original_value, options, 0, stream); 2515796c8dcSSimon Schubert break; 2525796c8dcSSimon Schubert } 2535796c8dcSSimon Schubert cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); 2545796c8dcSSimon Schubert break; 2555796c8dcSSimon Schubert 2565796c8dcSSimon Schubert case TYPE_CODE_METHODPTR: 2575796c8dcSSimon Schubert cplus_print_method_ptr (valaddr + embedded_offset, type, stream); 2585796c8dcSSimon Schubert break; 2595796c8dcSSimon Schubert 2605796c8dcSSimon Schubert case TYPE_CODE_PTR: 2615796c8dcSSimon Schubert if (options->format && options->format != 's') 2625796c8dcSSimon Schubert { 263*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 264*c50c785cSJohn Marino original_value, options, 0, stream); 2655796c8dcSSimon Schubert break; 2665796c8dcSSimon Schubert } 2675796c8dcSSimon Schubert if (options->vtblprint && cp_is_vtbl_ptr_type (type)) 2685796c8dcSSimon Schubert { 2695796c8dcSSimon Schubert /* Print the unmangled name if desired. */ 2705796c8dcSSimon Schubert /* Print vtable entry - we only get here if we ARE using 271*c50c785cSJohn Marino -fvtable_thunks. (Otherwise, look under 272*c50c785cSJohn Marino TYPE_CODE_STRUCT.) */ 2735796c8dcSSimon Schubert CORE_ADDR addr 2745796c8dcSSimon Schubert = extract_typed_address (valaddr + embedded_offset, type); 275cf7f2e2dSJohn Marino 2765796c8dcSSimon Schubert print_function_pointer_address (gdbarch, addr, stream, 2775796c8dcSSimon Schubert options->addressprint); 2785796c8dcSSimon Schubert break; 2795796c8dcSSimon Schubert } 2805796c8dcSSimon Schubert unresolved_elttype = TYPE_TARGET_TYPE (type); 2815796c8dcSSimon Schubert elttype = check_typedef (unresolved_elttype); 2825796c8dcSSimon Schubert { 2835796c8dcSSimon Schubert addr = unpack_pointer (type, valaddr + embedded_offset); 2845796c8dcSSimon Schubert print_unpacked_pointer: 2855796c8dcSSimon Schubert 2865796c8dcSSimon Schubert if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) 2875796c8dcSSimon Schubert { 2885796c8dcSSimon Schubert /* Try to print what function it points to. */ 2895796c8dcSSimon Schubert print_function_pointer_address (gdbarch, addr, stream, 2905796c8dcSSimon Schubert options->addressprint); 291*c50c785cSJohn Marino /* Return value is irrelevant except for string 292*c50c785cSJohn Marino pointers. */ 2935796c8dcSSimon Schubert return (0); 2945796c8dcSSimon Schubert } 2955796c8dcSSimon Schubert 2965796c8dcSSimon Schubert if (options->addressprint) 2975796c8dcSSimon Schubert fputs_filtered (paddress (gdbarch, addr), stream); 2985796c8dcSSimon Schubert 2995796c8dcSSimon Schubert /* For a pointer to a textual type, also print the string 3005796c8dcSSimon Schubert pointed to, unless pointer is null. */ 3015796c8dcSSimon Schubert 302*c50c785cSJohn Marino if (c_textual_element_type (unresolved_elttype, 303*c50c785cSJohn Marino options->format) 3045796c8dcSSimon Schubert && addr != 0) 3055796c8dcSSimon Schubert { 306*c50c785cSJohn Marino i = val_print_string (unresolved_elttype, NULL, 307*c50c785cSJohn Marino addr, -1, 308*c50c785cSJohn Marino stream, options); 3095796c8dcSSimon Schubert } 3105796c8dcSSimon Schubert else if (cp_is_vtbl_member (type)) 3115796c8dcSSimon Schubert { 312*c50c785cSJohn Marino /* Print vtbl's nicely. */ 313*c50c785cSJohn Marino CORE_ADDR vt_address = unpack_pointer (type, 314*c50c785cSJohn Marino valaddr 315*c50c785cSJohn Marino + embedded_offset); 3165796c8dcSSimon Schubert 3175796c8dcSSimon Schubert struct minimal_symbol *msymbol = 3185796c8dcSSimon Schubert lookup_minimal_symbol_by_pc (vt_address); 319cf7f2e2dSJohn Marino if ((msymbol != NULL) 320cf7f2e2dSJohn Marino && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) 3215796c8dcSSimon Schubert { 3225796c8dcSSimon Schubert fputs_filtered (" <", stream); 3235796c8dcSSimon Schubert fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); 3245796c8dcSSimon Schubert fputs_filtered (">", stream); 3255796c8dcSSimon Schubert } 3265796c8dcSSimon Schubert if (vt_address && options->vtblprint) 3275796c8dcSSimon Schubert { 3285796c8dcSSimon Schubert struct value *vt_val; 3295796c8dcSSimon Schubert struct symbol *wsym = (struct symbol *) NULL; 3305796c8dcSSimon Schubert struct type *wtype; 3315796c8dcSSimon Schubert struct block *block = (struct block *) NULL; 3325796c8dcSSimon Schubert int is_this_fld; 3335796c8dcSSimon Schubert 3345796c8dcSSimon Schubert if (msymbol != NULL) 335*c50c785cSJohn Marino wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), 336*c50c785cSJohn Marino block, VAR_DOMAIN, 337*c50c785cSJohn Marino &is_this_fld); 3385796c8dcSSimon Schubert 3395796c8dcSSimon Schubert if (wsym) 3405796c8dcSSimon Schubert { 3415796c8dcSSimon Schubert wtype = SYMBOL_TYPE (wsym); 3425796c8dcSSimon Schubert } 3435796c8dcSSimon Schubert else 3445796c8dcSSimon Schubert { 3455796c8dcSSimon Schubert wtype = unresolved_elttype; 3465796c8dcSSimon Schubert } 3475796c8dcSSimon Schubert vt_val = value_at (wtype, vt_address); 348*c50c785cSJohn Marino common_val_print (vt_val, stream, recurse + 1, 349*c50c785cSJohn Marino options, current_language); 3505796c8dcSSimon Schubert if (options->pretty) 3515796c8dcSSimon Schubert { 3525796c8dcSSimon Schubert fprintf_filtered (stream, "\n"); 3535796c8dcSSimon Schubert print_spaces_filtered (2 + 2 * recurse, stream); 3545796c8dcSSimon Schubert } 3555796c8dcSSimon Schubert } 3565796c8dcSSimon Schubert } 3575796c8dcSSimon Schubert 358*c50c785cSJohn Marino /* Return number of characters printed, including the 359*c50c785cSJohn Marino terminating '\0' if we reached the end. val_print_string 360*c50c785cSJohn Marino takes care including the terminating '\0' if 361*c50c785cSJohn Marino necessary. */ 3625796c8dcSSimon Schubert return i; 3635796c8dcSSimon Schubert } 3645796c8dcSSimon Schubert break; 3655796c8dcSSimon Schubert 3665796c8dcSSimon Schubert case TYPE_CODE_REF: 3675796c8dcSSimon Schubert elttype = check_typedef (TYPE_TARGET_TYPE (type)); 3685796c8dcSSimon Schubert if (options->addressprint) 3695796c8dcSSimon Schubert { 3705796c8dcSSimon Schubert CORE_ADDR addr 3715796c8dcSSimon Schubert = extract_typed_address (valaddr + embedded_offset, type); 372cf7f2e2dSJohn Marino 3735796c8dcSSimon Schubert fprintf_filtered (stream, "@"); 3745796c8dcSSimon Schubert fputs_filtered (paddress (gdbarch, addr), stream); 3755796c8dcSSimon Schubert if (options->deref_ref) 3765796c8dcSSimon Schubert fputs_filtered (": ", stream); 3775796c8dcSSimon Schubert } 3785796c8dcSSimon Schubert /* De-reference the reference. */ 3795796c8dcSSimon Schubert if (options->deref_ref) 3805796c8dcSSimon Schubert { 3815796c8dcSSimon Schubert if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) 3825796c8dcSSimon Schubert { 3835796c8dcSSimon Schubert struct value *deref_val = 3845796c8dcSSimon Schubert value_at 3855796c8dcSSimon Schubert (TYPE_TARGET_TYPE (type), 3865796c8dcSSimon Schubert unpack_pointer (type, valaddr + embedded_offset)); 387cf7f2e2dSJohn Marino 3885796c8dcSSimon Schubert common_val_print (deref_val, stream, recurse, options, 3895796c8dcSSimon Schubert current_language); 3905796c8dcSSimon Schubert } 3915796c8dcSSimon Schubert else 3925796c8dcSSimon Schubert fputs_filtered ("???", stream); 3935796c8dcSSimon Schubert } 3945796c8dcSSimon Schubert break; 3955796c8dcSSimon Schubert 3965796c8dcSSimon Schubert case TYPE_CODE_UNION: 3975796c8dcSSimon Schubert if (recurse && !options->unionprint) 3985796c8dcSSimon Schubert { 3995796c8dcSSimon Schubert fprintf_filtered (stream, "{...}"); 4005796c8dcSSimon Schubert break; 4015796c8dcSSimon Schubert } 4025796c8dcSSimon Schubert /* Fall through. */ 4035796c8dcSSimon Schubert case TYPE_CODE_STRUCT: 404*c50c785cSJohn Marino /*FIXME: Abstract this away. */ 4055796c8dcSSimon Schubert if (options->vtblprint && cp_is_vtbl_ptr_type (type)) 4065796c8dcSSimon Schubert { 4075796c8dcSSimon Schubert /* Print the unmangled name if desired. */ 4085796c8dcSSimon Schubert /* Print vtable entry - we only get here if NOT using 409*c50c785cSJohn Marino -fvtable_thunks. (Otherwise, look under 410*c50c785cSJohn Marino TYPE_CODE_PTR.) */ 411*c50c785cSJohn Marino int offset = (embedded_offset 412*c50c785cSJohn Marino + TYPE_FIELD_BITPOS (type, 413*c50c785cSJohn Marino VTBL_FNADDR_OFFSET) / 8); 414*c50c785cSJohn Marino struct type *field_type = TYPE_FIELD_TYPE (type, 415*c50c785cSJohn Marino VTBL_FNADDR_OFFSET); 4165796c8dcSSimon Schubert CORE_ADDR addr 4175796c8dcSSimon Schubert = extract_typed_address (valaddr + offset, field_type); 4185796c8dcSSimon Schubert 4195796c8dcSSimon Schubert print_function_pointer_address (gdbarch, addr, stream, 4205796c8dcSSimon Schubert options->addressprint); 4215796c8dcSSimon Schubert } 4225796c8dcSSimon Schubert else 423cf7f2e2dSJohn Marino cp_print_value_fields_rtti (type, valaddr, 424*c50c785cSJohn Marino embedded_offset, address, 425*c50c785cSJohn Marino stream, recurse, 426*c50c785cSJohn Marino original_value, options, 427*c50c785cSJohn Marino NULL, 0); 4285796c8dcSSimon Schubert break; 4295796c8dcSSimon Schubert 4305796c8dcSSimon Schubert case TYPE_CODE_ENUM: 4315796c8dcSSimon Schubert if (options->format) 4325796c8dcSSimon Schubert { 433*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 434*c50c785cSJohn Marino original_value, options, 0, stream); 4355796c8dcSSimon Schubert break; 4365796c8dcSSimon Schubert } 4375796c8dcSSimon Schubert len = TYPE_NFIELDS (type); 4385796c8dcSSimon Schubert val = unpack_long (type, valaddr + embedded_offset); 4395796c8dcSSimon Schubert for (i = 0; i < len; i++) 4405796c8dcSSimon Schubert { 4415796c8dcSSimon Schubert QUIT; 4425796c8dcSSimon Schubert if (val == TYPE_FIELD_BITPOS (type, i)) 4435796c8dcSSimon Schubert { 4445796c8dcSSimon Schubert break; 4455796c8dcSSimon Schubert } 4465796c8dcSSimon Schubert } 4475796c8dcSSimon Schubert if (i < len) 4485796c8dcSSimon Schubert { 4495796c8dcSSimon Schubert fputs_filtered (TYPE_FIELD_NAME (type, i), stream); 4505796c8dcSSimon Schubert } 4515796c8dcSSimon Schubert else 4525796c8dcSSimon Schubert { 4535796c8dcSSimon Schubert print_longest (stream, 'd', 0, val); 4545796c8dcSSimon Schubert } 4555796c8dcSSimon Schubert break; 4565796c8dcSSimon Schubert 4575796c8dcSSimon Schubert case TYPE_CODE_FLAGS: 4585796c8dcSSimon Schubert if (options->format) 459*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 460*c50c785cSJohn Marino original_value, options, 0, stream); 4615796c8dcSSimon Schubert else 462*c50c785cSJohn Marino val_print_type_code_flags (type, valaddr + embedded_offset, 463*c50c785cSJohn Marino stream); 4645796c8dcSSimon Schubert break; 4655796c8dcSSimon Schubert 4665796c8dcSSimon Schubert case TYPE_CODE_FUNC: 4675796c8dcSSimon Schubert case TYPE_CODE_METHOD: 4685796c8dcSSimon Schubert if (options->format) 4695796c8dcSSimon Schubert { 470*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 471*c50c785cSJohn Marino original_value, options, 0, stream); 4725796c8dcSSimon Schubert break; 4735796c8dcSSimon Schubert } 474*c50c785cSJohn Marino /* FIXME, we should consider, at least for ANSI C language, 475*c50c785cSJohn Marino eliminating the distinction made between FUNCs and POINTERs 476*c50c785cSJohn Marino to FUNCs. */ 4775796c8dcSSimon Schubert fprintf_filtered (stream, "{"); 4785796c8dcSSimon Schubert type_print (type, "", stream, -1); 4795796c8dcSSimon Schubert fprintf_filtered (stream, "} "); 4805796c8dcSSimon Schubert /* Try to print what function it points to, and its address. */ 4815796c8dcSSimon Schubert print_address_demangle (gdbarch, address, stream, demangle); 4825796c8dcSSimon Schubert break; 4835796c8dcSSimon Schubert 4845796c8dcSSimon Schubert case TYPE_CODE_BOOL: 4855796c8dcSSimon Schubert if (options->format || options->output_format) 4865796c8dcSSimon Schubert { 4875796c8dcSSimon Schubert struct value_print_options opts = *options; 4885796c8dcSSimon Schubert opts.format = (options->format ? options->format 4895796c8dcSSimon Schubert : options->output_format); 490*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 491*c50c785cSJohn Marino original_value, &opts, 0, stream); 4925796c8dcSSimon Schubert } 4935796c8dcSSimon Schubert else 4945796c8dcSSimon Schubert { 4955796c8dcSSimon Schubert val = unpack_long (type, valaddr + embedded_offset); 4965796c8dcSSimon Schubert if (val == 0) 4975796c8dcSSimon Schubert fputs_filtered ("false", stream); 4985796c8dcSSimon Schubert else if (val == 1) 4995796c8dcSSimon Schubert fputs_filtered ("true", stream); 5005796c8dcSSimon Schubert else 5015796c8dcSSimon Schubert print_longest (stream, 'd', 0, val); 5025796c8dcSSimon Schubert } 5035796c8dcSSimon Schubert break; 5045796c8dcSSimon Schubert 5055796c8dcSSimon Schubert case TYPE_CODE_RANGE: 5065796c8dcSSimon Schubert /* FIXME: create_range_type does not set the unsigned bit in a 507*c50c785cSJohn Marino range type (I think it probably should copy it from the 508*c50c785cSJohn Marino target type), so we won't print values which are too large to 5095796c8dcSSimon Schubert fit in a signed integer correctly. */ 5105796c8dcSSimon Schubert /* FIXME: Doesn't handle ranges of enums correctly. (Can't just 511*c50c785cSJohn Marino print with the target type, though, because the size of our 512*c50c785cSJohn Marino type and the target type might differ). */ 5135796c8dcSSimon Schubert /* FALLTHROUGH */ 5145796c8dcSSimon Schubert 5155796c8dcSSimon Schubert case TYPE_CODE_INT: 5165796c8dcSSimon Schubert if (options->format || options->output_format) 5175796c8dcSSimon Schubert { 5185796c8dcSSimon Schubert struct value_print_options opts = *options; 519cf7f2e2dSJohn Marino 5205796c8dcSSimon Schubert opts.format = (options->format ? options->format 5215796c8dcSSimon Schubert : options->output_format); 522*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 523*c50c785cSJohn Marino original_value, &opts, 0, stream); 5245796c8dcSSimon Schubert } 5255796c8dcSSimon Schubert else 5265796c8dcSSimon Schubert { 527*c50c785cSJohn Marino val_print_type_code_int (type, valaddr + embedded_offset, 528*c50c785cSJohn Marino stream); 529*c50c785cSJohn Marino /* C and C++ has no single byte int type, char is used 530*c50c785cSJohn Marino instead. Since we don't know whether the value is really 531*c50c785cSJohn Marino intended to be used as an integer or a character, print 532*c50c785cSJohn Marino the character equivalent as well. */ 533cf7f2e2dSJohn Marino if (c_textual_element_type (unresolved_type, options->format)) 5345796c8dcSSimon Schubert { 5355796c8dcSSimon Schubert fputs_filtered (" ", stream); 536*c50c785cSJohn Marino LA_PRINT_CHAR (unpack_long (type, valaddr + embedded_offset), 5375796c8dcSSimon Schubert unresolved_type, stream); 5385796c8dcSSimon Schubert } 5395796c8dcSSimon Schubert } 5405796c8dcSSimon Schubert break; 5415796c8dcSSimon Schubert 5425796c8dcSSimon Schubert case TYPE_CODE_CHAR: 5435796c8dcSSimon Schubert if (options->format || options->output_format) 5445796c8dcSSimon Schubert { 5455796c8dcSSimon Schubert struct value_print_options opts = *options; 5465796c8dcSSimon Schubert opts.format = (options->format ? options->format 5475796c8dcSSimon Schubert : options->output_format); 548*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 549*c50c785cSJohn Marino original_value, &opts, 0, stream); 5505796c8dcSSimon Schubert } 5515796c8dcSSimon Schubert else 5525796c8dcSSimon Schubert { 5535796c8dcSSimon Schubert val = unpack_long (type, valaddr + embedded_offset); 5545796c8dcSSimon Schubert if (TYPE_UNSIGNED (type)) 5555796c8dcSSimon Schubert fprintf_filtered (stream, "%u", (unsigned int) val); 5565796c8dcSSimon Schubert else 5575796c8dcSSimon Schubert fprintf_filtered (stream, "%d", (int) val); 5585796c8dcSSimon Schubert fputs_filtered (" ", stream); 559*c50c785cSJohn Marino LA_PRINT_CHAR (val, unresolved_type, stream); 5605796c8dcSSimon Schubert } 5615796c8dcSSimon Schubert break; 5625796c8dcSSimon Schubert 5635796c8dcSSimon Schubert case TYPE_CODE_FLT: 5645796c8dcSSimon Schubert if (options->format) 5655796c8dcSSimon Schubert { 566*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 567*c50c785cSJohn Marino original_value, options, 0, stream); 5685796c8dcSSimon Schubert } 5695796c8dcSSimon Schubert else 5705796c8dcSSimon Schubert { 5715796c8dcSSimon Schubert print_floating (valaddr + embedded_offset, type, stream); 5725796c8dcSSimon Schubert } 5735796c8dcSSimon Schubert break; 5745796c8dcSSimon Schubert 5755796c8dcSSimon Schubert case TYPE_CODE_DECFLOAT: 5765796c8dcSSimon Schubert if (options->format) 577*c50c785cSJohn Marino val_print_scalar_formatted (type, valaddr, embedded_offset, 578*c50c785cSJohn Marino original_value, options, 0, stream); 5795796c8dcSSimon Schubert else 580*c50c785cSJohn Marino print_decimal_floating (valaddr + embedded_offset, 581*c50c785cSJohn Marino type, stream); 5825796c8dcSSimon Schubert break; 5835796c8dcSSimon Schubert 5845796c8dcSSimon Schubert case TYPE_CODE_VOID: 5855796c8dcSSimon Schubert fprintf_filtered (stream, "void"); 5865796c8dcSSimon Schubert break; 5875796c8dcSSimon Schubert 5885796c8dcSSimon Schubert case TYPE_CODE_ERROR: 589cf7f2e2dSJohn Marino fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); 5905796c8dcSSimon Schubert break; 5915796c8dcSSimon Schubert 5925796c8dcSSimon Schubert case TYPE_CODE_UNDEF: 593*c50c785cSJohn Marino /* This happens (without TYPE_FLAG_STUB set) on systems which 594*c50c785cSJohn Marino don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a 595*c50c785cSJohn Marino "struct foo *bar" and no complete type for struct foo in that 596*c50c785cSJohn Marino file. */ 5975796c8dcSSimon Schubert fprintf_filtered (stream, _("<incomplete type>")); 5985796c8dcSSimon Schubert break; 5995796c8dcSSimon Schubert 6005796c8dcSSimon Schubert case TYPE_CODE_COMPLEX: 6015796c8dcSSimon Schubert if (options->format) 602*c50c785cSJohn Marino val_print_scalar_formatted (TYPE_TARGET_TYPE (type), 603*c50c785cSJohn Marino valaddr, embedded_offset, 604*c50c785cSJohn Marino original_value, options, 0, stream); 6055796c8dcSSimon Schubert else 606*c50c785cSJohn Marino print_floating (valaddr + embedded_offset, 607*c50c785cSJohn Marino TYPE_TARGET_TYPE (type), 6085796c8dcSSimon Schubert stream); 6095796c8dcSSimon Schubert fprintf_filtered (stream, " + "); 6105796c8dcSSimon Schubert if (options->format) 611*c50c785cSJohn Marino val_print_scalar_formatted (TYPE_TARGET_TYPE (type), 612*c50c785cSJohn Marino valaddr, 613*c50c785cSJohn Marino embedded_offset 6145796c8dcSSimon Schubert + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), 615*c50c785cSJohn Marino original_value, 6165796c8dcSSimon Schubert options, 0, stream); 6175796c8dcSSimon Schubert else 6185796c8dcSSimon Schubert print_floating (valaddr + embedded_offset 6195796c8dcSSimon Schubert + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), 6205796c8dcSSimon Schubert TYPE_TARGET_TYPE (type), 6215796c8dcSSimon Schubert stream); 6225796c8dcSSimon Schubert fprintf_filtered (stream, " * I"); 6235796c8dcSSimon Schubert break; 6245796c8dcSSimon Schubert 6255796c8dcSSimon Schubert default: 626*c50c785cSJohn Marino error (_("Invalid C/C++ type code %d in symbol table."), 627*c50c785cSJohn Marino TYPE_CODE (type)); 6285796c8dcSSimon Schubert } 6295796c8dcSSimon Schubert gdb_flush (stream); 6305796c8dcSSimon Schubert return (0); 6315796c8dcSSimon Schubert } 6325796c8dcSSimon Schubert 6335796c8dcSSimon Schubert int 6345796c8dcSSimon Schubert c_value_print (struct value *val, struct ui_file *stream, 6355796c8dcSSimon Schubert const struct value_print_options *options) 6365796c8dcSSimon Schubert { 6375796c8dcSSimon Schubert struct type *type, *real_type, *val_type; 6385796c8dcSSimon Schubert int full, top, using_enc; 6395796c8dcSSimon Schubert struct value_print_options opts = *options; 6405796c8dcSSimon Schubert 6415796c8dcSSimon Schubert opts.deref_ref = 1; 6425796c8dcSSimon Schubert 6435796c8dcSSimon Schubert /* If it is a pointer, indicate what it points to. 6445796c8dcSSimon Schubert 6455796c8dcSSimon Schubert Print type also if it is a reference. 6465796c8dcSSimon Schubert 6475796c8dcSSimon Schubert C++: if it is a member pointer, we will take care 6485796c8dcSSimon Schubert of that when we print it. */ 6495796c8dcSSimon Schubert 6505796c8dcSSimon Schubert /* Preserve the original type before stripping typedefs. We prefer 6515796c8dcSSimon Schubert to pass down the original type when possible, but for local 6525796c8dcSSimon Schubert checks it is better to look past the typedefs. */ 6535796c8dcSSimon Schubert val_type = value_type (val); 6545796c8dcSSimon Schubert type = check_typedef (val_type); 6555796c8dcSSimon Schubert 6565796c8dcSSimon Schubert if (TYPE_CODE (type) == TYPE_CODE_PTR 6575796c8dcSSimon Schubert || TYPE_CODE (type) == TYPE_CODE_REF) 6585796c8dcSSimon Schubert { 6595796c8dcSSimon Schubert /* Hack: remove (char *) for char strings. Their 6605796c8dcSSimon Schubert type is indicated by the quoted string anyway. 661cf7f2e2dSJohn Marino (Don't use c_textual_element_type here; quoted strings 6625796c8dcSSimon Schubert are always exactly (char *), (wchar_t *), or the like. */ 6635796c8dcSSimon Schubert if (TYPE_CODE (val_type) == TYPE_CODE_PTR 6645796c8dcSSimon Schubert && TYPE_NAME (val_type) == NULL 6655796c8dcSSimon Schubert && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL 666*c50c785cSJohn Marino && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)), 667*c50c785cSJohn Marino "char") == 0 6685796c8dcSSimon Schubert || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type))))) 6695796c8dcSSimon Schubert { 670*c50c785cSJohn Marino /* Print nothing. */ 6715796c8dcSSimon Schubert } 6725796c8dcSSimon Schubert else if (options->objectprint 6735796c8dcSSimon Schubert && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) 6745796c8dcSSimon Schubert { 6755796c8dcSSimon Schubert 6765796c8dcSSimon Schubert if (TYPE_CODE(type) == TYPE_CODE_REF) 6775796c8dcSSimon Schubert { 6785796c8dcSSimon Schubert /* Copy value, change to pointer, so we don't get an 679*c50c785cSJohn Marino error about a non-pointer type in 680*c50c785cSJohn Marino value_rtti_target_type. */ 6815796c8dcSSimon Schubert struct value *temparg; 6825796c8dcSSimon Schubert temparg=value_copy(val); 683*c50c785cSJohn Marino deprecated_set_value_type 684*c50c785cSJohn Marino (temparg, lookup_pointer_type (TYPE_TARGET_TYPE (type))); 6855796c8dcSSimon Schubert val = temparg; 6865796c8dcSSimon Schubert } 687*c50c785cSJohn Marino /* Pointer to class, check real type of object. */ 6885796c8dcSSimon Schubert fprintf_filtered (stream, "("); 689*c50c785cSJohn Marino 690*c50c785cSJohn Marino if (value_entirely_available (val)) 691*c50c785cSJohn Marino { 6925796c8dcSSimon Schubert real_type = value_rtti_target_type (val, &full, &top, &using_enc); 6935796c8dcSSimon Schubert if (real_type) 6945796c8dcSSimon Schubert { 695*c50c785cSJohn Marino /* RTTI entry found. */ 6965796c8dcSSimon Schubert if (TYPE_CODE (type) == TYPE_CODE_PTR) 6975796c8dcSSimon Schubert { 698*c50c785cSJohn Marino /* Create a pointer type pointing to the real 699*c50c785cSJohn Marino type. */ 7005796c8dcSSimon Schubert type = lookup_pointer_type (real_type); 7015796c8dcSSimon Schubert } 7025796c8dcSSimon Schubert else 7035796c8dcSSimon Schubert { 704*c50c785cSJohn Marino /* Create a reference type referencing the real 705*c50c785cSJohn Marino type. */ 7065796c8dcSSimon Schubert type = lookup_reference_type (real_type); 7075796c8dcSSimon Schubert } 708*c50c785cSJohn Marino /* Need to adjust pointer value. */ 709*c50c785cSJohn Marino val = value_from_pointer (type, value_as_address (val) - top); 7105796c8dcSSimon Schubert 711*c50c785cSJohn Marino /* Note: When we look up RTTI entries, we don't get 712*c50c785cSJohn Marino any information on const or volatile 713*c50c785cSJohn Marino attributes. */ 714*c50c785cSJohn Marino } 7155796c8dcSSimon Schubert } 7165796c8dcSSimon Schubert type_print (type, "", stream, -1); 7175796c8dcSSimon Schubert fprintf_filtered (stream, ") "); 7185796c8dcSSimon Schubert val_type = type; 7195796c8dcSSimon Schubert } 7205796c8dcSSimon Schubert else 7215796c8dcSSimon Schubert { 7225796c8dcSSimon Schubert /* normal case */ 7235796c8dcSSimon Schubert fprintf_filtered (stream, "("); 7245796c8dcSSimon Schubert type_print (value_type (val), "", stream, -1); 7255796c8dcSSimon Schubert fprintf_filtered (stream, ") "); 7265796c8dcSSimon Schubert } 7275796c8dcSSimon Schubert } 7285796c8dcSSimon Schubert 7295796c8dcSSimon Schubert if (!value_initialized (val)) 7305796c8dcSSimon Schubert fprintf_filtered (stream, " [uninitialized] "); 7315796c8dcSSimon Schubert 7325796c8dcSSimon Schubert if (options->objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS)) 7335796c8dcSSimon Schubert { 734*c50c785cSJohn Marino /* Attempt to determine real type of object. */ 7355796c8dcSSimon Schubert real_type = value_rtti_type (val, &full, &top, &using_enc); 7365796c8dcSSimon Schubert if (real_type) 7375796c8dcSSimon Schubert { 738*c50c785cSJohn Marino /* We have RTTI information, so use it. */ 739*c50c785cSJohn Marino val = value_full_object (val, real_type, 740*c50c785cSJohn Marino full, top, using_enc); 7415796c8dcSSimon Schubert fprintf_filtered (stream, "(%s%s) ", 7425796c8dcSSimon Schubert TYPE_NAME (real_type), 7435796c8dcSSimon Schubert full ? "" : _(" [incomplete object]")); 744*c50c785cSJohn Marino /* Print out object: enclosing type is same as real_type if 745*c50c785cSJohn Marino full. */ 7465796c8dcSSimon Schubert return val_print (value_enclosing_type (val), 747cf7f2e2dSJohn Marino value_contents_for_printing (val), 0, 7485796c8dcSSimon Schubert value_address (val), stream, 0, 749cf7f2e2dSJohn Marino val, &opts, current_language); 750*c50c785cSJohn Marino /* Note: When we look up RTTI entries, we don't get any 751*c50c785cSJohn Marino information on const or volatile attributes. */ 7525796c8dcSSimon Schubert } 7535796c8dcSSimon Schubert else if (type != check_typedef (value_enclosing_type (val))) 7545796c8dcSSimon Schubert { 755*c50c785cSJohn Marino /* No RTTI information, so let's do our best. */ 7565796c8dcSSimon Schubert fprintf_filtered (stream, "(%s ?) ", 7575796c8dcSSimon Schubert TYPE_NAME (value_enclosing_type (val))); 7585796c8dcSSimon Schubert return val_print (value_enclosing_type (val), 759cf7f2e2dSJohn Marino value_contents_for_printing (val), 0, 7605796c8dcSSimon Schubert value_address (val), stream, 0, 761cf7f2e2dSJohn Marino val, &opts, current_language); 7625796c8dcSSimon Schubert } 763*c50c785cSJohn Marino /* Otherwise, we end up at the return outside this "if". */ 7645796c8dcSSimon Schubert } 7655796c8dcSSimon Schubert 766cf7f2e2dSJohn Marino return val_print (val_type, value_contents_for_printing (val), 7675796c8dcSSimon Schubert value_embedded_offset (val), 7685796c8dcSSimon Schubert value_address (val), 769cf7f2e2dSJohn Marino stream, 0, 770cf7f2e2dSJohn Marino val, &opts, current_language); 7715796c8dcSSimon Schubert } 772