Return unique_xmalloc_ptr for generate_c_for_variable_locations
[deliverable/binutils-gdb.git] / gdb / compile / compile-c-types.c
index 77fbd686db0cee14150864578f123814968927e9..212cfe66bef4b478f721d3b474a847ab84cdb72c 100644 (file)
@@ -1,6 +1,6 @@
 /* Convert types from GDB to GCC
 
-   Copyright (C) 2014-2015 Free Software Foundation, Inc.
+   Copyright (C) 2014-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,6 +21,8 @@
 #include "defs.h"
 #include "gdbtypes.h"
 #include "compile-internal.h"
+#include "objfiles.h"
+
 /* An object that maps a gdb type to a gcc type.  */
 
 struct type_map_instance
@@ -31,7 +33,7 @@ struct type_map_instance
 
   /* The corresponding gcc type handle.  */
 
-  gcc_type gcc_type;
+  gcc_type gcc_type_handle;
 };
 
 /* Hash a type_map_instance.  */
@@ -39,7 +41,7 @@ struct type_map_instance
 static hashval_t
 hash_type_map_instance (const void *p)
 {
-  const struct type_map_instance *inst = p;
+  const struct type_map_instance *inst = (const struct type_map_instance *) p;
 
   return htab_hash_pointer (inst->type);
 }
@@ -49,8 +51,8 @@ hash_type_map_instance (const void *p)
 static int
 eq_type_map_instance (const void *a, const void *b)
 {
-  const struct type_map_instance *insta = a;
-  const struct type_map_instance *instb = 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;
 }
@@ -72,13 +74,13 @@ insert_type (struct compile_c_instance *context, struct type *type,
   void **slot;
 
   inst.type = type;
-  inst.gcc_type = gcc_type;
+  inst.gcc_type_handle = gcc_type;
   slot = htab_find_slot (context->type_map, &inst, INSERT);
 
-  add = *slot;
+  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 != gcc_type)
+  if (add != NULL && add->gcc_type_handle != gcc_type)
     error (_("Unexpected type id from GCC, check you use recent enough GCC."));
 
   if (add == NULL)
@@ -123,18 +125,17 @@ convert_array (struct compile_c_instance *context, struct type *type)
       || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST)
     {
       gcc_type result;
-      char *upper_bound;
 
       if (TYPE_VECTOR (type))
        return C_CTX (context)->c_ops->error (C_CTX (context),
                                              _("variably-sized vector type"
                                                " is not supported"));
 
-      upper_bound = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high);
+      std::string upper_bound
+       = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high);
       result = C_CTX (context)->c_ops->build_vla_array_type (C_CTX (context),
                                                             element_type,
-                                                            upper_bound);
-      xfree (upper_bound);
+                                                            upper_bound.c_str ());
       return result;
     }
   else
@@ -206,9 +207,9 @@ convert_enum (struct compile_c_instance *context, struct type *type)
   int i;
   struct gcc_c_context *ctx = C_CTX (context);
 
-  int_type = ctx->c_ops->int_type (ctx,
-                                  TYPE_UNSIGNED (type),
-                                  TYPE_LENGTH (type));
+  int_type = ctx->c_ops->int_type_v0 (ctx,
+                                     TYPE_UNSIGNED (type),
+                                     TYPE_LENGTH (type));
 
   result = ctx->c_ops->build_enum_type (ctx, int_type);
   for (i = 0; i < TYPE_NFIELDS (type); ++i)
@@ -234,9 +235,25 @@ convert_func (struct compile_c_instance *context, struct type *type)
   struct gcc_type_array array;
   int is_varargs = TYPE_VARARGS (type) || !TYPE_PROTOTYPED (type);
 
+  struct type *target_type = TYPE_TARGET_TYPE (type);
+
+  /* Functions with no debug info have no return type.  Ideally we'd
+     want to fallback to the type of the cast just before the
+     function, like GDB's built-in expression parser, but we don't
+     have access to that type here.  For now, fallback to int, like
+     GDB's parser used to do.  */
+  if (target_type == NULL)
+    {
+      if (TYPE_OBJFILE_OWNED (type))
+       target_type = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
+      else
+       target_type = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
+      warning (_("function has unknown return type; assuming int"));
+    }
+
   /* This approach means we can't make self-referential function
      types.  Those are impossible in C, though.  */
