]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/compile/compile-c-symbols.c
gdb: remove TYPE_FIELD macro
[thirdparty/binutils-gdb.git] / gdb / compile / compile-c-symbols.c
index dcd530d3cb9be46f645b19afeb05c7a5a6cd6247..758b12db1a784370b38bd48b0cdc3b6943405f48 100644 (file)
@@ -1,6 +1,6 @@
 /* Convert symbols from GDB to GCC
 
-   Copyright (C) 2014-2016 Free Software Foundation, Inc.
+   Copyright (C) 2014-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,6 +20,7 @@
 
 #include "defs.h"
 #include "compile-internal.h"
+#include "compile-c.h"
 #include "symtab.h"
 #include "parser-defs.h"
 #include "block.h"
 #include "value.h"
 #include "exceptions.h"
 #include "gdbtypes.h"
-#include "dwarf2loc.h"
-
-\f
-
-/* 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);
-}
-
-/* Associate SYMBOL with some error text.  */
-
-static void
-insert_symbol_error (htab_t hash, const struct symbol *sym, const char *text)
-{
-  struct symbol_error e;
-  void **slot;
-
-  e.sym = sym;
-  slot = htab_find_slot (hash, &e, INSERT);
-  if (*slot == NULL)
-    {
-      struct symbol_error *e = XNEW (struct symbol_error);
-
-      e->sym = sym;
-      e->message = xstrdup (text);
-      *slot = e;
-    }
-}
-
-/* Emit the error message corresponding to SYM, if one exists, and
-   arrange for it not to be emitted again.  */
-
-static void
-error_symbol_once (struct compile_c_instance *context,
-                  const struct symbol *sym)
-{
-  struct symbol_error search;
-  struct symbol_error *err;
-  char *message;
-
-  if (context->symbol_err_map == NULL)
-    return;
-
-  search.sym = sym;
-  err = (struct symbol_error *) htab_find (context->symbol_err_map, &search);
-  if (err == NULL || err->message == NULL)
-    return;
-
-  message = err->message;
-  err->message = NULL;
-  make_cleanup (xfree, message);
-  error (_("%s"), message);
-}
+#include "dwarf2/loc.h"
 
 \f
 
 /* Compute the name of the pointer representing a local symbol's
    address.  */
 
-static char *
-symbol_substitution_name (struct symbol *sym)
+gdb::unique_xmalloc_ptr<char>
+c_symbol_substitution_name (struct symbol *sym)
 {
-  return concat ("__", SYMBOL_NATURAL_NAME (sym), "_ptr", (char *) NULL);
+  return gdb::unique_xmalloc_ptr<char>
+    (concat ("__", sym->natural_name (), "_ptr", (char *) NULL));
 }
 
 /* Convert a given symbol, SYM, to the compiler's representation.
@@ -142,7 +51,7 @@ symbol_substitution_name (struct symbol *sym)
    scope.)  */
 
 static void
-convert_one_symbol (struct compile_c_instance *context,
+convert_one_symbol (compile_c_instance *context,
                    struct block_symbol sym,
                    int is_global,
                    int is_local)
@@ -151,26 +60,25 @@ convert_one_symbol (struct compile_c_instance *context,
   const char *filename = symbol_symtab (sym.symbol)->filename;
   unsigned short line = SYMBOL_LINE (sym.symbol);
 
-  error_symbol_once (context, sym.symbol);
+  context->error_symbol_once (sym.symbol);
 
   if (SYMBOL_CLASS (sym.symbol) == LOC_LABEL)
     sym_type = 0;
   else
-    sym_type = convert_type (context, SYMBOL_TYPE (sym.symbol));
+    sym_type = context->convert_type (SYMBOL_TYPE (sym.symbol));
 
   if (SYMBOL_DOMAIN (sym.symbol) == STRUCT_DOMAIN)
     {
       /* Binding a tag, so we don't need to build a decl.  */
-      C_CTX (context)->c_ops->tagbind (C_CTX (context),
-                                      SYMBOL_NATURAL_NAME (sym.symbol),
-                                      sym_type, filename, line);
+      context->plugin ().tagbind (sym.symbol->natural_name (),
+                                 sym_type, filename, line);
     }
   else
     {
       gcc_decl decl;
       enum gcc_c_symbol_kind kind;
       CORE_ADDR addr = 0;
-      char *symbol_name = NULL;
+      gdb::unique_xmalloc_ptr<char> symbol_name;
 
       switch (SYMBOL_CLASS (sym.symbol))
        {
@@ -185,41 +93,40 @@ convert_one_symbol (struct compile_c_instance *context,
 
        case LOC_BLOCK:
          kind = GCC_C_SYMBOL_FUNCTION;
-         addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym.symbol));
+         addr = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym.symbol));
          if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym.symbol)))
            addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
          break;
 
        case LOC_CONST:
