* gdbtypes.h: Add TYPE_FLAG_TARGET_STUB.

* gdbtypes.c (check_stub_type): On TYPE_FLAG_TARGET_STUB, do
	what cleanup_undefined_types does for arrays, except we clear
	TYPE_FLAG_TARGET_STUB if we fix up the type.
	* stabsread.c (cleanup_undefined_types): Add comments about how
	doing arrays here is no longer the clean way to do it.
	(read_array_type): Set TYPE_FLAG_TARGET_STUB as well as calling
	add_undefined_type.
	* c-typeprint.c, ch-typeprint.c: Move call to check_stub_type
	outside switch so it happens for all type codes.
	* cp-valprint.c (cp_print_value_fields): Recurse to val_print,
	instead of c_val_print, so that check_stub_type gets called.

	* gdbtypes.h, gdbtypes.c, m2-lang.c, ch-lang.c, c-lang.c: Remove
	TYPE_FLAG_SIGNED.  It was inconsistently set, never checked
	(except in recursive_dump_type), and is pointless.
This commit is contained in:
Jim Kingdon 1993-11-15 20:13:30 +00:00
parent f130fb33e5
commit dda398c369
10 changed files with 119 additions and 59 deletions

View file

@ -1,3 +1,22 @@
Mon Nov 15 11:38:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
* gdbtypes.h: Add TYPE_FLAG_TARGET_STUB.
* gdbtypes.c (check_stub_type): On TYPE_FLAG_TARGET_STUB, do
what cleanup_undefined_types does for arrays, except we clear
TYPE_FLAG_TARGET_STUB if we fix up the type.
* stabsread.c (cleanup_undefined_types): Add comments about how
doing arrays here is no longer the clean way to do it.
(read_array_type): Set TYPE_FLAG_TARGET_STUB as well as calling
add_undefined_type.
* c-typeprint.c, ch-typeprint.c: Move call to check_stub_type
outside switch so it happens for all type codes.
* cp-valprint.c (cp_print_value_fields): Recurse to val_print,
instead of c_val_print, so that check_stub_type gets called.
* gdbtypes.h, gdbtypes.c, m2-lang.c, ch-lang.c, c-lang.c: Remove
TYPE_FLAG_SIGNED. It was inconsistently set, never checked
(except in recursive_dump_type), and is pointless.
Mon Nov 15 00:40:38 1993 Jeffrey A. Law (law@snake.cs.utah.edu) Mon Nov 15 00:40:38 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
* paread.c (pa_symfile_init): Look for the $TEXT$ section rather * paread.c (pa_symfile_init): Look for the $TEXT$ section rather

View file

@ -243,7 +243,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_CHAR: case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "signed char", objfile); 0, "signed char", objfile);
break; break;
case FT_UNSIGNED_CHAR: case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -258,7 +258,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_SHORT: case FT_SIGNED_SHORT:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "short", objfile); /* FIXME-fnf */ 0, "short", objfile); /* FIXME-fnf */
break; break;
case FT_UNSIGNED_SHORT: case FT_UNSIGNED_SHORT:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -273,7 +273,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_INTEGER: case FT_SIGNED_INTEGER:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT, TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */ 0, "int", objfile); /* FIXME -fnf */
break; break;
case FT_UNSIGNED_INTEGER: case FT_UNSIGNED_INTEGER:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -288,7 +288,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_LONG: case FT_SIGNED_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */ 0, "long", objfile); /* FIXME -fnf */
break; break;
case FT_UNSIGNED_LONG: case FT_UNSIGNED_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -303,7 +303,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_LONG_LONG: case FT_SIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "signed long long", objfile); 0, "signed long long", objfile);
break; break;
case FT_UNSIGNED_LONG_LONG: case FT_UNSIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,

View file

