X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=type.c;h=966ac7b3584ea804192b8fb9ac50d2fa3cb416b7;hb=80aace927df0964832a24fe1bca284ba56cc1811;hp=3257dc5e864e913a451da62a6b03e10023ebde4a;hpb=342aedf9066719e251f15ba100b2fd136c41b79e;p=cparser diff --git a/type.c b/type.c index 3257dc5..966ac7b 100644 --- a/type.c +++ b/type.c @@ -119,20 +119,20 @@ static atomic_type_properties_t atomic_type_properties[ATOMIC_TYPE_LAST+1] = { }, [ATOMIC_TYPE_FLOAT] = { .size = 4, - .alignment = 4, - .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC + .alignment = (unsigned) -1, + .flags = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC | ATOMIC_TYPE_FLAG_SIGNED, }, [ATOMIC_TYPE_DOUBLE] = { .size = 8, - .alignment = 8, - .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC + .alignment = (unsigned) -1, + .flags = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC | ATOMIC_TYPE_FLAG_SIGNED, }, [ATOMIC_TYPE_LONG_DOUBLE] = { .size = 12, - .alignment = 12, - .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC + .alignment = (unsigned) -1, + .flags = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC | ATOMIC_TYPE_FLAG_SIGNED, }, /* complex and imaginary types are set in init_types */ @@ -173,22 +173,6 @@ void init_types(void) 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,44 +198,74 @@ void print_type_qualifiers(type_qualifiers_t qualifiers) } /** - * Prints the name of a atomic type. + * Prints the name of an atomic type kinds. * - * @param type The type. + * @param kind The type kind. */ static -void print_atomic_type(const atomic_type_t *type) +void print_atomic_kinds(atomic_type_kind_t kind) { - print_type_qualifiers(type->type.qualifiers); - 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; + 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. + */ +static +void print_atomic_type(const atomic_type_t *type) +{ + print_type_qualifiers(type->base.qualifiers); + print_atomic_kinds(type->akind); +} + +/** + * 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); +} + /** * Print the first part (the prefix) of a type. * @@ -260,7 +274,7 @@ void print_atomic_type(const atomic_type_t *type) */ static void print_function_type_pre(const function_type_t *type, bool top) { - print_type_qualifiers(type->type.qualifiers); + print_type_qualifiers(type->base.qualifiers); intern_print_type_pre(type->return_type, false); @@ -331,7 +345,7 @@ static void print_pointer_type_pre(const pointer_type_t *type) { intern_print_type_pre(type->points_to, false); fputs("*", out); - print_type_qualifiers(type->type.qualifiers); + print_type_qualifiers(type->base.qualifiers); } /** @@ -365,7 +379,7 @@ static void print_array_type_post(const array_type_t *type) if(type->is_static) { fputs("static ", out); } - print_type_qualifiers(type->type.qualifiers); + print_type_qualifiers(type->base.qualifiers); if(type->size_expression != NULL && (print_implicit_array_size || !type->has_implicit_size)) { print_expression(type->size_expression); @@ -383,7 +397,7 @@ static void print_bitfield_type_post(const bitfield_type_t *type) { fputs(" : ", out); print_expression(type->size); - intern_print_type_post(type->base, false); + intern_print_type_post(type->base_type, false); } /** @@ -428,7 +442,7 @@ void print_enum_definition(const declaration_t *declaration) */ static void print_type_enum(const enum_type_t *type) { - print_type_qualifiers(type->type.qualifiers); + print_type_qualifiers(type->base.qualifiers); fputs("enum ", out); declaration_t *declaration = type->declaration; @@ -469,12 +483,12 @@ void print_compound_definition(const declaration_t *declaration) */ static void print_compound_type(const compound_type_t *type) { - print_type_qualifiers(type->type.qualifiers); + print_type_qualifiers(type->base.qualifiers); - if(type->type.kind == TYPE_COMPOUND_STRUCT) { + if(type->base.kind == TYPE_COMPOUND_STRUCT) { fputs("struct ", out); } else { - assert(type->type.kind == TYPE_COMPOUND_UNION); + assert(type->base.kind == TYPE_COMPOUND_UNION); fputs("union ", out); } @@ -494,7 +508,7 @@ static void print_compound_type(const compound_type_t *type) */ static void print_typedef_type_pre(const typedef_type_t *const type) { - print_type_qualifiers(type->type.qualifiers); + print_type_qualifiers(type->base.qualifiers); fputs(type->declaration->symbol->string, out); } @@ -535,6 +549,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); @@ -549,7 +569,7 @@ static void intern_print_type_pre(const type_t *const type, const bool top) print_pointer_type_pre(&type->pointer); return; case TYPE_BITFIELD: - intern_print_type_pre(type->bitfield.base, top); + intern_print_type_pre(type->bitfield.base_type, top); return; case TYPE_ARRAY: print_array_type_pre(&type->array); @@ -588,6 +608,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 +659,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); @@ -776,12 +800,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); + } } /** @@ -835,6 +866,12 @@ bool is_type_incomplete(const type_t *type) 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_POINTER: case TYPE_BUILTIN: case TYPE_ERROR: @@ -930,6 +967,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); @@ -1048,6 +1089,26 @@ unsigned get_atomic_type_flags(atomic_type_kind_t kind) return atomic_type_properties[kind].flags; } +atomic_type_kind_t get_intptr_kind(void) +{ + if(machine_size <= 32) + return ATOMIC_TYPE_INT; + else if(machine_size <= 64) + return ATOMIC_TYPE_LONG; + else + return ATOMIC_TYPE_LONGLONG; +} + +atomic_type_kind_t get_uintptr_kind(void) +{ + if(machine_size <= 32) + return ATOMIC_TYPE_UINT; + else if(machine_size <= 64) + return ATOMIC_TYPE_ULONG; + else + return ATOMIC_TYPE_ULONGLONG; +} + /** * Find the atomic type kind representing a given size (signed). */ @@ -1121,17 +1182,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); }