This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 01/10] vla: introduce new bound type abstraction adapt uses


The rational behind this patch is to get started to implement the feature
described in dwarf4 standard (2.19) Static and Dynamic Values of Attributes.
It adds new DWARF2_PROP to store either a constant, exprloc, or reference to
describe an upper-/lower bound of a subrange. Other than that no new features
are introduce.

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* dwarf2read.c (read_subrange_type): Use struct dwarf2_prop for
	declaring high/low bounds and change uses accordingly. Call
	create_range_type_1 instead of create_range_type,
	* gdbtypes.c (create_range_type_1): New function.
	(create_range_type): Convert bounds into struct dwarf2_prop and pass
	them to create_range_type_1.
	* gdbtypes.h (struct dwarf2_prop): New struct.
	(create_range_type_1): New function prototype.
	(struct range_bounds): Use struct dwarf2_prop instead of LONGEST for
	high/low bounds.
	(TYPE_LOW_BOUND,TYPE_HIGH_BOUND): Adapt macros to refer to the static
	part of the bound.

Change-Id: I04ccd6b9bbf7519b99e814e9ee7119dbcd1f7baa
---
 gdb/dwarf2read.c |   40 +++++++++++++++++++++++-----------------
 gdb/gdbtypes.c   |   43 +++++++++++++++++++++++++++++++------------
 gdb/gdbtypes.h   |   38 ++++++++++++++++++++++++++++++++++----
 3 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 3974d0b..36ed9bd 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14142,7 +14142,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *base_type, *orig_base_type;
   struct type *range_type;
   struct attribute *attr;
-  LONGEST low, high;
+  struct dwarf2_prop low, high;
   int low_default_is_valid;
   const char *name;
   LONGEST negative_mask;
@@ -14159,33 +14159,37 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (range_type)
     return range_type;
 
+  low.kind = DWARF_CONST;
+  high.kind = DWARF_CONST;
+  high.data.const_val = 0;
+
   /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
      omitting DW_AT_lower_bound.  */
   switch (cu->language)
     {
     case language_c:
     case language_cplus:
-      low = 0;
+      low.data.const_val = 0;
       low_default_is_valid = 1;
       break;
     case language_fortran:
-      low = 1;
+      low.data.const_val = 1;
       low_default_is_valid = 1;
       break;
     case language_d:
     case language_java:
     case language_objc:
-      low = 0;
+      low.data.const_val = 0;
       low_default_is_valid = (cu->header.version >= 4);
       break;
     case language_ada:
     case language_m2:
     case language_pascal:
-      low = 1;
+      low.data.const_val = 1;
       low_default_is_valid = (cu->header.version >= 4);
       break;
     default:
-      low = 0;
+      low.data.const_val = 0;
       low_default_is_valid = 0;
       break;
     }
@@ -14195,7 +14199,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
      but we don't know how to handle it.  */
   attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
   if (attr)
-    low = dwarf2_get_attr_constant_value (attr, low);
+    low.data.const_val = dwarf2_get_attr_constant_value (attr, low.data.const_val);
   else if (!low_default_is_valid)
     complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
 				      "- DIE at 0x%x [in module %s]"),
@@ -14217,10 +14221,10 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
              either; we just represent them as zero-length
              arrays.  Choose an appropriate upper bound given
              the lower bound we've computed above.  */
-          high = low - 1;
+          high.data.const_val = low.data.const_val - 1;
         }
       else
-        high = dwarf2_get_attr_constant_value (attr, 1);
+        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
     }
   else
     {
@@ -14228,12 +14232,12 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
       if (attr)
 	{
 	  int count = dwarf2_get_attr_constant_value (attr, 1);
-	  high = low + count - 1;
+	  high.data.const_val = low.data.const_val + count - 1;
 	}
       else
 	{
 	  /* Unspecified array length.  */
-	  high = low - 1;
+	  high.data.const_val = low.data.const_val - 1;
 	}
     }
 
