- some comments
[cparser] / type.c
diff --git a/type.c b/type.c
index 416f090..6fb1528 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 "adt/util.h"
 #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 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 {
@@ -45,6 +46,9 @@ struct atomic_type_properties_t {
        unsigned   flags;             /**< type flags from atomic_type_flag_t */
 };
 
+/**
+ * Properties of atomic types.
+ */
 static atomic_type_properties_t atomic_type_properties[ATOMIC_TYPE_LAST+1] = {
        //ATOMIC_TYPE_INVALID = 0,
        [ATOMIC_TYPE_VOID] = {
@@ -300,9 +304,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.
- * @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:
@@ -323,7 +326,7 @@ static void print_function_type_pre(const function_type_t *type, bool top)
        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;
@@ -332,25 +335,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;
        }
-
-       /* 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.
- * @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,
-                                     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) {
@@ -366,12 +360,14 @@ static void print_function_type_post(const function_type_t *type,
        } else {
                entity_t *parameter = parameters->entities;
                for (; parameter != NULL; parameter = parameter->base.next) {
+                       if (parameter->kind != ENTITY_PARAMETER)
+                               continue;
+
                        if (first) {
                                first = false;
                        } else {
                                fputs(", ", out);
                        }
-                       assert(is_declaration(parameter));
                        const type_t *const type = parameter->declaration.type;
                        if (type == NULL) {
                                fputs(parameter->base.symbol->string, out);
@@ -393,7 +389,7 @@ static void print_function_type_post(const function_type_t *type,
        }
        fputc(')', out);
 
-       intern_print_type_post(type->return_type, false);
+       intern_print_type_post(type->return_type);
 }
 
 /**
@@ -403,7 +399,10 @@ static void print_function_type_post(const function_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);
@@ -418,24 +417,30 @@ static void print_pointer_type_pre(const pointer_type_t *type)
 }
 
 /**
- * Prints the prefix part of a reference type.
+ * Prints the postfix 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 postfix part of a pointer type.
+ * Prints the prefix 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);
 }
 
 /**
@@ -445,7 +450,10 @@ static void print_pointer_type_post(const pointer_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);
 }
 
 /**
@@ -455,7 +463,7 @@ static void print_reference_type_post(const reference_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);
 }
 
 /**
@@ -477,7 +485,7 @@ static void print_array_type_post(const array_type_t *type)
                print_expression(type->size_expression);
        }
        fputc(']', out);
-       intern_print_type_post(type->element_type, false);
+       intern_print_type_post(type->element_type);
 }
 
 /**
@@ -489,7 +497,7 @@ static void print_bitfield_type_post(const bitfield_type_t *type)
 {
        fputs(" : ", out);
        print_expression(type->size_expression);
-       intern_print_type_post(type->base_type, false);
+       intern_print_type_post(type->base_type);
 }
 
 /**
@@ -632,9 +640,8 @@ static void print_typeof_type_pre(const typeof_type_t *const 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:
@@ -663,7 +670,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:
-               print_function_type_pre(&type->function, top);
+               print_function_type_pre(&type->function);
                return;
        case TYPE_POINTER:
                print_pointer_type_pre(&type->pointer);
@@ -672,7 +679,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:
-               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);
@@ -691,13 +698,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.
- * @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:
-               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);
@@ -748,15 +754,15 @@ void print_type_ext(const type_t *const type, const symbol_t *symbol,
                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) {
-               print_function_type_post(&type->function, parameters, true);
+               print_function_type_post(&type->function, parameters);
        } else {
-               intern_print_type_post(type, true);
+               intern_print_type_post(type);
        }
 }
 
@@ -823,12 +829,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 *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)
@@ -856,11 +857,7 @@ type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual)
                return type;
        }
 
-       type = typehash_insert(copy);
-       if (type != copy)
-               obstack_free(type_obst, copy);
-
-       return type;
+       return identify_new_type(copy);
 }
 
 /**
@@ -1241,18 +1238,11 @@ type_t *skip_typeref(type_t *type)
                        type = typedef_type->typedefe->type;
                        continue;
                }
-               case TYPE_TYPEOF: {
+               case TYPE_TYPEOF:
                        qualifiers |= type->base.qualifiers;
                        modifiers  |= type->base.modifiers;
-
-                       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;
-                       }
+                       type        = type->typeoft.typeof_type;
                        continue;
-               }
                default:
                        break;
                }
@@ -1279,16 +1269,14 @@ type_t *skip_typeref(type_t *type)
                        copy->base.alignment   = alignment;
                }
 
-               type = typehash_insert(copy);
-               if (type != copy) {
-                       obstack_free(type_obst, copy);
-               }
+               type = identify_new_type(copy);
        }
 
        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) {
@@ -1303,15 +1291,9 @@ type_qualifiers_t get_type_qualifier(const type_t *type, bool skip_array_type) {
                        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;
-               }
                case TYPE_ARRAY:
                        if (skip_array_type) {
                                type = type->array.element_type;
@@ -1367,7 +1349,8 @@ atomic_type_kind_t get_uintptr_kind(void)
 /**
  * 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);
@@ -1380,7 +1363,7 @@ atomic_type_kind_t find_signed_int_atomic_type_kind_for_size(unsigned size) {
                        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;
@@ -1394,7 +1377,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).
  */
-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);
@@ -1407,7 +1391,7 @@ atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size) {
                        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;
@@ -1422,7 +1406,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.
  */
-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) {