xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/tdesc.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
18dffb485Schristos /* Target description support for GDB.
28dffb485Schristos 
3*5ba1f45fSchristos    Copyright (C) 2018-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    This file is part of GDB.
68dffb485Schristos 
78dffb485Schristos    This program is free software; you can redistribute it and/or modify
88dffb485Schristos    it under the terms of the GNU General Public License as published by
98dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
108dffb485Schristos    (at your option) any later version.
118dffb485Schristos 
128dffb485Schristos    This program is distributed in the hope that it will be useful,
138dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
148dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
158dffb485Schristos    GNU General Public License for more details.
168dffb485Schristos 
178dffb485Schristos    You should have received a copy of the GNU General Public License
188dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
198dffb485Schristos 
208dffb485Schristos #include "gdbsupport/tdesc.h"
218dffb485Schristos 
228dffb485Schristos tdesc_reg::tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
238dffb485Schristos 		      int regnum, int save_restore_, const char *group_,
248dffb485Schristos 		      int bitsize_, const char *type_)
258dffb485Schristos   : name (name_), target_regnum (regnum),
268dffb485Schristos     save_restore (save_restore_),
278dffb485Schristos     group (group_ != NULL ? group_ : ""),
288dffb485Schristos     bitsize (bitsize_),
298dffb485Schristos     type (type_ != NULL ? type_ : "<unknown>")
308dffb485Schristos {
318dffb485Schristos   /* If the register's type is target-defined, look it up now.  We may not
328dffb485Schristos      have easy access to the containing feature when we want it later.  */
338dffb485Schristos   tdesc_type = tdesc_named_type (feature, type.c_str ());
348dffb485Schristos }
358dffb485Schristos 
368dffb485Schristos /* Predefined types.  */
378dffb485Schristos static tdesc_type_builtin tdesc_predefined_types[] =
388dffb485Schristos {
398dffb485Schristos   { "bool", TDESC_TYPE_BOOL },
408dffb485Schristos   { "int8", TDESC_TYPE_INT8 },
418dffb485Schristos   { "int16", TDESC_TYPE_INT16 },
428dffb485Schristos   { "int32", TDESC_TYPE_INT32 },
438dffb485Schristos   { "int64", TDESC_TYPE_INT64 },
448dffb485Schristos   { "int128", TDESC_TYPE_INT128 },
458dffb485Schristos   { "uint8", TDESC_TYPE_UINT8 },
468dffb485Schristos   { "uint16", TDESC_TYPE_UINT16 },
478dffb485Schristos   { "uint32", TDESC_TYPE_UINT32 },
488dffb485Schristos   { "uint64", TDESC_TYPE_UINT64 },
498dffb485Schristos   { "uint128", TDESC_TYPE_UINT128 },
508dffb485Schristos   { "code_ptr", TDESC_TYPE_CODE_PTR },
518dffb485Schristos   { "data_ptr", TDESC_TYPE_DATA_PTR },
528dffb485Schristos   { "ieee_half", TDESC_TYPE_IEEE_HALF },
538dffb485Schristos   { "ieee_single", TDESC_TYPE_IEEE_SINGLE },
548dffb485Schristos   { "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
558dffb485Schristos   { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
568dffb485Schristos   { "i387_ext", TDESC_TYPE_I387_EXT },
578dffb485Schristos   { "bfloat16", TDESC_TYPE_BFLOAT16 }
588dffb485Schristos };
598dffb485Schristos 
608dffb485Schristos void tdesc_feature::accept (tdesc_element_visitor &v) const
618dffb485Schristos {
628dffb485Schristos   v.visit_pre (this);
638dffb485Schristos 
648dffb485Schristos   for (const tdesc_type_up &type : types)
658dffb485Schristos     type->accept (v);
668dffb485Schristos 
678dffb485Schristos   for (const tdesc_reg_up &reg : registers)
688dffb485Schristos     reg->accept (v);
698dffb485Schristos 
708dffb485Schristos   v.visit_post (this);
718dffb485Schristos }
728dffb485Schristos 
738dffb485Schristos bool tdesc_feature::operator== (const tdesc_feature &other) const
748dffb485Schristos {
758dffb485Schristos   if (name != other.name)
768dffb485Schristos     return false;
778dffb485Schristos 
788dffb485Schristos   if (registers.size () != other.registers.size ())
798dffb485Schristos     return false;
808dffb485Schristos 
818dffb485Schristos   for (int ix = 0; ix < registers.size (); ix++)
828dffb485Schristos     {
838dffb485Schristos       const tdesc_reg_up &reg1 = registers[ix];
848dffb485Schristos       const tdesc_reg_up &reg2 = other.registers[ix];
858dffb485Schristos 
868dffb485Schristos       if (reg1 != reg2 && *reg1 != *reg2)
878dffb485Schristos 	return false;
888dffb485Schristos       }
898dffb485Schristos 
908dffb485Schristos   if (types.size () != other.types.size ())
918dffb485Schristos     return false;
928dffb485Schristos 
938dffb485Schristos   for (int ix = 0; ix < types.size (); ix++)
948dffb485Schristos     {
958dffb485Schristos       const tdesc_type_up &type1 = types[ix];
968dffb485Schristos       const tdesc_type_up &type2 = other.types[ix];
978dffb485Schristos 
988dffb485Schristos       if (type1 != type2 && *type1 != *type2)
998dffb485Schristos 	return false;
1008dffb485Schristos     }
1018dffb485Schristos 
1028dffb485Schristos   return true;
1038dffb485Schristos }
1048dffb485Schristos 
1058dffb485Schristos /* Lookup a predefined type.  */
1068dffb485Schristos 
1078dffb485Schristos static struct tdesc_type *
1088dffb485Schristos tdesc_predefined_type (enum tdesc_type_kind kind)
1098dffb485Schristos {
1108dffb485Schristos   for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
1118dffb485Schristos     if (tdesc_predefined_types[ix].kind == kind)
1128dffb485Schristos       return &tdesc_predefined_types[ix];
1138dffb485Schristos 
1148dffb485Schristos   gdb_assert_not_reached ("bad predefined tdesc type");
1158dffb485Schristos }
1168dffb485Schristos 
1178dffb485Schristos /* See gdbsupport/tdesc.h.  */
1188dffb485Schristos 
1198dffb485Schristos struct tdesc_type *
1208dffb485Schristos tdesc_named_type (const struct tdesc_feature *feature, const char *id)
1218dffb485Schristos {
1228dffb485Schristos   /* First try target-defined types.  */
1238dffb485Schristos   for (const tdesc_type_up &type : feature->types)
1248dffb485Schristos     if (type->name == id)
1258dffb485Schristos       return type.get ();
1268dffb485Schristos 
1278dffb485Schristos   /* Next try the predefined types.  */
1288dffb485Schristos   for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
1298dffb485Schristos     if (tdesc_predefined_types[ix].name == id)
1308dffb485Schristos       return &tdesc_predefined_types[ix];
1318dffb485Schristos 
1328dffb485Schristos   return NULL;
1338dffb485Schristos }
1348dffb485Schristos 
1358dffb485Schristos /* See gdbsupport/tdesc.h.  */
1368dffb485Schristos 
1378dffb485Schristos void
1388dffb485Schristos tdesc_create_reg (struct tdesc_feature *feature, const char *name,
1398dffb485Schristos 		  int regnum, int save_restore, const char *group,
1408dffb485Schristos 		  int bitsize, const char *type)
1418dffb485Schristos {
1428dffb485Schristos   tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore,
1438dffb485Schristos 				  group, bitsize, type);
1448dffb485Schristos 
1458dffb485Schristos   feature->registers.emplace_back (reg);
1468dffb485Schristos }
1478dffb485Schristos 
1488dffb485Schristos /* See gdbsupport/tdesc.h.  */
1498dffb485Schristos 
1508dffb485Schristos struct tdesc_type *
1518dffb485Schristos tdesc_create_vector (struct tdesc_feature *feature, const char *name,
1528dffb485Schristos 		     struct tdesc_type *field_type, int count)
1538dffb485Schristos {
1548dffb485Schristos   tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count);
1558dffb485Schristos   feature->types.emplace_back (type);
1568dffb485Schristos 
1578dffb485Schristos   return type;
1588dffb485Schristos }
1598dffb485Schristos 
1608dffb485Schristos /* See gdbsupport/tdesc.h.  */
1618dffb485Schristos 
1628dffb485Schristos tdesc_type_with_fields *
1638dffb485Schristos tdesc_create_struct (struct tdesc_feature *feature, const char *name)
1648dffb485Schristos {
1658dffb485Schristos   tdesc_type_with_fields *type
1668dffb485Schristos     = new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT);
1678dffb485Schristos   feature->types.emplace_back (type);
1688dffb485Schristos 
1698dffb485Schristos   return type;
1708dffb485Schristos }
1718dffb485Schristos 
1728dffb485Schristos /* See gdbsupport/tdesc.h.  */
1738dffb485Schristos 
1748dffb485Schristos void
1758dffb485Schristos tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
1768dffb485Schristos {
1778dffb485Schristos   gdb_assert (type->kind == TDESC_TYPE_STRUCT);
1788dffb485Schristos   gdb_assert (size > 0);
1798dffb485Schristos   type->size = size;
1808dffb485Schristos }
1818dffb485Schristos 
1828dffb485Schristos /* See gdbsupport/tdesc.h.  */
1838dffb485Schristos 
1848dffb485Schristos tdesc_type_with_fields *
1858dffb485Schristos tdesc_create_union (struct tdesc_feature *feature, const char *name)
1868dffb485Schristos {
1878dffb485Schristos   tdesc_type_with_fields *type
1888dffb485Schristos     = new tdesc_type_with_fields (name, TDESC_TYPE_UNION);
1898dffb485Schristos   feature->types.emplace_back (type);
1908dffb485Schristos 
1918dffb485Schristos   return type;
1928dffb485Schristos }
1938dffb485Schristos 
1948dffb485Schristos /* See gdbsupport/tdesc.h.  */
1958dffb485Schristos 
1968dffb485Schristos tdesc_type_with_fields *
1978dffb485Schristos tdesc_create_flags (struct tdesc_feature *feature, const char *name,
1988dffb485Schristos 		    int size)
1998dffb485Schristos {
2008dffb485Schristos   gdb_assert (size > 0);
2018dffb485Schristos 
2028dffb485Schristos   tdesc_type_with_fields *type
2038dffb485Schristos     = new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size);
2048dffb485Schristos   feature->types.emplace_back (type);
2058dffb485Schristos 
2068dffb485Schristos   return type;
2078dffb485Schristos }
2088dffb485Schristos 
2098dffb485Schristos /* See gdbsupport/tdesc.h.  */
2108dffb485Schristos 
2118dffb485Schristos tdesc_type_with_fields *
2128dffb485Schristos tdesc_create_enum (struct tdesc_feature *feature, const char *name,
2138dffb485Schristos 		   int size)
2148dffb485Schristos {
2158dffb485Schristos   gdb_assert (size > 0);
2168dffb485Schristos 
2178dffb485Schristos   tdesc_type_with_fields *type
2188dffb485Schristos     = new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size);
2198dffb485Schristos   feature->types.emplace_back (type);
2208dffb485Schristos 
2218dffb485Schristos   return type;
2228dffb485Schristos }
2238dffb485Schristos 
2248dffb485Schristos /* See gdbsupport/tdesc.h.  */
2258dffb485Schristos 
2268dffb485Schristos void
2278dffb485Schristos tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
2288dffb485Schristos 		 struct tdesc_type *field_type)
2298dffb485Schristos {
2308dffb485Schristos   gdb_assert (type->kind == TDESC_TYPE_UNION
2318dffb485Schristos 	      || type->kind == TDESC_TYPE_STRUCT);
2328dffb485Schristos 
2338dffb485Schristos   /* Initialize start and end so we know this is not a bit-field
2348dffb485Schristos      when we print-c-tdesc.  */
2358dffb485Schristos   type->fields.emplace_back (field_name, field_type, -1, -1);
2368dffb485Schristos }
2378dffb485Schristos 
2388dffb485Schristos /* See gdbsupport/tdesc.h.  */
2398dffb485Schristos 
2408dffb485Schristos void
2418dffb485Schristos tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name,
2428dffb485Schristos 			  int start, int end, struct tdesc_type *field_type)
2438dffb485Schristos {
2448dffb485Schristos   gdb_assert (type->kind == TDESC_TYPE_STRUCT
2458dffb485Schristos 	      || type->kind == TDESC_TYPE_FLAGS);
2468dffb485Schristos   gdb_assert (start >= 0 && end >= start);
2478dffb485Schristos 
2488dffb485Schristos   type->fields.emplace_back (field_name, field_type, start, end);
2498dffb485Schristos }
2508dffb485Schristos 
2518dffb485Schristos /* See gdbsupport/tdesc.h.  */
2528dffb485Schristos 
2538dffb485Schristos void
2548dffb485Schristos tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
2558dffb485Schristos 		    int start, int end)
2568dffb485Schristos {
2578dffb485Schristos   struct tdesc_type *field_type;
2588dffb485Schristos 
2598dffb485Schristos   gdb_assert (start >= 0 && end >= start);
2608dffb485Schristos 
2618dffb485Schristos   if (type->size > 4)
2628dffb485Schristos     field_type = tdesc_predefined_type (TDESC_TYPE_UINT64);
2638dffb485Schristos   else
2648dffb485Schristos     field_type = tdesc_predefined_type (TDESC_TYPE_UINT32);
2658dffb485Schristos 
2668dffb485Schristos   tdesc_add_typed_bitfield (type, field_name, start, end, field_type);
2678dffb485Schristos }
2688dffb485Schristos 
2698dffb485Schristos /* See gdbsupport/tdesc.h.  */
2708dffb485Schristos 
2718dffb485Schristos void
2728dffb485Schristos tdesc_add_flag (tdesc_type_with_fields *type, int start,
2738dffb485Schristos 		const char *flag_name)
2748dffb485Schristos {
2758dffb485Schristos   gdb_assert (type->kind == TDESC_TYPE_FLAGS
2768dffb485Schristos 	      || type->kind == TDESC_TYPE_STRUCT);
2778dffb485Schristos 
2788dffb485Schristos   type->fields.emplace_back (flag_name,
2798dffb485Schristos 			     tdesc_predefined_type (TDESC_TYPE_BOOL),
2808dffb485Schristos 			     start, start);
2818dffb485Schristos }
2828dffb485Schristos 
2838dffb485Schristos /* See gdbsupport/tdesc.h.  */
2848dffb485Schristos 
2858dffb485Schristos void
2868dffb485Schristos tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
2878dffb485Schristos 		      const char *name)
2888dffb485Schristos {
2898dffb485Schristos   gdb_assert (type->kind == TDESC_TYPE_ENUM);
2908dffb485Schristos   type->fields.emplace_back (name,
2918dffb485Schristos 			     tdesc_predefined_type (TDESC_TYPE_INT32),
2928dffb485Schristos 			     value, -1);
2938dffb485Schristos }
2948dffb485Schristos 
2958dffb485Schristos void print_xml_feature::visit_pre (const tdesc_feature *e)
2968dffb485Schristos {
2978dffb485Schristos   add_line ("<feature name=\"%s\">", e->name.c_str ());
2988dffb485Schristos   indent (1);
2998dffb485Schristos }
3008dffb485Schristos 
3018dffb485Schristos void print_xml_feature::visit_post (const tdesc_feature *e)
3028dffb485Schristos {
3038dffb485Schristos   indent (-1);
3048dffb485Schristos   add_line ("</feature>");
3058dffb485Schristos }
3068dffb485Schristos 
3078dffb485Schristos void print_xml_feature::visit (const tdesc_type_builtin *t)
3088dffb485Schristos {
3098dffb485Schristos   error (_("xml output is not supported for type \"%s\"."), t->name.c_str ());
3108dffb485Schristos }
3118dffb485Schristos 
3128dffb485Schristos void print_xml_feature::visit (const tdesc_type_vector *t)
3138dffb485Schristos {
3148dffb485Schristos   add_line ("<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
3158dffb485Schristos 	    t->name.c_str (), t->element_type->name.c_str (), t->count);
3168dffb485Schristos }
3178dffb485Schristos 
3188dffb485Schristos void print_xml_feature::visit (const tdesc_type_with_fields *t)
3198dffb485Schristos {
3208dffb485Schristos   const static char *types[] = { "struct", "union", "flags", "enum" };
3218dffb485Schristos 
3228dffb485Schristos   gdb_assert (t->kind >= TDESC_TYPE_STRUCT && t->kind <= TDESC_TYPE_ENUM);
3238dffb485Schristos 
3248dffb485Schristos   std::string tmp;
3258dffb485Schristos 
3268dffb485Schristos   string_appendf (tmp,
3278dffb485Schristos 		  "<%s id=\"%s\"", types[t->kind - TDESC_TYPE_STRUCT],
3288dffb485Schristos 		  t->name.c_str ());
3298dffb485Schristos 
3308dffb485Schristos   switch (t->kind)
3318dffb485Schristos     {
3328dffb485Schristos     case TDESC_TYPE_STRUCT:
3338dffb485Schristos     case TDESC_TYPE_FLAGS:
3348dffb485Schristos       if (t->size > 0)
3358dffb485Schristos 	string_appendf (tmp, " size=\"%d\"", t->size);
3368dffb485Schristos       string_appendf (tmp, ">");
3378dffb485Schristos       add_line (tmp);
3388dffb485Schristos 
3398dffb485Schristos       for (const tdesc_type_field &f : t->fields)
3408dffb485Schristos 	{
3418dffb485Schristos 	  tmp.clear ();
3428dffb485Schristos 	  string_appendf (tmp, "  <field name=\"%s\"", f.name.c_str ());
3438dffb485Schristos 	  if (f.start != -1)
3448dffb485Schristos 	    string_appendf (tmp, " start=\"%d\" end=\"%d\"", f.start,
3458dffb485Schristos 			    f.end);
3468dffb485Schristos 	  string_appendf (tmp, " type=\"%s\"/>",
3478dffb485Schristos 			  f.type->name.c_str ());
3488dffb485Schristos 	  add_line (tmp);
3498dffb485Schristos 	}
3508dffb485Schristos       break;
3518dffb485Schristos 
3528dffb485Schristos     case TDESC_TYPE_ENUM:
3534b169a6bSchristos       if (t->size > 0)
3544b169a6bSchristos 	string_appendf (tmp, " size=\"%d\"", t->size);
3558dffb485Schristos       string_appendf (tmp, ">");
3568dffb485Schristos       add_line (tmp);
3574b169a6bSchristos       /* The 'start' of the field is reused as the enum value.  The 'end'
3584b169a6bSchristos 	 of the field is always set to -1 for enum values.  */
3598dffb485Schristos       for (const tdesc_type_field &f : t->fields)
3604b169a6bSchristos 	add_line ("  <evalue name=\"%s\" value=\"%d\"/>",
3618dffb485Schristos 		  f.name.c_str (), f.start);
3628dffb485Schristos       break;
3638dffb485Schristos 
3648dffb485Schristos     case TDESC_TYPE_UNION:
3658dffb485Schristos       string_appendf (tmp, ">");
3668dffb485Schristos       add_line (tmp);
3678dffb485Schristos       for (const tdesc_type_field &f : t->fields)
3688dffb485Schristos 	add_line ("  <field name=\"%s\" type=\"%s\"/>",
3698dffb485Schristos 		  f.name.c_str (), f.type->name.c_str ());
3708dffb485Schristos       break;
3718dffb485Schristos 
3728dffb485Schristos     default:
3738dffb485Schristos       error (_("xml output is not supported for type \"%s\"."),
3748dffb485Schristos 	     t->name.c_str ());
3758dffb485Schristos     }
3768dffb485Schristos 
3778dffb485Schristos   add_line ("</%s>", types[t->kind - TDESC_TYPE_STRUCT]);
3788dffb485Schristos }
3798dffb485Schristos 
3808dffb485Schristos void print_xml_feature::visit (const tdesc_reg *r)
3818dffb485Schristos {
3828dffb485Schristos   std::string tmp;
3838dffb485Schristos 
3848dffb485Schristos   string_appendf (tmp,
3858dffb485Schristos 		  "<reg name=\"%s\" bitsize=\"%d\" type=\"%s\" regnum=\"%ld\"",
3868dffb485Schristos 		  r->name.c_str (), r->bitsize, r->type.c_str (),
3878dffb485Schristos 		  r->target_regnum);
3888dffb485Schristos 
3898dffb485Schristos   if (r->group.length () > 0)
3908dffb485Schristos     string_appendf (tmp, " group=\"%s\"", r->group.c_str ());
3918dffb485Schristos 
3928dffb485Schristos   if (r->save_restore == 0)
3938dffb485Schristos     string_appendf (tmp, " save-restore=\"no\"");
3948dffb485Schristos 
3958dffb485Schristos   string_appendf (tmp, "/>");
3968dffb485Schristos 
3978dffb485Schristos   add_line (tmp);
3988dffb485Schristos }
3998dffb485Schristos 
4008dffb485Schristos void print_xml_feature::visit_pre (const target_desc *e)
4018dffb485Schristos {
4028dffb485Schristos #ifndef IN_PROCESS_AGENT
4038dffb485Schristos   add_line ("<?xml version=\"1.0\"?>");
4048dffb485Schristos   add_line ("<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
4058dffb485Schristos   add_line ("<target>");
4068dffb485Schristos   indent (1);
4078dffb485Schristos   if (tdesc_architecture_name (e))
4088dffb485Schristos     add_line ("<architecture>%s</architecture>",
4098dffb485Schristos 	      tdesc_architecture_name (e));
4108dffb485Schristos 
4118dffb485Schristos   const char *osabi = tdesc_osabi_name (e);
4128dffb485Schristos   if (osabi != nullptr)
4138dffb485Schristos     add_line ("<osabi>%s</osabi>", osabi);
4148dffb485Schristos 
4158dffb485Schristos   const std::vector<tdesc_compatible_info_up> &compatible_list
4168dffb485Schristos     = tdesc_compatible_info_list (e);
4178dffb485Schristos   for (const auto &c : compatible_list)
4188dffb485Schristos     add_line ("<compatible>%s</compatible>",
4198dffb485Schristos 	      tdesc_compatible_info_arch_name (c));
4208dffb485Schristos #endif
4218dffb485Schristos }
4228dffb485Schristos 
4238dffb485Schristos void print_xml_feature::visit_post (const target_desc *e)
4248dffb485Schristos {
4258dffb485Schristos   indent (-1);
4268dffb485Schristos   add_line ("</target>");
4278dffb485Schristos }
4288dffb485Schristos 
4298dffb485Schristos /* See gdbsupport/tdesc.h.  */
4308dffb485Schristos 
4318dffb485Schristos void
4328dffb485Schristos print_xml_feature::add_line (const std::string &str)
4338dffb485Schristos {
4348dffb485Schristos   string_appendf (*m_buffer, "%*s", m_depth, "");
4358dffb485Schristos   string_appendf (*m_buffer, "%s", str.c_str ());
4368dffb485Schristos   string_appendf (*m_buffer, "\n");
4378dffb485Schristos }
4388dffb485Schristos 
4398dffb485Schristos /* See gdbsupport/tdesc.h.  */
4408dffb485Schristos 
4418dffb485Schristos void
4428dffb485Schristos print_xml_feature::add_line (const char *fmt, ...)
4438dffb485Schristos {
4448dffb485Schristos   std::string tmp;
4458dffb485Schristos 
4468dffb485Schristos   va_list ap;
4478dffb485Schristos   va_start (ap, fmt);
4488dffb485Schristos   string_vappendf (tmp, fmt, ap);
4498dffb485Schristos   va_end (ap);
4508dffb485Schristos   add_line (tmp);
4518dffb485Schristos }
452