-         if (TYPE_CODE (SYMBOL_TYPE (sym.symbol)) == TYPE_CODE_ENUM)
+         if (SYMBOL_TYPE (sym.symbol)->code () == TYPE_CODE_ENUM)
            {
              /* Already handled by convert_enum.  */
              return;
            }
-         C_CTX (context)->c_ops->build_constant
-           (C_CTX (context),
-            sym_type, SYMBOL_NATURAL_NAME (sym.symbol),
+         context->plugin ().build_constant
+           (sym_type, sym.symbol->natural_name (),
             SYMBOL_VALUE (sym.symbol),
             filename, line);
          return;
 
        case LOC_CONST_BYTES:
          error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
-                SYMBOL_PRINT_NAME (sym.symbol));
+                sym.symbol->print_name ());
 
        case LOC_UNDEF:
          internal_error (__FILE__, __LINE__, _("LOC_UNDEF found for \"%s\"."),
-                         SYMBOL_PRINT_NAME (sym.symbol));
+                         sym.symbol->print_name ());
 
        case LOC_COMMON_BLOCK:
          error (_("Fortran common block is unsupported for compilation "
                   "evaluaton of symbol \"%s\"."),
-                SYMBOL_PRINT_NAME (sym.symbol));
+                sym.symbol->print_name ());
 
        case LOC_OPTIMIZED_OUT:
          error (_("Symbol \"%s\" cannot be used for compilation evaluation "
                   "as it is optimized out."),
-                SYMBOL_PRINT_NAME (sym.symbol));
+                sym.symbol->print_name ());
 
        case LOC_COMPUTED:
          if (is_local)
@@ -228,7 +135,7 @@ convert_one_symbol (struct compile_c_instance *context,
          warning (_("Symbol \"%s\" is thread-local and currently can only "
                     "be referenced from the current thread in "
                     "compiled code."),
-                  SYMBOL_PRINT_NAME (sym.symbol));
+                  sym.symbol->print_name ());
          /* FALLTHROUGH */
        case LOC_UNRESOLVED:
          /* 'symbol_name' cannot be used here as that one is used only for
@@ -245,14 +152,14 @@ convert_one_symbol (struct compile_c_instance *context,
                if (frame == NULL)
                  error (_("Symbol \"%s\" cannot be used because "
                           "there is no selected frame"),
-                        SYMBOL_PRINT_NAME (sym.symbol));
+                        sym.symbol->print_name ());
              }
 
            val = read_var_value (sym.symbol, sym.block, frame);
            if (VALUE_LVAL (val) != lval_memory)
              error (_("Symbol \"%s\" cannot be used for compilation "
                       "evaluation as its address has not been found."),
-                    SYMBOL_PRINT_NAME (sym.symbol));
+                    sym.symbol->print_name ());
 
            kind = GCC_C_SYMBOL_VARIABLE;
            addr = value_address (val);
@@ -267,7 +174,7 @@ convert_one_symbol (struct compile_c_instance *context,
        case LOC_LOCAL:
        substitution:
          kind = GCC_C_SYMBOL_VARIABLE;
-         symbol_name = symbol_substitution_name (sym.symbol);
+         symbol_name = c_symbol_substitution_name (sym.symbol);
          break;
 
        case LOC_STATIC:
@@ -282,21 +189,18 @@ convert_one_symbol (struct compile_c_instance *context,
        }
 
       /* Don't emit local variable decls for a raw expression.  */
