#include <config.h>
+#include <stdbool.h>
+
#include "type_hash.h"
#include "adt/error.h"
#undef HashSetIterator
#undef HashSet
-static
-unsigned hash_ptr(const void *ptr)
+/* TODO: ^= is a bad way of combining hashes since most addresses are very
+ * similar */
+
+static unsigned hash_ptr(const void *ptr)
{
unsigned ptr_int = ((char*) ptr - (char*) NULL);
return ptr_int >> 3;
}
-static
-unsigned hash_atomic_type(const atomic_type_t *type)
+static unsigned hash_atomic_type(const atomic_type_t *type)
{
unsigned some_prime = 27644437;
+ unsigned result = type->atype * some_prime;
- return type->atype * some_prime;
+ return result;
}
-static
-unsigned hash_pointer_type(const pointer_type_t *type)
+static unsigned hash_pointer_type(const pointer_type_t *type)
{
return hash_ptr(type->points_to);
}
-static
-unsigned hash_compound_type(const compound_type_t *type)
+static unsigned hash_array_type(const array_type_t *type)
{
- unsigned result = hash_ptr(type->symbol);
+ return hash_ptr(type->element_type);
+}
- return result;
+static unsigned hash_compound_type(const compound_type_t *type)
+{
+ return hash_ptr(type->declaration);
}
-static
-unsigned hash_type(const type_t *type);
+static unsigned hash_type(const type_t *type);
-static
-unsigned hash_method_type(const method_type_t *type)
+static unsigned hash_function_type(const function_type_t *type)
{
unsigned result = hash_ptr(type->result_type);
- method_parameter_t *parameter = type->parameters;
+ function_parameter_t *parameter = type->parameters;
while(parameter != NULL) {
- result ^= hash_ptr(parameter);
+ result ^= hash_ptr(parameter->type);
parameter = parameter->next;
}
return result;
}
-static
-unsigned hash_enum_type(const enum_type_t *type)
+static unsigned hash_enum_type(const enum_type_t *type)
{
- unsigned result = hash_ptr(type->symbol);
+ return hash_ptr(type->declaration);
+}
- /* TODO */
+static unsigned hash_typeof_type(const typeof_type_t *type)
+{
+ unsigned result = hash_ptr(type->expression);
+ result ^= hash_ptr(type->typeof_type);
return result;
}
-static
-unsigned hash_type(const type_t *type)
+static unsigned hash_type(const type_t *type)
{
- unsigned hash;
+ unsigned hash = 0;
switch(type->type) {
case TYPE_INVALID:
case TYPE_COMPOUND_UNION:
hash = hash_compound_type((const compound_type_t*) type);
break;
- case TYPE_METHOD:
- hash = hash_method_type((const method_type_t*) type);
+ case TYPE_FUNCTION:
+ hash = hash_function_type((const function_type_t*) type);
break;
case TYPE_POINTER:
hash = hash_pointer_type((const pointer_type_t*) type);
break;
+ case TYPE_ARRAY:
+ hash = hash_array_type((const array_type_t*) type);
+ break;
case TYPE_BUILTIN:
hash = hash_ptr(((const builtin_type_t*) type)->symbol);
break;
+ case TYPE_TYPEDEF:
+ hash = hash_ptr(((const compound_type_t*) type)->declaration);
+ break;
+ case TYPE_TYPEOF:
+ hash = hash_typeof_type((const typeof_type_t*) type);
+ break;
}
unsigned some_prime = 99991;
return hash;
}
-static
-int atomic_types_equal(const atomic_type_t *type1, const atomic_type_t *type2)
+static bool atomic_types_equal(const atomic_type_t *type1,
+ const atomic_type_t *type2)
{
return type1->atype == type2->atype;
}
-static
-int compound_types_equal(const compound_type_t *type1,
- const compound_type_t *type2)
-{
- if(type1->type.type != type2->type.type)
- return 0;
- if(type1->symbol != type2->symbol)
- return 0;
-
- if(type1->symbol == NULL) {
- /* previous tests should already have checked for this */
- assert(type1 != type2);
- /* anonymous types are only equal if they are the very same type */
- return 0;
- } else {
- /* non-anonymous types are equal if they have the same symbol */
- /* TODO: is this correct */
- return 1;
- }
-
-#if 0
- declaration_t *entry1 = type1->context.declarations;
- declaration_t *entry2 = type2->context.declarations;
-
- while(entry1 != NULL && entry2 != NULL) {
- if(entry1->type != entry2->type)
- return 0;
- if(entry1->symbol != entry2->symbol)
- return 0;
- entry1 = entry1->next;
- entry2 = entry2->next;
- }
- if(entry1 != NULL || entry2 != NULL)
- return 0;
-#endif
-
- return 1;
-}
-
-static
-int method_types_equal(const method_type_t *type1, const method_type_t *type2)
+static bool function_types_equal(const function_type_t *type1,
+ const function_type_t *type2)
{
if(type1->result_type != type2->result_type)
- return 0;
-
- method_parameter_t *param1 = type1->parameters;
- method_parameter_t *param2 = type2->parameters;
+ return false;
+ if(type1->variadic != type2->variadic)
+ return false;
+ if(type1->unspecified_parameters != type2->unspecified_parameters)
+ return false;
+
+ function_parameter_t *param1 = type1->parameters;
+ function_parameter_t *param2 = type2->parameters;
while(param1 != NULL && param2 != NULL) {
if(param1->type != param2->type)
- return 0;
+ return false;
param1 = param1->next;
param2 = param2->next;
}
if(param1 != NULL || param2 != NULL)
- return 0;
+ return false;
- return 1;
+ return true;
}
-static
-int pointer_types_equal(const pointer_type_t *type1,
- const pointer_type_t *type2)
+static bool pointer_types_equal(const pointer_type_t *type1,
+ const pointer_type_t *type2)
{
return type1->points_to == type2->points_to;
}
-static
-int enum_types_equal(const enum_type_t *type1, const enum_type_t *type2)
+static bool array_types_equal(const array_type_t *type1,
+ const array_type_t *type2)
{
- if(type1->symbol != NULL && type1->symbol == type2->symbol)
- return 1;
-
- enum_entry_t *entry1 = type1->entries;
- enum_entry_t *entry2 = type2->entries;
- while(entry1 != NULL && entry2 != NULL) {
- if(entry1->symbol != entry2->symbol)
- return 0;
- /* TODO: compare expressions */
- entry1 = entry1->next;
- entry2 = entry2->next;
- }
- if(entry1 != NULL || entry2 != NULL)
- return 0;
-
- return 1;
+ if(type1->element_type != type2->element_type)
+ return false;
+ if(type1->is_variable != type2->is_variable)
+ return false;
+ if(type1->is_static != type2->is_static)
+ return false;
+ /* TODO: compare expressions for equality... */
+ if(type1->size != type2->size)
+ return false;
+
+ return true;
}
-static
-int builtin_types_equal(const builtin_type_t *type1,
- const builtin_type_t *type2)
+static bool builtin_types_equal(const builtin_type_t *type1,
+ const builtin_type_t *type2)
{
return type1->symbol == type2->symbol;
}
-static
-int types_equal(const type_t *type1, const type_t *type2)
+static bool compound_types_equal(const compound_type_t *type1,
+ const compound_type_t *type2)
+{
+ return type1->declaration == type2->declaration;
+}
+
+static bool enum_types_equal(const enum_type_t *type1,
+ const enum_type_t *type2)
+{
+ return type1->declaration == type2->declaration;
+}
+
+static bool typedef_types_equal(const typedef_type_t *type1,
+ const typedef_type_t *type2)
+{
+ return type1->declaration == type2->declaration;
+}
+
+static bool typeof_types_equal(const typeof_type_t *type1,
+ const typeof_type_t *type2)
+{
+ if(type1->expression != type2->expression)
+ return false;
+ if(type1->typeof_type != type2->typeof_type)
+ return false;
+
+ return true;
+}
+
+static bool types_equal(const type_t *type1, const type_t *type2)
{
if(type1 == type2)
- return 1;
+ return true;
if(type1->type != type2->type)
- return 0;
+ return false;
if(type1->qualifiers != type2->qualifiers)
- return 0;
+ return false;
switch(type1->type) {
case TYPE_INVALID:
- return 0;
+ return false;
case TYPE_ATOMIC:
return atomic_types_equal((const atomic_type_t*) type1,
(const atomic_type_t*) type2);
+ case TYPE_ENUM:
+ return enum_types_equal((const enum_type_t*) type1,
+ (const enum_type_t*) type2);
case TYPE_COMPOUND_STRUCT:
case TYPE_COMPOUND_UNION:
return compound_types_equal((const compound_type_t*) type1,
(const compound_type_t*) type2);
- case TYPE_ENUM:
- return enum_types_equal((const enum_type_t*) type1,
- (const enum_type_t*) type2);
- case TYPE_METHOD:
- return method_types_equal((const method_type_t*) type1,
- (const method_type_t*) type2);
+ case TYPE_FUNCTION:
+ return function_types_equal((const function_type_t*) type1,
+ (const function_type_t*) type2);
case TYPE_POINTER:
return pointer_types_equal((const pointer_type_t*) type1,
(const pointer_type_t*) type2);
+ case TYPE_ARRAY:
+ return array_types_equal((const array_type_t*) type1,
+ (const array_type_t*) type2);
case TYPE_BUILTIN:
return builtin_types_equal((const builtin_type_t*) type1,
(const builtin_type_t*) type2);
+ case TYPE_TYPEOF:
+ return typeof_types_equal((const typeof_type_t*) type1,
+ (const typeof_type_t*) type2);
+ case TYPE_TYPEDEF:
+ return typedef_types_equal((const typedef_type_t*) type1,
+ (const typedef_type_t*) type2);
}
abort();