diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4b4039fae35..27472c8a8a4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-22  Simon Marchi  <simon.marchi@efficios.com>
+
+	* gdbtypes.h (struct type) <field>: New method.
+	(TYPE_FIELDS): Remove, replace all uses with either type::fields
+	or type::field.
+
 2020-05-22  Simon Marchi  <simon.marchi@efficios.com>
 
 	* gdbtypes.h (struct type) <fields, set_fields>: New methods.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d4377a1a495..c99705ca74b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -8242,7 +8242,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
       if (branch_type == NULL)
         {
           for (f = variant_field + 1; f < rtype->num_fields (); f += 1)
-            TYPE_FIELDS (rtype)[f - 1] = TYPE_FIELDS (rtype)[f];
+            rtype->field (f - 1) = rtype->field (f);
 	  rtype->set_num_fields (rtype->num_fields () - 1);
         }
       else
@@ -8355,7 +8355,7 @@ template_to_static_fixed_type (struct type *type0)
 	      field *fields =
 		((struct field *)
 		 TYPE_ALLOC (type, nfields * sizeof (struct field)));
-	      memcpy (fields, TYPE_FIELDS (type0),
+	      memcpy (fields, type0->fields (),
 		      sizeof (struct field) * nfields);
 	      type->set_fields (fields);
 
@@ -8407,7 +8407,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
 
   field *fields =
     (struct field *) TYPE_ALLOC (rtype, nfields * sizeof (struct field));
-  memcpy (fields, TYPE_FIELDS (type), sizeof (struct field) * nfields);
+  memcpy (fields, type->fields (), sizeof (struct field) * nfields);
   rtype->set_fields (fields);
 
   rtype->set_name (ada_type_name (type));
@@ -8427,7 +8427,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
       int f;
 
       for (f = variant_field + 1; f < nfields; f += 1)
-        TYPE_FIELDS (rtype)[f - 1] = TYPE_FIELDS (rtype)[f];
+        rtype->field (f - 1) = rtype->field (f);
       rtype->set_num_fields (rtype->num_fields () - 1);
     }
   else
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 955cfd60451..29ac595cb25 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -277,7 +277,7 @@ cp_type_print_method_args (struct type *mtype, const char *prefix,
 			   enum language language,
 			   const struct type_print_options *flags)
 {
-  struct field *args = TYPE_FIELDS (mtype);
+  struct field *args = mtype->fields ();
   int nargs = mtype->num_fields ();
   int varargs = TYPE_VARARGS (mtype);
   int i;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 08d235865b0..e6d08110b2a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9458,7 +9458,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       field *new_fields
 	= (struct field *) TYPE_ZALLOC (type, ((type->num_fields () + 1)
 					       * sizeof (struct field)));
-      memcpy (new_fields + 1, TYPE_FIELDS (type),
+      memcpy (new_fields + 1, type->fields (),
 	      type->num_fields () * sizeof (struct field));
       type->set_fields (new_fields);
       type->set_num_fields (type->num_fields () + 1);
@@ -15002,7 +15002,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 	   of the method itself (TYPE_CODE_METHOD).  */
       smash_to_method_type (fnp->type, type,
 			    TYPE_TARGET_TYPE (this_type),
-			    TYPE_FIELDS (this_type),
+			    this_type->fields (),
 			    this_type->num_fields (),
 			    TYPE_VARARGS (this_type));
 
@@ -15219,7 +15219,7 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
   new_type = alloc_type (objfile);
   smash_to_method_type (new_type, self_type, TYPE_TARGET_TYPE (pfn_type),
-			TYPE_FIELDS (pfn_type), pfn_type->num_fields (),
+			pfn_type->fields (), pfn_type->num_fields (),
 			TYPE_VARARGS (pfn_type));
   smash_to_methodptr_type (type, new_type);
 }
@@ -15937,7 +15937,7 @@ update_enumeration_type_from_children (struct die_info *die,
       type->set_fields
 	((struct field *)
 	 TYPE_ALLOC (type, sizeof (struct field) * fields.size ()));
-      memcpy (TYPE_FIELDS (type), fields.data (),
+      memcpy (type->fields (), fields.data (),
 	      sizeof (struct field) * fields.size ());
     }
 
@@ -16723,7 +16723,7 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
 	= alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
 
       smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
-			    TYPE_FIELDS (to_type), to_type->num_fields (),
+			    to_type->fields (), to_type->num_fields (),
 			    TYPE_VARARGS (to_type));
       type = lookup_methodptr_type (new_type);
     }