-      if (context->base.scope != COMPILE_I_RAW_SCOPE
+      if (context->scope () != COMPILE_I_RAW_SCOPE
          || symbol_name == NULL)
        {
-         decl = C_CTX (context)->c_ops->build_decl
-           (C_CTX (context),
-            SYMBOL_NATURAL_NAME (sym.symbol),
+         decl = context->plugin ().build_decl
+           (sym.symbol->natural_name (),
             kind,
             sym_type,
-            symbol_name, addr,
+            symbol_name.get (), addr,
             filename, line);
 
-         C_CTX (context)->c_ops->bind (C_CTX (context), decl, is_global);
+         context->plugin ().bind (decl, is_global);
        }
-
-      xfree (symbol_name);
     }
 }
 
@@ -305,7 +209,7 @@ convert_one_symbol (struct compile_c_instance *context,
    itself, and DOMAIN is the domain which was searched.  */
 
 static void
-convert_symbol_sym (struct compile_c_instance *context, const char *identifier,
+convert_symbol_sym (compile_c_instance *context, const char *identifier,
                    struct block_symbol sym, domain_enum domain)
 {
   const struct block *static_block;
@@ -355,7 +259,7 @@ convert_symbol_sym (struct compile_c_instance *context, const char *identifier,
    to use and BMSYM is the minimal symbol to convert.  */
 
 static void
-convert_symbol_bmsym (struct compile_c_instance *context,
+convert_symbol_bmsym (compile_c_instance *context,
                      struct bound_minimal_symbol bmsym)
 {
   struct minimal_symbol *msym = bmsym.minsym;
@@ -379,9 +283,7 @@ convert_symbol_bmsym (struct compile_c_instance *context,
       break;
 
     case mst_text_gnu_ifunc:
-      /* nodebug_text_gnu_ifunc_symbol would cause:
-        function return type cannot be function  */
-      type = objfile_type (objfile)->nodebug_text_symbol;
+      type = objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
       kind = GCC_C_SYMBOL_FUNCTION;
       addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
       break;
@@ -405,12 +307,11 @@ convert_symbol_bmsym (struct compile_c_instance *context,
       break;
     }
 
-  sym_type = convert_type (context, type);
-  decl = C_CTX (context)->c_ops->build_decl (C_CTX (context),
-                                            MSYMBOL_NATURAL_NAME (msym),
-                                            kind, sym_type, NULL, addr,
-                                            NULL, 0);
-  C_CTX (context)->c_ops->bind (C_CTX (context), decl, 1 /* is_global */);
+  sym_type = context->convert_type (type);
+  decl = context->plugin ().build_decl (msym->natural_name (),
+                                       kind, sym_type, NULL, addr,
+                                       NULL, 0);
+  context->plugin ().bind (decl, 1 /* is_global */);
 }
 
 /* See compile-internal.h.  */
@@ -421,7 +322,8 @@ gcc_convert_symbol (void *datum,
                    enum gcc_c_oracle_request request,
                    const char *identifier)
 {
-  struct compile_c_instance *context = (struct compile_c_instance *) datum;
+  compile_c_instance *context
+    = static_cast<compile_c_instance *> (datum);
   domain_enum domain;
   int found = 0;
 
@@ -442,11 +344,11 @@ gcc_convert_symbol (void *datum,
 
   /* We can't allow exceptions to escape out of this callback.  Safest
      is to simply emit a gcc error.  */
-  TRY
+  try
     {
       struct block_symbol sym;
 
-      sym = lookup_symbol (identifier, context->base.block, domain, NULL);
+      sym = lookup_symbol (identifier, context->block (), domain, NULL);
       if (sym.symbol != NULL)
        {
          convert_symbol_sym (context, identifier, sym, domain);
@@ -465,11 +367,10 @@ gcc_convert_symbol (void *datum,
        }
     }
 
-  CATCH (e, RETURN_MASK_ALL)
+  catch (const gdb_exception &e)
     {
-      C_CTX (context)->c_ops->error (C_CTX (context), e.message);
+      context->plugin ().error (e.what ());
     }
-  END_CATCH
 
   if (compile_debug && !found)
     fprintf_unfiltered (gdb_stdlog,
@@ -484,13 +385,14 @@ gcc_address
 gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
                    const char *identifier)
 {
-  struct compile_c_instance *context = (struct compile_c_instance *) datum;
+  compile_c_instance *context
+    = static_cast<compile_c_instance *> (datum);
   gcc_address result = 0;
   int found = 0;
 
   /* We can't allow exceptions to escape out of this callback.  Safest
      is to simply emit a gcc error.  */
-  TRY
+  try
     {
       struct symbol *sym;
 
@@ -502,7 +404,7 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
            fprintf_unfiltered (gdb_stdlog,
                                "gcc_symbol_address \"%s\": full symbol\n",
                                identifier);
-         result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+         result = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
          if (TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
            result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
          found = 1;
@@ -527,11 +429,10 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
        }
     }
 
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
-      C_CTX (context)->c_ops->error (C_CTX (context), e.message);
+      context->plugin ().error (e.what ());
     }
-  END_CATCH
 
   if (compile_debug && !found)
     fprintf_unfiltered (gdb_stdlog,
@@ -549,7 +450,7 @@ hash_symname (const void *a)
 {
   const struct symbol *sym = (const struct symbol *) a;
 
-  return htab_hash_string (SYMBOL_NATURAL_NAME (sym));
+  return htab_hash_string (sym->natural_name ());
 }
 
 /* A comparison function for hash tables that just looks at symbol
@@ -561,7 +462,7 @@ eq_symname (const void *a, const void *b)
   const struct symbol *syma = (const struct symbol *) a;
   const struct symbol *symb = (const struct symbol *) b;
 
-  return strcmp (SYMBOL_NATURAL_NAME (syma), SYMBOL_NATURAL_NAME (symb)) == 0;
+  return strcmp (syma->natural_name (), symb->natural_name ()) == 0;
 }
 
 /* If a symbol with the same name as SYM is already in HASHTAB, return
@@ -583,8 +484,8 @@ symbol_seen (htab_t hashtab, struct symbol *sym)
 /* Generate C code to compute the length of a VLA.  */
 
 static void
-generate_vla_size (struct compile_c_instance *compiler,
-                  struct ui_file *stream,
+generate_vla_size (compile_instance *compiler,
+                  string_file *stream,
                   struct gdbarch *gdbarch,
                   unsigned char *registers_used,
                   CORE_ADDR pc,
@@ -593,10 +494,10 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_RANGE:
       {
@@ -604,13 +505,11 @@ generate_vla_size (struct compile_c_instance *compiler,
            || TYPE_HIGH_BOUND_KIND (type) == PROP_LOCLIST)
          {
            const struct dynamic_prop *prop = &TYPE_RANGE_DATA (type)->high;
-           char *name = c_get_range_decl_name (prop);
-           struct cleanup *cleanup = make_cleanup (xfree, name);
+           std::string name = c_get_range_decl_name (prop);
 
-           dwarf2_compile_property_to_c (stream, name,
+           dwarf2_compile_property_to_c (stream, name.c_str (),
                                          gdbarch, registers_used,
                                          prop, pc, sym);
-           do_cleanups (cleanup);
          }
       }
       break;
@@ -627,8 +526,8 @@ generate_vla_size (struct compile_c_instance *compiler,
       {
        int i;
 
-       for (i = 0; i < TYPE_NFIELDS (type); ++i)
-         if (!field_is_static (&TYPE_FIELD (type, i)))
+       for (i = 0; i < type->num_fields (); ++i)
+         if (!field_is_static (&type->field (i)))
            generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
                               TYPE_FIELD_TYPE (type, i), sym);
       }
@@ -639,44 +538,42 @@ generate_vla_size (struct compile_c_instance *compiler,
 /* Generate C code to compute the address of SYM.  */
 
 static void
-generate_c_for_for_one_variable (struct compile_c_instance *compiler,
-                                struct ui_file *stream,
+generate_c_for_for_one_variable (compile_instance *compiler,
+                                string_file *stream,
                                 struct gdbarch *gdbarch,
                                 unsigned char *registers_used,
                                 CORE_ADDR pc,
                                 struct symbol *sym)
 {
 
-  TRY
+  try
     {
       if (is_dynamic_type (SYMBOL_TYPE (sym)))
        {
-         struct ui_file *size_file = mem_fileopen ();
-         struct cleanup *cleanup = make_cleanup_ui_file_delete (size_file);
+         /* We need to emit to a temporary buffer in case an error
+            occurs in the middle.  */
+         string_file local_file;
 
-         generate_vla_size (compiler, size_file, gdbarch, registers_used, pc,
+         generate_vla_size (compiler, &local_file, gdbarch, registers_used, pc,
                             SYMBOL_TYPE (sym), sym);
-         ui_file_put (size_file, ui_file_write_for_put, stream);
 
-         do_cleanups (cleanup);
+         stream->write (local_file.c_str (), local_file.size ());
        }
 
       if (SYMBOL_COMPUTED_OPS (sym) != NULL)
        {
-         char *generated_name = symbol_substitution_name (sym);
-         struct cleanup *cleanup = make_cleanup (xfree, generated_name);
+         gdb::unique_xmalloc_ptr<char> generated_name
+           = c_symbol_substitution_name (sym);
          /* We need to emit to a temporary buffer in case an error
             occurs in the middle.  */
-         struct ui_file *local_file = mem_fileopen ();
+         string_file local_file;
 
-         make_cleanup_ui_file_delete (local_file);
-         SYMBOL_COMPUTED_OPS (sym)->generate_c_location (sym, local_file,
+         SYMBOL_COMPUTED_OPS (sym)->generate_c_location (sym, &local_file,
                                                          gdbarch,
                                                          registers_used,
-                                                         pc, generated_name);
-         ui_file_put (local_file, ui_file_write_for_put, stream);
-
-         do_cleanups (cleanup);
+                                                         pc,
+                                                         generated_name.get ());
+         stream->write (local_file.c_str (), local_file.size ());
        }
       else
        {
@@ -701,47 +598,35 @@ generate_c_for_for_one_variable (struct compile_c_instance *compiler,
        }
     }
 
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
-      if (compiler->symbol_err_map == NULL)
-       compiler->symbol_err_map = htab_create_alloc (10,
-                                                     hash_symbol_error,
-                                                     eq_symbol_error,
-                                                     del_symbol_error,
-                                                     xcalloc,
-                                                     xfree);
-      insert_symbol_error (compiler->symbol_err_map, sym, e.message);
+      compiler->insert_symbol_error (sym, e.what ());
     }
-  END_CATCH
 }
 
-/* See compile-internal.h.  */
+/* See compile-c.h.  */
 
-unsigned char *
-generate_c_for_variable_locations (struct compile_c_instance *compiler,
-                                  struct ui_file *stream,
+gdb::unique_xmalloc_ptr<unsigned char>
+generate_c_for_variable_locations (compile_instance *compiler,
+                                  string_file *stream,
                                   struct gdbarch *gdbarch,
                                   const struct block *block,
                                   CORE_ADDR pc)
 {
-  struct cleanup *cleanup, *outer;
-  htab_t symhash;
   const struct block *static_block = block_static_block (block);
-  unsigned char *registers_used;
 
   /* If we're already in the static or global block, there is nothing
      to write.  */
   if (static_block == NULL || block == static_block)
     return NULL;
 
-  registers_used = XCNEWVEC (unsigned char, gdbarch_num_regs (gdbarch));
-  outer = make_cleanup (xfree, registers_used);
+  gdb::unique_xmalloc_ptr<unsigned char> registers_used
+    (XCNEWVEC (unsigned char, gdbarch_num_regs (gdbarch)));
 
   /* Ensure that a given name is only entered once.  This reflects the
      reality of shadowing.  */
-  symhash = htab_create_alloc (1, hash_symname, eq_symname, NULL,
-                              xcalloc, xfree);
-  cleanup = make_cleanup_htab_delete (symhash);
+  htab_up symhash (htab_create_alloc (1, hash_symname, eq_symname, NULL,
+                                     xcalloc, xfree));
 
   while (1)
     {
@@ -754,9 +639,9 @@ generate_c_for_variable_locations (struct compile_c_instance *compiler,
           sym != NULL;
           sym = block_iterator_next (&iter))
        {
-         if (!symbol_seen (symhash, sym))
+         if (!symbol_seen (symhash.get (), sym))
            generate_c_for_for_one_variable (compiler, stream, gdbarch,
-                                            registers_used, pc, sym);
+                                            registers_used.get (), pc, sym);
        }
 
       /* If we just finished the outermost block of a function, we're
@@ -766,7 +651,5 @@ generate_c_for_variable_locations (struct compile_c_instance *compiler,
       block = BLOCK_SUPERBLOCK (block);
     }
 
-  do_cleanups (cleanup);
-  discard_cleanups (outer);
   return registers_used;
 }