aboutsummaryrefslogtreecommitdiff
path: root/gdb/eval.c
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1995-10-05 20:57:30 +0000
committerSteve Chamberlain <sac@cygnus>1995-10-05 20:57:30 +0000
commit0694bce61924ece755442f0871d5900728b2e88b (patch)
tree435c9fb1687c8a8c8ec042ca9c4dbd4c0c5f456a /gdb/eval.c
parentf4791d95f1ff9ffdf107b1fbf79aa6e3bf58c441 (diff)
downloadgdb-0694bce61924ece755442f0871d5900728b2e88b.zip
gdb-0694bce61924ece755442f0871d5900728b2e88b.tar.gz
gdb-0694bce61924ece755442f0871d5900728b2e88b.tar.bz2
Thu Oct 5 13:27:30 1995 steve chamberlain <sac@slash.cygnus.com>
* win32.c: New file; support for debugging on windows NT. * configure.in: (i[345]86-*-win32): New target. * configure: Regnerated. * eval.c (evaluate_subexp_standard): Remove unused name. * serial.c (gdb_string.h): Include. * source.c (value.h): Include. * config/i386/i386win32.mh (XDEPFILES): Add win32.o * config/i386/i386win32.mt: New. * config/i386/tm-i386win32.h: New.
Diffstat (limited to 'gdb/eval.c')
-rw-r--r--gdb/eval.c209
1 files changed, 148 insertions, 61 deletions
diff --git a/gdb/eval.c b/gdb/eval.c
index 9964c31..9bc898c 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdb_string.h"
@@ -141,75 +141,165 @@ evaluate_type (exp)
return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
}
-/* Helper function called by evaluate_subexp to initialize a field
- a structure from a tuple in Chill. This is recursive, to handle
- more than one field name labels.
+/* If the next expression is an OP_LABELED, skips past it,
+ returning the label. Otherwise, does nothing and returns NULL. */
- STRUCT_VAL is the structure value we are constructing.
- (*FIELDNOP) is the field to set, if there is no label.
- It is set to the field following this one.
- EXP, POS, and NOSIDE are as for evaluate_subexp.
-
- This function does not handle variant records. FIXME */
-
-static value_ptr
-evaluate_labeled_field_init (struct_val, fieldnop, exp, pos, noside)
- value_ptr struct_val;
- int *fieldnop;
+static char*
+get_label (exp, pos)
register struct expression *exp;
- register int *pos;
- enum noside noside;
+ int *pos;
{
- int fieldno = *fieldnop;
- value_ptr val;
- int bitpos, bitsize;
- char *addr;
- struct type *struct_type = VALUE_TYPE (struct_val);
if (exp->elts[*pos].opcode == OP_LABELED)
{
int pc = (*pos)++;
char *name = &exp->elts[pc + 2].string;
int tem = longest_to_int (exp->elts[pc + 1].longconst);
(*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
- for (fieldno = 0; ; fieldno++)
- {
- if (fieldno >= TYPE_NFIELDS (struct_type))
- error ("there is no field named %s", name);
- if (STREQ (TYPE_FIELD_NAME (struct_type, fieldno), name))
- break;
- }
- *fieldnop = fieldno;
- val = evaluate_labeled_field_init (struct_val, fieldnop,
- exp, pos, noside);
+ return name;
}
else
+ return NULL;
+}
+
+/* This function evaluates tupes (in Chill) or brace-initializers
+ (in C/C++) for structure types. */
+
+static value_ptr
+evaluate_struct_tuple (struct_val, exp, pos, noside, nargs)
+ value_ptr struct_val;
+ register struct expression *exp;
+ register int *pos;
+ enum noside noside;
+ int nargs;
+{
+ struct type *struct_type = VALUE_TYPE (struct_val);
+ struct type *substruct_type = struct_type;
+ struct type *field_type;
+ int fieldno = -1;
+ int variantno = -1;
+ int subfieldno = -1;
+ while (--nargs >= 0)
{
- fieldno = (*fieldnop)++;
- if (fieldno >= TYPE_NFIELDS (struct_type))
- error ("too many initializers");
- val = evaluate_subexp (TYPE_FIELD_TYPE (struct_type, fieldno),
- exp, pos, noside);
- }
+ int pc = *pos;
+ value_ptr val = NULL;
+ int nlabels = 0;
+ int bitpos, bitsize;
+ char *addr;
+
+ /* Skip past the labels, and count them. */
+ while (get_label (exp, pos) != NULL)
+ nlabels++;
- /* Assign val to field fieldno. */
- if (VALUE_TYPE (val) != TYPE_FIELD_TYPE (struct_type, fieldno))
- val = value_cast (TYPE_FIELD_TYPE (struct_type, fieldno), val);
-#if 1
- bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno);
- bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
- addr = VALUE_CONTENTS (struct_val);
- addr += bitpos / 8;
- if (bitsize)
- modify_field (addr, value_as_long (val),
- bitpos % 8, bitsize);
- else
- memcpy (addr, VALUE_CONTENTS (val),
- TYPE_LENGTH (VALUE_TYPE (val)));
-#else
- value_assign (value_primitive_field (struct_val, 0, fieldno, struct_type),
- val);
-#endif
- return val;
+ do
+ {
+ char *label = get_label (exp, &pc);
+ if (label)
+ {
+ for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type);
+ fieldno++)
+ {
+ char *field_name = TYPE_FIELD_NAME (struct_type, fieldno);
+ if (field_name != NULL && STREQ (field_name, label))
+ {
+ variantno = -1;
+ subfieldno = fieldno;
+ substruct_type = struct_type;
+ goto found;
+ }
+ }
+ for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type);
+ fieldno++)
+ {
+ char *field_name = TYPE_FIELD_NAME (struct_type, fieldno);
+ field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
+ if ((field_name == 0 || *field_name == '\0')
+ && TYPE_CODE (field_type) == TYPE_CODE_UNION)
+ {
+ variantno = 0;
+ for (; variantno < TYPE_NFIELDS (field_type);
+ variantno++)
+ {
+ substruct_type
+ = TYPE_FIELD_TYPE (field_type, variantno);
+ if (TYPE_CODE (substruct_type) == TYPE_CODE_STRUCT)
+ {
+ for (subfieldno = 0;
+ subfieldno < TYPE_NFIELDS (substruct_type);
+ subfieldno++)
+ {
+ if (STREQ (TYPE_FIELD_NAME (substruct_type,
+ subfieldno),
+ label))
+ {
+ goto found;
+ }
+ }
+ }
+ }
+ }
+ }
+ error ("there is no field named %s", label);
+ found:
+ ;
+ }
+ else
+ {
+ /* Unlabelled tuple element - go to next field. */
+ if (variantno >= 0)
+ {
+ subfieldno++;
+ if (subfieldno >= TYPE_NFIELDS (substruct_type))
+ {
+ variantno = -1;
+ substruct_type = struct_type;
+ }
+ }
+ if (variantno < 0)
+ {
+ fieldno++;
+ subfieldno = fieldno;
+ if (fieldno >= TYPE_NFIELDS (struct_type))
+ error ("too many initializers");
+ field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
+ if (TYPE_CODE (field_type) == TYPE_CODE_UNION
+ && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0')
+ error ("don't know which variant you want to set");
+ }
+ }
+
+ /* Here, struct_type is the type of the inner struct,
+ while substruct_type is the type of the inner struct.
+ These are the same for normal structures, but a variant struct
+ contains anonymous union fields that contain substruct fields.
+ The value fieldno is the index of the top-level (normal or
+ anonymous union) field in struct_field, while the value
+ subfieldno is the index of the actual real (named inner) field
+ in substruct_type. */
+
+ field_type = TYPE_FIELD_TYPE (substruct_type, subfieldno);
+ if (val == 0)
+ val = evaluate_subexp (substruct_type, exp, pos, noside);
+
+ /* Now actually set the field in struct_val. */
+
+ /* Assign val to field fieldno. */
+ if (VALUE_TYPE (val) != field_type)
+ val = value_cast (field_type, val);
+
+ bitsize = TYPE_FIELD_BITSIZE (substruct_type, subfieldno);
+ bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
+ if (variantno >= 0)
+ bitpos += TYPE_FIELD_BITPOS (substruct_type, subfieldno);
+ addr = VALUE_CONTENTS (struct_val) + bitpos / 8;
+ if (bitsize)
+ modify_field (addr, value_as_long (val),
+ bitpos % 8, bitsize);
+ else
+ memcpy (addr, VALUE_CONTENTS (val),
+ TYPE_LENGTH (VALUE_TYPE (val)));
+ } while (--nlabels > 0);
+ }
+ return struct_val;
}
value_ptr
@@ -350,11 +440,8 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
&& TYPE_CODE (expect_type) == TYPE_CODE_STRUCT)
{
value_ptr rec = allocate_value (expect_type);
- int fieldno = 0;
memset (VALUE_CONTENTS_RAW (rec), '\0', TYPE_LENGTH (expect_type));
- for (tem = 0; tem < nargs; tem++)
- evaluate_labeled_field_init (rec, &fieldno, exp, pos, noside);
- return rec;
+ return evaluate_struct_tuple (rec, exp, pos, noside, nargs);
}
if (expect_type != NULL_TYPE && noside != EVAL_SKIP