diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index 7bc30a5b3d..0b74e4b4cd 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -33,81 +33,16 @@
 
 
 
-/* Object of this type are stored in the compiler's symbol_err_map.  */
-
-struct symbol_error
-{
-  /* The symbol.  */
-
-  const struct symbol *sym;
-
-  /* The error message to emit.  This is malloc'd and owned by the
-     hash table.  */
-
-  char *message;
-};
-
-/* Hash function for struct symbol_error.  */
-
-static hashval_t
-hash_symbol_error (const void *a)
-{
-  const struct symbol_error *se = (const struct symbol_error *) a;
-
-  return htab_hash_pointer (se->sym);
-}
-
-/* Equality function for struct symbol_error.  */
-
-static int
-eq_symbol_error (const void *a, const void *b)
-{
-  const struct symbol_error *sea = (const struct symbol_error *) a;
-  const struct symbol_error *seb = (const struct symbol_error *) b;
-
-  return sea->sym == seb->sym;
-}
-
-/* Deletion function for struct symbol_error.  */
-
-static void
-del_symbol_error (void *a)
-{
-  struct symbol_error *se = (struct symbol_error *) a;
-
-  xfree (se->message);
-  xfree (se);
-}
-
 /* See compile-internal.h.  */
 
 void
 compile_instance::insert_symbol_error (const struct symbol *sym,
-				       const char *text)
+				       std::string text)
 {
-  struct symbol_error e;
-  void **slot;
+  symbol_err_map_t::iterator pos = m_symbol_err_map.find (sym);
 
-  if (m_symbol_err_map == NULL)
-    {
-      m_symbol_err_map = htab_create_alloc (10,
-					    hash_symbol_error,
-					    eq_symbol_error,
-					    del_symbol_error,
-					    xcalloc,
-					    xfree);
-    }
-
-  e.sym = sym;
-  slot = htab_find_slot (m_symbol_err_map, &e, INSERT);
-  if (*slot == NULL)
-    {
-      struct symbol_error *e = XNEW (struct symbol_error);
-
-      e->sym = sym;
-      e->message = xstrdup (text);
-      *slot = e;
-    }
+  if (pos == m_symbol_err_map.end ())
+    m_symbol_err_map.insert (std::make_pair (sym, text));
 }
 
 /* See compile-internal.h.  */
