/* Convert types from GDB to GCC
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
+ Copyright (C) 2014-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
-#include "common/preprocessor.h"
+#include "gdbsupport/preprocessor.h"
#include "gdbtypes.h"
#include "compile-internal.h"
#include "compile-cplus.h"
-#include "gdb_assert.h"
+#include "gdbsupport/gdb_assert.h"
#include "symtab.h"
#include "source.h"
#include "cp-support.h"
#include "cp-abi.h"
-#include "symtab.h"
#include "objfiles.h"
#include "block.h"
#include "gdbcmd.h"
#include "c-lang.h"
-#include "compile-c.h" /* Included for c_get_range_decl_name
- et al. */
+#include "compile-c.h"
#include <algorithm>
/* Default compile flags for C++. */
/* Flag to enable internal debugging. */
-static int debug_compile_cplus_types = 0;
+static bool debug_compile_cplus_types = false;
/* Flag to enable internal scope switching debugging. */
-static int debug_compile_cplus_scopes = 0;
+static bool debug_compile_cplus_scopes = false;
/* Forward declarations. */
if (natural == nullptr)
return nullptr;
- char *name = cp_func_name (natural);
+ gdb::unique_xmalloc_ptr<char> name = cp_func_name (natural);
if (name != nullptr)
- return gdb::unique_xmalloc_ptr<char> (name);
+ return name;
- return gdb::unique_xmalloc_ptr<char> (xstrdup (natural));
+ return make_unique_xstrdup (natural);
}
/* Get the access flag for the NUM'th field of TYPE. */
enum gcc_cp_symbol_kind
get_method_access_flag (const struct type *type, int fni, int num)
{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);
+ gdb_assert (type->code () == TYPE_CODE_STRUCT);
/* If this type was not declared a class, everything is public. */
if (!TYPE_DECLARED_CLASS (type))
for (const auto &comp: scope)
{
const char *symbol = (comp.bsymbol.symbol != nullptr
- ? SYMBOL_NATURAL_NAME (comp.bsymbol.symbol)
+ ? comp.bsymbol.symbol->natural_name ()
: "<none>");
printf_unfiltered ("\tname = %s, symbol = %s\n", comp.name.c_str (),
scope.push_back (comp);
- if (TYPE_CODE (SYMBOL_TYPE (bsymbol.symbol)) != TYPE_CODE_NAMESPACE)
+ if (SYMBOL_TYPE (bsymbol.symbol)->code () != TYPE_CODE_NAMESPACE)
{
/* We're done. */
break;
/* See description in compile-cplus.h. */
void
-compile_cplus_instance::enter_scope (compile_scope &new_scope)
+compile_cplus_instance::enter_scope (compile_scope &&new_scope)
{
bool must_push = m_scopes.empty () || m_scopes.back () != new_scope;
new_scope.m_pushed = must_push;
/* Save the new scope. */
- m_scopes.push_back (new_scope);
+ m_scopes.push_back (std::move (new_scope));
if (must_push)
{
if (debug_compile_cplus_scopes)
{
fprintf_unfiltered (gdb_stdlog, "entering new scope %s\n",
- host_address_to_string (&new_scope));
+ host_address_to_string (&m_scopes.back ()));
}
/* Push the global namespace. */
/* Push all other namespaces. Note that we do not push the last
scope_component -- that's the actual type we are converting. */
std::for_each
- (new_scope.begin (), new_scope.end () - 1,
+ (m_scopes.back ().begin (), m_scopes.back ().end () - 1,
[this] (const scope_component &comp)
{
- gdb_assert (TYPE_CODE (SYMBOL_TYPE (comp.bsymbol.symbol))
+ gdb_assert (SYMBOL_TYPE (comp.bsymbol.symbol)->code ()
== TYPE_CODE_NAMESPACE);
const char *ns = (comp.name == CP_ANONYMOUS_NAMESPACE_STR ? nullptr
std::for_each
(current.begin (),current.end () - 1,
[this] (const scope_component &comp) {
- gdb_assert (TYPE_CODE (SYMBOL_TYPE (comp.bsymbol.symbol))
+ gdb_assert (SYMBOL_TYPE (comp.bsymbol.symbol)->code ()
== TYPE_CODE_NAMESPACE);
this->plugin ().pop_binding_level (comp.name.c_str ());
});
class, the previous call will give us that type's gcc_type.
Upper layers are expecting to get the original type's
gcc_type! */
- get_cached_type (type, scope.m_nested_type);
+ get_cached_type (type, &scope.m_nested_type);
return scope;
}
}
else
{
- if (TYPE_NAME (type) == nullptr)
+ if (type->name () == nullptr)
{
/* Anonymous type */
{
scope_component comp
= {
- decl_name (TYPE_NAME (type)).get (),
- lookup_symbol (TYPE_NAME (type), block (), VAR_DOMAIN, nullptr)
+ decl_name (type->name ()).get (),
+ lookup_symbol (type->name (), block (), VAR_DOMAIN, nullptr)
};
scope.push_back (comp);
}
gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type));
enum gcc_cp_ref_qualifiers quals = GCC_CP_REF_QUAL_NONE;
- switch (TYPE_CODE (type))
+ switch (type->code ())
{
case TYPE_CODE_REF:
quals = GCC_CP_REF_QUAL_LVALUE;
compile_cplus_convert_array (compile_cplus_instance *instance,
struct type *type)
{
- struct type *range = TYPE_INDEX_TYPE (type);
+ struct type *range = type->index_type ();
gcc_type element_type = instance->convert_type (TYPE_TARGET_TYPE (type));
- if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST)
+ if (range->bounds ()->low.kind () != PROP_CONST)
{
const char *s = _("array type with non-constant"
" lower bound is not supported");
return instance->plugin ().error (s);
}
- if (TYPE_LOW_BOUND (range) != 0)
+ if (range->bounds ()->low.const_val () != 0)
{
const char *s = _("cannot convert array type with "
"non-zero lower bound to C");
return instance->plugin ().error (s);
}
- if (TYPE_HIGH_BOUND_KIND (range) == PROP_LOCEXPR
- || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST)
+ if (range->bounds ()->high.kind () == PROP_LOCEXPR
+ || range->bounds ()->high.kind () == PROP_LOCLIST)
{
- if (TYPE_VECTOR (type))
+ if (type->is_vector ())
{
const char *s = _("variably-sized vector type is not supported");
}
std::string upper_bound
- = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high);
+ = c_get_range_decl_name (&range->bounds ()->high);
return instance->plugin ().build_vla_array_type (element_type,
upper_bound.c_str ());
}
{
LONGEST low_bound, high_bound, count;
- if (get_array_bounds (type, &low_bound, &high_bound) == 0)
+ if (!get_array_bounds (type, &low_bound, &high_bound))
count = -1;
else
{
count = high_bound + 1;
}
- if (TYPE_VECTOR (type))
+ if (type->is_vector ())
return instance->plugin ().build_vector_type (element_type, count);
return instance->plugin ().build_array_type (element_type, count);
struct type *type,
enum gcc_cp_symbol_kind nested_access)
{
- compile_scope scope = instance->new_scope (TYPE_NAME (type), type);
+ compile_scope scope = instance->new_scope (type->name (), type);
if (scope.nested_type () != GCC_TYPE_NONE)
return scope.nested_type ();
gdb::unique_xmalloc_ptr<char> name
- = compile_cplus_instance::decl_name (TYPE_NAME (type));
+ = compile_cplus_instance::decl_name (type->name ());
/* Make sure the scope for this type has been pushed. */
- instance->enter_scope (scope);
+ instance->enter_scope (std::move (scope));
/* Convert the typedef's real type. */
gcc_type typedef_type = instance->convert_type (check_typedef (type));
compile_cplus_convert_struct_or_union_members
(compile_cplus_instance *instance, struct type *type, gcc_type comp_type)
{
- for (int i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); ++i)
+ for (int i = TYPE_N_BASECLASSES (type); i < type->num_fields (); ++i)
{
const char *field_name = TYPE_FIELD_NAME (type, i);
field_name = nullptr;
gcc_type field_type
- = instance->convert_type (TYPE_FIELD_TYPE (type, i));
+ = instance->convert_type (type->field (i).type ());
- if (field_is_static (&TYPE_FIELD (type, i)))
+ if (field_is_static (&type->field (i)))
{
CORE_ADDR physaddr;
| get_field_access_flag (type, i);
if (bitsize == 0)
- bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i));
+ bitsize = 8 * TYPE_LENGTH (type->field (i).type ());
instance->plugin ().build_field
(field_name, field_type, field_flags, bitsize,
type and corresponding qualifier flags. */
gcc_type func_type = compile_cplus_convert_func (instance, method_type, true);
gcc_type class_type = instance->convert_type (parent_type);
- gcc_cp_qualifiers_flags quals = (enum gcc_cp_qualifiers) 0;
+ gcc_cp_qualifiers_flags quals = 0;
if (TYPE_CONST (method_type))
quals |= GCC_CP_QUALIFIER_CONST;
gcc_cp_ref_qualifiers_flags rquals = GCC_CP_REF_QUAL_NONE;
return instance->plugin ().build_method_type
- (class_type, func_type, quals, rquals);
+ (class_type, func_type, quals.raw (), rquals.raw ());
}
/* Convert a member or method pointer represented by TYPE. */
(sym_kind
| get_method_access_flag (type, i, j)
| GCC_CP_FLAG_VIRTUAL_FUNCTION
- | GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION),
+ | GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION).raw (),
method_type, nullptr, 0, nullptr, 0);
continue;
}
instance->plugin ().build_decl
(kind, overloaded_name.get (),
- sym_kind | get_method_access_flag (type, i, j),
+ (sym_kind | get_method_access_flag (type, i, j)).raw (),
method_type, nullptr, address, filename, line);
}
}
/* Get the decl name of this type. */
gdb::unique_xmalloc_ptr<char> name
- = compile_cplus_instance::decl_name (TYPE_NAME (type));
+ = compile_cplus_instance::decl_name (type->name ());
/* Create a new scope for TYPE. */
- compile_scope scope = instance->new_scope (TYPE_NAME (type), type);
+ compile_scope scope = instance->new_scope (type->name (), type);
if (scope.nested_type () != GCC_TYPE_NONE)
{
}
/* Push all scopes. */
- instance->enter_scope (scope);
+ instance->enter_scope (std::move (scope));
/* First we create the resulting type and enter it into our hash
table. This lets recursive types work. */
gcc_decl resuld;
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ if (type->code () == TYPE_CODE_STRUCT)
{
- const char *what = TYPE_DECLARED_CLASS (type) ? "struct" : "class";
+ const char *what = TYPE_DECLARED_CLASS (type) ? "class" : "struct";
resuld = instance->plugin ().build_decl
(what, name.get (), (GCC_CP_SYMBOL_CLASS | nested_access
}
else
{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
+ gdb_assert (type->code () == TYPE_CODE_UNION);
resuld = instance->plugin ().build_decl
("union", name.get (), GCC_CP_SYMBOL_UNION | nested_access,
0, nullptr, 0, filename, line);
}
gcc_type result;
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ if (type->code () == TYPE_CODE_STRUCT)
{
- struct gcc_vbase_array bases;
int num_baseclasses = TYPE_N_BASECLASSES (type);
+ std::vector<gcc_type> elements (num_baseclasses);
+ std::vector<enum gcc_cp_symbol_kind> flags (num_baseclasses);
- memset (&bases, 0, sizeof (bases));
+ struct gcc_vbase_array bases {};
+ bases.elements = elements.data ();
+ bases.flags = flags.data ();
+ bases.n_elements = num_baseclasses;
- if (num_baseclasses > 0)
+ for (int i = 0; i < num_baseclasses; ++i)
{
- bases.elements = XNEWVEC (gcc_type, num_baseclasses);
- bases.flags = XNEWVEC (enum gcc_cp_symbol_kind, num_baseclasses);
- bases.n_elements = num_baseclasses;
- for (int i = 0; i < num_baseclasses; ++i)
- {
- struct type *base_type = TYPE_BASECLASS (type, i);
-
- bases.flags[i] = GCC_CP_SYMBOL_BASECLASS
- | get_field_access_flag (type, i)
- | (BASETYPE_VIA_VIRTUAL (type, i)
- ? GCC_CP_FLAG_BASECLASS_VIRTUAL
- : GCC_CP_FLAG_BASECLASS_NOFLAG);
- bases.elements[i] = instance->convert_type (base_type);
- }
+ struct type *base_type = TYPE_BASECLASS (type, i);
+
+ bases.flags[i] = (GCC_CP_SYMBOL_BASECLASS
+ | get_field_access_flag (type, i)
+ | (BASETYPE_VIA_VIRTUAL (type, i)
+ ? GCC_CP_FLAG_BASECLASS_VIRTUAL
+ : GCC_CP_FLAG_BASECLASS_NOFLAG));
+ bases.elements[i] = instance->convert_type (base_type);
}
result = instance->plugin ().start_class_type
(name.get (), resuld, &bases, filename, line);
- xfree (bases.flags);
- xfree (bases.elements);
}
else
{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
+ gdb_assert (type->code () == TYPE_CODE_UNION);
result = instance->plugin ().start_class_type
(name.get (), resuld, nullptr, filename, line);
}
compile_cplus_convert_enum (compile_cplus_instance *instance, struct type *type,
enum gcc_cp_symbol_kind nested_access)
{
- int scoped_enum_p = FALSE;
+ bool scoped_enum_p = false;
/* Create a new scope for this type. */
- compile_scope scope = instance->new_scope (TYPE_NAME (type), type);
+ compile_scope scope = instance->new_scope (type->name (), type);
if (scope.nested_type () != GCC_TYPE_NONE)
{
}
gdb::unique_xmalloc_ptr<char> name
- = compile_cplus_instance::decl_name (TYPE_NAME (type));
+ = compile_cplus_instance::decl_name (type->name ());
/* Push all scopes. */
- instance->enter_scope (scope);
+ instance->enter_scope (std::move (scope));
gcc_type int_type
- = instance->plugin ().get_int_type (TYPE_UNSIGNED (type),
+ = instance->plugin ().get_int_type (type->is_unsigned (),
TYPE_LENGTH (type), nullptr);
gcc_type result
= instance->plugin ().start_enum_type (name.get (), int_type,
? GCC_CP_FLAG_ENUM_SCOPED
: GCC_CP_FLAG_ENUM_NOFLAG),
nullptr, 0);
- for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+ for (int i = 0; i < type->num_fields (); ++i)
{
gdb::unique_xmalloc_ptr<char> fname
= compile_cplus_instance::decl_name (TYPE_FIELD_NAME (type, i));
compile_cplus_convert_func (compile_cplus_instance *instance,
struct type *type, bool strip_artificial)
{
- int is_varargs = TYPE_VARARGS (type);
+ int is_varargs = type->has_varargs ();
struct type *target_type = TYPE_TARGET_TYPE (type);
/* Functions with no debug info have no return type. Ideally we'd
GDB's parser used to do. */
if (target_type == nullptr)
{
- if (TYPE_OBJFILE_OWNED (type))
- target_type = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
+ if (type->is_objfile_owned ())
+ target_type = objfile_type (type->objfile_owner ())->builtin_int;
else
- target_type = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
+ target_type = builtin_type (type->arch_owner ())->builtin_int;
warning (_("function has unknown return type; assuming int"));
}
types. Those are impossible in C, though. */
gcc_type return_type = instance->convert_type (target_type);
- struct gcc_type_array array =
- { TYPE_NFIELDS (type), XNEWVEC (gcc_type, TYPE_NFIELDS (type)) };
+ std::vector<gcc_type> elements (type->num_fields ());
+ struct gcc_type_array array = { type->num_fields (), elements.data () };
int artificials = 0;
- for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+ for (int i = 0; i < type->num_fields (); ++i)
{
if (strip_artificial && TYPE_FIELD_ARTIFICIAL (type, i))
{
else
{
array.elements[i - artificials]
- = instance->convert_type (TYPE_FIELD_TYPE (type, i));
+ = instance->convert_type (type->field (i).type ());
}
}
with some minsyms like printf (compile-cplus.exp has examples). */
gcc_type result = instance->plugin ().build_function_type
(return_type, &array, is_varargs);
- xfree (array.elements);
return result;
}
static gcc_type
compile_cplus_convert_int (compile_cplus_instance *instance, struct type *type)
{
- if (TYPE_NOSIGN (type))
+ if (type->has_no_signedness ())
{
gdb_assert (TYPE_LENGTH (type) == 1);
return instance->plugin ().get_char_type ();
}
return instance->plugin ().get_int_type
- (TYPE_UNSIGNED (type), TYPE_LENGTH (type), TYPE_NAME (type));
+ (type->is_unsigned (), TYPE_LENGTH (type), type->name ());
}
/* Convert a floating-point type to its gcc representation. */
struct type *type)
{
return instance->plugin ().get_float_type
- (TYPE_LENGTH (type), TYPE_NAME (type));
+ (TYPE_LENGTH (type), type->name ());
}
/* Convert the 'void' type to its gcc representation. */
gcc_type result = base;
if (quals != 0)
- result = plugin ().build_qualified_type (base, quals);
+ result = plugin ().build_qualified_type (base, quals.raw ());
return result;
}
compile_cplus_convert_namespace (compile_cplus_instance *instance,
struct type *type)
{
- compile_scope scope = instance->new_scope (TYPE_NAME (type), type);
+ compile_scope scope = instance->new_scope (type->name (), type);
gdb::unique_xmalloc_ptr<char> name
- = compile_cplus_instance::decl_name (TYPE_NAME (type));
+ = compile_cplus_instance::decl_name (type->name ());
/* Push scope. */
- instance->enter_scope (scope);
+ instance->enter_scope (std::move (scope));
/* Convert this namespace. */
instance->plugin ().push_namespace (name.get ());
{
/* If we are converting a qualified type, first convert the
unqualified type and then apply the qualifiers. */
- if ((TYPE_INSTANCE_FLAGS (type) & (TYPE_INSTANCE_FLAG_CONST
- | TYPE_INSTANCE_FLAG_VOLATILE
- | TYPE_INSTANCE_FLAG_RESTRICT)) != 0)
+ if ((type->instance_flags () & (TYPE_INSTANCE_FLAG_CONST
+ | TYPE_INSTANCE_FLAG_VOLATILE
+ | TYPE_INSTANCE_FLAG_RESTRICT)) != 0)
return compile_cplus_convert_qualified (instance, type);
- switch (TYPE_CODE (type))
+ switch (type->code ())
{
case TYPE_CODE_REF:
case TYPE_CODE_RVALUE_REF:
}
std::string s = string_printf (_("unhandled TYPE_CODE %d"),
- TYPE_CODE (type));
+ type->code ());
return instance->plugin ().error (s.c_str ());
}
{
/* Check if TYPE has already been converted. */
gcc_type result;
- if (get_cached_type (type, result))
+ if (get_cached_type (type, &result))
return result;
/* It is the first time this type has been seen -- convert it
gcc_decl. */
static void
-compile_cplus_debug_output_1 (gcc_type arg)
+compile_cplus_debug_output_1 (ULONGEST arg)
{
- fprintf_unfiltered (gdb_stdlog, "%lld", arg);
+ fprintf_unfiltered (gdb_stdlog, "%s", pulongest (arg));
}
static void
return pop_binding_level ();
}
+void _initialize_compile_cplus_types ();
void
_initialize_compile_cplus_types ()
{