aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-05-25 16:08:44 +0100
committerYao Qi <yao.qi@linaro.org>2017-06-20 11:34:10 +0100
commit7b162e155c0c39cad83d7542a61918114d130407 (patch)
tree93e198d4e33d62132fba7a1ff32ae678ada32d71 /gdb
parent7432117013f61a4ad87ff803d043672888d43aa7 (diff)
downloadgdb-7b162e155c0c39cad83d7542a61918114d130407.zip
gdb-7b162e155c0c39cad83d7542a61918114d130407.tar.gz
gdb-7b162e155c0c39cad83d7542a61918114d130407.tar.bz2
Use visitor pattern for "maint print c-tdesc"
Target description can be modeled as a tree, the target description is the root node, features are children nodes, registers and types are grand-children nodes. So command "maint print c-tdesc" in effect traverse/visit each node, and print them in c. This can be implemented by visitor pattern, this is the first reason. Secondly, I want to this command prints c files in a different way for some specific xml files, but still print c files the same way for the rest of xml files. Third, I even want to print xml files from target descriptions, so that GDBserver can use it to reply GDB's query qXfer:features:read:target.xml. After this change, all features/*.c should be re-generated, but this patch only includes part changes features/*.c files. gdb: 2017-05-25 Yao Qi <yao.qi@linaro.org> * target-descriptions.c (tdesc_element_visitor): New class. (tdesc_element): New class. (tdesc_reg): Inherit from tdesc_element. (tdesc_reg::accept): New function. (tdesc_type): Inherit from tdesc_element. (tdesc_type::accept): New function. (tdesc_feature): Inherit from tdesc_element. (tdesc_feature::accept): New function. (target_desc): Inherit from tdesc_element. (target_desc::target_desc): New. (target_desc::~target_desc): New. (target_desc::accept): New. (allocate_target_description): Use new. (free_target_description): Use delete. (print_c_tdesc): New class. (maint_print_c_tdesc_cmd): Adjust. * features/i386/i386-avx-avx512-linux.c: Re-generated. * features/i386/i386-avx-linux.c: Re-generated. * features/i386/i386-avx-mpx-avx512-pku-linux.c: Re-generated. * features/i386/i386-avx-mpx-linux.c: Re-generated. * features/i386/i386-linux.c: Re-generated. * features/i386/i386-mmx-linux.c: Re-generated.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/features/i386/i386-avx-avx512-linux.c8
-rw-r--r--gdb/features/i386/i386-avx-avx512.c8
-rw-r--r--gdb/features/i386/i386-avx-linux.c8
-rw-r--r--gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c8
-rw-r--r--gdb/features/i386/i386-avx-mpx-avx512-pku.c8
-rw-r--r--gdb/features/i386/i386-avx-mpx-linux.c8
-rw-r--r--gdb/features/i386/i386-avx-mpx.c8
-rw-r--r--gdb/features/i386/i386-avx.c8
-rw-r--r--gdb/features/i386/i386-linux.c8
-rw-r--r--gdb/features/i386/i386-mmx-linux.c8
-rw-r--r--gdb/features/i386/i386-mmx.c8
-rw-r--r--gdb/features/i386/i386-mpx-linux.c8
-rw-r--r--gdb/features/i386/i386-mpx.c8
-rw-r--r--gdb/features/i386/i386.c8
-rw-r--r--gdb/target-descriptions.c657
15 files changed, 427 insertions, 342 deletions
diff --git a/gdb/features/i386/i386-avx-avx512-linux.c b/gdb/features/i386/i386-avx-avx512-linux.c
index 81149d5..545149d 100644
--- a/gdb/features/i386/i386-avx-avx512-linux.c
+++ b/gdb/features/i386/i386-avx-avx512-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_avx_avx512_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx-avx512.c b/gdb/features/i386/i386-avx-avx512.c
index 1075ca0..585a0ac 100644
--- a/gdb/features/i386/i386-avx-avx512.c
+++ b/gdb/features/i386/i386-avx-avx512.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386_avx_avx512 (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx-linux.c b/gdb/features/i386/i386-avx-linux.c
index 4a8c6b5..3ef087d 100644
--- a/gdb/features/i386/i386-avx-linux.c
+++ b/gdb/features/i386/i386-avx-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_avx_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c
index f90c834..e6eebf1 100644
--- a/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c
+++ b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_avx_mpx_avx512_pku_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx-mpx-avx512-pku.c b/gdb/features/i386/i386-avx-mpx-avx512-pku.c
index 08d9b4b..d7dd3bb 100644
--- a/gdb/features/i386/i386-avx-mpx-avx512-pku.c
+++ b/gdb/features/i386/i386-avx-mpx-avx512-pku.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386_avx_mpx_avx512_pku (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx-mpx-linux.c b/gdb/features/i386/i386-avx-mpx-linux.c
index 4b27bfc..f62c487 100644
--- a/gdb/features/i386/i386-avx-mpx-linux.c
+++ b/gdb/features/i386/i386-avx-mpx-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_avx_mpx_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx-mpx.c b/gdb/features/i386/i386-avx-mpx.c
index b27b40a..f479bda 100644
--- a/gdb/features/i386/i386-avx-mpx.c
+++ b/gdb/features/i386/i386-avx-mpx.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386_avx_mpx (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-avx.c b/gdb/features/i386/i386-avx.c
index 1cb0f9e..f888335 100644
--- a/gdb/features/i386/i386-avx.c
+++ b/gdb/features/i386/i386-avx.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386_avx (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-linux.c b/gdb/features/i386/i386-linux.c
index c7796c3..0394842 100644
--- a/gdb/features/i386/i386-linux.c
+++ b/gdb/features/i386/i386-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-mmx-linux.c b/gdb/features/i386/i386-mmx-linux.c
index e53b55f..1577972 100644
--- a/gdb/features/i386/i386-mmx-linux.c
+++ b/gdb/features/i386/i386-mmx-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_mmx_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-mmx.c b/gdb/features/i386/i386-mmx.c
index 74f67ed..02aee89 100644
--- a/gdb/features/i386/i386-mmx.c
+++ b/gdb/features/i386/i386-mmx.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386_mmx (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-mpx-linux.c b/gdb/features/i386/i386-mpx-linux.c
index 43ea192..6dea8e0 100644
--- a/gdb/features/i386/i386-mpx-linux.c
+++ b/gdb/features/i386/i386-mpx-linux.c
@@ -10,15 +10,15 @@ static void
initialize_tdesc_i386_mpx_linux (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386-mpx.c b/gdb/features/i386/i386-mpx.c
index e832d2e..d08441b 100644
--- a/gdb/features/i386/i386-mpx.c
+++ b/gdb/features/i386/i386-mpx.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386_mpx (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/features/i386/i386.c b/gdb/features/i386/i386.c
index ede73fc..eb9a266 100644
--- a/gdb/features/i386/i386.c
+++ b/gdb/features/i386/i386.c
@@ -10,13 +10,13 @@ static void
initialize_tdesc_i386 (void)
{
struct target_desc *result = allocate_target_description ();
- struct tdesc_feature *feature;
- struct tdesc_type *field_type;
- struct tdesc_type *type;
-
set_tdesc_architecture (result, bfd_scan_arch ("i386"));
+ struct tdesc_feature *feature;
+
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
type = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type, 0, "CF");
tdesc_add_flag (type, 1, "");
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 0b5b46f..60bc4e5 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -35,6 +35,23 @@
#include "hashtab.h"
#include "inferior.h"
+class tdesc_element_visitor
+{
+public:
+ virtual void visit (const target_desc *e) = 0;
+ virtual void visit_end (const target_desc *e) = 0;
+
+ virtual void visit (const tdesc_feature *e) = 0;
+ virtual void visit (const tdesc_type *e) = 0;
+ virtual void visit (const tdesc_reg *e) = 0;
+};
+
+class tdesc_element
+{
+public:
+ virtual void accept (tdesc_element_visitor &v) const = 0;
+};
+
/* Types. */
typedef struct property
@@ -46,7 +63,7 @@ DEF_VEC_O(property_s);
/* An individual register from a target description. */
-typedef struct tdesc_reg
+typedef struct tdesc_reg : tdesc_element
{
tdesc_reg (struct tdesc_feature *feature, const char *name_,
int regnum, int save_restore_, const char *group_,
@@ -62,7 +79,7 @@ typedef struct tdesc_reg
tdesc_type = tdesc_named_type (feature, type);
}
- ~tdesc_reg ()
+ virtual ~tdesc_reg ()
{
xfree (name);
xfree (type);
@@ -106,6 +123,12 @@ typedef struct tdesc_reg
/* The target-described type corresponding to TYPE, if found. */
struct tdesc_type *tdesc_type;
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+ }
+
} *tdesc_reg_p;
DEF_VEC_P(tdesc_reg_p);
@@ -151,7 +174,7 @@ enum tdesc_type_kind
TDESC_TYPE_ENUM
};
-typedef struct tdesc_type
+typedef struct tdesc_type : tdesc_element
{
tdesc_type (const char *name_, enum tdesc_type_kind kind_)
: name (xstrdup (name_)), kind (kind_)
@@ -159,7 +182,7 @@ typedef struct tdesc_type
memset (&u, 0, sizeof (u));
}
- ~tdesc_type ()
+ virtual ~tdesc_type ()
{
switch (kind)
{
@@ -214,19 +237,24 @@ typedef struct tdesc_type
int size;
} u;
} u;
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+ }
+
} *tdesc_type_p;
DEF_VEC_P(tdesc_type_p);
/* A feature from a target description. Each feature is a collection
of other elements, e.g. registers and types. */
-typedef struct tdesc_feature
+typedef struct tdesc_feature : tdesc_element
{
tdesc_feature (const char *name_)
: name (xstrdup (name_))
{}
- ~tdesc_feature ()
+ virtual ~tdesc_feature ()
{
struct tdesc_reg *reg;
struct tdesc_type *type;
@@ -256,6 +284,30 @@ typedef struct tdesc_feature
/* The types associated with this feature. */
VEC(tdesc_type_p) *types = NULL;
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+
+ struct tdesc_type *type;
+
+ for (int ix = 0;
+ VEC_iterate (tdesc_type_p, types, ix, type);
+ ix++)
+ {
+ type->accept (v);
+ }
+
+ struct tdesc_reg *reg;
+
+ for (int ix = 0;
+ VEC_iterate (tdesc_reg_p, registers, ix, reg);
+ ix++)
+ {
+ reg->accept (v);
+ }
+ }
+
} *tdesc_feature_p;
DEF_VEC_P(tdesc_feature_p);
@@ -265,23 +317,67 @@ DEF_VEC_P(arch_p);
/* A target description. */
-struct target_desc
+struct target_desc : tdesc_element
{
+public:
+ target_desc ()
+ {}
+
+ virtual ~target_desc ()
+ {
+ struct tdesc_feature *feature;
+ struct property *prop;
+ int ix;
+
+ for (ix = 0;
+ VEC_iterate (tdesc_feature_p, features, ix, feature);
+ ix++)
+ delete feature;
+ VEC_free (tdesc_feature_p, features);
+
+ for (ix = 0;
+ VEC_iterate (property_s, properties, ix, prop);
+ ix++)
+ {
+ xfree (prop->key);
+ xfree (prop->value);
+ }
+
+ VEC_free (property_s, properties);
+ VEC_free (arch_p, compatible);
+ }
+
/* The architecture reported by the target, if any. */
- const struct bfd_arch_info *arch;
+ const struct bfd_arch_info *arch = NULL;
/* The osabi reported by the target, if any; GDB_OSABI_UNKNOWN
otherwise. */
- enum gdb_osabi osabi;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
/* The list of compatible architectures reported by the target. */
- VEC(arch_p) *compatible;
+ VEC(arch_p) *compatible = NULL;
/* Any architecture-specific properties specified by the target. */
- VEC(property_s) *properties;
+ VEC(property_s) *properties = NULL;
/* The features associated with this target. */
- VEC(tdesc_feature_p) *features;
+ VEC(tdesc_feature_p) *features = NULL;
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+
+ struct tdesc_feature *feature;
+
+ for (int ix = 0;
+ VEC_iterate (tdesc_feature_p, features, ix, feature);
+ ix++)
+ {
+ feature->accept (v);
+ }
+
+ v.visit_end (this);
+ }
};
/* Per-architecture data associated with a target description. The
@@ -1551,35 +1647,15 @@ tdesc_create_feature (struct target_desc *tdesc, const char *name)
struct target_desc *
allocate_target_description (void)
{
- return XCNEW (struct target_desc);
+ return new target_desc ();
}
static void
free_target_description (void *arg)
{
struct target_desc *target_desc = (struct target_desc *) arg;
- struct tdesc_feature *feature;
- struct property *prop;
- int ix;
- for (ix = 0;
- VEC_iterate (tdesc_feature_p, target_desc->features, ix, feature);
- ix++)
- delete feature;
- VEC_free (tdesc_feature_p, target_desc->features);
-
- for (ix = 0;
- VEC_iterate (property_s, target_desc->properties, ix, prop);
- ix++)
- {
- xfree (prop->key);
- xfree (prop->value);
- }
- VEC_free (property_s, target_desc->properties);
-
- VEC_free (arch_p, target_desc->compatible);
-
- xfree (target_desc);
+ delete target_desc;
}
struct cleanup *
@@ -1704,279 +1780,288 @@ unset_tdesc_filename_cmd (char *args, int from_tty)
target_find_description ();
}
-static void
-maint_print_c_tdesc_cmd (char *args, int from_tty)
+class print_c_tdesc : public tdesc_element_visitor
{
- const struct target_desc *tdesc;
- const struct bfd_arch_info *compatible;
- const char *filename, *inp;
- char *function, *outp;
- struct property *prop;
- struct tdesc_feature *feature;
- struct tdesc_reg *reg;
- struct tdesc_type *type;
- struct tdesc_type_field *f;
- int ix, ix2, ix3;
- int printed_field_type = 0;
+public:
+ print_c_tdesc (std::string &filename_after_features)
+ : m_filename_after_features (filename_after_features)
+ {
+ const char *inp;
+ char *outp;
+ const char *filename = lbasename (m_filename_after_features.c_str ());
- /* Use the global target-supplied description, not the current
- architecture's. This lets a GDB for one architecture generate C
- for another architecture's description, even though the gdbarch
- initialization code will reject the new description. */
- tdesc = current_target_desc;
- if (tdesc == NULL)
- error (_("There is no target description to print."));
+ m_function = (char *) xmalloc (strlen (filename) + 1);
+ for (inp = filename, outp = m_function; *inp != '\0'; inp++)
+ if (*inp == '.')
+ break;
+ else if (*inp == '-')
+ *outp++ = '_';
+ else
+ *outp++ = *inp;
+ *outp = '\0';
+
+ /* Standard boilerplate. */
+ printf_unfiltered ("/* THIS FILE IS GENERATED. "
+ "-*- buffer-read-only: t -*- vi"
+ ":set ro:\n");
+ printf_unfiltered (" Original: %s */\n\n", filename);
+ }
- if (target_description_filename == NULL)
- error (_("The current target description did not come from an XML file."));
+ ~print_c_tdesc ()
+ {
+ xfree (m_function);
+ }
- filename = lbasename (target_description_filename);
- function = (char *) alloca (strlen (filename) + 1);
- for (inp = filename, outp = function; *inp != '\0'; inp++)
- if (*inp == '.')
- break;
- else if (*inp == '-')
- *outp++ = '_';
- else
- *outp++ = *inp;
- *outp = '\0';
-
- /* Standard boilerplate. */
- printf_unfiltered ("/* THIS FILE IS GENERATED. "
- "-*- buffer-read-only: t -*- vi"
- ":set ro:\n");
- printf_unfiltered (" Original: %s */\n\n", filename);
- printf_unfiltered ("#include \"defs.h\"\n");
- printf_unfiltered ("#include \"osabi.h\"\n");
- printf_unfiltered ("#include \"target-descriptions.h\"\n");
- printf_unfiltered ("\n");
-
- printf_unfiltered ("struct target_desc *tdesc_%s;\n", function);
- printf_unfiltered ("static void\n");
- printf_unfiltered ("initialize_tdesc_%s (void)\n", function);
- printf_unfiltered ("{\n");
- printf_unfiltered
- (" struct target_desc *result = allocate_target_description ();\n");
- printf_unfiltered (" struct tdesc_feature *feature;\n");
-
- /* Now we do some "filtering" in order to know which variables to
- declare. This is needed because otherwise we would declare unused
- variables `field_type' and `type'. */
- for (ix = 0;
- VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature);
- ix++)
- {
- int printed_desc_type = 0;
+ void visit (const target_desc *e) override
+ {
+ printf_unfiltered ("#include \"defs.h\"\n");
+ printf_unfiltered ("#include \"osabi.h\"\n");
+ printf_unfiltered ("#include \"target-descriptions.h\"\n");
+ printf_unfiltered ("\n");
- for (ix2 = 0;
- VEC_iterate (tdesc_type_p, feature->types, ix2, type);
- ix2++)
- {
- if (!printed_field_type)
- {
- printf_unfiltered (" struct tdesc_type *field_type;\n");
- printed_field_type = 1;
- }
+ printf_unfiltered ("struct target_desc *tdesc_%s;\n", m_function);
+ printf_unfiltered ("static void\n");
+ printf_unfiltered ("initialize_tdesc_%s (void)\n", m_function);
+ printf_unfiltered ("{\n");
+ printf_unfiltered
+ (" struct target_desc *result = allocate_target_description ();\n");
- if ((type->kind == TDESC_TYPE_UNION
- || type->kind == TDESC_TYPE_STRUCT
- || type->kind == TDESC_TYPE_FLAGS
- || type->kind == TDESC_TYPE_ENUM)
- && VEC_length (tdesc_type_field, type->u.u.fields) > 0)
- {
- printf_unfiltered (" struct tdesc_type *type;\n");
- printed_desc_type = 1;
- break;
- }
- }
+ if (tdesc_architecture (e) != NULL)
+ {
+ printf_unfiltered
+ (" set_tdesc_architecture (result, bfd_scan_arch (\"%s\"));\n",
+ tdesc_architecture (e)->printable_name);
+ printf_unfiltered ("\n");
+ }
+ if (tdesc_osabi (e) > GDB_OSABI_UNKNOWN
+ && tdesc_osabi (e) < GDB_OSABI_INVALID)
+ {
+ printf_unfiltered
+ (" set_tdesc_osabi (result, osabi_from_tdesc_string (\"%s\"));\n",
+ gdbarch_osabi_name (tdesc_osabi (e)));
+ printf_unfiltered ("\n");
+ }
- if (printed_desc_type)
- break;
- }
+ int ix;
+ const struct bfd_arch_info *compatible;
+ struct property *prop;
- printf_unfiltered ("\n");
+ for (ix = 0; VEC_iterate (arch_p, e->compatible, ix, compatible);
+ ix++)
+ {
+ printf_unfiltered
+ (" tdesc_add_compatible (result, bfd_scan_arch (\"%s\"));\n",
+ compatible->printable_name);
+ }
- if (tdesc_architecture (tdesc) != NULL)
- {
- printf_unfiltered
- (" set_tdesc_architecture (result, bfd_scan_arch (\"%s\"));\n",
- tdesc_architecture (tdesc)->printable_name);
+ if (ix)
printf_unfiltered ("\n");
- }
- if (tdesc_osabi (tdesc) > GDB_OSABI_UNKNOWN
- && tdesc_osabi (tdesc) < GDB_OSABI_INVALID)
- {
- printf_unfiltered
- (" set_tdesc_osabi (result, osabi_from_tdesc_string (\"%s\"));\n",
- gdbarch_osabi_name (tdesc_osabi (tdesc)));
- printf_unfiltered ("\n");
- }
+ for (ix = 0; VEC_iterate (property_s, e->properties, ix, prop);
+ ix++)
+ {
+ printf_unfiltered (" set_tdesc_property (result, \"%s\", \"%s\");\n",
+ prop->key, prop->value);
+ }
+ printf_unfiltered (" struct tdesc_feature *feature;\n");
+ }
- for (ix = 0; VEC_iterate (arch_p, tdesc->compatible, ix, compatible);
- ix++)
- {
- printf_unfiltered
- (" tdesc_add_compatible (result, bfd_scan_arch (\"%s\"));\n",
- compatible->printable_name);
- }
- if (ix)
- printf_unfiltered ("\n");
+ void visit (const tdesc_feature *e) override
+ {
+ printf_unfiltered ("\n feature = tdesc_create_feature (result, \"%s\");\n",
+ e->name);
+ }
- for (ix = 0; VEC_iterate (property_s, tdesc->properties, ix, prop);
- ix++)
- {
- printf_unfiltered (" set_tdesc_property (result, \"%s\", \"%s\");\n",
- prop->key, prop->value);
- }
+ void visit_end (const target_desc *e) override
+ {
+ printf_unfiltered ("\n tdesc_%s = result;\n", m_function);
+ printf_unfiltered ("}\n");
+ }
- for (ix = 0;
- VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature);
- ix++)
- {
- printf_unfiltered (" \
-feature = tdesc_create_feature (result, \"%s\");\n",
- feature->name);
+ void visit (const tdesc_type *type) override
+ {
+ struct tdesc_type_field *f;
- for (ix2 = 0;
- VEC_iterate (tdesc_type_p, feature->types, ix2, type);
- ix2++)
- {
- switch (type->kind)
- {
- case TDESC_TYPE_VECTOR:
- printf_unfiltered
- (" field_type = tdesc_named_type (feature, \"%s\");\n",
- type->u.v.type->name);
+ /* Now we do some "filtering" in order to know which variables to
+ declare. This is needed because otherwise we would declare unused
+ variables `field_type' and `type'. */
+ if (!m_printed_field_type)
+ {
+ printf_unfiltered (" struct tdesc_type *field_type;\n");
+ m_printed_field_type = true;
+ }
+
+ if ((type->kind == TDESC_TYPE_UNION
+ || type->kind == TDESC_TYPE_STRUCT
+ || type->kind == TDESC_TYPE_FLAGS
+ || type->kind == TDESC_TYPE_ENUM)
+ && VEC_length (tdesc_type_field, type->u.u.fields) > 0
+ && !m_printed_type)
+ {
+ printf_unfiltered (" struct tdesc_type *type;\n");
+ m_printed_type = true;
+ }
+
+ switch (type->kind)
+ {
+ case TDESC_TYPE_VECTOR:
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature, \"%s\");\n",
+ type->u.v.type->name);
+ printf_unfiltered
+ (" tdesc_create_vector (feature, \"%s\", field_type, %d);\n",
+ type->name, type->u.v.count);
+ break;
+ case TDESC_TYPE_STRUCT:
+ case TDESC_TYPE_FLAGS:
+ if (type->kind == TDESC_TYPE_STRUCT)
+ {
+ printf_unfiltered
+ (" type = tdesc_create_struct (feature, \"%s\");\n",
+ type->name);
+ if (type->u.u.size != 0)
printf_unfiltered
- (" tdesc_create_vector (feature, \"%s\", field_type, %d);\n",
- type->name, type->u.v.count);
- break;
- case TDESC_TYPE_STRUCT:
- case TDESC_TYPE_FLAGS:
- if (type->kind == TDESC_TYPE_STRUCT)
- {
- printf_unfiltered
- (" type = tdesc_create_struct (feature, \"%s\");\n",
- type->name);
- if (type->u.u.size != 0)
+ (" tdesc_set_struct_size (type, %d);\n",
+ type->u.u.size);
+ }
+ else
+ {
+ printf_unfiltered
+ (" type = tdesc_create_flags (feature, \"%s\", %d);\n",
+ type->name, type->u.u.size);
+ }
+ for (int ix3 = 0;
+ VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
+ ix3++)
+ {
+ const char *type_name;
+
+ gdb_assert (f->type != NULL);
+ type_name = f->type->name;
+
+ /* To minimize changes to generated files, don't emit type
+ info for fields that have defaulted types. */
+ if (f->start != -1)
+ {
+ gdb_assert (f->end != -1);
+ if (f->type->kind == TDESC_TYPE_BOOL)
+ {
+ gdb_assert (f->start == f->end);
printf_unfiltered
- (" tdesc_set_struct_size (type, %d);\n",
- type->u.u.size);
- }
- else
- {
- printf_unfiltered
- (" type = tdesc_create_flags (feature, \"%s\", %d);\n",
- type->name, type->u.u.size);
- }
- for (ix3 = 0;
- VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
- ix3++)
- {
- const char *type_name;
-
- gdb_assert (f->type != NULL);
- type_name = f->type->name;
-
- /* To minimize changes to generated files, don't emit type
- info for fields that have defaulted types. */
- if (f->start != -1)
- {
- gdb_assert (f->end != -1);
- if (f->type->kind == TDESC_TYPE_BOOL)
- {
- gdb_assert (f->start == f->end);
- printf_unfiltered
- (" tdesc_add_flag (type, %d, \"%s\");\n",
- f->start, f->name);
- }
- else if ((type->u.u.size == 4
- && f->type->kind == TDESC_TYPE_UINT32)
- || (type->u.u.size == 8
- && f->type->kind == TDESC_TYPE_UINT64))
- {
- printf_unfiltered
- (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n",
- f->name, f->start, f->end);
- }
- else
- {
- printf_unfiltered
- (" field_type = tdesc_named_type (feature,"
- " \"%s\");\n",
- type_name);
- printf_unfiltered
- (" tdesc_add_typed_bitfield (type, \"%s\","
- " %d, %d, field_type);\n",
- f->name, f->start, f->end);
- }
- }
- else /* Not a bitfield. */
- {
- gdb_assert (f->end == -1);
- gdb_assert (type->kind == TDESC_TYPE_STRUCT);
- printf_unfiltered
- (" field_type = tdesc_named_type (feature,"
- " \"%s\");\n",
- type_name);
- printf_unfiltered
- (" tdesc_add_field (type, \"%s\", field_type);\n",
- f->name);
- }
- }
- break;
- case TDESC_TYPE_UNION:
- printf_unfiltered
- (" type = tdesc_create_union (feature, \"%s\");\n",
- type->name);
- for (ix3 = 0;
- VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
- ix3++)
- {
- printf_unfiltered
- (" field_type = tdesc_named_type (feature, \"%s\");\n",
- f->type->name);
- printf_unfiltered
- (" tdesc_add_field (type, \"%s\", field_type);\n",
- f->name);
- }
- break;
- case TDESC_TYPE_ENUM:
- printf_unfiltered
- (" type = tdesc_create_enum (feature, \"%s\", %d);\n",
- type->name, type->u.u.size);
- for (ix3 = 0;
- VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
- ix3++)
+ (" tdesc_add_flag (type, %d, \"%s\");\n",
+ f->start, f->name);
+ }
+ else if ((type->u.u.size == 4
+ && f->type->kind == TDESC_TYPE_UINT32)
+ || (type->u.u.size == 8
+ && f->type->kind == TDESC_TYPE_UINT64))
+ {
+ printf_unfiltered
+ (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n",
+ f->name, f->start, f->end);
+ }
+ else
+ {
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature,"
+ " \"%s\");\n",
+ type_name);
+ printf_unfiltered
+ (" tdesc_add_typed_bitfield (type, \"%s\","
+ " %d, %d, field_type);\n",
+ f->name, f->start, f->end);
+ }
+ }
+ else /* Not a bitfield. */
+ {
+ gdb_assert (f->end == -1);
+ gdb_assert (type->kind == TDESC_TYPE_STRUCT);
printf_unfiltered
- (" tdesc_add_enum_value (type, %d, \"%s\");\n",
- f->start, f->name);
- break;
- default:
- error (_("C output is not supported type \"%s\"."), type->name);
- }
- printf_unfiltered ("\n");
- }
+ (" field_type = tdesc_named_type (feature,"
+ " \"%s\");\n",
+ type_name);
+ printf_unfiltered
+ (" tdesc_add_field (type, \"%s\", field_type);\n",
+ f->name);
+ }
+ }
+ break;
+ case TDESC_TYPE_UNION:
+ printf_unfiltered
+ (" type = tdesc_create_union (feature, \"%s\");\n",
+ type->name);
+ for (int ix3 = 0;
+ VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
+ ix3++)
+ {
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature, \"%s\");\n",
+ f->type->name);
+ printf_unfiltered
+ (" tdesc_add_field (type, \"%s\", field_type);\n",
+ f->name);
+ }
+ break;
+ case TDESC_TYPE_ENUM:
+ printf_unfiltered
+ (" type = tdesc_create_enum (feature, \"%s\", %d);\n",
+ type->name, type->u.u.size);
+ for (int ix3 = 0;
+ VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
+ ix3++)
+ printf_unfiltered
+ (" tdesc_add_enum_value (type, %d, \"%s\");\n",
+ f->start, f->name);
+ break;
+ default:
+ error (_("C output is not supported type \"%s\"."), type->name);
+ }
+ printf_unfiltered ("\n");
+ }
- for (ix2 = 0;
- VEC_iterate (tdesc_reg_p, feature->registers, ix2, reg);
- ix2++)
- {
- printf_unfiltered (" tdesc_create_reg (feature, \"%s\", %ld, %d, ",
- reg->name, reg->target_regnum, reg->save_restore);
- if (reg->group)
- printf_unfiltered ("\"%s\", ", reg->group);
- else
- printf_unfiltered ("NULL, ");
- printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
- }
+ void visit (const tdesc_reg *reg) override
+ {
+ printf_unfiltered (" tdesc_create_reg (feature, \"%s\", %ld, %d, ",
+ reg->name, reg->target_regnum, reg->save_restore);
+ if (reg->group)
+ printf_unfiltered ("\"%s\", ", reg->group);
+ else
+ printf_unfiltered ("NULL, ");
+ printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
+ }
- printf_unfiltered ("\n");
- }
+private:
+ char *m_function;
+ std::string m_filename_after_features;
+ bool m_printed_field_type = false;
+ bool m_printed_type = false;
+};
+
+static void
+maint_print_c_tdesc_cmd (char *args, int from_tty)
+{
+ const struct target_desc *tdesc;
+
+ /* Use the global target-supplied description, not the current
+ architecture's. This lets a GDB for one architecture generate C
+ for another architecture's description, even though the gdbarch
+ initialization code will reject the new description. */
+ tdesc = current_target_desc;
+ if (tdesc == NULL)
+ error (_("There is no target description to print."));
+
+ if (target_description_filename == NULL)
+ error (_("The current target description did not come from an XML file."));
+
+ std::string filename_after_features (target_description_filename);
+ auto loc = filename_after_features.rfind ("/features/");
+
+ if (loc != std::string::npos)
+ filename_after_features = filename_after_features.substr (loc + 10);
+
+ print_c_tdesc v (filename_after_features);
- printf_unfiltered (" tdesc_%s = result;\n", function);
- printf_unfiltered ("}\n");
+ tdesc->accept (v);
}
/* Provide a prototype to silence -Wmissing-prototypes. */