@@ -115,20 +50,13 @@ compile_instance::insert_symbol_error (const struct symbol *sym,
 void
 compile_instance::error_symbol_once (const struct symbol *sym)
 {
-  struct symbol_error search;
-  struct symbol_error *err;
-
-  if (m_symbol_err_map == NULL)
-    return;
-
-  search.sym = sym;
-  err = (struct symbol_error *) htab_find (m_symbol_err_map, &search);
-  if (err == NULL || err->message == NULL)
+  symbol_err_map_t::iterator pos = m_symbol_err_map.find (sym);
+  if (pos == m_symbol_err_map.end () || pos->second.length () == 0)
     return;
 
-  gdb::unique_xmalloc_ptr<char> message (err->message);
-  err->message = NULL;
-  error (_("%s"), message.get ());
+  std::string message (pos->second);
+  pos->second.clear ();
+  ::error (_("%s"), message.c_str ());
 }
 
 
diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c
index 44b8317739..1ad6c2a4da 100644
--- a/gdb/compile/compile-c-types.c
+++ b/gdb/compile/compile-c-types.c
@@ -24,78 +24,24 @@
 #include "compile-c.h"
 #include "objfiles.h"
 
-/* An object that maps a gdb type to a gcc type.  */
-
-struct type_map_instance
-{
-  /* The gdb type.  */
-
-  struct type *type;
-
-  /* The corresponding gcc type handle.  */
-
-  gcc_type gcc_type_handle;
-};
-
-/* Hash a type_map_instance.  */
-
-static hashval_t
-hash_type_map_instance (const void *p)
-{
-  const struct type_map_instance *inst = (const struct type_map_instance *) p;
-
-  return htab_hash_pointer (inst->type);
-}
-
-/* Check two type_map_instance objects for equality.  */
-
-static int
-eq_type_map_instance (const void *a, const void *b)
-{
-  const struct type_map_instance *insta = (const struct type_map_instance *) a;
-  const struct type_map_instance *instb = (const struct type_map_instance *) b;
-
-  return insta->type == instb->type;
-}
-
-/* Constructor for compile_instance.  */
-
-compile_instance::compile_instance (struct gcc_base_context *gcc_fe,
-				    const char *options)
-  : m_gcc_fe (gcc_fe), m_gcc_target_options (options),
-    m_symbol_err_map (NULL)
-{
-  m_type_map = htab_create_alloc (10, hash_type_map_instance,
-				  eq_type_map_instance,
-				  xfree, xcalloc, xfree);
-}
-
-
-
 /* See compile-internal.h.  */
 
 void
 compile_instance::insert_type (struct type *type, gcc_type gcc_type)
 {
-  struct type_map_instance inst, *add;
-  void **slot;
-
-  inst.type = type;
-  inst.gcc_type_handle = gcc_type;
-  slot = htab_find_slot (m_type_map, &inst, INSERT);
+  type_map_t::iterator pos = m_type_map.find (type);
 
-  add = (struct type_map_instance *) *slot;
-  /* The type might have already been inserted in order to handle
-     recursive types.  */
-  if (add != NULL && add->gcc_type_handle != gcc_type)
-    error (_("Unexpected type id from GCC, check you use recent enough GCC."));
-
-  if (add == NULL)
+  if (pos != m_type_map.end ())
     {
-      add = XNEW (struct type_map_instance);
-      *add = inst;
-      *slot = add;
+      /* The type might have already been inserted in order to handle
+         recursive types.  */
+      if (pos->second != gcc_type)
+        error (_("Unexpected type id from GCC, check for recent "
+                 "enough GCC."));
     }
+  else
+    m_type_map.insert (std::make_pair (type, gcc_type));
+
 }
 
 /* Convert a pointer type to its gcc representation.  */
@@ -422,19 +368,15 @@ const char *compile_c_instance::m_default_cflags = "-std=gnu11"
 gcc_type
 compile_c_instance::convert_type (struct type *type)
 {
-  struct type_map_instance inst, *found;
-  gcc_type result;
-
   /* We don't ever have to deal with typedefs in this code, because
      those are only needed as symbols by the C compiler.  */
   type = check_typedef (type);
 
-  inst.type = type;
-  found = (struct type_map_instance *) htab_find (m_type_map, &inst);
-  if (found != NULL)
-    return found->gcc_type_handle;
+  type_map_t::iterator pos = m_type_map.find (type);
+  if (pos != m_type_map.end ())
+    return pos->second;
 
-  result = convert_type_basic (this, type);
+  gcc_type result = convert_type_basic (this, type);
   insert_type (type, result);
   return result;
 }
diff --git a/gdb/compile/compile-internal.h b/gdb/compile/compile-internal.h
index 8cfb214c02..e7b428da3f 100644
--- a/gdb/compile/compile-internal.h
+++ b/gdb/compile/compile-internal.h
@@ -19,6 +19,9 @@
 
 #include "gcc-c-interface.h"
 
+#include <string>
+#include <unordered_map>
+
 /* Debugging flag for the "compile" family of commands.  */
 
 extern int compile_debug;
@@ -31,15 +34,13 @@ struct block;
 class compile_instance
 {
 public:
-  compile_instance (struct gcc_base_context *gcc_fe, const char *options);
-
-  virtual ~compile_instance ()
+  compile_instance (struct gcc_base_context *gcc_fe, const char *options)
+      : m_gcc_fe (gcc_fe), m_gcc_target_options (options)
   {
-    htab_delete (m_type_map);
-    if (m_symbol_err_map != NULL)
-      htab_delete (m_symbol_err_map);
   }
 
+  virtual ~compile_instance () = default;
+
   /* Returns the GCC options to be passed during compilation.  */
   const std::string &gcc_target_options () const
   {
@@ -53,7 +54,7 @@ public:
   void insert_type (struct type *type, gcc_type gcc_type);
 
   /* Associate SYMBOL with some error text.  */
-  void insert_symbol_error (const struct symbol *sym, const char *text);
+  void insert_symbol_error (const struct symbol *sym, std::string text);
 
   /* Emit the error message corresponding to SYM, if one exists, and
      arrange for it not to be emitted again.  */
@@ -117,8 +118,9 @@ public:
 protected:
   /* Map types used by the compile instance for caching type conversions.
      and error tracking.  */
-  typedef htab_t type_map_t;
-  typedef htab_t symbol_err_map_t;
+  typedef std::unordered_map<const struct type *, gcc_type> type_map_t;
+  typedef std::unordered_map<const struct symbol *, std::string>
+    symbol_err_map_t;
 
   /* The GCC front end.  */
   struct gcc_base_context *m_gcc_fe;