@ -488,6 +488,8 @@ c_type_print_base (type, stream, show, level)
return; return;
} }
check_stub_type (type);
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
@ -529,8 +531,6 @@ c_type_print_base (type, stream, show, level)
} }
else if (show > 0) else if (show > 0)
{ {
check_stub_type (type);
cp_type_print_derivation_info (stream, type); cp_type_print_derivation_info (stream, type);
fprintf_filtered (stream, "{\n"); fprintf_filtered (stream, "{\n");

View file

@ -212,13 +212,13 @@ chill_create_fundamental_type (objfile, typeid)
type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile); type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
break; break;
case FT_SIGNED_CHAR: case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_SIGNED, "BYTE", objfile); type = init_type (TYPE_CODE_INT, 1, 0, "BYTE", objfile);
break; break;
case FT_UNSIGNED_CHAR: case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile); type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
break; break;
case FT_SHORT: /* Chill ints are 2 bytes */ case FT_SHORT: /* Chill ints are 2 bytes */
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_SIGNED, "INT", objfile); type = init_type (TYPE_CODE_INT, 2, 0, "INT", objfile);
break; break;
case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */ case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile); type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
@ -227,7 +227,7 @@ chill_create_fundamental_type (objfile, typeid)
case FT_SIGNED_INTEGER: /* FIXME? */ case FT_SIGNED_INTEGER: /* FIXME? */
case FT_LONG: /* Chill longs are 4 bytes */ case FT_LONG: /* Chill longs are 4 bytes */
case FT_SIGNED_LONG: /* Chill longs are 4 bytes */ case FT_SIGNED_LONG: /* Chill longs are 4 bytes */
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_SIGNED, "LONG", objfile); type = init_type (TYPE_CODE_INT, 4, 0, "LONG", objfile);
break; break;
case FT_UNSIGNED_INTEGER: /* FIXME? */ case FT_UNSIGNED_INTEGER: /* FIXME? */
case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */ case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */

View file

@ -100,6 +100,8 @@ chill_type_print_base (type, stream, show, level)
return; return;
} }
check_stub_type (type);
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {
case TYPE_CODE_PTR: case TYPE_CODE_PTR:
@ -161,7 +163,6 @@ chill_type_print_base (type, stream, show, level)
} }
else else
{ {
check_stub_type (type);
fprintf_filtered (stream, "(\n"); fprintf_filtered (stream, "(\n");
if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
{ {

View file

@ -52,15 +52,6 @@ extern struct obstack dont_print_obstack;
/* END-FIXME */ /* END-FIXME */
/* BEGIN-FIXME: Hooks into c-valprint.c */
extern int
c_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int, int,
enum val_prettyprint));
/* END-FIXME */
void void
cp_print_class_method (valaddr, type, stream) cp_print_class_method (valaddr, type, stream)
char *valaddr; char *valaddr;
@ -305,8 +296,8 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
v = value_from_longest (TYPE_FIELD_TYPE (type, i), v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i)); unpack_field_as_long (type, valaddr, i));
c_val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0, val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
stream, format, 0, recurse + 1, pretty); stream, format, 0, recurse + 1, pretty);
} }
} }
else else
@ -317,9 +308,9 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
} }
else else
{ {
c_val_print (TYPE_FIELD_TYPE (type, i), val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8, valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
0, stream, format, 0, recurse + 1, pretty); 0, stream, format, 0, recurse + 1, pretty);
} }
} }
} }

View file