diff --git a/gdb/eval.c b/gdb/eval.c
index 069cf5ddbc4..3f23cebfb29 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -692,7 +692,7 @@ fake_method::fake_method (type_instance_flags flags,
 
 fake_method::~fake_method ()
 {
-  xfree (TYPE_FIELDS (&m_type));
+  xfree (m_type.fields ());
 }
 
 /* Helper for evaluating an OP_VAR_VALUE.  */
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index d1623457a13..96b75a00a92 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -2242,8 +2242,8 @@ resolve_dynamic_union (struct type *type,
     ((struct field *)
      TYPE_ALLOC (resolved_type,
 		 resolved_type->num_fields () * sizeof (struct field)));
-  memcpy (TYPE_FIELDS (resolved_type),
-	  TYPE_FIELDS (type),
+  memcpy (resolved_type->fields (),
+	  type->fields (),
 	  resolved_type->num_fields () * sizeof (struct field));
   for (i = 0; i < resolved_type->num_fields (); ++i)
     {
@@ -2453,8 +2453,8 @@ resolve_dynamic_struct (struct type *type,
 	((struct field *)
 	 TYPE_ALLOC (resolved_type,
 		     resolved_type->num_fields () * sizeof (struct field)));
-      memcpy (TYPE_FIELDS (resolved_type),
-	      TYPE_FIELDS (type),
+      memcpy (resolved_type->fields (),
+	      type->fields (),
 	      resolved_type->num_fields () * sizeof (struct field));
     }
 
@@ -5103,7 +5103,7 @@ recursive_dump_type (struct type *type, int spaces)
     }
   puts_filtered ("\n");
   printfi_filtered (spaces, "nfields %d ", type->num_fields ());
-  gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout);
+  gdb_print_host_address (type->fields (), gdb_stdout);
   puts_filtered ("\n");
   for (idx = 0; idx < type->num_fields (); idx++)
     {
@@ -5634,9 +5634,9 @@ append_composite_type_field_raw (struct type *t, const char *name,
   struct field *f;
 
   t->set_num_fields (t->num_fields () + 1);
-  t->set_fields (XRESIZEVEC (struct field, TYPE_FIELDS (t),
+  t->set_fields (XRESIZEVEC (struct field, t->fields (),
 			     t->num_fields ()));
-  f = &(TYPE_FIELDS (t)[t->num_fields () - 1]);
+  f = &t->field (t->num_fields () - 1);
   memset (f, 0, sizeof f[0]);
   FIELD_TYPE (f[0]) = field;
   FIELD_NAME (f[0]) = name;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 3ed9f8e7fc1..f91adbc6cc2 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -914,13 +914,19 @@ struct type
   }
 
   /* Get the fields array of this type.  */
-  field *fields () const
+  struct field *fields () const
   {
     return this->main_type->flds_bnds.fields;
   }
 
+  /* Get the field at index IDX.  */
+  struct field &field (int idx) const
+  {
+    return this->fields ()[idx];
+  }
+
   /* Set the fields array of this type.  */
-  void set_fields (field *fields)
+  void set_fields (struct field *fields)
   {
     this->main_type->flds_bnds.fields = fields;
   }
@@ -1470,8 +1476,6 @@ extern unsigned type_align (struct type *);
    space in struct type.  */
 extern bool set_type_align (struct type *, ULONGEST);
 
-#define TYPE_FIELDS(thistype) (thistype)->fields ()
-
 #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
 #define TYPE_RANGE_DATA(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.bounds
 #define TYPE_LOW_BOUND(range_type) \
@@ -1667,7 +1671,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
 #define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
 #define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
 #define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
-#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_FIELDS ((thisfn)[n].type)
+#define TYPE_FN_FIELD_ARGS(thisfn, n) (((thisfn)[n].type)->fields ())
 #define TYPE_FN_FIELD_CONST(thisfn, n) ((thisfn)[n].is_const)
 #define TYPE_FN_FIELD_VOLATILE(thisfn, n) ((thisfn)[n].is_volatile)
 #define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private)
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index b216087e778..e58f1474699 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -512,7 +512,7 @@ tyscm_field_smob_to_field (field_smob *f_smob)
   struct type *type = tyscm_field_smob_containing_type (f_smob);
 
   /* This should be non-NULL by construction.  */
-  gdb_assert (TYPE_FIELDS (type) != NULL);
+  gdb_assert (type->fields () != NULL);
 
   return &TYPE_FIELD (type, f_smob->field_num);
 }
diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c
index 18d207535b4..b35b45ea4c5 100644
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -607,7 +607,7 @@ iq2000_pass_8bytetype_by_address (struct type *type)
   if (type->num_fields () != 1)
     return 1;
   /* Get field type.  */
-  ftype = (TYPE_FIELDS (type))[0].type;
+  ftype = type->field (0).type;
   /* The field type must have size 8, otherwise pass by address.  */
   if (TYPE_LENGTH (ftype) != 8)
     return 1;
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index aeecb14f19e..20fdd40d508 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -1233,8 +1233,8 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 
     case stMember:		/* member of struct or union */
       {
-	struct field *f
-	  = &TYPE_FIELDS (top_stack->cur_type)[top_stack->cur_field++];
+	struct field *f = &top_stack->cur_type->field (top_stack->cur_field);
+	top_stack->cur_field++;
 	FIELD_NAME (*f) = name;
 	SET_FIELD_BITPOS (*f, sh->value);
 	bitsize = 0;
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index a3ab8c80e37..c602398506b 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -5247,7 +5247,7 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, struct value *function,
 				: MIPS_V0_REGNUM);
 	   field < type->num_fields (); field++, regnum += 2)
 	{
-	  int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field])
+	  int offset = (FIELD_BITPOS (type->field (field))
 			/ TARGET_CHAR_BIT);
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n",
@@ -5799,7 +5799,7 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
       for (field = 0, regnum = mips_regnum (gdbarch)->fp0;
 	   field < type->num_fields (); field++, regnum += 2)
 	{
-	  int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field])
+	  int offset = (FIELD_BITPOS (type->fields ()[field])
 			/ TARGET_CHAR_BIT);
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n",
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index e710a43b7a0..8d535294524 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -1840,7 +1840,7 @@ again:
 	func_type->set_fields
 	  ((struct field *) TYPE_ALLOC (func_type,
 					num_args * sizeof (struct field)));
-        memset (TYPE_FIELDS (func_type), 0, num_args * sizeof (struct field));
+        memset (func_type->fields (), 0, num_args * sizeof (struct field));
         {
           int i;
           struct type_list *t;
@@ -3313,7 +3313,7 @@ attach_fields_to_type (struct stab_field_info *fip, struct type *type,
   type->set_fields
     ((struct field *)
      TYPE_ALLOC (type, sizeof (struct field) * nfields));
-  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+  memset (type->fields (), 0, sizeof (struct field) * nfields);
 
   if (non_public_fields)
     {
@@ -3660,7 +3660,7 @@ read_enum_type (const char **pp, struct type *type,
   type->set_fields
     ((struct field *)
      TYPE_ALLOC (type, sizeof (struct field) * nsyms));
-  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nsyms);
+  memset (type->fields (), 0, sizeof (struct field) * nsyms);
 
   /* Find the symbols for the values and put them into the type.
      The symbols can be found in the symlist that we put them on