projects
/
cparser
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Move (void) parameter detection into a separate function, simplify daisy chaining...
[cparser]
/
type.c
diff --git
a/type.c
b/type.c
index
6640145
..
5967262
100644
(file)
--- a/
type.c
+++ b/
type.c
@@
-27,6
+27,7
@@
#include "symbol_t.h"
#include "type_hash.h"
#include "adt/error.h"
#include "symbol_t.h"
#include "type_hash.h"
#include "adt/error.h"
+#include "adt/util.h"
#include "lang_features.h"
static struct obstack _type_obst;
#include "lang_features.h"
static struct obstack _type_obst;
@@
-35,8
+36,8
@@
struct obstack *type_obst = &_type_obst;
static int type_visited = 0;
static bool print_implicit_array_size = false;
static int type_visited = 0;
static bool print_implicit_array_size = false;
-static void intern_print_type_pre(const type_t *type
, bool top
);
-static void intern_print_type_post(const type_t *type
, bool top
);
+static void intern_print_type_pre(const type_t *type);
+static void intern_print_type_post(const type_t *type);
typedef struct atomic_type_properties_t atomic_type_properties_t;
struct atomic_type_properties_t {
typedef struct atomic_type_properties_t atomic_type_properties_t;
struct atomic_type_properties_t {
@@
-52,6
+53,12
@@
static atomic_type_properties_t atomic_type_properties[ATOMIC_TYPE_LAST+1] = {
.alignment = 0,
.flags = ATOMIC_TYPE_FLAG_NONE
},
.alignment = 0,
.flags = ATOMIC_TYPE_FLAG_NONE
},
+ [ATOMIC_TYPE_WCHAR_T] = {
+ .size = (unsigned)-1,
+ .alignment = (unsigned)-1,
+ /* signed flag will be set when known */
+ .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+ },
[ATOMIC_TYPE_CHAR] = {
.size = 1,
.alignment = 1,
[ATOMIC_TYPE_CHAR] = {
.size = 1,
.alignment = 1,
@@
-177,6
+184,8
@@
void init_types(void)
/* TODO: make this configurable for platforms which do not use byte sized
* bools. */
props[ATOMIC_TYPE_BOOL] = props[ATOMIC_TYPE_UCHAR];
/* TODO: make this configurable for platforms which do not use byte sized
* bools. */
props[ATOMIC_TYPE_BOOL] = props[ATOMIC_TYPE_UCHAR];
+
+ props[ATOMIC_TYPE_WCHAR_T] = props[wchar_atomic_kind];
}
void exit_types(void)
}
void exit_types(void)
@@
-216,6
+225,7
@@
const char *get_atomic_kind_name(atomic_type_kind_t kind)
switch(kind) {
case ATOMIC_TYPE_INVALID: break;
case ATOMIC_TYPE_VOID: return "void";
switch(kind) {
case ATOMIC_TYPE_INVALID: break;
case ATOMIC_TYPE_VOID: return "void";
+ case ATOMIC_TYPE_WCHAR_T: return "wchar_t";
case ATOMIC_TYPE_BOOL: return c_mode & _CXX ? "bool" : "_Bool";
case ATOMIC_TYPE_CHAR: return "char";
case ATOMIC_TYPE_SCHAR: return "signed char";
case ATOMIC_TYPE_BOOL: return c_mode & _CXX ? "bool" : "_Bool";
case ATOMIC_TYPE_CHAR: return "char";
case ATOMIC_TYPE_SCHAR: return "signed char";
@@
-291,9
+301,8
@@
void print_imaginary_type(const imaginary_type_t *type)
* Print the first part (the prefix) of a type.
*
* @param type The type to print.
* Print the first part (the prefix) of a type.
*
* @param type The type to print.
- * @param top true, if this is the top type, false if it's an embedded type.
*/
*/
-static void print_function_type_pre(const function_type_t *type
, bool top
)
+static void print_function_type_pre(const function_type_t *type)
{
switch (type->linkage) {
case LINKAGE_INVALID:
{
switch (type->linkage) {
case LINKAGE_INVALID:
@@
-314,7
+323,7
@@
static void print_function_type_pre(const function_type_t *type, bool top)
if (type->base.qualifiers != 0)
fputc(' ', out);
if (type->base.qualifiers != 0)
fputc(' ', out);
- intern_print_type_pre(type->return_type
, false
);
+ intern_print_type_pre(type->return_type);
switch (type->calling_convention) {
case CC_CDECL: fputs("__cdecl ", out); break;
switch (type->calling_convention) {
case CC_CDECL: fputs("__cdecl ", out); break;
@@
-323,25
+332,16
@@
static void print_function_type_pre(const function_type_t *type, bool top)
case CC_THISCALL: fputs("__thiscall ", out); break;
case CC_DEFAULT: break;
}
case CC_THISCALL: fputs("__thiscall ", out); break;
case CC_DEFAULT: break;
}
-
- /* don't emit parenthesis if we're the toplevel type... */
- if (!top)
- fputc('(', out);
}
/**
* Print the second part (the postfix) of a type.
*
* @param type The type to print.
}
/**
* Print the second part (the postfix) of a type.
*
* @param type The type to print.
- * @param top true, if this is the top type, false if it's an embedded type.
*/
static void print_function_type_post(const function_type_t *type,
*/
static void print_function_type_post(const function_type_t *type,
- const scope_t *parameters
, bool top
)
+ const scope_t *parameters)
{
{
- /* don't emit parenthesis if we're the toplevel type... */
- if (!top)
- fputc(')', out);
-
fputc('(', out);
bool first = true;
if (parameters == NULL) {
fputc('(', out);
bool first = true;
if (parameters == NULL) {
@@
-356,15
+356,21
@@
static void print_function_type_post(const function_type_t *type,
}
} else {
entity_t *parameter = parameters->entities;
}
} else {
entity_t *parameter = parameters->entities;
- for( ; parameter != NULL; parameter = parameter->base.next) {
+ for (; parameter != NULL; parameter = parameter->base.next) {
+ if (parameter->kind != ENTITY_PARAMETER)
+ continue;
+
if (first) {
first = false;
} else {
fputs(", ", out);
}
if (first) {
first = false;
} else {
fputs(", ", out);
}
- assert(is_declaration(parameter));
- print_type_ext(parameter->declaration.type, parameter->base.symbol,
- NULL);
+ const type_t *const type = parameter->declaration.type;
+ if (type == NULL) {
+ fputs(parameter->base.symbol->string, out);
+ } else {
+ print_type_ext(type, parameter->base.symbol, NULL);
+ }
}
}
if (type->variadic) {
}
}
if (type->variadic) {
@@
-380,7
+386,7
@@
static void print_function_type_post(const function_type_t *type,
}
fputc(')', out);
}
fputc(')', out);
- intern_print_type_post(type->return_type
, false
);
+ intern_print_type_post(type->return_type);
}
/**
}
/**
@@
-390,38
+396,48
@@
static void print_function_type_post(const function_type_t *type,
*/
static void print_pointer_type_pre(const pointer_type_t *type)
{
*/
static void print_pointer_type_pre(const pointer_type_t *type)
{
- intern_print_type_pre(type->points_to, false);
+ type_t const *const points_to = type->points_to;
+ intern_print_type_pre(points_to);
+ if (points_to->kind == TYPE_ARRAY || points_to->kind == TYPE_FUNCTION)
+ fputs(" (", out);
variable_t *const variable = type->base_variable;
if (variable != NULL) {
fputs(" __based(", out);
fputs(variable->base.base.symbol->string, out);
fputs(") ", out);
}
variable_t *const variable = type->base_variable;
if (variable != NULL) {
fputs(" __based(", out);
fputs(variable->base.base.symbol->string, out);
fputs(") ", out);
}
- fput
s("*"
, out);
-
print_type_qualifiers(type->base.qualifiers)
;
- if (
type->base.qualifiers
!= 0)
+ fput
c('*'
, out);
+
type_qualifiers_t const qual = type->base.qualifiers
;
+ if (
qual
!= 0)
fputc(' ', out);
fputc(' ', out);
+ print_type_qualifiers(qual);
}
/**
}
/**
- * Prints the p
refix part of a reference
type.
+ * Prints the p
ostfix part of a pointer
type.
*
*
- * @param type The
reference
type.
+ * @param type The
pointer
type.
*/
*/
-static void print_
reference_type_pre(const reference
_type_t *type)
+static void print_
pointer_type_post(const pointer
_type_t *type)
{
{
- intern_print_type_pre(type->refers_to, false);
- fputc('&', out);
+ type_t const *const points_to = type->points_to;
+ if (points_to->kind == TYPE_ARRAY || points_to->kind == TYPE_FUNCTION)
+ fputc(')', out);
+ intern_print_type_post(points_to);
}
/**
}
/**
- * Prints the p
ostfix part of a pointer
type.
+ * Prints the p
refix part of a reference
type.
*
*
- * @param type The
pointer
type.
+ * @param type The
reference
type.
*/
*/
-static void print_
pointer_type_post(const pointer
_type_t *type)
+static void print_
reference_type_pre(const reference
_type_t *type)
{
{
- intern_print_type_post(type->points_to, false);
+ type_t const *const refers_to = type->refers_to;
+ intern_print_type_pre(refers_to);
+ if (refers_to->kind == TYPE_ARRAY || refers_to->kind == TYPE_FUNCTION)
+ fputs(" (", out);
+ fputc('&', out);
}
/**
}
/**
@@
-431,7
+447,10
@@
static void print_pointer_type_post(const pointer_type_t *type)
*/
static void print_reference_type_post(const reference_type_t *type)
{
*/
static void print_reference_type_post(const reference_type_t *type)
{
- intern_print_type_post(type->refers_to, false);
+ type_t const *const refers_to = type->refers_to;
+ if (refers_to->kind == TYPE_ARRAY || refers_to->kind == TYPE_FUNCTION)
+ fputc(')', out);
+ intern_print_type_post(refers_to);
}
/**
}
/**
@@
-441,7
+460,7
@@
static void print_reference_type_post(const reference_type_t *type)
*/
static void print_array_type_pre(const array_type_t *type)
{
*/
static void print_array_type_pre(const array_type_t *type)
{
- intern_print_type_pre(type->element_type
, false
);
+ intern_print_type_pre(type->element_type);
}
/**
}
/**
@@
-463,7
+482,7
@@
static void print_array_type_post(const array_type_t *type)
print_expression(type->size_expression);
}
fputc(']', out);
print_expression(type->size_expression);
}
fputc(']', out);
- intern_print_type_post(type->element_type
, false
);
+ intern_print_type_post(type->element_type);
}
/**
}
/**
@@
-475,7
+494,7
@@
static void print_bitfield_type_post(const bitfield_type_t *type)
{
fputs(" : ", out);
print_expression(type->size_expression);
{
fputs(" : ", out);
print_expression(type->size_expression);
- intern_print_type_post(type->base_type
, false
);
+ intern_print_type_post(type->base_type);
}
/**
}
/**
@@
-494,9
+513,9
@@
void print_enum_definition(const enum_t *enume)
entry = entry->base.next) {
print_indent();
entry = entry->base.next) {
print_indent();
- fp
rintf(out, "%s", entry->base.symbol->string
);
+ fp
uts(entry->base.symbol->string, out
);
if (entry->enum_value.value != NULL) {
if (entry->enum_value.value != NULL) {
- fp
rintf(out, " = "
);
+ fp
uts(" = ", out
);
/* skip the implicit cast */
expression_t *expression = entry->enum_value.value;
/* skip the implicit cast */
expression_t *expression = entry->enum_value.value;
@@
-505,12
+524,12
@@
void print_enum_definition(const enum_t *enume)
}
print_expression(expression);
}
}
print_expression(expression);
}
- fp
rintf(out, ",\n"
);
+ fp
uts(",\n", out
);
}
change_indent(-1);
print_indent();
}
change_indent(-1);
print_indent();
- fput
s("}"
, out);
+ fput
c('}'
, out);
}
/**
}
/**
@@
-553,7
+572,7
@@
void print_compound_definition(const compound_t *compound)
change_indent(-1);
print_indent();
change_indent(-1);
print_indent();
- fput
s("}"
, out);
+ fput
c('}'
, out);
if (compound->modifiers & DM_TRANSPARENT_UNION) {
fputs("__attribute__((__transparent_union__))", out);
}
if (compound->modifiers & DM_TRANSPARENT_UNION) {
fputs("__attribute__((__transparent_union__))", out);
}
@@
-607,7
+626,6
@@
static void print_typeof_type_pre(const typeof_type_t *const type)
{
fputs("typeof(", out);
if (type->expression != NULL) {
{
fputs("typeof(", out);
if (type->expression != NULL) {
- assert(type->typeof_type == NULL);
print_expression(type->expression);
} else {
print_type(type->typeof_type);
print_expression(type->expression);
} else {
print_type(type->typeof_type);
@@
-619,9
+637,8
@@
static void print_typeof_type_pre(const typeof_type_t *const type)
* Prints the prefix part of a type.
*
* @param type The type.
* Prints the prefix part of a type.
*
* @param type The type.
- * @param top true if we print the toplevel type, false else.
*/
*/
-static void intern_print_type_pre(const type_t *const type
, const bool top
)
+static void intern_print_type_pre(const type_t *const type)
{
switch(type->kind) {
case TYPE_ERROR:
{
switch(type->kind) {
case TYPE_ERROR:
@@
-650,7
+667,7
@@
static void intern_print_type_pre(const type_t *const type, const bool top)
fputs(type->builtin.symbol->string, out);
return;
case TYPE_FUNCTION:
fputs(type->builtin.symbol->string, out);
return;
case TYPE_FUNCTION:
- print_function_type_pre(&type->function
, top
);
+ print_function_type_pre(&type->function);
return;
case TYPE_POINTER:
print_pointer_type_pre(&type->pointer);
return;
case TYPE_POINTER:
print_pointer_type_pre(&type->pointer);
@@
-659,7
+676,7
@@
static void intern_print_type_pre(const type_t *const type, const bool top)
print_reference_type_pre(&type->reference);
return;
case TYPE_BITFIELD:
print_reference_type_pre(&type->reference);
return;
case TYPE_BITFIELD:
- intern_print_type_pre(type->bitfield.base_type
, top
);
+ intern_print_type_pre(type->bitfield.base_type);
return;
case TYPE_ARRAY:
print_array_type_pre(&type->array);
return;
case TYPE_ARRAY:
print_array_type_pre(&type->array);
@@
-678,13
+695,12
@@
static void intern_print_type_pre(const type_t *const type, const bool top)
* Prints the postfix part of a type.
*
* @param type The type.
* Prints the postfix part of a type.
*
* @param type The type.
- * @param top true if we print the toplevel type, false else.
*/
*/
-static void intern_print_type_post(const type_t *const type
, const bool top
)
+static void intern_print_type_post(const type_t *const type)
{
switch(type->kind) {
case TYPE_FUNCTION:
{
switch(type->kind) {
case TYPE_FUNCTION:
- print_function_type_post(&type->function, NULL
, top
);
+ print_function_type_post(&type->function, NULL);
return;
case TYPE_POINTER:
print_pointer_type_post(&type->pointer);
return;
case TYPE_POINTER:
print_pointer_type_post(&type->pointer);
@@
-735,15
+751,15
@@
void print_type_ext(const type_t *const type, const symbol_t *symbol,
return;
}
return;
}
- intern_print_type_pre(type
, true
);
+ intern_print_type_pre(type);
if (symbol != NULL) {
fputc(' ', out);
fputs(symbol->string, out);
}
if (type->kind == TYPE_FUNCTION) {
if (symbol != NULL) {
fputc(' ', out);
fputs(symbol->string, out);
}
if (type->kind == TYPE_FUNCTION) {
- print_function_type_post(&type->function, parameters
, true
);
+ print_function_type_post(&type->function, parameters);
} else {
} else {
- intern_print_type_post(type
, true
);
+ intern_print_type_post(type);
}
}
}
}
@@
-789,6
+805,7
@@
type_t *duplicate_type(const type_t *type)
type_t *copy = obstack_alloc(type_obst, size);
memcpy(copy, type, size);
type_t *copy = obstack_alloc(type_obst, size);
memcpy(copy, type, size);
+ copy->base.firm_type = NULL;
return copy;
}
return copy;
}
@@
-809,12
+826,7
@@
type_t *get_unqualified_type(type_t *type)
type_t *unqualified_type = duplicate_type(type);
unqualified_type->base.qualifiers = TYPE_QUALIFIER_NONE;
type_t *unqualified_type = duplicate_type(type);
unqualified_type->base.qualifiers = TYPE_QUALIFIER_NONE;
- type_t *result = typehash_insert(unqualified_type);
- if (result != unqualified_type) {
- obstack_free(type_obst, unqualified_type);
- }
-
- return result;
+ return identify_new_type(unqualified_type);
}
type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual)
}
type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual)
@@
-842,11
+854,7
@@
type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual)
return type;
}
return type;
}
- type = typehash_insert(copy);
- if (type != copy)
- obstack_free(type_obst, copy);
-
- return type;
+ return identify_new_type(copy);
}
/**
}
/**
@@
-1206,14
+1214,19
@@
type_t *skip_typeref(type_t *type)
{
type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
type_modifiers_t modifiers = TYPE_MODIFIER_NONE;
{
type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
type_modifiers_t modifiers = TYPE_MODIFIER_NONE;
+ il_alignment_t alignment = 0;
while (true) {
while (true) {
+ if (alignment < type->base.alignment)
+ alignment = type->base.alignment;
+
switch (type->kind) {
case TYPE_ERROR:
return type;
case TYPE_TYPEDEF: {
qualifiers |= type->base.qualifiers;
modifiers |= type->base.modifiers;
switch (type->kind) {
case TYPE_ERROR:
return type;
case TYPE_TYPEDEF: {
qualifiers |= type->base.qualifiers;
modifiers |= type->base.modifiers;
+
const typedef_type_t *typedef_type = &type->typedeft;
if (typedef_type->resolved_type != NULL) {
type = typedef_type->resolved_type;
const typedef_type_t *typedef_type = &type->typedeft;
if (typedef_type->resolved_type != NULL) {
type = typedef_type->resolved_type;
@@
-1222,22
+1235,20
@@
type_t *skip_typeref(type_t *type)
type = typedef_type->typedefe->type;
continue;
}
type = typedef_type->typedefe->type;
continue;
}
- case TYPE_TYPEOF: {
- const typeof_type_t *typeof_type = &type->typeoft;
- if (typeof_type->typeof_type != NULL) {
- type = typeof_type->typeof_type;
- } else {
- type = typeof_type->expression->base.type;
- }
+ case TYPE_TYPEOF:
+ qualifiers |= type->base.qualifiers;
+ modifiers |= type->base.modifiers;
+ type = type->typeoft.typeof_type;
continue;
continue;
- }
default:
break;
}
break;
}
default:
break;
}
break;
}
- if (qualifiers != TYPE_QUALIFIER_NONE || modifiers != TYPE_MODIFIER_NONE) {
+ if (qualifiers != TYPE_QUALIFIER_NONE ||
+ modifiers != TYPE_MODIFIER_NONE ||
+ alignment > type->base.alignment) {
type_t *const copy = duplicate_type(type);
/* for const with typedefed array type the element type has to be
type_t *const copy = duplicate_type(type);
/* for const with typedefed array type the element type has to be
@@
-1247,22
+1258,22
@@
type_t *skip_typeref(type_t *type)
element_type = duplicate_type(element_type);
element_type->base.qualifiers |= qualifiers;
element_type->base.modifiers |= modifiers;
element_type = duplicate_type(element_type);
element_type->base.qualifiers |= qualifiers;
element_type->base.modifiers |= modifiers;
+ element_type->base.alignment = alignment;
copy->array.element_type = element_type;
} else {
copy->base.qualifiers |= qualifiers;
copy->base.modifiers |= modifiers;
copy->array.element_type = element_type;
} else {
copy->base.qualifiers |= qualifiers;
copy->base.modifiers |= modifiers;
+ copy->base.alignment = alignment;
}
}
- type = typehash_insert(copy);
- if (type != copy) {
- obstack_free(type_obst, copy);
- }
+ type = identify_new_type(copy);
}
return type;
}
}
return type;
}
-type_qualifiers_t get_type_qualifier(const type_t *type, bool skip_array_type) {
+type_qualifiers_t get_type_qualifier(const type_t *type, bool skip_array_type)
+{
type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
while (true) {
type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
while (true) {
@@
-1277,15
+1288,9
@@
type_qualifiers_t get_type_qualifier(const type_t *type, bool skip_array_type) {
else
type = typedef_type->typedefe->type;
continue;
else
type = typedef_type->typedefe->type;
continue;
- case TYPE_TYPEOF: {
- const typeof_type_t *typeof_type = &type->typeoft;
- if (typeof_type->typeof_type != NULL) {
- type = typeof_type->typeof_type;
- } else {
- type = typeof_type->expression->base.type;
- }
+ case TYPE_TYPEOF:
+ type = type->typeoft.typeof_type;
continue;
continue;
- }
case TYPE_ARRAY:
if (skip_array_type) {
type = type->array.element_type;
case TYPE_ARRAY:
if (skip_array_type) {
type = type->array.element_type;
@@
-1341,7
+1346,8
@@
atomic_type_kind_t get_uintptr_kind(void)
/**
* Find the atomic type kind representing a given size (signed).
*/
/**
* Find the atomic type kind representing a given size (signed).
*/
-atomic_type_kind_t find_signed_int_atomic_type_kind_for_size(unsigned size) {
+atomic_type_kind_t find_signed_int_atomic_type_kind_for_size(unsigned size)
+{
static atomic_type_kind_t kinds[32];
assert(size < 32);
static atomic_type_kind_t kinds[32];
assert(size < 32);
@@
-1354,7
+1360,7
@@
atomic_type_kind_t find_signed_int_atomic_type_kind_for_size(unsigned size) {
ATOMIC_TYPE_LONG,
ATOMIC_TYPE_LONGLONG
};
ATOMIC_TYPE_LONG,
ATOMIC_TYPE_LONGLONG
};
- for
(unsigned i = 0; i < sizeof(possible_kinds)/sizeof(possible_kinds[0]
); ++i) {
+ for
(size_t i = 0; i < lengthof(possible_kinds
); ++i) {
if (get_atomic_type_size(possible_kinds[i]) == size) {
kind = possible_kinds[i];
break;
if (get_atomic_type_size(possible_kinds[i]) == size) {
kind = possible_kinds[i];
break;
@@
-1368,7
+1374,8
@@
atomic_type_kind_t find_signed_int_atomic_type_kind_for_size(unsigned size) {
/**
* Find the atomic type kind representing a given size (signed).
*/
/**
* Find the atomic type kind representing a given size (signed).
*/
-atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size) {
+atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size)
+{
static atomic_type_kind_t kinds[32];
assert(size < 32);
static atomic_type_kind_t kinds[32];
assert(size < 32);
@@
-1381,7
+1388,7
@@
atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size) {
ATOMIC_TYPE_ULONG,
ATOMIC_TYPE_ULONGLONG
};
ATOMIC_TYPE_ULONG,
ATOMIC_TYPE_ULONGLONG
};
- for
(unsigned i = 0; i < sizeof(possible_kinds)/sizeof(possible_kinds[0]
); ++i) {
+ for
(size_t i = 0; i < lengthof(possible_kinds
); ++i) {
if (get_atomic_type_size(possible_kinds[i]) == size) {
kind = possible_kinds[i];
break;
if (get_atomic_type_size(possible_kinds[i]) == size) {
kind = possible_kinds[i];
break;
@@
-1396,7
+1403,7
@@
atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size) {
* Hash the given type and return the "singleton" version
* of it.
*/
* Hash the given type and return the "singleton" version
* of it.
*/
-
static
type_t *identify_new_type(type_t *type)
+type_t *identify_new_type(type_t *type)
{
type_t *result = typehash_insert(type);
if (result != type) {
{
type_t *result = typehash_insert(type);
if (result != type) {