The struct alignment of long double on 32 bit Darwin is 16 bytes.
[cparser] / type.c
diff --git a/type.c b/type.c
index f1dedbb..03c5052 100644 (file)
--- a/type.c
+++ b/type.c
@@ -52,8 +52,6 @@ static size_t get_type_struct_size(type_kind_t kind)
 {
        static const size_t sizes[] = {
                [TYPE_ATOMIC]          = sizeof(atomic_type_t),
-               [TYPE_COMPLEX]         = sizeof(complex_type_t),
-               [TYPE_IMAGINARY]       = sizeof(imaginary_type_t),
                [TYPE_COMPOUND_STRUCT] = sizeof(compound_type_t),
                [TYPE_COMPOUND_UNION]  = sizeof(compound_type_t),
                [TYPE_ENUM]            = sizeof(enum_type_t),
@@ -87,78 +85,105 @@ atomic_type_properties_t atomic_type_properties[ATOMIC_TYPE_LAST+1] = {
        [ATOMIC_TYPE_VOID] = {
                .size      = 0,
                .alignment = 0,
-               .flags     = ATOMIC_TYPE_FLAG_NONE
+               .flags     = ATOMIC_TYPE_FLAG_NONE,
+               .rank      = 0,
        },
-       [ATOMIC_TYPE_WCHAR_T] = {
-               .size      = (unsigned)-1,
-               .alignment = (unsigned)-1,
-               .flags     = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+       [ATOMIC_TYPE_BOOL] = {
+               .size       = 1,
+               .alignment  = 1,
+               .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank       = 1,
        },
        [ATOMIC_TYPE_CHAR] = {
                .size      = 1,
                .alignment = 1,
                .flags     = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank      = 2,
        },
        [ATOMIC_TYPE_SCHAR] = {
                .size      = 1,
                .alignment = 1,
                .flags     = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
                           | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank      = 2,
        },
        [ATOMIC_TYPE_UCHAR] = {
                .size      = 1,
                .alignment = 1,
                .flags     = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank      = 2,
        },
        [ATOMIC_TYPE_SHORT] = {
                .size       = 2,
                .alignment  = 2,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
-                             | ATOMIC_TYPE_FLAG_SIGNED
+                             | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank       = 3,
        },
        [ATOMIC_TYPE_USHORT] = {
                .size       = 2,
                .alignment  = 2,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank       = 3,
        },
        [ATOMIC_TYPE_INT] = {
                .size       = (unsigned) -1,
                .alignment  = (unsigned) -1,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
                              | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank       = 4,
        },
        [ATOMIC_TYPE_UINT] = {
                .size       = (unsigned) -1,
                .alignment  = (unsigned) -1,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank       = 4,
        },
        [ATOMIC_TYPE_LONG] = {
                .size       = (unsigned) -1,
                .alignment  = (unsigned) -1,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
                              | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank       = 5,
        },
        [ATOMIC_TYPE_ULONG] = {
                .size       = (unsigned) -1,
                .alignment  = (unsigned) -1,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank       = 5,
        },
-       [ATOMIC_TYPE_BOOL] = {
-               .size       = 1,
-               .alignment  = 1,
+       [ATOMIC_TYPE_LONGLONG] = {
+               .size       = 8,
+               .alignment  = 8,
+               .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
+                             | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank       = 6,
+       },
+       [ATOMIC_TYPE_ULONGLONG] = {
+               .size       = 8,
+               .alignment  = 8,
                .flags      = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank       = 6,
        },
        [ATOMIC_TYPE_FLOAT] = {
                .size       = 4,
                .alignment  = 4,
                .flags      = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC
                              | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank       = 0,
        },
        [ATOMIC_TYPE_DOUBLE] = {
                .size       = 8,
                .alignment  = 8,
                .flags      = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC
                              | ATOMIC_TYPE_FLAG_SIGNED,
+               .rank       = 0,
+       },
+       [ATOMIC_TYPE_WCHAR_T] = {
+               .size      = (unsigned)-1,
+               .alignment = (unsigned)-1,
+               .flags     = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC,
+               .rank      = (unsigned)-1,
        },
 };
 atomic_type_properties_t pointer_properties = {
@@ -196,15 +221,11 @@ void init_types(unsigned machine_size)
        pointer_properties.alignment        = long_size;
        pointer_properties.struct_alignment = long_size;
 
-       props[ATOMIC_TYPE_LONGLONG]    = props[ATOMIC_TYPE_LONG];
-       props[ATOMIC_TYPE_ULONGLONG]   = props[ATOMIC_TYPE_ULONG];
        props[ATOMIC_TYPE_LONG_DOUBLE] = props[ATOMIC_TYPE_DOUBLE];
        props[ATOMIC_TYPE_WCHAR_T]     = props[ATOMIC_TYPE_INT];
 
        /* set struct alignments to the same value as alignment */
-       for (size_t i = 0;
-            i < sizeof(atomic_type_properties)/sizeof(atomic_type_properties[0]);
-            ++i) {
+       for (size_t i = 0; i != lengthof(atomic_type_properties); ++i) {
                props[i].struct_alignment = props[i].alignment;
        }
 }
@@ -285,7 +306,7 @@ static void print_atomic_type(const atomic_type_t *type)
  *
  * @param type  The type.
  */
-static void print_complex_type(const complex_type_t *type)
+static void print_complex_type(const atomic_type_t *type)
 {
        print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END);
        print_string("_Complex");
@@ -297,7 +318,7 @@ static void print_complex_type(const complex_type_t *type)
  *
  * @param type  The type.
  */
-static void print_imaginary_type(const imaginary_type_t *type)
+static void print_imaginary_type(const atomic_type_t *type)
 {
        print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END);
        print_string("_Imaginary ");
@@ -529,7 +550,7 @@ void print_enum_definition(const enum_t *enume)
  */
 static void print_type_enum(const enum_type_t *type)
 {
-       print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END);
+       print_type_qualifiers(type->base.base.qualifiers, QUAL_SEP_END);
        print_string("enum ");
 
        enum_t   *enume  = type->enume;
@@ -637,10 +658,10 @@ static void intern_print_type_pre(const type_t *const type)
                print_atomic_type(&type->atomic);
                return;
        case TYPE_COMPLEX:
-               print_complex_type(&type->complex);
+               print_complex_type(&type->atomic);
                return;
        case TYPE_IMAGINARY:
-               print_imaginary_type(&type->imaginary);
+               print_imaginary_type(&type->atomic);
                return;
        case TYPE_COMPOUND_STRUCT:
        case TYPE_COMPOUND_UNION:
@@ -894,11 +915,9 @@ bool is_type_arithmetic(const type_t *type)
        case TYPE_ENUM:
                return true;
        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);
+               return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_ARITHMETIC);
        default:
                return false;
        }
@@ -956,13 +975,9 @@ bool is_type_incomplete(const type_t *type)
                        && !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_COMPLEX:
+               return type->atomic.akind == ATOMIC_TYPE_VOID;
 
        case TYPE_FUNCTION:
        case TYPE_POINTER:
@@ -1079,11 +1094,9 @@ bool types_compatible(const type_t *type1, const type_t *type2)
        case TYPE_FUNCTION:
                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_COMPLEX:
+               return type1->atomic.akind == type2->atomic.akind;
        case TYPE_ARRAY:
                return array_types_compatible(&type1->array, &type2->array);
 
@@ -1176,19 +1189,17 @@ unsigned get_type_size(type_t *type)
        case TYPE_ERROR:
                return 0;
        case TYPE_ATOMIC:
+       case TYPE_IMAGINARY:
+       case TYPE_ENUM:
                return get_atomic_type_size(type->atomic.akind);
        case TYPE_COMPLEX:
-               return get_atomic_type_size(type->complex.akind) * 2;
-       case TYPE_IMAGINARY:
-               return get_atomic_type_size(type->imaginary.akind);
+               return get_atomic_type_size(type->atomic.akind) * 2;
        case TYPE_COMPOUND_UNION:
                layout_union_type(&type->compound);
                return type->compound.compound->size;
        case TYPE_COMPOUND_STRUCT:
                layout_struct_type(&type->compound);
                return type->compound.compound->size;
-       case TYPE_ENUM:
-               return get_atomic_type_size(type->enumt.akind);
        case TYPE_FUNCTION:
                return 0; /* non-const (but "address-const") */
        case TYPE_REFERENCE:
@@ -1217,19 +1228,16 @@ unsigned get_type_alignment(type_t *type)
        case TYPE_ERROR:
                return 0;
        case TYPE_ATOMIC:
-               return get_atomic_type_alignment(type->atomic.akind);
-       case TYPE_COMPLEX:
-               return get_atomic_type_alignment(type->complex.akind);
        case TYPE_IMAGINARY:
-               return get_atomic_type_alignment(type->imaginary.akind);
+       case TYPE_COMPLEX:
+       case TYPE_ENUM:
+               return get_atomic_type_alignment(type->atomic.akind);
        case TYPE_COMPOUND_UNION:
                layout_union_type(&type->compound);
                return type->compound.compound->alignment;
        case TYPE_COMPOUND_STRUCT:
                layout_struct_type(&type->compound);
                return type->compound.compound->alignment;
-       case TYPE_ENUM:
-               return get_atomic_type_alignment(type->enumt.akind);
        case TYPE_FUNCTION:
                /* gcc says 1 here... */
                return 1;
@@ -1437,11 +1445,12 @@ type_t *make_atomic_type(atomic_type_kind_t akind, type_qualifiers_t qualifiers)
  * @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 *make_complex_type(atomic_type_kind_t akind,
+                          type_qualifiers_t qualifiers)
 {
        type_t *const type = allocate_type_zero(TYPE_COMPLEX);
        type->base.qualifiers = qualifiers;
-       type->complex.akind   = akind;
+       type->atomic.akind   = akind;
 
        return identify_new_type(type);
 }
@@ -1452,11 +1461,12 @@ type_t *make_complex_type(atomic_type_kind_t akind, type_qualifiers_t qualifiers
  * @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 *make_imaginary_type(atomic_type_kind_t akind,
+                            type_qualifiers_t qualifiers)
 {
        type_t *const type = allocate_type_zero(TYPE_IMAGINARY);
        type->base.qualifiers = qualifiers;
-       type->imaginary.akind = akind;
+       type->atomic.akind = akind;
 
        return identify_new_type(type);
 }
@@ -1694,7 +1704,7 @@ function_parameter_t *allocate_parameter(type_t *const type)
 }
 
 type_t *make_function_2_type(type_t *return_type, type_t *argument_type1,
-                             type_t *argument_type2)
+                             type_t *argument_type2, decl_modifiers_t modifiers)
 {
        function_parameter_t *const parameter2 = allocate_parameter(argument_type2);
        function_parameter_t *const parameter1 = allocate_parameter(argument_type1);
@@ -1703,25 +1713,29 @@ type_t *make_function_2_type(type_t *return_type, type_t *argument_type1,
        type_t *type               = allocate_type_zero(TYPE_FUNCTION);
        type->function.return_type = return_type;
        type->function.parameters  = parameter1;
+       type->function.modifiers  |= modifiers;
        type->function.linkage     = LINKAGE_C;
 
        return identify_new_type(type);
 }
 
-type_t *make_function_1_type(type_t *return_type, type_t *argument_type)
+type_t *make_function_1_type(type_t *return_type, type_t *argument_type,
+                             decl_modifiers_t modifiers)
 {
        function_parameter_t *const parameter = allocate_parameter(argument_type);
 
        type_t *type               = allocate_type_zero(TYPE_FUNCTION);
        type->function.return_type = return_type;
        type->function.parameters  = parameter;
+       type->function.modifiers  |= modifiers;
        type->function.linkage     = LINKAGE_C;
 
        return identify_new_type(type);
 }
 
 type_t *make_function_1_type_variadic(type_t *return_type,
-                                      type_t *argument_type)
+                                      type_t *argument_type,
+                                      decl_modifiers_t modifiers)
 {
        function_parameter_t *const parameter = allocate_parameter(argument_type);
 
@@ -1729,16 +1743,18 @@ type_t *make_function_1_type_variadic(type_t *return_type,
        type->function.return_type = return_type;
        type->function.parameters  = parameter;
        type->function.variadic    = true;
+       type->function.modifiers  |= modifiers;
        type->function.linkage     = LINKAGE_C;
 
        return identify_new_type(type);
 }
 
-type_t *make_function_0_type(type_t *return_type)
+type_t *make_function_0_type(type_t *return_type, decl_modifiers_t modifiers)
 {
        type_t *type               = allocate_type_zero(TYPE_FUNCTION);
        type->function.return_type = return_type;
        type->function.parameters  = NULL;
+       type->function.modifiers  |= modifiers;
        type->function.linkage     = LINKAGE_C;
 
        return identify_new_type(type);