@ -790,13 +790,14 @@ fill_in_vptr_fieldno (type)
If this is a stubbed struct (i.e. declared as struct foo *), see if If this is a stubbed struct (i.e. declared as struct foo *), see if
we can find a full definition in some other file. If so, copy this we can find a full definition in some other file. If so, copy this
definition, so we can use it in future. If not, set a flag so we definition, so we can use it in future. There used to be a comment (but
don't waste too much time in future. (FIXME, this doesn't seem not any code) that if we don't find a full definition, we'd set a flag
to be happening...) so we don't spend time in the future checking the same type. That would
be a mistake, though--we might load in more symbols which contain a
full definition for the type.
This used to be coded as a macro, but I don't think it is called This used to be coded as a macro, but I don't think it is called
often enough to merit such treatment. often enough to merit such treatment. */
*/
struct complaint stub_noname_complaint = struct complaint stub_noname_complaint =
{"stub type has NULL name", 0, 0}; {"stub type has NULL name", 0, 0};
@ -822,7 +823,31 @@ check_stub_type (type)
(struct symtab **) NULL); (struct symtab **) NULL);
if (sym) if (sym)
{ {
memcpy ((char *)type, (char *)SYMBOL_TYPE(sym), sizeof (struct type)); memcpy ((char *)type,
(char *)SYMBOL_TYPE(sym),
sizeof (struct type));
}
}
if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
{
struct type *range_type;
check_stub_type (TYPE_TARGET_TYPE (type));
if (!(TYPE_FLAGS (TYPE_TARGET_TYPE (type)) & TYPE_FLAG_STUB)
&& TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_NFIELDS (type) == 1
&& (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
== TYPE_CODE_RANGE))
{
/* Now recompute the length of the array type, based on its
number of elements and the target type's length. */
TYPE_LENGTH (type) =
((TYPE_FIELD_BITPOS (range_type, 1)
- TYPE_FIELD_BITPOS (range_type, 0)
+ 1)
* TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
} }
} }
} }
@ -1295,10 +1320,6 @@ recursive_dump_type (type, spaces)
{ {
puts_filtered (" TYPE_FLAG_UNSIGNED"); puts_filtered (" TYPE_FLAG_UNSIGNED");
} }
if (TYPE_FLAGS (type) & TYPE_FLAG_SIGNED)
{
puts_filtered (" TYPE_FLAG_SIGNED");
}
if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
{ {
puts_filtered (" TYPE_FLAG_STUB"); puts_filtered (" TYPE_FLAG_STUB");
@ -1375,7 +1396,7 @@ _initialize_gdbtypes ()
"char", (struct objfile *) NULL); "char", (struct objfile *) NULL);
builtin_type_signed_char = builtin_type_signed_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, 0,
"signed char", (struct objfile *) NULL); "signed char", (struct objfile *) NULL);
builtin_type_unsigned_char = builtin_type_unsigned_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,

View file