@@ -14277,12 +14281,14 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   negative_mask =
     (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
-  if (!TYPE_UNSIGNED (base_type) && (low & negative_mask))
-    low |= negative_mask;
-  if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
-    high |= negative_mask;
-
-  range_type = create_range_type (NULL, orig_base_type, low, high);
+  if (low.kind == DWARF_CONST
+      && !TYPE_UNSIGNED (base_type) && (low.data.const_val & negative_mask))
+    low.data.const_val |= negative_mask;
+  if (high.kind == DWARF_CONST
+      && !TYPE_UNSIGNED (base_type) && (high.data.const_val & negative_mask))
+    high.data.const_val |= negative_mask;
+
+  range_type = create_range_type_1 (NULL, orig_base_type, &low, &high);
 
   /* Mark arrays with dynamic length at least as an array of unspecified
      length.  GDB could check the boundary but before it gets implemented at
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 9069a11..3cfcf62 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -796,6 +796,27 @@ allocate_stub_method (struct type *type)
   return mtype;
 }
 
+struct type *
+create_range_type_1 (struct type *result_type, struct type *index_type,
+		     const struct dwarf2_prop *low_bound,
+		     const struct dwarf2_prop *high_bound)
+{
+  if (result_type == NULL)
+    result_type = alloc_type_copy (index_type);
+  TYPE_CODE (result_type) = TYPE_CODE_RANGE;
+  TYPE_TARGET_TYPE (result_type) = index_type;
+  if (TYPE_STUB (index_type))
+    TYPE_TARGET_STUB (result_type) = 1;
+  else
+    TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
+  TYPE_RANGE_DATA (result_type) = (struct range_bounds *)
+    TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
+  TYPE_RANGE_DATA (result_type)->low = *low_bound;
+  TYPE_RANGE_DATA (result_type)->high = *high_bound;
+
+  return result_type;
+}
+
 /* Create a range type using either a blank type supplied in
    RESULT_TYPE, or creating a new type, inheriting the objfile from
    INDEX_TYPE.
@@ -810,18 +831,16 @@ struct type *
 create_range_type (struct type *result_type, struct type *index_type,
 		   LONGEST low_bound, LONGEST high_bound)
 {
-  if (result_type == NULL)
-    result_type = alloc_type_copy (index_type);
-  TYPE_CODE (result_type) = TYPE_CODE_RANGE;
-  TYPE_TARGET_TYPE (result_type) = index_type;
-  if (TYPE_STUB (index_type))
-    TYPE_TARGET_STUB (result_type) = 1;
-  else
-    TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
-  TYPE_RANGE_DATA (result_type) = (struct range_bounds *)
-    TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
-  TYPE_LOW_BOUND (result_type) = low_bound;
-  TYPE_HIGH_BOUND (result_type) = high_bound;
+  struct dwarf2_prop low, high;
+
+  low.kind = DWARF_CONST;
+  low.data.const_val = low_bound;
+
+  high.kind = DWARF_CONST;
+  high.data.const_val = high_bound;
+
+  result_type = create_range_type_1 (result_type, index_type,
+				     &low, &high);
 
   if (low_bound >= 0)
     TYPE_UNSIGNED (result_type) = 1;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index d7fdedf..f563a1c 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -365,6 +365,29 @@ enum type_instance_flag_value
 #define TYPE_ADDRESS_CLASS_ALL(t) (TYPE_INSTANCE_FLAGS(t) \
 				   & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
 
+/* Used to store bound information for a type.  */
+
+struct dwarf2_prop
+{
+  /* Determine which field of the union dwarf2_prop.data is used.  */
+  enum
+  {
+    DWARF_CONST,
+    DWARF_LOCEXPR,
+    DWARF_LOCLIST
+  } kind;
+
+  /* Stores information as location expression, location list,
+     or constant value.  */
+  union data
+  {
+    LONGEST const_val;
+    struct dwarf2_locexpr_baton *locexpr;
+    struct dwarf2_loclist_baton *loclist;
+  } data;
+};
+
+
 /* Determine which field of the union main_type.fields[x].loc is used.  */
 
 enum field_loc_kind
@@ -589,11 +612,11 @@ struct main_type
     {
       /* Low bound of range.  */
 
-      LONGEST low;
+      struct dwarf2_prop low;
 
       /* High bound of range.  */
 
-      LONGEST high;
+      struct dwarf2_prop high;
 
       /* Flags indicating whether the values of low and high are
          valid.  When true, the respective range value is
@@ -1066,8 +1089,10 @@ extern void allocate_gnat_aux_type (struct type *);
 
 #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) TYPE_RANGE_DATA(range_type)->low
-#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high
+#define TYPE_LOW_BOUND(range_type) \
+  TYPE_RANGE_DATA(range_type)->low.data.const_val
+#define TYPE_HIGH_BOUND(range_type) \
+  TYPE_RANGE_DATA(range_type)->high.data.const_val
 #define TYPE_LOW_BOUND_UNDEFINED(range_type) \
    TYPE_RANGE_DATA(range_type)->low_undefined
 #define TYPE_HIGH_BOUND_UNDEFINED(range_type) \
@@ -1526,6 +1551,11 @@ extern struct type *lookup_function_type_with_arguments (struct type *,
 							 int,
 							 struct type **);
 
+extern struct type *create_range_type_1 (struct type *, struct type *,
+					 const struct dwarf2_prop *,
+					 const struct dwarf2_prop *);
+
+
 extern struct type *create_range_type (struct type *, struct type *, LONGEST,
 				       LONGEST);
 
-- 
1.7.0.7


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]