+ intern_print_type_post(type, true);
+ }
+}
+
+static size_t get_type_size(type_t *type)
+{
+ switch(type->kind) {
+ case TYPE_ATOMIC: return sizeof(atomic_type_t);
+ case TYPE_COMPOUND_STRUCT:
+ case TYPE_COMPOUND_UNION: return sizeof(compound_type_t);
+ case TYPE_ENUM: return sizeof(enum_type_t);
+ case TYPE_FUNCTION: return sizeof(function_type_t);
+ case TYPE_POINTER: return sizeof(pointer_type_t);
+ case TYPE_ARRAY: return sizeof(array_type_t);
+ case TYPE_BUILTIN: return sizeof(builtin_type_t);
+ case TYPE_TYPEDEF: return sizeof(typedef_type_t);
+ case TYPE_TYPEOF: return sizeof(typeof_type_t);
+ case TYPE_BITFIELD: return sizeof(bitfield_type_t);
+ case TYPE_INVALID: panic("invalid type found");
+ }
+ panic("unknown type found");
+}
+
+/**
+ * duplicates a type
+ * note that this does not produce a deep copy!
+ */
+type_t *duplicate_type(type_t *type)
+{
+ size_t size = get_type_size(type);
+
+ type_t *copy = obstack_alloc(type_obst, size);
+ memcpy(copy, type, size);
+
+ return copy;
+}
+
+type_t *get_unqualified_type(type_t *type)
+{
+ if(type->base.qualifiers == TYPE_QUALIFIER_NONE)
+ return 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);