X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=type.c;h=ac34d3d166fa1377ade876976452aed2b0eed5d1;hb=eb7ecee7dc9a522c23d1ddf3ea8a4cb02817b9fc;hp=2bcc56c8c5ff920b312c43ae67bbb6aa7cc13e27;hpb=89b9993818af868a736c32fb0ac51cbfaae6b54b;p=cparser diff --git a/type.c b/type.c index 2bcc56c..ac34d3d 100644 --- a/type.c +++ b/type.c @@ -167,28 +167,13 @@ void init_types(void) /* TODO: backend specific, need a way to query the backend for this. * The following are good settings for x86 */ - props[ATOMIC_TYPE_FLOAT].alignment = 4; - props[ATOMIC_TYPE_DOUBLE].alignment = 4; - props[ATOMIC_TYPE_LONGLONG].alignment = 4; - props[ATOMIC_TYPE_ULONGLONG].alignment = 4; + props[ATOMIC_TYPE_FLOAT].alignment = 4; + props[ATOMIC_TYPE_DOUBLE].alignment = 4; + props[ATOMIC_TYPE_LONG_DOUBLE].alignment = 4; + props[ATOMIC_TYPE_LONGLONG].alignment = 4; + props[ATOMIC_TYPE_ULONGLONG].alignment = 4; props[ATOMIC_TYPE_BOOL] = props[ATOMIC_TYPE_UINT]; - - /* initialize complex/imaginary types */ - props[ATOMIC_TYPE_FLOAT_COMPLEX] = props[ATOMIC_TYPE_FLOAT]; - props[ATOMIC_TYPE_FLOAT_COMPLEX].flags |= ATOMIC_TYPE_FLAG_COMPLEX; - props[ATOMIC_TYPE_FLOAT_COMPLEX].size *= 2; - props[ATOMIC_TYPE_DOUBLE_COMPLEX] = props[ATOMIC_TYPE_DOUBLE]; - props[ATOMIC_TYPE_DOUBLE_COMPLEX].flags |= ATOMIC_TYPE_FLAG_COMPLEX; - props[ATOMIC_TYPE_DOUBLE_COMPLEX].size *= 2; - props[ATOMIC_TYPE_LONG_DOUBLE_COMPLEX] - = props[ATOMIC_TYPE_LONG_DOUBLE]; - props[ATOMIC_TYPE_LONG_DOUBLE_COMPLEX].flags |= ATOMIC_TYPE_FLAG_COMPLEX; - props[ATOMIC_TYPE_LONG_DOUBLE_COMPLEX].size *= 2; - - props[ATOMIC_TYPE_FLOAT_IMAGINARY] = props[ATOMIC_TYPE_FLOAT]; - props[ATOMIC_TYPE_DOUBLE_IMAGINARY] = props[ATOMIC_TYPE_DOUBLE]; - props[ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY] = props[ATOMIC_TYPE_LONG_DOUBLE]; } void exit_types(void) @@ -214,7 +199,38 @@ void print_type_qualifiers(type_qualifiers_t qualifiers) } /** - * Prints the name of a atomic type. + * Prints the name of an atomic type kinds. + * + * @param kind The type kind. + */ +static +void print_atomic_kinds(atomic_type_kind_t kind) +{ + const char *s = "INVALIDATOMIC"; + switch(kind) { + case ATOMIC_TYPE_INVALID: break; + case ATOMIC_TYPE_VOID: s = "void"; break; + case ATOMIC_TYPE_BOOL: s = "_Bool"; break; + case ATOMIC_TYPE_CHAR: s = "char"; break; + case ATOMIC_TYPE_SCHAR: s = "signed char"; break; + case ATOMIC_TYPE_UCHAR: s = "unsigned char"; break; + case ATOMIC_TYPE_INT: s = "int"; break; + case ATOMIC_TYPE_UINT: s = "unsigned int"; break; + case ATOMIC_TYPE_SHORT: s = "short"; break; + case ATOMIC_TYPE_USHORT: s = "unsigned short"; break; + case ATOMIC_TYPE_LONG: s = "long"; break; + case ATOMIC_TYPE_ULONG: s = "unsigned long"; break; + case ATOMIC_TYPE_LONGLONG: s = "long long"; break; + case ATOMIC_TYPE_ULONGLONG: s = "unsigned long long"; break; + case ATOMIC_TYPE_LONG_DOUBLE: s = "long double"; break; + case ATOMIC_TYPE_FLOAT: s = "float"; break; + case ATOMIC_TYPE_DOUBLE: s = "double"; break; + } + fputs(s, out); +} + +/** + * Prints the name of an atomic type. * * @param type The type. */ @@ -222,34 +238,33 @@ static void print_atomic_type(const atomic_type_t *type) { print_type_qualifiers(type->base.qualifiers); + print_atomic_kinds(type->akind); +} - const char *s = "INVALIDATOMIC"; - switch((atomic_type_kind_t) type->akind) { - case ATOMIC_TYPE_INVALID: break; - case ATOMIC_TYPE_VOID: s = "void"; break; - case ATOMIC_TYPE_BOOL: s = "_Bool"; break; - case ATOMIC_TYPE_CHAR: s = "char"; break; - case ATOMIC_TYPE_SCHAR: s = "signed char"; break; - case ATOMIC_TYPE_UCHAR: s = "unsigned char"; break; - case ATOMIC_TYPE_INT: s = "int"; break; - case ATOMIC_TYPE_UINT: s = "unsigned int"; break; - case ATOMIC_TYPE_SHORT: s = "short"; break; - case ATOMIC_TYPE_USHORT: s = "unsigned short"; break; - case ATOMIC_TYPE_LONG: s = "long"; break; - case ATOMIC_TYPE_ULONG: s = "unsigned long"; break; - case ATOMIC_TYPE_LONGLONG: s = "long long"; break; - case ATOMIC_TYPE_ULONGLONG: s = "unsigned long long"; break; - case ATOMIC_TYPE_LONG_DOUBLE: s = "long double"; break; - case ATOMIC_TYPE_FLOAT: s = "float"; break; - case ATOMIC_TYPE_DOUBLE: s = "double"; break; - case ATOMIC_TYPE_FLOAT_COMPLEX: s = "_Complex float"; break; - case ATOMIC_TYPE_DOUBLE_COMPLEX: s = "_Complex float"; break; - case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX: s = "_Complex float"; break; - case ATOMIC_TYPE_FLOAT_IMAGINARY: s = "_Imaginary float"; break; - case ATOMIC_TYPE_DOUBLE_IMAGINARY: s = "_Imaginary float"; break; - case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY: s = "_Imaginary float"; break; - } - fputs(s, out); +/** + * Prints the name of a complex type. + * + * @param type The type. + */ +static +void print_complex_type(const complex_type_t *type) +{ + print_type_qualifiers(type->base.qualifiers); + fputs("_Complex ", out); + print_atomic_kinds(type->akind); +} + +/** + * Prints the name of an imaginary type. + * + * @param type The type. + */ +static +void print_imaginary_type(const imaginary_type_t *type) +{ + print_type_qualifiers(type->base.qualifiers); + fputs("_Imaginary ", out); + print_atomic_kinds(type->akind); } /** @@ -285,12 +300,12 @@ static void print_function_type_post(const function_type_t *type, fputc('(', out); - int first = 1; + bool first = true; if(scope == NULL) { function_parameter_t *parameter = type->parameters; for( ; parameter != NULL; parameter = parameter->next) { if(first) { - first = 0; + first = false; } else { fputs(", ", out); } @@ -300,7 +315,7 @@ static void print_function_type_post(const function_type_t *type, declaration_t *parameter = scope->declarations; for( ; parameter != NULL; parameter = parameter->next) { if(first) { - first = 0; + first = false; } else { fputs(", ", out); } @@ -310,7 +325,7 @@ static void print_function_type_post(const function_type_t *type, } if(type->variadic) { if(first) { - first = 0; + first = false; } else { fputs(", ", out); } @@ -535,6 +550,12 @@ static void intern_print_type_pre(const type_t *const type, const bool top) case TYPE_ATOMIC: print_atomic_type(&type->atomic); return; + case TYPE_COMPLEX: + print_complex_type(&type->complex); + return; + case TYPE_IMAGINARY: + print_imaginary_type(&type->imaginary); + return; case TYPE_COMPOUND_STRUCT: case TYPE_COMPOUND_UNION: print_compound_type(&type->compound); @@ -588,6 +609,8 @@ static void intern_print_type_post(const type_t *const type, const bool top) case TYPE_ERROR: case TYPE_INVALID: case TYPE_ATOMIC: + case TYPE_COMPLEX: + case TYPE_IMAGINARY: case TYPE_ENUM: case TYPE_COMPOUND_STRUCT: case TYPE_COMPOUND_UNION: @@ -637,6 +660,8 @@ static size_t get_type_size(const type_t *type) { switch(type->kind) { case TYPE_ATOMIC: return sizeof(atomic_type_t); + case TYPE_COMPLEX: return sizeof(complex_type_t); + case TYPE_IMAGINARY: return sizeof(imaginary_type_t); case TYPE_COMPOUND_STRUCT: case TYPE_COMPOUND_UNION: return sizeof(compound_type_t); case TYPE_ENUM: return sizeof(enum_type_t); @@ -723,6 +748,8 @@ bool is_type_integer(const type_t *type) if(type->kind == TYPE_ENUM) return true; + if(type->kind == TYPE_BITFIELD) + return true; if(type->kind != TYPE_ATOMIC) return false; @@ -759,6 +786,8 @@ bool is_type_signed(const type_t *type) /* enum types are int for now */ if(type->kind == TYPE_ENUM) return true; + if(type->kind == TYPE_BITFIELD) + return is_type_signed(type->bitfield.base_type); if(type->kind != TYPE_ATOMIC) return false; @@ -776,12 +805,19 @@ bool is_type_arithmetic(const type_t *type) { assert(!is_typeref(type)); - if(type->kind == TYPE_BITFIELD || type->kind == TYPE_ENUM) + switch(type->kind) { + case TYPE_BITFIELD: + case TYPE_ENUM: return true; - if(type->kind != TYPE_ATOMIC) + case TYPE_ATOMIC: + return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_ARITHMETIC); + case TYPE_COMPLEX: + return test_atomic_type_flag(type->complex.akind, ATOMIC_TYPE_FLAG_ARITHMETIC); + case TYPE_IMAGINARY: + return test_atomic_type_flag(type->imaginary.akind, ATOMIC_TYPE_FLAG_ARITHMETIC); + default: return false; - - return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_ARITHMETIC); + } } /** @@ -818,23 +854,29 @@ bool is_type_incomplete(const type_t *type) case TYPE_COMPOUND_UNION: { const compound_type_t *compound_type = &type->compound; declaration_t *declaration = compound_type->declaration; - return !declaration->init.is_defined; + return !declaration->init.complete; } case TYPE_ENUM: { const enum_type_t *enum_type = &type->enumt; declaration_t *declaration = enum_type->declaration; - return !declaration->init.is_defined; + return !declaration->init.complete; } - case TYPE_BITFIELD: - case TYPE_FUNCTION: - return true; case TYPE_ARRAY: - return type->array.size_expression == NULL; + return type->array.size_expression == NULL + && !type->array.size_constant; case TYPE_ATOMIC: return type->atomic.akind == ATOMIC_TYPE_VOID; + case TYPE_COMPLEX: + return type->complex.akind == ATOMIC_TYPE_VOID; + + case TYPE_IMAGINARY: + return type->imaginary.akind == ATOMIC_TYPE_VOID; + + case TYPE_BITFIELD: + case TYPE_FUNCTION: case TYPE_POINTER: case TYPE_BUILTIN: case TYPE_ERROR: @@ -862,10 +904,10 @@ static bool function_types_compatible(const function_type_t *func1, return false; /* can parameters be compared? */ - if(func1->unspecified_parameters || func2->unspecified_parameters) + if (func1->unspecified_parameters || func2->unspecified_parameters) return true; - if(func1->variadic != func2->variadic) + if (func1->variadic != func2->variadic) return false; /* TODO: handling of unspecified parameters not correct yet */ @@ -873,7 +915,7 @@ static bool function_types_compatible(const function_type_t *func1, /* all argument types must be compatible */ function_parameter_t *parameter1 = func1->parameters; function_parameter_t *parameter2 = func2->parameters; - for( ; parameter1 != NULL && parameter2 != NULL; + for ( ; parameter1 != NULL && parameter2 != NULL; parameter1 = parameter1->next, parameter2 = parameter2->next) { type_t *parameter1_type = skip_typeref(parameter1->type); type_t *parameter2_type = skip_typeref(parameter2->type); @@ -881,11 +923,11 @@ static bool function_types_compatible(const function_type_t *func1, parameter1_type = get_unqualified_type(parameter1_type); parameter2_type = get_unqualified_type(parameter2_type); - if(!types_compatible(parameter1_type, parameter2_type)) + if (!types_compatible(parameter1_type, parameter2_type)) return false; } /* same number of arguments? */ - if(parameter1 != NULL || parameter2 != NULL) + if (parameter1 != NULL || parameter2 != NULL) return false; return true; @@ -930,6 +972,10 @@ bool types_compatible(const type_t *type1, const type_t *type2) return function_types_compatible(&type1->function, &type2->function); case TYPE_ATOMIC: return type1->atomic.akind == type2->atomic.akind; + case TYPE_COMPLEX: + return type1->complex.akind == type2->complex.akind; + case TYPE_IMAGINARY: + return type1->imaginary.akind == type2->imaginary.akind; case TYPE_ARRAY: return array_types_compatible(&type1->array, &type2->array); @@ -1141,17 +1187,53 @@ static type_t *identify_new_type(type_t *type) * @param akind The kind of the atomic type. * @param qualifiers Type qualifiers for the new type. */ -type_t *make_atomic_type(atomic_type_kind_t atype, type_qualifiers_t qualifiers) +type_t *make_atomic_type(atomic_type_kind_t akind, type_qualifiers_t qualifiers) { type_t *type = obstack_alloc(type_obst, sizeof(atomic_type_t)); memset(type, 0, sizeof(atomic_type_t)); type->kind = TYPE_ATOMIC; type->base.qualifiers = qualifiers; - type->base.alignment = 0; - type->atomic.akind = atype; + type->base.alignment = get_atomic_type_alignment(akind); + type->atomic.akind = akind; - /* TODO: set the alignment depending on the atype here */ + return identify_new_type(type); +} + +/** + * Creates a new complex type. + * + * @param akind The kind of the atomic type. + * @param qualifiers Type qualifiers for the new type. + */ +type_t *make_complex_type(atomic_type_kind_t akind, type_qualifiers_t qualifiers) +{ + type_t *type = obstack_alloc(type_obst, sizeof(complex_type_t)); + memset(type, 0, sizeof(complex_type_t)); + + type->kind = TYPE_COMPLEX; + type->base.qualifiers = qualifiers; + type->base.alignment = get_atomic_type_alignment(akind); + type->complex.akind = akind; + + return identify_new_type(type); +} + +/** + * Creates a new imaginary type. + * + * @param akind The kind of the atomic type. + * @param qualifiers Type qualifiers for the new type. + */ +type_t *make_imaginary_type(atomic_type_kind_t akind, type_qualifiers_t qualifiers) +{ + type_t *type = obstack_alloc(type_obst, sizeof(imaginary_type_t)); + memset(type, 0, sizeof(imaginary_type_t)); + + type->kind = TYPE_IMAGINARY; + type->base.qualifiers = qualifiers; + type->base.alignment = get_atomic_type_alignment(akind); + type->imaginary.akind = akind; return identify_new_type(type); }