return res;
}
-static ir_mode *_atomic_modes[ATOMIC_TYPE_LAST];
+static ir_mode *_atomic_modes[ATOMIC_TYPE_LAST+1];
static ir_mode *mode_int, *mode_uint;
_atomic_modes[ATOMIC_TYPE_LONG_DOUBLE] = mode_E;
_atomic_modes[ATOMIC_TYPE_BOOL] = get_umode(int_size);
-#ifdef PROVIDE_COMPLEX
+ _atomic_modes[ATOMIC_TYPE_INT8] = get_smode(1);
+ _atomic_modes[ATOMIC_TYPE_INT16] = get_smode(2);
+ _atomic_modes[ATOMIC_TYPE_INT32] = get_smode(4);
+ _atomic_modes[ATOMIC_TYPE_INT64] = get_smode(8);
+ _atomic_modes[ATOMIC_TYPE_INT128] = get_smode(16);
+ _atomic_modes[ATOMIC_TYPE_UINT8] = get_umode(1);
+ _atomic_modes[ATOMIC_TYPE_UINT16] = get_umode(2);
+ _atomic_modes[ATOMIC_TYPE_UINT32] = get_umode(4);
+ _atomic_modes[ATOMIC_TYPE_UINT64] = get_umode(8);
+ _atomic_modes[ATOMIC_TYPE_UINT128] = get_umode(16);
+
_atomic_modes[ATOMIC_TYPE_BOOL] = _atomic_modes[ATOMIC_TYPE_INT];
_atomic_modes[ATOMIC_TYPE_FLOAT_IMAGINARY] = _atomic_modes[ATOMIC_TYPE_FLOAT];
_atomic_modes[ATOMIC_TYPE_DOUBLE_IMAGINARY] = _atomic_modes[ATOMIC_TYPE_DOUBLE];
_atomic_modes[ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY] = _atomic_modes[ATOMIC_TYPE_LONG_DOUBLE];
-#endif
/* Hmm, pointers should be machine size */
set_modeP_data(get_ptrmode(machine_size >> 3, NULL));
static ir_mode *get_atomic_mode(const atomic_type_t* atomic_type)
{
ir_mode *res = NULL;
- if ((unsigned)atomic_type->akind < (unsigned)ATOMIC_TYPE_LAST)
+ if ((unsigned)atomic_type->akind <= (unsigned)ATOMIC_TYPE_LAST)
res = _atomic_modes[(unsigned)atomic_type->akind];
if (res == NULL)
panic("Encountered unknown atomic type");
return res;
}
-static unsigned get_atomic_type_size(const atomic_type_t *type)
-{
- switch(type->akind) {
- case ATOMIC_TYPE_CHAR:
- case ATOMIC_TYPE_SCHAR:
- case ATOMIC_TYPE_UCHAR:
- return 1;
-
- case ATOMIC_TYPE_SHORT:
- case ATOMIC_TYPE_USHORT:
- return 2;
-
- case ATOMIC_TYPE_BOOL:
- case ATOMIC_TYPE_INT:
- case ATOMIC_TYPE_UINT:
- return machine_size >> 3;
-
- case ATOMIC_TYPE_LONG:
- case ATOMIC_TYPE_ULONG:
- return machine_size > 16 ? machine_size >> 3 : 4;
-
- case ATOMIC_TYPE_LONGLONG:
- case ATOMIC_TYPE_ULONGLONG:
- return machine_size > 16 ? 8 : 4;
-
- case ATOMIC_TYPE_FLOAT:
- return 4;
-
- case ATOMIC_TYPE_DOUBLE:
- return 8;
-
- case ATOMIC_TYPE_LONG_DOUBLE:
- return 12;
-
- case ATOMIC_TYPE_VOID:
- return 1;
-
- case ATOMIC_TYPE_INVALID:
- case ATOMIC_TYPE_LAST:
- break;
- }
- panic("Trying to determine size of invalid atomic type");
-}
-
static unsigned get_compound_type_size(compound_type_t *type)
{
ir_type *irtype = get_ir_type((type_t*) type);
case TYPE_ERROR:
panic("error type occured");
case TYPE_ATOMIC:
- return get_atomic_type_size(&type->atomic);
+ return get_atomic_type_size(type->atomic.akind);
case TYPE_ENUM:
return get_mode_size_bytes(mode_int);
case TYPE_COMPOUND_UNION:
static ir_node *classify_type_to_firm(const classify_type_expression_t *const expr)
{
- const type_t *const type = expr->type_expression->base.type;
+ const type_t *const type = skip_typeref(expr->type_expression->base.type);
gcc_type_class tc;
switch (type->kind)
{
case TYPE_ATOMIC: {
const atomic_type_t *const atomic_type = &type->atomic;
- switch (atomic_type->akind) {
+ switch ((atomic_type_kind_t) atomic_type->akind) {
/* should not be reached */
case ATOMIC_TYPE_INVALID:
tc = no_type_class;
- break;
+ goto make_const;
/* gcc cannot do that */
case ATOMIC_TYPE_VOID:
tc = void_type_class;
- break;
+ goto make_const;
case ATOMIC_TYPE_CHAR: /* gcc handles this as integer */
case ATOMIC_TYPE_SCHAR: /* gcc handles this as integer */
case ATOMIC_TYPE_LONGLONG:
case ATOMIC_TYPE_ULONGLONG:
case ATOMIC_TYPE_BOOL: /* gcc handles this as integer */
+ /* microsoft types */
+ case ATOMIC_TYPE_INT8:
+ case ATOMIC_TYPE_INT16:
+ case ATOMIC_TYPE_INT32:
+ case ATOMIC_TYPE_INT64:
+ case ATOMIC_TYPE_INT128:
+ case ATOMIC_TYPE_UINT8:
+ case ATOMIC_TYPE_UINT16:
+ case ATOMIC_TYPE_UINT32:
+ case ATOMIC_TYPE_UINT64:
+ case ATOMIC_TYPE_UINT128:
tc = integer_type_class;
- break;
+ goto make_const;
case ATOMIC_TYPE_FLOAT:
case ATOMIC_TYPE_DOUBLE:
case ATOMIC_TYPE_LONG_DOUBLE:
tc = real_type_class;
- break;
+ goto make_const;
-#ifdef PROVIDE_COMPLEX
case ATOMIC_TYPE_FLOAT_COMPLEX:
case ATOMIC_TYPE_DOUBLE_COMPLEX:
case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
tc = complex_type_class;
- break;
+ goto make_const;
case ATOMIC_TYPE_FLOAT_IMAGINARY:
case ATOMIC_TYPE_DOUBLE_IMAGINARY:
case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
tc = complex_type_class;
- break;
-#endif
-
- default:
- panic("Unimplemented case in classify_type_to_firm().");
+ goto make_const;
}
- break;
+ panic("Unexpected atomic type in classify_type_to_firm().");
}
+ case TYPE_BITFIELD: tc = integer_type_class; goto make_const;
case TYPE_ARRAY: /* gcc handles this as pointer */
case TYPE_FUNCTION: /* gcc handles this as pointer */
- case TYPE_POINTER: tc = pointer_type_class; break;
- case TYPE_COMPOUND_STRUCT: tc = record_type_class; break;
- case TYPE_COMPOUND_UNION: tc = union_type_class; break;
+ case TYPE_POINTER: tc = pointer_type_class; goto make_const;
+ case TYPE_COMPOUND_STRUCT: tc = record_type_class; goto make_const;
+ case TYPE_COMPOUND_UNION: tc = union_type_class; goto make_const;
/* gcc handles this as integer */
- case TYPE_ENUM: tc = integer_type_class; break;
-
- default:
- panic("Unimplemented case in classify_type_to_firm().");
+ case TYPE_ENUM: tc = integer_type_class; goto make_const;
+
+ case TYPE_BUILTIN:
+ /* typedef/typeof should be skipped already */
+ case TYPE_TYPEDEF:
+ case TYPE_TYPEOF:
+ case TYPE_INVALID:
+ case TYPE_ERROR:
+ break;
}
+ panic("unexpected TYPE classify_type_to_firm().");
+make_const: ;
dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
ir_mode *const mode = mode_int;
tarval *const tv = new_tarval_from_long(tc, mode);
if(type->kind == TYPE_BITFIELD)
type = type->bitfield.base;
+ /* handle microsofts explicit size types */
+ atomic_type_kind_t kind = type->atomic.akind;
+ if(kind >= ATOMIC_TYPE_INT8 && kind <= ATOMIC_TYPE_UINT128) {
+ unsigned size = get_atomic_type_size(kind);
+ if(kind <= ATOMIC_TYPE_INT128) {
+ if(size <= get_atomic_type_size(ATOMIC_TYPE_INT)) {
+ return type_int;
+ }
+ } else {
+ if(size <= get_atomic_type_size(ATOMIC_TYPE_UINT)) {
+ return type_unsigned_int;
+ }
+ }
+
+ return type;
+ }
+
if(get_rank(type) < ATOMIC_TYPE_INT)
type = type_int;
SPECIFIER_FLOAT = 1 << 8,
SPECIFIER_BOOL = 1 << 9,
SPECIFIER_VOID = 1 << 10,
+ SPECIFIER_INT8 = 1 << 11,
+ SPECIFIER_INT16 = 1 << 12,
+ SPECIFIER_INT32 = 1 << 13,
+ SPECIFIER_INT64 = 1 << 14,
+ SPECIFIER_INT128 = 1 << 15,
#ifdef PROVIDE_COMPLEX
- SPECIFIER_COMPLEX = 1 << 11,
- SPECIFIER_IMAGINARY = 1 << 12,
+ SPECIFIER_COMPLEX = 1 << 16,
+ SPECIFIER_IMAGINARY = 1 << 17,
#endif
} specifiers_t;
MATCH_SPECIFIER(T_signed, SPECIFIER_SIGNED, "signed")
MATCH_SPECIFIER(T_unsigned, SPECIFIER_UNSIGNED, "unsigned")
MATCH_SPECIFIER(T__Bool, SPECIFIER_BOOL, "_Bool")
+ MATCH_SPECIFIER(T__int8, SPECIFIER_INT8, "_int8")
+ MATCH_SPECIFIER(T__int16, SPECIFIER_INT16, "_int16")
+ MATCH_SPECIFIER(T__int32, SPECIFIER_INT32, "_int32")
+ MATCH_SPECIFIER(T__int64, SPECIFIER_INT64, "_int64")
+ MATCH_SPECIFIER(T__int128, SPECIFIER_INT128, "_int128")
#ifdef PROVIDE_COMPLEX
MATCH_SPECIFIER(T__Complex, SPECIFIER_COMPLEX, "_Complex")
MATCH_SPECIFIER(T__Imaginary, SPECIFIER_IMAGINARY, "_Imaginary")
| SPECIFIER_INT:
atomic_type = ATOMIC_TYPE_ULONGLONG;
break;
+
+ case SPECIFIER_UNSIGNED | SPECIFIER_INT8:
+ atomic_type = ATOMIC_TYPE_UINT8;
+ break;
+
+ case SPECIFIER_UNSIGNED | SPECIFIER_INT16:
+ atomic_type = ATOMIC_TYPE_UINT16;
+ break;
+
+ case SPECIFIER_UNSIGNED | SPECIFIER_INT32:
+ atomic_type = ATOMIC_TYPE_UINT32;
+ break;
+
+ case SPECIFIER_UNSIGNED | SPECIFIER_INT64:
+ atomic_type = ATOMIC_TYPE_UINT64;
+ break;
+
+ case SPECIFIER_UNSIGNED | SPECIFIER_INT128:
+ atomic_type = ATOMIC_TYPE_UINT128;
+ break;
+
+ case SPECIFIER_INT8:
+ case SPECIFIER_SIGNED | SPECIFIER_INT8:
+ atomic_type = ATOMIC_TYPE_INT8;
+ break;
+
+ case SPECIFIER_INT16:
+ case SPECIFIER_SIGNED | SPECIFIER_INT16:
+ atomic_type = ATOMIC_TYPE_INT16;
+ break;
+
+ case SPECIFIER_INT32:
+ case SPECIFIER_SIGNED | SPECIFIER_INT32:
+ atomic_type = ATOMIC_TYPE_INT32;
+ break;
+
+ case SPECIFIER_INT64:
+ case SPECIFIER_SIGNED | SPECIFIER_INT64:
+ atomic_type = ATOMIC_TYPE_INT64;
+ break;
+
+ case SPECIFIER_INT128:
+ case SPECIFIER_SIGNED | SPECIFIER_INT128:
+ atomic_type = ATOMIC_TYPE_INT128;
+ break;
+
case SPECIFIER_FLOAT:
atomic_type = ATOMIC_TYPE_FLOAT;
break;
T(_MS, based, "_based",)
T(_MS, __based, "__based", = T_based)
-T(_MS, ptr32, "__ptr32",)
-T(_MS, ptr64, "__ptr64",)
-T(_MS, sptr, "__sptr",)
-T(_MS, uptr, "__uptr",)
-T(_MS, w64, "__w64",)
+T(_MS, __ptr32, "__ptr32",)
+T(_MS, __ptr64, "__ptr64",)
+T(_MS, __sptr, "__sptr",)
+T(_MS, __uptr, "__uptr",)
+T(_MS, __w64, "__w64",)
-T(_MS, int8, "_int8",)
-T(_MS, __int8, "__int8", = T_int8)
-T(_MS, int16, "_int16",)
-T(_MS, __int16, "__int16", = T_int16)
-T(_MS, int32, "_int32",)
-T(_MS, __int32, "__int32", = T_int32)
-T(_MS, int64, "_int64",)
-T(_MS, __int64, "__int64", = T_int64)
+T(_MS, _int8, "_int8",)
+T(_MS, __int8, "__int8", = T__int8)
+T(_MS, _int16, "_int16",)
+T(_MS, __int16, "__int16", = T__int16)
+T(_MS, _int32, "_int32",)
+T(_MS, __int32, "__int32", = T__int32)
+T(_MS, _int64, "_int64",)
+T(_MS, __int64, "__int64", = T__int64)
+T(_MS, _int128, "_int128",)
+T(_MS, __int128, "__int128", = T__int128)
#undef _T
#include "symbol_t.h"
#include "type_hash.h"
#include "adt/error.h"
+#include "lang_features.h"
static struct obstack _type_obst;
static FILE *out;
{
print_type_qualifiers(type->type.qualifiers);
- const char *s;
- switch(type->akind) {
- case ATOMIC_TYPE_INVALID: s = "INVALIDATOMIC"; break;
- case ATOMIC_TYPE_VOID: s = "void"; break;
- case ATOMIC_TYPE_BOOL: s = "_Bool"; break;
- case ATOMIC_TYPE_CHAR: s = "char"; break;
- case ATOMIC_TYPE_SCHAR: s = "signed char"; break;
- case ATOMIC_TYPE_UCHAR: s = "unsigned char"; break;
- case ATOMIC_TYPE_INT: s = "int"; break;
- case ATOMIC_TYPE_UINT: s = "unsigned int"; break;
- case ATOMIC_TYPE_SHORT: s = "short"; break;
- case ATOMIC_TYPE_USHORT: s = "unsigned short"; break;
- case ATOMIC_TYPE_LONG: s = "long"; break;
- case ATOMIC_TYPE_ULONG: s = "unsigned long"; break;
- case ATOMIC_TYPE_LONGLONG: s = "long long"; break;
- case ATOMIC_TYPE_ULONGLONG: s = "unsigned long long"; break;
- case ATOMIC_TYPE_LONG_DOUBLE: s = "long double"; break;
- case ATOMIC_TYPE_FLOAT: s = "float"; break;
- case ATOMIC_TYPE_DOUBLE: s = "double"; break;
- default: s = "UNKNOWNATOMIC"; break;
+ const char *s = "INVALIDATOMIC";
+ switch((atomic_type_kind_t) type->akind) {
+ case ATOMIC_TYPE_INVALID: break;
+ case ATOMIC_TYPE_VOID: s = "void"; break;
+ case ATOMIC_TYPE_BOOL: s = "_Bool"; break;
+ case ATOMIC_TYPE_CHAR: s = "char"; break;
+ case ATOMIC_TYPE_SCHAR: s = "signed char"; break;
+ case ATOMIC_TYPE_UCHAR: s = "unsigned char"; break;
+ case ATOMIC_TYPE_INT: s = "int"; break;
+ case ATOMIC_TYPE_UINT: s = "unsigned int"; break;
+ case ATOMIC_TYPE_SHORT: s = "short"; break;
+ case ATOMIC_TYPE_USHORT: s = "unsigned short"; break;
+ case ATOMIC_TYPE_LONG: s = "long"; break;
+ case ATOMIC_TYPE_ULONG: s = "unsigned long"; break;
+ case ATOMIC_TYPE_LONGLONG: s = "long long"; break;
+ case ATOMIC_TYPE_ULONGLONG: s = "unsigned long long"; break;
+ case ATOMIC_TYPE_LONG_DOUBLE: s = "long double"; break;
+ case ATOMIC_TYPE_FLOAT: s = "float"; break;
+ case ATOMIC_TYPE_DOUBLE: s = "double"; break;
+ case ATOMIC_TYPE_INT8: s = "__int8"; break;
+ case ATOMIC_TYPE_INT16: s = "__int16"; break;
+ case ATOMIC_TYPE_INT32: s = "__int32"; break;
+ case ATOMIC_TYPE_INT64: s = "__int64"; break;
+ case ATOMIC_TYPE_INT128: s = "__int128"; break;
+ case ATOMIC_TYPE_UINT8: s = "unsigned __int8"; break;
+ case ATOMIC_TYPE_UINT16: s = "unsigned __int16"; break;
+ case ATOMIC_TYPE_UINT32: s = "unsigned __int32"; break;
+ case ATOMIC_TYPE_UINT64: s = "unsigned __int64"; break;
+ case ATOMIC_TYPE_UINT128: s = "unsigned __int128"; break;
+ case ATOMIC_TYPE_FLOAT_COMPLEX: s = "_Complex float"; break;
+ case ATOMIC_TYPE_DOUBLE_COMPLEX: s = "_Complex float"; break;
+ case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX: s = "_Complex float"; break;
+ case ATOMIC_TYPE_FLOAT_IMAGINARY: s = "_Imaginary float"; break;
+ case ATOMIC_TYPE_DOUBLE_IMAGINARY: s = "_Imaginary float"; break;
+ case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY: s = "_Imaginary float"; break;
}
fputs(s, out);
}
if(type->kind != TYPE_ATOMIC)
return false;
- switch(type->atomic.akind) {
+ switch((atomic_type_kind_t) type->atomic.akind) {
case ATOMIC_TYPE_BOOL:
case ATOMIC_TYPE_CHAR:
case ATOMIC_TYPE_SCHAR:
case ATOMIC_TYPE_ULONG:
case ATOMIC_TYPE_LONGLONG:
case ATOMIC_TYPE_ULONGLONG:
+ case ATOMIC_TYPE_INT8:
+ case ATOMIC_TYPE_INT16:
+ case ATOMIC_TYPE_INT32:
+ case ATOMIC_TYPE_INT64:
+ case ATOMIC_TYPE_INT128:
+ case ATOMIC_TYPE_UINT8:
+ case ATOMIC_TYPE_UINT16:
+ case ATOMIC_TYPE_UINT32:
+ case ATOMIC_TYPE_UINT64:
+ case ATOMIC_TYPE_UINT128:
return true;
- default:
+
+ case ATOMIC_TYPE_INVALID:
+ case ATOMIC_TYPE_VOID:
+ case ATOMIC_TYPE_FLOAT:
+ case ATOMIC_TYPE_DOUBLE:
+ case ATOMIC_TYPE_LONG_DOUBLE:
+ case ATOMIC_TYPE_FLOAT_COMPLEX:
+ case ATOMIC_TYPE_DOUBLE_COMPLEX:
+ case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
+ case ATOMIC_TYPE_FLOAT_IMAGINARY:
+ case ATOMIC_TYPE_DOUBLE_IMAGINARY:
+ case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
return false;
}
+
+ panic("unexpected atomic type kind");
}
/**
if(type->kind != TYPE_ATOMIC)
return false;
- switch(type->atomic.akind) {
+ switch((atomic_type_kind_t) type->atomic.akind) {
case ATOMIC_TYPE_FLOAT:
case ATOMIC_TYPE_DOUBLE:
case ATOMIC_TYPE_LONG_DOUBLE:
-#ifdef PROVIDE_COMPLEX
case ATOMIC_TYPE_FLOAT_COMPLEX:
case ATOMIC_TYPE_DOUBLE_COMPLEX:
case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
case ATOMIC_TYPE_FLOAT_IMAGINARY:
case ATOMIC_TYPE_DOUBLE_IMAGINARY:
case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
-#endif
return true;
- default:
+
+ case ATOMIC_TYPE_INVALID:
+ case ATOMIC_TYPE_VOID:
+ case ATOMIC_TYPE_BOOL:
+ case ATOMIC_TYPE_CHAR:
+ case ATOMIC_TYPE_SCHAR:
+ case ATOMIC_TYPE_UCHAR:
+ case ATOMIC_TYPE_SHORT:
+ case ATOMIC_TYPE_USHORT:
+ case ATOMIC_TYPE_INT:
+ case ATOMIC_TYPE_UINT:
+ case ATOMIC_TYPE_LONG:
+ case ATOMIC_TYPE_ULONG:
+ case ATOMIC_TYPE_LONGLONG:
+ case ATOMIC_TYPE_ULONGLONG:
+ case ATOMIC_TYPE_INT8:
+ case ATOMIC_TYPE_INT16:
+ case ATOMIC_TYPE_INT32:
+ case ATOMIC_TYPE_INT64:
+ case ATOMIC_TYPE_INT128:
+ case ATOMIC_TYPE_UINT8:
+ case ATOMIC_TYPE_UINT16:
+ case ATOMIC_TYPE_UINT32:
+ case ATOMIC_TYPE_UINT64:
+ case ATOMIC_TYPE_UINT128:
return false;
}
+
+ panic("unexpected atomic type kind");
}
/**
if(type->kind != TYPE_ATOMIC)
return false;
- switch(type->atomic.akind) {
+ switch((atomic_type_kind_t) type->atomic.akind) {
case ATOMIC_TYPE_CHAR:
case ATOMIC_TYPE_SCHAR:
case ATOMIC_TYPE_SHORT:
case ATOMIC_TYPE_FLOAT:
case ATOMIC_TYPE_DOUBLE:
case ATOMIC_TYPE_LONG_DOUBLE:
-#ifdef PROVIDE_COMPLEX
+ case ATOMIC_TYPE_INT8:
+ case ATOMIC_TYPE_INT16:
+ case ATOMIC_TYPE_INT32:
+ case ATOMIC_TYPE_INT64:
+ case ATOMIC_TYPE_INT128:
case ATOMIC_TYPE_FLOAT_COMPLEX:
case ATOMIC_TYPE_DOUBLE_COMPLEX:
case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
case ATOMIC_TYPE_FLOAT_IMAGINARY:
case ATOMIC_TYPE_DOUBLE_IMAGINARY:
case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
-#endif
return true;
case ATOMIC_TYPE_BOOL:
case ATOMIC_TYPE_UINT:
case ATOMIC_TYPE_ULONG:
case ATOMIC_TYPE_ULONGLONG:
+ case ATOMIC_TYPE_UINT8:
+ case ATOMIC_TYPE_UINT16:
+ case ATOMIC_TYPE_UINT32:
+ case ATOMIC_TYPE_UINT64:
+ case ATOMIC_TYPE_UINT128:
return false;
case ATOMIC_TYPE_VOID:
case ATOMIC_TYPE_INVALID:
- case ATOMIC_TYPE_LAST:
return false;
}
return type;
}
+unsigned get_atomic_type_size(atomic_type_kind_t kind)
+{
+ switch(kind) {
+ case ATOMIC_TYPE_CHAR:
+ case ATOMIC_TYPE_SCHAR:
+ case ATOMIC_TYPE_UCHAR:
+ case ATOMIC_TYPE_INT8:
+ case ATOMIC_TYPE_UINT8:
+ return 1;
+
+ case ATOMIC_TYPE_SHORT:
+ case ATOMIC_TYPE_USHORT:
+ case ATOMIC_TYPE_INT16:
+ case ATOMIC_TYPE_UINT16:
+ return 2;
+
+ case ATOMIC_TYPE_INT32:
+ case ATOMIC_TYPE_UINT32:
+ return 4;
+
+ case ATOMIC_TYPE_INT64:
+ case ATOMIC_TYPE_UINT64:
+ return 8;
+
+ case ATOMIC_TYPE_INT128:
+ case ATOMIC_TYPE_UINT128:
+ return 16;
+
+ case ATOMIC_TYPE_BOOL:
+ case ATOMIC_TYPE_INT:
+ case ATOMIC_TYPE_UINT:
+ return machine_size >> 3;
+
+ case ATOMIC_TYPE_LONG:
+ case ATOMIC_TYPE_ULONG:
+ return machine_size > 16 ? machine_size >> 3 : 4;
+
+ case ATOMIC_TYPE_LONGLONG:
+ case ATOMIC_TYPE_ULONGLONG:
+ return machine_size > 16 ? 8 : 4;
+
+ case ATOMIC_TYPE_FLOAT_IMAGINARY:
+ case ATOMIC_TYPE_FLOAT:
+ return 4;
+
+ case ATOMIC_TYPE_DOUBLE_IMAGINARY:
+ case ATOMIC_TYPE_DOUBLE:
+ return 8;
+
+ case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
+ case ATOMIC_TYPE_LONG_DOUBLE:
+ return 12;
+
+ case ATOMIC_TYPE_VOID:
+ return 1;
+
+ case ATOMIC_TYPE_FLOAT_COMPLEX:
+ return 2 * get_atomic_type_size(ATOMIC_TYPE_FLOAT);
+
+ case ATOMIC_TYPE_DOUBLE_COMPLEX:
+ return 2 * get_atomic_type_size(ATOMIC_TYPE_DOUBLE);
+
+ case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
+ return 2 * get_atomic_type_size(ATOMIC_TYPE_LONG_DOUBLE);
+
+ case ATOMIC_TYPE_INVALID:
+ break;
+ }
+ panic("Trying to determine size of invalid atomic type");
+}
+
/**
* Hash the given type and return the "singleton" version
* of it.
#include "ast.h"
#include "symbol.h"
+/* note that the constant values represent the rank of the types as defined
+ * in § 6.3.1 */
+typedef enum {
+ ATOMIC_TYPE_INVALID = 0,
+ ATOMIC_TYPE_VOID,
+ ATOMIC_TYPE_CHAR,
+ ATOMIC_TYPE_SCHAR,
+ ATOMIC_TYPE_UCHAR,
+ ATOMIC_TYPE_SHORT,
+ ATOMIC_TYPE_USHORT,
+ ATOMIC_TYPE_INT,
+ ATOMIC_TYPE_UINT,
+ ATOMIC_TYPE_LONG,
+ ATOMIC_TYPE_ULONG,
+ ATOMIC_TYPE_LONGLONG,
+ ATOMIC_TYPE_ULONGLONG,
+ ATOMIC_TYPE_FLOAT,
+ ATOMIC_TYPE_DOUBLE,
+ ATOMIC_TYPE_LONG_DOUBLE,
+ ATOMIC_TYPE_BOOL,
+ /* microsoft extensions */
+ ATOMIC_TYPE_INT8,
+ ATOMIC_TYPE_INT16,
+ ATOMIC_TYPE_INT32,
+ ATOMIC_TYPE_INT64,
+ ATOMIC_TYPE_INT128,
+ ATOMIC_TYPE_UINT8,
+ ATOMIC_TYPE_UINT16,
+ ATOMIC_TYPE_UINT32,
+ ATOMIC_TYPE_UINT64,
+ ATOMIC_TYPE_UINT128,
+
+ ATOMIC_TYPE_FLOAT_COMPLEX,
+ ATOMIC_TYPE_DOUBLE_COMPLEX,
+ ATOMIC_TYPE_LONG_DOUBLE_COMPLEX,
+ ATOMIC_TYPE_FLOAT_IMAGINARY,
+ ATOMIC_TYPE_DOUBLE_IMAGINARY,
+ ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY,
+
+ ATOMIC_TYPE_LAST = ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY
+} atomic_type_kind_t;
+
typedef struct type_base_t type_base_t;
typedef struct atomic_type_t atomic_type_t;
typedef struct pointer_type_t pointer_type_t;
type_t *get_unqualified_type(type_t *type);
type_t *skip_typeref(type_t *type);
+/**
+ * returns size of an atomic type kind in bytes
+ */
+unsigned get_atomic_type_size(atomic_type_kind_t kind);
+
+/**
+ * returns alignment of an atomic type kind in bytes
+ */
+unsigned get_atomic_type_align(atomic_type_kind_t kind);
+
#endif
TYPE_TYPEOF,
} type_kind_t;
-/* note that the constant values represent the rank of the types as defined
- * in § 6.3.1 */
-typedef enum {
- ATOMIC_TYPE_INVALID = 0,
- ATOMIC_TYPE_VOID,
- ATOMIC_TYPE_CHAR,
- ATOMIC_TYPE_SCHAR,
- ATOMIC_TYPE_UCHAR,
- ATOMIC_TYPE_SHORT,
- ATOMIC_TYPE_USHORT,
- ATOMIC_TYPE_INT,
- ATOMIC_TYPE_UINT,
- ATOMIC_TYPE_LONG,
- ATOMIC_TYPE_ULONG,
- ATOMIC_TYPE_LONGLONG,
- ATOMIC_TYPE_ULONGLONG,
- ATOMIC_TYPE_FLOAT,
- ATOMIC_TYPE_DOUBLE,
- ATOMIC_TYPE_LONG_DOUBLE,
- ATOMIC_TYPE_BOOL,
-#ifdef PROVIDE_COMPLEX
- ATOMIC_TYPE_FLOAT_COMPLEX,
- ATOMIC_TYPE_DOUBLE_COMPLEX,
- ATOMIC_TYPE_LONG_DOUBLE_COMPLEX,
- ATOMIC_TYPE_FLOAT_IMAGINARY,
- ATOMIC_TYPE_DOUBLE_IMAGINARY,
- ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY,
-#endif
- ATOMIC_TYPE_LAST
-} atomic_type_kind_t;
-
typedef enum {
TYPE_QUALIFIER_NONE = 0,
TYPE_QUALIFIER_CONST = 1 << 0,