#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;
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 {
* 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:
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;
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) {
} 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);
}
fputc(')', out);
- intern_print_type_post(type->return_type, false);
+ intern_print_type_post(type->return_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);
}
/**
- * 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);
}
/**
*/
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);
}
/**
*/
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);
}
/**
print_expression(type->size_expression);
}
fputc(']', out);
- intern_print_type_post(type->element_type, false);
+ intern_print_type_post(type->element_type);
}
/**
{
fputs(" : ", out);
print_expression(type->size_expression);
- intern_print_type_post(type->base_type, false);
+ intern_print_type_post(type->base_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:
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);
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);
* 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);
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);
}
}
type_t *copy = obstack_alloc(type_obst, size);
memcpy(copy, type, size);
+ copy->base.firm_type = NULL;
return copy;
}
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)
return type;
}
- type = typehash_insert(copy);
- if (type != copy)
- obstack_free(type_obst, copy);
-
- return type;
+ return identify_new_type(copy);
}
/**
{
type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
type_modifiers_t modifiers = TYPE_MODIFIER_NONE;
+ il_alignment_t alignment = 0;
while (true) {
+ if (alignment < type->base.alignment)
+ alignment = type->base.alignment;
+
switch (type->kind) {
case TYPE_ERROR:
return type;
case TYPE_TYPEDEF: {
qualifiers |= type->base.qualifiers;
modifiers |= type->base.modifiers;
+
const typedef_type_t *typedef_type = &type->typedeft;
if (typedef_type->resolved_type != NULL) {
type = typedef_type->resolved_type;
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:
+ qualifiers |= type->base.qualifiers;
+ modifiers |= type->base.modifiers;
+ type = type->typeoft.typeof_type;
continue;
- }
default:
break;
}
break;
}
- if (qualifiers != TYPE_QUALIFIER_NONE || modifiers != TYPE_MODIFIER_NONE) {
+ if (qualifiers != TYPE_QUALIFIER_NONE ||
+ modifiers != TYPE_MODIFIER_NONE ||
+ alignment > type->base.alignment) {
type_t *const copy = duplicate_type(type);
/* for const with typedefed array type the element type has to be
element_type = duplicate_type(element_type);
element_type->base.qualifiers |= qualifiers;
element_type->base.modifiers |= modifiers;
+ element_type->base.alignment = alignment;
copy->array.element_type = element_type;
} else {
copy->base.qualifiers |= qualifiers;
copy->base.modifiers |= modifiers;
+ 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) {
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;
/**
* 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);
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;
/**
* 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);
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;
* 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) {