diff options
author | Daniel Jacobowitz <drow@false.org> | 2002-05-14 18:30:53 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2002-05-14 18:30:53 +0000 |
commit | 2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a (patch) | |
tree | 903dab80e68aebe7f27ef803ce4da2bc9632eaed /gdb/gdbtypes.c | |
parent | e31f1a7cdb547636f561a24f6c2288228c3cf3a0 (diff) | |
download | gdb-2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a.zip gdb-2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a.tar.gz gdb-2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a.tar.bz2 |
2002-05-14 Daniel Jacobowitz <drow@mvista.com>
* gdbtypes.h: Update accessor macros to use TYPE_MAIN_TYPE.
(TYPE_CONST, TYPE_VOLATILE, TYPE_CODE_SPACE, TYPE_DATA_SPACE): Use
TYPE_INSTANCE_FLAGS.
(struct main_type): New.
(struct type): Move most members to struct main_type. Change
cv_type and as_type to new type_chain member. Add instance_flags.
(TYPE_MAIN_TYPE, TYPE_CHAIN, TYPE_INSTANCE_FLAGS): New macros.
(TYPE_CV_TYPE, TYPE_AS_TYPE): Remove.
(finish_cv_type): Remove prototype.
* gdbtypes.c (alloc_type): Update comment. Allocate TYPE_MAIN_TYPE.
Set TYPE_CHAIN.
(alloc_type_instance): New function.
(smash_type): New function.
(make_pointer_type, make_reference_type, make_function_type)
(smash_to_member_type, smash_to_method_type): Call smash_type.
(make_qualified_type): New function.
(make_type_with_address_space): Call make_qualified_type.
(make_cv_type): Likewise.
(finish_cv_type): Remove unnecessary function.
(replace_type): Update comment. Copy TYPE_MAIN_TYPE.
(recursive_dump_type): Dump TYPE_CHAIN and TYPE_INSTANCE_FLAGS;
remove TYPE_CV_TYPE and TYPE_AS_TYPE.
* c-typeprint.c (c_type_print_modifier): Use TYPE_INSTANCE_FLAGS.
* dwarf2read.c (read_structure_scope): Don't call finish_cv_type.
* hpread.c (hpread_read_struct_type): Likewise.
* stabsread.c (read_struct_type): Likewise.
2002-05-14 Daniel Jacobowitz <drow@mvista.com>
* gdb.base/maint.exp (maint print type): Update for new type
structure.
Diffstat (limited to 'gdb/gdbtypes.c')
-rw-r--r-- | gdb/gdbtypes.c | 318 |
1 files changed, 150 insertions, 168 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index fff720d..e8ba96d 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -135,7 +135,8 @@ static void virtual_base_list_aux (struct type *dclass); /* Alloc a new type structure and fill it with some defaults. If OBJFILE is non-NULL, then allocate the space for the type structure - in that objfile's type_obstack. */ + in that objfile's type_obstack. Otherwise allocate the new type structure + by xmalloc () (for permanent types). */ struct type * alloc_type (struct objfile *objfile) @@ -146,27 +147,73 @@ alloc_type (struct objfile *objfile) if (objfile == NULL) { - type = (struct type *) xmalloc (sizeof (struct type)); + type = xmalloc (sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + TYPE_MAIN_TYPE (type) = xmalloc (sizeof (struct main_type)); } else { - type = (struct type *) obstack_alloc (&objfile->type_obstack, - sizeof (struct type)); + type = obstack_alloc (&objfile->type_obstack, + sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + TYPE_MAIN_TYPE (type) = obstack_alloc (&objfile->type_obstack, + sizeof (struct main_type)); OBJSTAT (objfile, n_types++); } - memset ((char *) type, 0, sizeof (struct type)); + memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type)); /* Initialize the fields that might not be zero. */ TYPE_CODE (type) = TYPE_CODE_UNDEF; TYPE_OBJFILE (type) = objfile; TYPE_VPTR_FIELDNO (type) = -1; - TYPE_CV_TYPE (type) = type; /* chain back to itself */ - TYPE_AS_TYPE (type) = type; /* ditto */ + TYPE_CHAIN (type) = type; /* Chain back to itself. */ return (type); } +/* Alloc a new type instance structure, fill it with some defaults, + and point it at OLDTYPE. Allocate the new type instance from the + same place as OLDTYPE. */ + +static struct type * +alloc_type_instance (struct type *oldtype) +{ + struct type *type; + + /* Allocate the structure. */ + + if (TYPE_OBJFILE (oldtype) == NULL) + { + type = xmalloc (sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + } + else + { + type = obstack_alloc (&TYPE_OBJFILE (oldtype)->type_obstack, + sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + } + TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype); + + TYPE_CHAIN (type) = type; /* Chain back to itself for now. */ + + return (type); +} + +/* Clear all remnants of the previous type at TYPE, in preparation for + replacing it with something else. */ +static void +smash_type (struct type *type) +{ + memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type)); + + /* For now, delete the rings. */ + TYPE_CHAIN (type) = type; + + /* For now, leave the pointer/reference types alone. */ +} + /* Lookup a pointer to a type TYPE. TYPEPTR, if nonzero, points to a pointer to memory where the pointer type should be stored. If *TYPEPTR is zero, update it to point to the pointer type we return. @@ -202,7 +249,7 @@ make_pointer_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -269,7 +316,7 @@ make_reference_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -318,7 +365,7 @@ make_function_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -368,45 +415,63 @@ address_space_int_to_name (int space_flag) return NULL; } -/* Make an address-space-delimited variant of a type -- a type that - is identical to the one supplied except that it has an address - space attribute attached to it (such as "code" or "data"). - - This is for Harvard architectures. */ +/* Create a new type with instance flags NEW_FLAGS, based on TYPE. + If STORAGE is non-NULL, create the new type instance there. */ struct type * -make_type_with_address_space (struct type *type, int space_flag) +make_qualified_type (struct type *type, int new_flags, + struct type *storage) { struct type *ntype; ntype = type; do { - if ((ntype->flags & space_flag) != 0) + if (TYPE_INSTANCE_FLAGS (ntype) == new_flags) return ntype; - ntype = TYPE_AS_TYPE (ntype); + ntype = TYPE_CHAIN (ntype); } while (ntype != type); - /* Create a new, duplicate type. */ - ntype = alloc_type (TYPE_OBJFILE (type)); - /* Copy original type. */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); + /* Create a new type instance. */ + if (storage == NULL) + ntype = alloc_type_instance (type); + else + { + ntype = storage; + TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type); + TYPE_CHAIN (ntype) = ntype; + } /* Pointers or references to the original type are not relevant to - the new type; but if the original type is a pointer, the new type - points to the same thing (so TYPE_TARGET_TYPE remains unchanged). */ + the new type. */ TYPE_POINTER_TYPE (ntype) = (struct type *) 0; TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; - TYPE_CV_TYPE (ntype) = ntype; - /* Chain the new address-space-specific type to the old type. */ - ntype->as_type = type->as_type; - type->as_type = ntype; + /* Chain the new qualified type to the old type. */ + TYPE_CHAIN (ntype) = TYPE_CHAIN (type); + TYPE_CHAIN (type) = ntype; + + /* Now set the instance flags and return the new type. */ + TYPE_INSTANCE_FLAGS (ntype) = new_flags; - /* Now set the address-space flag, and return the new type. */ - ntype->flags |= space_flag; return ntype; } +/* Make an address-space-delimited variant of a type -- a type that + is identical to the one supplied except that it has an address + space attribute attached to it (such as "code" or "data"). + + This is for Harvard architectures. */ + +struct type * +make_type_with_address_space (struct type *type, int space_flag) +{ + struct type *ntype; + int new_flags = ((TYPE_INSTANCE_FLAGS (type) + & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE)) + | space_flag); + + return make_qualified_type (type, new_flags, NULL); +} /* Make a "c-v" variant of a type -- a type that is identical to the one supplied except that it may have const or volatile attributes @@ -425,142 +490,60 @@ make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr) register struct type *tmp_type = type; /* tmp type */ struct objfile *objfile; - ntype = TYPE_CV_TYPE (type); - - while (ntype != type) - { - if ((TYPE_CONST (ntype) == cnst) && - (TYPE_VOLATILE (ntype) == voltl)) - { - if (typeptr == 0) - return ntype; - else if (*typeptr == 0) - { - *typeptr = ntype; /* Tracking alloc, and we have new type. */ - return ntype; - } - } - tmp_type = ntype; - ntype = TYPE_CV_TYPE (ntype); - } - - if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ - { - ntype = alloc_type (TYPE_OBJFILE (type)); - if (typeptr) - *typeptr = ntype; - } - else - /* We have storage, but need to reset it. */ - { - ntype = *typeptr; - objfile = TYPE_OBJFILE (ntype); - /* memset ((char *) ntype, 0, sizeof (struct type)); */ - TYPE_OBJFILE (ntype) = objfile; - } - - /* Copy original type */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); - /* But zero out fields that shouldn't be copied */ - TYPE_POINTER_TYPE (ntype) = (struct type *) 0; /* Need new pointer kind */ - TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; /* Need new referene kind */ - TYPE_AS_TYPE (ntype) = ntype; /* Need new address-space kind. */ - /* Note: TYPE_TARGET_TYPE can be left as is */ + int new_flags = (TYPE_INSTANCE_FLAGS (type) + & ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE)); - /* Set flags appropriately */ if (cnst) - TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST; - else - TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST; + new_flags |= TYPE_FLAG_CONST; if (voltl) - TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE; - else - TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE; - - /* Fix the chain of cv variants */ - TYPE_CV_TYPE (ntype) = type; - TYPE_CV_TYPE (tmp_type) = ntype; - - return ntype; -} - -/* When reading in a class type, we may have created references to - cv-qualified versions of the type (in method arguments, for - instance). Update everything on the cv ring from the primary - type TYPE. - - The only reason we do not need to do the same thing for address - spaces is that type readers do not create address space qualified - types. */ -void -finish_cv_type (struct type *type) -{ - struct type *ntype, *cv_type, *ptr_type, *ref_type; - int cv_flags; + new_flags |= TYPE_FLAG_VOLATILE; - gdb_assert (!TYPE_CONST (type) && !TYPE_VOLATILE (type)); - - ntype = type; - while ((ntype = TYPE_CV_TYPE (ntype)) != type) + if (typeptr && *typeptr != NULL) { - /* Save cv_flags. */ - cv_flags = TYPE_FLAGS (ntype) & (TYPE_FLAG_VOLATILE | TYPE_FLAG_CONST); + /* Objfile is per-core-type. This const-qualified type had best + belong to the same objfile as the type it is qualifying, unless + we are overwriting a stub type, in which case the safest thing + to do is to copy the core type into the new objfile. */ - /* If any reference or pointer types were created, save them too. */ - ptr_type = TYPE_POINTER_TYPE (ntype); - ref_type = TYPE_REFERENCE_TYPE (ntype); - - /* Don't disturb the CV chain. */ - cv_type = TYPE_CV_TYPE (ntype); - - /* Verify that we haven't added any address-space qualified types, - for the future. */ - gdb_assert (ntype == TYPE_AS_TYPE (ntype)); - - /* Copy original type */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); + gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type) + || TYPE_STUB (*typeptr)); + if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type)) + { + TYPE_MAIN_TYPE (*typeptr) + = TYPE_ALLOC (*typeptr, sizeof (struct main_type)); + *TYPE_MAIN_TYPE (*typeptr) + = *TYPE_MAIN_TYPE (type); + } + } + + ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL); - /* Restore everything. */ - TYPE_POINTER_TYPE (ntype) = ptr_type; - TYPE_REFERENCE_TYPE (ntype) = ref_type; - TYPE_CV_TYPE (ntype) = cv_type; - TYPE_FLAGS (ntype) = TYPE_FLAGS (ntype) | cv_flags; + if (typeptr != NULL) + *typeptr = ntype; - TYPE_AS_TYPE (ntype) = ntype; - } + return ntype; } -/* Replace the contents of ntype with the type *type. +/* Replace the contents of ntype with the type *type. This changes the + contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus + the changes are propogated to all types in the TYPE_CHAIN. In order to build recursive types, it's inevitable that we'll need to update types in place --- but this sort of indiscriminate smashing is ugly, and needs to be replaced with something more - controlled. For example, Daniel Jacobowitz has suggested moving - the fields common to a set of c/v variants into their own object, - which the variants would share. - - This function does not handle the replacement type being - cv-qualified; it could be easily fixed to, but it would be better - to just change the whole approach. */ + controlled. TYPE_MAIN_TYPE is a step in this direction; it's not + clear if more steps are needed. */ void replace_type (struct type *ntype, struct type *type) { struct type *cv_chain, *as_chain, *ptr, *ref; - cv_chain = TYPE_CV_TYPE (ntype); - as_chain = TYPE_AS_TYPE (ntype); - ptr = TYPE_POINTER_TYPE (ntype); - ref = TYPE_REFERENCE_TYPE (ntype); - - *ntype = *type; - - TYPE_POINTER_TYPE (ntype) = ptr; - TYPE_REFERENCE_TYPE (ntype) = ref; - TYPE_CV_TYPE (ntype) = cv_chain; - TYPE_AS_TYPE (ntype) = as_chain; + *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type); - finish_cv_type (ntype); + /* Assert that the two types have equivalent instance qualifiers. + This should be true for at least all of our debug readers. */ + gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type)); } /* Implement direct support for MEMBER_TYPE in GNU C++. @@ -879,7 +862,7 @@ smash_to_member_type (struct type *type, struct type *domain, objfile = TYPE_OBJFILE (type); - memset ((char *) type, 0, sizeof (struct type)); + smash_type (type); TYPE_OBJFILE (type) = objfile; TYPE_TARGET_TYPE (type) = to_type; TYPE_DOMAIN_TYPE (type) = domain; @@ -902,7 +885,7 @@ smash_to_method_type (struct type *type, struct type *domain, objfile = TYPE_OBJFILE (type); - memset ((char *) type, 0, sizeof (struct type)); + smash_type (type); TYPE_OBJFILE (type) = objfile; TYPE_TARGET_TYPE (type) = to_type; TYPE_DOMAIN_TYPE (type) = domain; @@ -3011,12 +2994,27 @@ recursive_dump_type (struct type *type, int spaces) printfi_filtered (spaces, "reference_type "); gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout); printf_filtered ("\n"); - printfi_filtered (spaces, "cv_type "); - gdb_print_host_address (TYPE_CV_TYPE (type), gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "as_type "); - gdb_print_host_address (TYPE_AS_TYPE (type), gdb_stdout); + printfi_filtered (spaces, "type_chain "); + gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout); printf_filtered ("\n"); + printfi_filtered (spaces, "instance_flags 0x%x", TYPE_INSTANCE_FLAGS (type)); + if (TYPE_CONST (type)) + { + puts_filtered (" TYPE_FLAG_CONST"); + } + if (TYPE_VOLATILE (type)) + { + puts_filtered (" TYPE_FLAG_VOLATILE"); + } + if (TYPE_CODE_SPACE (type)) + { + puts_filtered (" TYPE_FLAG_CODE_SPACE"); + } + if (TYPE_DATA_SPACE (type)) + { + puts_filtered (" TYPE_FLAG_DATA_SPACE"); + } + puts_filtered ("\n"); printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type)); if (TYPE_UNSIGNED (type)) { @@ -3038,14 +3036,6 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_FLAG_STATIC"); } - if (TYPE_CONST (type)) - { - puts_filtered (" TYPE_FLAG_CONST"); - } - if (TYPE_VOLATILE (type)) - { - puts_filtered (" TYPE_FLAG_VOLATILE"); - } if (TYPE_PROTOTYPED (type)) { puts_filtered (" TYPE_FLAG_PROTOTYPED"); @@ -3054,14 +3044,6 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_FLAG_INCOMPLETE"); } - if (TYPE_CODE_SPACE (type)) - { - puts_filtered (" TYPE_FLAG_CODE_SPACE"); - } - if (TYPE_DATA_SPACE (type)) - { - puts_filtered (" TYPE_FLAG_DATA_SPACE"); - } if (TYPE_VARARGS (type)) { puts_filtered (" TYPE_FLAG_VARARGS"); |