-  return_type = convert_type (context, TYPE_TARGET_TYPE (type));
+  return_type = convert_type (context, target_type);
 
   array.n_elements = TYPE_NFIELDS (type);
   array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type));
@@ -256,9 +273,22 @@ convert_func (struct compile_c_instance *context, struct type *type)
 static gcc_type
 convert_int (struct compile_c_instance *context, struct type *type)
 {
-  return C_CTX (context)->c_ops->int_type (C_CTX (context),
-                                          TYPE_UNSIGNED (type),
-                                          TYPE_LENGTH (type));
+  if (C_CTX (context)->c_ops->c_version >= GCC_C_FE_VERSION_1)
+    {
+      if (TYPE_NOSIGN (type))
+       {
+         gdb_assert (TYPE_LENGTH (type) == 1);
+         return C_CTX (context)->c_ops->char_type (C_CTX (context));
+       }
+      return C_CTX (context)->c_ops->int_type (C_CTX (context),
+                                              TYPE_UNSIGNED (type),
+                                              TYPE_LENGTH (type),
+                                              TYPE_NAME (type));
+    }
+  else
+    return C_CTX (context)->c_ops->int_type_v0 (C_CTX (context),
+                                               TYPE_UNSIGNED (type),
+                                               TYPE_LENGTH (type));
 }
 
 /* Convert a floating-point type to its gcc representation.  */
@@ -266,8 +296,13 @@ convert_int (struct compile_c_instance *context, struct type *type)
 static gcc_type
 convert_float (struct compile_c_instance *context, struct type *type)
 {
-  return C_CTX (context)->c_ops->float_type (C_CTX (context),
-                                            TYPE_LENGTH (type));
+  if (C_CTX (context)->c_ops->c_version >= GCC_C_FE_VERSION_1)
+    return C_CTX (context)->c_ops->float_type (C_CTX (context),
+                                              TYPE_LENGTH (type),
+                                              TYPE_NAME (type));
+  else
+    return C_CTX (context)->c_ops->float_type_v0 (C_CTX (context),
+                                                 TYPE_LENGTH (type));
 }
 
 /* Convert the 'void' type to its gcc representation.  */
@@ -293,7 +328,7 @@ convert_qualified (struct compile_c_instance *context, struct type *type)
 {
   struct type *unqual = make_unqualified_type (type);
   gcc_type unqual_converted;
-  int quals = 0;
+  gcc_qualifiers_flags quals = 0;
 
   unqual_converted = convert_type (context, unqual);
 
@@ -366,6 +401,21 @@ convert_type_basic (struct compile_c_instance *context, struct type *type)
 
     case TYPE_CODE_COMPLEX:
       return convert_complex (context, type);
+
+    case TYPE_CODE_ERROR:
+      {
+       /* Ideally, if we get here due to a cast expression, we'd use
+          the cast-to type as the variable's type, like GDB's
+          built-in parser does.  For now, assume "int" like GDB's
+          built-in parser used to do, but at least warn.  */
+       struct type *fallback;
+       if (TYPE_OBJFILE_OWNED (type))
+         fallback = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
+       else
+         fallback = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
+       warning (_("variable has unknown type; assuming int"));
+       return convert_int (context, fallback);
+      }
     }
 
   return C_CTX (context)->c_ops->error (C_CTX (context),
@@ -386,9 +436,9 @@ convert_type (struct compile_c_instance *context, struct type *type)
   type = check_typedef (type);
 
   inst.type = type;
-  found = htab_find (context->type_map, &inst);
+  found = (struct type_map_instance *) htab_find (context->type_map, &inst);
   if (found != NULL)
-    return found->gcc_type;
+    return found->gcc_type_handle;
 
   result = convert_type_basic (context, type);
   insert_type (context, type, result);
This page took 0.027149 seconds and 4 git commands to generate.