@ -21,9 +21,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (GDBTYPES_H) #if !defined (GDBTYPES_H)
#define GDBTYPES_H 1 #define GDBTYPES_H 1
/* When gdb creates fundamental types, it uses one of the following /* Codes for `fundamental types'. This is a monstrosity based on the
type identifiers. The identifiers are used to index a vector of bogus notion that there are certain compiler-independent
pointers to any types that are created. */ `fundamental types'. None of these is well-defined (how big is
FT_SHORT? Does it depend on the language? How does the
language-specific code know which type to correlate to FT_SHORT?) */
#define FT_VOID 0 #define FT_VOID 0
#define FT_BOOLEAN 1 #define FT_BOOLEAN 1
@ -114,20 +116,23 @@ enum type_code
/* Some bits for the type's flags word. */ /* Some bits for the type's flags word. */
/* Explicitly unsigned integer type */ /* Unsigned integer type. If this is not set for a TYPE_CODE_INT, the
type is signed. */
#define TYPE_FLAG_UNSIGNED (1 << 0) #define TYPE_FLAG_UNSIGNED (1 << 0)
/* Explicitly signed integer type */
#define TYPE_FLAG_SIGNED (1 << 1)
/* This appears in a type's flags word if it is a stub type (e.g., if /* This appears in a type's flags word if it is a stub type (e.g., if
someone referenced a type that wasn't defined in a source file someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */ via (struct sir_not_appearing_in_this_film *)). */
#define TYPE_FLAG_STUB (1 << 2) #define TYPE_FLAG_STUB (1 << 2)
/* The target type of this type is a stub type, and this type needs to
be updated if it gets un-stubbed in check_stub_type. Currently only
used for arrays, in which TYPE_LENGTH of the array gets set based
on the TYPE_LENGTH of the target type. */
#define TYPE_FLAG_TARGET_STUB (1 << 3)
struct type struct type
{ {

View file

@ -236,7 +236,7 @@ m2_create_fundamental_type (objfile, typeid)
case FT_SIGNED_CHAR: case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "signed char", objfile); 0, "signed char", objfile);
break; break;
case FT_UNSIGNED_CHAR: case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -251,7 +251,7 @@ m2_create_fundamental_type (objfile, typeid)
case FT_SIGNED_SHORT: case FT_SIGNED_SHORT:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "short", objfile); /* FIXME-fnf */ 0, "short", objfile); /* FIXME-fnf */
break; break;
case FT_UNSIGNED_SHORT: case FT_UNSIGNED_SHORT:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -266,7 +266,7 @@ m2_create_fundamental_type (objfile, typeid)
case FT_SIGNED_INTEGER: case FT_SIGNED_INTEGER:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT, TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */ 0, "int", objfile); /* FIXME -fnf */
break; break;
case FT_UNSIGNED_INTEGER: case FT_UNSIGNED_INTEGER:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -286,7 +286,7 @@ m2_create_fundamental_type (objfile, typeid)
case FT_SIGNED_LONG: case FT_SIGNED_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */ 0, "long", objfile); /* FIXME -fnf */
break; break;
case FT_UNSIGNED_LONG: case FT_UNSIGNED_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
@ -301,7 +301,7 @@ m2_create_fundamental_type (objfile, typeid)
case FT_SIGNED_LONG_LONG: case FT_SIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "signed long long", objfile); 0, "signed long long", objfile);
break; break;
case FT_UNSIGNED_LONG_LONG: case FT_UNSIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT, type = init_type (TYPE_CODE_INT,

View file

@ -1346,13 +1346,12 @@ read_type (pp, objfile)
*pp = from + 1; *pp = from + 1;
} }
/* Now check to see whether the type has already been declared. */ /* Now check to see whether the type has already been
/* This is necessary at least in the case where the declared. This was written for arrays of cross-referenced
program says something like types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty
struct foo bar[5]; sure it is not necessary anymore. But it might be a good
The compiler puts out a cross-reference; we better find idea, to save a little memory. */
set the length of the structure correctly so we can
set the length of the array. */
for (ppt = file_symbols; ppt; ppt = ppt->next) for (ppt = file_symbols; ppt; ppt = ppt->next)
for (i = 0; i < ppt->nsyms; i++) for (i = 0; i < ppt->nsyms; i++)
{ {
@ -2827,9 +2826,14 @@ read_array_type (pp, type, objfile)
/* If we have an array whose element type is not yet known, but whose /* If we have an array whose element type is not yet known, but whose
bounds *are* known, record it to be adjusted at the end of the file. */ bounds *are* known, record it to be adjusted at the end of the file. */
/* FIXME: Why check for zero length rather than TYPE_FLAG_STUB? I think
the two have the same effect except that the latter is cleaner and the
former would be wrong for types which really are zero-length (if we
have any). */
if (TYPE_LENGTH (element_type) == 0 && !adjustable) if (TYPE_LENGTH (element_type) == 0 && !adjustable)
{ {
TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
add_undefined_type (type); add_undefined_type (type);
} }
@ -3527,7 +3531,10 @@ cleanup_undefined_types ()
case TYPE_CODE_UNION: case TYPE_CODE_UNION:
case TYPE_CODE_ENUM: case TYPE_CODE_ENUM:
{ {
/* Check if it has been defined since. */ /* Check if it has been defined since. Need to do this here
as well as in check_stub_type to deal with the (legitimate in
C though not C++) case of several types with the same name
in different source files. */
if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB) if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB)
{ {
struct pending *ppt; struct pending *ppt;
@ -3562,8 +3569,20 @@ cleanup_undefined_types ()
} }
break; break;
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
{ {
/* This is a kludge which is here for historical reasons
because I suspect that check_stub_type does not get
called everywhere it needs to be called for arrays. Even
with this kludge, those places are broken for the case
where the stub type is defined in another compilation
unit, but this kludge at least deals with it for the case
in which it is the same compilation unit.
Don't try to do this by calling check_stub_type; it might
cause symbols to be read in lookup_symbol, and the symbol
reader is not reentrant. */
struct type *range_type; struct type *range_type;
int lower, upper; int lower, upper;
@ -3581,6 +3600,9 @@ cleanup_undefined_types ()
upper = TYPE_FIELD_BITPOS (range_type, 1); upper = TYPE_FIELD_BITPOS (range_type, 1);
TYPE_LENGTH (*type) = (upper - lower + 1) TYPE_LENGTH (*type) = (upper - lower + 1)
* TYPE_LENGTH (TYPE_TARGET_TYPE (*type)); * TYPE_LENGTH (TYPE_TARGET_TYPE (*type));
/* If the target type is not a stub, we could be clearing
TYPE_FLAG_TARGET_STUB for *type. */
} }
break; break;
@ -3594,6 +3616,7 @@ GDB internal error. cleanup_undefined_types with bad type %d.", 0, 0};
break; break;
} }
} }
undef_types_length = 0; undef_types_length = 0;
} }