implement MS type extension types
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 17 Mar 2008 15:26:37 +0000 (15:26 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 17 Mar 2008 15:26:37 +0000 (15:26 +0000)
[r18963]

ast2firm.c
parser.c
tokens.inc
type.c
type.h
type_t.h

index 53e55c8..9584f9f 100644 (file)
@@ -212,7 +212,7 @@ static ir_mode *get_ptrmode(unsigned size, char *name)
        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;
 
@@ -245,12 +245,21 @@ static void init_atomic_modes(void) {
        _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));
@@ -263,57 +272,13 @@ static void init_atomic_modes(void) {
 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);
@@ -336,7 +301,7 @@ static unsigned get_type_size_const(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:
@@ -2597,23 +2562,23 @@ typedef enum gcc_type_class
 
 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 */
@@ -2627,47 +2592,61 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
                                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);
index 844ced3..0d012db 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -760,6 +760,23 @@ static type_t *promote_integer(type_t *type)
        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;
 
@@ -1996,9 +2013,14 @@ typedef enum {
        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;
 
@@ -2280,6 +2302,11 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers)
                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")
@@ -2412,6 +2439,52 @@ finish_specifiers:
                        | 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;
index 708fdbf..7299aa5 100644 (file)
@@ -136,19 +136,21 @@ T(_MS,      __declspec,       "__declspec",              = T_declspec)
 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
diff --git a/type.c b/type.c
index 97f38a8..2ef7b85 100644 (file)
--- a/type.c
+++ b/type.c
@@ -26,6 +26,7 @@
 #include "symbol_t.h"
 #include "type_hash.h"
 #include "adt/error.h"
+#include "lang_features.h"
 
 static struct obstack   _type_obst;
 static FILE            *out;
@@ -73,26 +74,41 @@ void print_atomic_type(const atomic_type_t *type)
 {
        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);
 }
@@ -565,7 +581,7 @@ bool is_type_integer(const type_t *type)
        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:
@@ -578,10 +594,33 @@ bool is_type_integer(const type_t *type)
        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");
 }
 
 /**
@@ -597,22 +636,46 @@ bool is_type_float(const type_t *type)
        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");
 }
 
 /**
@@ -632,7 +695,7 @@ bool is_type_signed(const type_t *type)
        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:
@@ -642,14 +705,17 @@ bool is_type_signed(const type_t *type)
        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:
@@ -658,11 +724,15 @@ bool is_type_signed(const type_t *type)
        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;
        }
 
@@ -935,6 +1005,77 @@ type_t *skip_typeref(type_t *type)
        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.
diff --git a/type.h b/type.h
index 8e3cd12..2cd6c28 100644 (file)
--- a/type.h
+++ b/type.h
 #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;
@@ -103,4 +145,14 @@ bool pointers_compatible(const type_t *type1, const type_t *type2);
 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
index 2d602ec..5832550 100644 (file)
--- a/type_t.h
+++ b/type_t.h
@@ -49,37 +49,6 @@ typedef enum {
        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,