Example #1
0
        int type_rank(Type *type)
        {
            int rank = type_ranks[(int)type->kind];

            assert(rank != 0);
            return(rank);
        }
Example #2
0
        Type *unsigned_type(Type *type)
        {
            switch (type->kind)
            {
            case TYPE_BOOL:
                return(type_bool);

            case TYPE_CHAR:
            case TYPE_SCHAR:
            case TYPE_UCHAR:
                return(type_uchar);

            case TYPE_SHORT:
            case TYPE_USHORT:
                return(type_ushort);

            case TYPE_INT:
            case TYPE_UINT:
                return(type_uint);

            case TYPE_LONG:
            case TYPE_ULONG:
                return(type_ulong);

            case TYPE_LLONG:
            case TYPE_ULLONG:
                return(type_ullong);

            default:
                assert(false);
                return(null);
            }
        }
Example #3
0
 Type *type_func(Type *[] params_a, int num_params, Type *ret, bool intrinsic, bool has_varargs, Type *varargs_type)
 {
     fixed(Type ** @params = params_a)
     {
         return(type_func(@params, num_params, ret, intrinsic, has_varargs, varargs_type));
     }
 }
Example #4
0
        Type *type_array(Type * @base, int num_elems, bool incomplete_elems)
        {
            var hash   = Map.hash_mix(Map.hash_ptr(@base), Map.hash_uint64((ulong)num_elems));
            var key    = hash != 0 ? hash : 1;
            var cached = (CachedArrayType *)cached_array_types.map_get_from_uint64(key);

            if (!incomplete_elems)
            {
                for (CachedArrayType *it = cached; it != null; it = it->next)
                {
                    Type *t = it->type;
                    if (t->@base == @base && t->num_elems == num_elems)
                    {
                        return(t);
                    }
                }
            }
            complete_type(@base);
            Type *type = type_alloc(TYPE_ARRAY);

            type->nonmodifiable    = @base->nonmodifiable;
            type->size             = num_elems * type_sizeof(@base);
            type->align            = type_alignof(@base);
            type->@base            = @base;
            type->num_elems        = num_elems;
            type->incomplete_elems = incomplete_elems;
            if (!incomplete_elems)
            {
                CachedArrayType *new_cached = xmalloc <CachedArrayType>();
                new_cached->type = type;
                new_cached->next = cached;
                cached_array_types.map_put_from_uint64(key, new_cached);
            }
            return(type);
        }
Example #5
0
        Type *type_complete_union(Type *type, TypeField *fields, int num_fields)
        {
            assert(type->kind == TYPE_COMPLETING);
            type->kind  = TYPE_UNION;
            type->size  = 0;
            type->align = 0;
            bool nonmodifiable = false;
            var  new_fields    = Buffer <TypeField> .Create();

            for (var it = fields; it != fields + num_fields; it++)
            {
                assert(it->type->kind > TYPE_COMPLETING);
                if (it->name != null)
                {
                    it->offset = 0;
                    new_fields.Add(it);
                }
                else
                {
                    add_type_fields(&new_fields, it->type, 0);
                }

                type->align   = MAX(type->align, type_alignof(it->type));
                type->size    = MAX(type->size, type_sizeof(it->type));
                nonmodifiable = it->type->nonmodifiable || nonmodifiable;
            }

            type->size                 = ALIGN_UP(type->size, type->align);
            type->aggregate.fields     = new_fields;
            type->aggregate.num_fields = new_fields.count;
            type->nonmodifiable        = nonmodifiable;
            return(type);
        }
Example #6
0
        Type *type_complete_struct(Type *type, TypeField *fields, int num_fields)
        {
            assert(type->kind == TYPE_COMPLETING);
            type->kind  = TYPE_STRUCT;
            type->size  = 0;
            type->align = 0;
            bool nonmodifiable = false;
            long field_sizes   = 0;
            var  new_fields    = Buffer <TypeField> .Create();

            for (var it = fields; it != fields + num_fields; it++)
            {
                assert(IS_POW2(type_alignof(it->type)));
                if (it->name != null)
                {
                    it->offset = type->size;
                    new_fields.Add(it);
                }
                else
                {
                    add_type_fields(&new_fields, it->type, type->size);
                }
                field_sizes  += type_sizeof(it->type);
                type->align   = MAX(type->align, type_alignof(it->type));
                type->size    = type_sizeof(it->type) + ALIGN_UP(type->size, type_alignof(it->type));
                nonmodifiable = it->type->nonmodifiable || nonmodifiable;
            }
            type->size                 = ALIGN_UP(type->size, type->align);
            type->padding              = type->size - field_sizes;
            type->aggregate.fields     = new_fields;
            type->aggregate.num_fields = new_fields.count;
            type->nonmodifiable        = nonmodifiable;
            return(type);
        }
Example #7
0
        void type_complete_tuple(Type *type, Type **fields, int num_fields)
        {
            type->kind  = TYPE_TUPLE;
            type->size  = 0;
            type->align = 0;
            bool nonmodifiable = false;
            long elem_sizes    = 0;
            var  new_fields    = Buffer <TypeField> .Create();

            for (int i = 0; i < num_fields; i++)
            {
                Type *field = fields[i];
                complete_type(fields[i]);
                assert(IS_POW2(type_alignof(field)));
                char *name      = ("_" + i).ToPtr();
                var   new_field = new TypeField {
                    name   = _I(name),
                    type   = fields[i],
                    offset = type->size,
                };
                new_fields.Add(new_field);
                elem_sizes   += type_sizeof(field);
                type->align   = MAX(type->align, type_alignof(field));
                type->size    = type_sizeof(field) + ALIGN_UP(type->size, type_alignof(field));
                nonmodifiable = field->nonmodifiable || nonmodifiable;
            }
            type->size                 = ALIGN_UP(type->size, type->align);
            type->padding              = type->size - elem_sizes;
            type->aggregate.fields     = new_fields;
            type->aggregate.num_fields = new_fields.count;
            type->nonmodifiable        = nonmodifiable;
        }
Example #8
0
        Type *type_tuple(Type **fields, int num_fields)
        {
            int fields_size = num_fields * PTR_SIZE;
            var hash        = Map.hash_bytes(fields, fields_size);
            var key         = hash != 0 ? hash : 1ul;
            var cached      = (TypeLink *)cached_tuple_types.map_get_from_uint64(key);

            for (TypeLink *it = cached; it != null; it = it->next)
            {
                Type *cached_type = it->type;
                if (cached_type->aggregate.num_fields == num_fields)
                {
                    for (int i = 0; i < num_fields; i++)
                    {
                        if (cached_type->aggregate.fields[i].type != fields[i])
                        {
                            goto next;
                        }
                    }
                    return(cached_type);
                }
                next :;
            }
            Type *type = type_alloc(TYPE_TUPLE);

            type_complete_tuple(type, fields, num_fields);
            TypeLink *new_cached = xmalloc <TypeLink>();

            new_cached->type = type;
            new_cached->next = cached;
            cached_tuple_types.map_put_from_uint64(key, new_cached);
            tuple_types->Add(type);
            return(type);
        }
Example #9
0
 void init_builtin_type(Type *type)
 {
     type->typeid = next_typeid++;
     register_typeid(type);
     type->size  = type_metrics[(int)type->kind].size;
     type->align = type_metrics[(int)type->kind].align;
 }
Example #10
0
 Type *unqualify_ptr_type(Type *type)
 {
     if (type->kind == TYPE_PTR)
     {
         type = type_ptr(unqualify_type(type->@base));
     }
     return(type);
 }
Example #11
0
 Type *qualify_type(Type *type, Type *qual)
 {
     type = unqualify_type(type);
     while (qual->kind == TYPE_CONST)
     {
         type = type_const(type);
         qual = qual->@base;
     }
     return(type);
 }
Example #12
0
        Type *type_enum(Sym *sym, Type * @base)
        {
            Type *type = type_alloc(TYPE_ENUM);

            type->sym   = sym;
            type->@base = @base;
            type->size  = type_int->size;
            type->align = type_int->align;
            return(type);
        }
Example #13
0
 Type *unqualify_type(Type *type)
 {
     if (type->kind == TYPE_CONST)
     {
         return(type->@base);
     }
     else
     {
         return(type);
     }
 }
Example #14
0
        Type *aggregate_item_field_type_from_name(Type *type, char *name)
        {
            assert(is_aggregate_type(type));
            int index = aggregate_item_field_index(type, name);

            if (index < 0)
            {
                return(null);
            }
            return(aggregate_item_field_type_from_index(type, index));
        }
Example #15
0
 void add_type_fields(Buffer <TypeField> *fields, Type *type, long offset)  //TypeField**
 {
     assert(type->kind == TYPE_STRUCT || type->kind == TYPE_UNION);
     for (var i = 0; i < type->aggregate.num_fields; i++)
     {
         TypeField *field = &type->aggregate.fields[i];
         fields->Add(new TypeField {
             name = field->name, type = field->type, offset = (field->offset + offset)
         });
     }
 }
Example #16
0
 int aggregate_item_field_index(Type *type, char *name)
 {
     assert(is_aggregate_type(type));
     for (int i = 0; i < type->aggregate.num_fields; i++)
     {
         if (type->aggregate.fields[i].name == name)
         {
             return(i);
         }
     }
     return(-1);
 }
Example #17
0
 // TODO: This probably shouldn't use an O(n^2) algorithm
 bool has_duplicate_fields(Type *type)
 {
     for (var i = 0; i < type->aggregate.num_fields; i++)
     {
         for (var j = i + 1; j < type->aggregate.num_fields; j++)
         {
             if (type->aggregate.fields[i].name == type->aggregate.fields[j].name)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #18
0
        Type *type_ptr(Type * @base)
        {
            var type = cached_ptr_types.map_get <Type>(@base);

            if (type == null)
            {
                type        = type_alloc(TYPE_PTR);
                type->size  = type_metrics[(int)TYPE_PTR].size;
                type->align = type_metrics[(int)TYPE_PTR].align;
                type->@base = @base;

                cached_ptr_types.map_put(@base, type);
            }
            return(type);
        }
Example #19
0
        bool is_signed_type(Type *type)
        {
            switch (type->kind)
            {
            case TYPE_CHAR:
                return(type_metrics[(int)TYPE_CHAR].sign);

            case TYPE_SCHAR:
            case TYPE_SHORT:
            case TYPE_INT:
            case TYPE_LONG:
            case TYPE_LLONG:
                return(true);

            default:
                return(false);
            }
        }
Example #20
0
        Type *type_const(Type * @base)
        {
            if (@base->kind == TYPE_CONST)
            {
                return(@base);
            }
            Type *type = cached_const_types.map_get <Type>(@base);

            if (type == null)
            {
                complete_type(@base);
                type = type_alloc(TYPE_CONST);
                type->nonmodifiable = true;
                type->size          = @base->size;
                type->align         = @base->align;
                type->@base         = @base;
                cached_const_types.map_put(@base, type);
            }
            return(type);
        }
Example #21
0
        void init_builtin_types()
        {
            init_builtin_type(type_void);
            init_builtin_type(type_bool);
            init_builtin_type(type_char);
            init_builtin_type(type_uchar);
            init_builtin_type(type_schar);
            init_builtin_type(type_short);
            init_builtin_type(type_ushort);
            init_builtin_type(type_int);
            init_builtin_type(type_uint);
            init_builtin_type(type_long);
            init_builtin_type(type_ulong);
            init_builtin_type(type_llong);
            init_builtin_type(type_ullong);
            init_builtin_type(type_float);
            init_builtin_type(type_double);


            type_char_ptr   = type_ptr(type_char);
            type_alloc_func = type_func(new [] { type_usize, type_usize }, 2, type_ptr(type_void), false, false, type_void);
        }
Example #22
0
        Type *type_func(Type ** @params, int num_params, Type *ret, bool intrinsic, bool has_varargs, Type *varargs_type)
        {
            var params_size = num_params * PTR_SIZE;
            var hash        = Map.hash_mix(Map.hash_bytes(@params, params_size), Map.hash_ptr(ret));
            var key         = hash != 0 ? hash : 1;

            var cached = (TypeLink *)cached_func_types.map_get_from_uint64(key);

            for (TypeLink *it = cached; it != null; it = it->next)
            {
                Type *type1 = it->type;
                if (type1->func.num_params == num_params && type1->func.ret == ret && type1->func.intrinsic == intrinsic && type1->func.has_varargs == has_varargs && type1->func.varargs_type == varargs_type)
                {
                    if (memcmp(type1->func.@params, @params, num_params))
                    {
                        return(type1);
                    }
                }
            }

            Type *type = type_alloc(TYPE_FUNC);

            type->size              = type_metrics[(int)TYPE_PTR].size;
            type->align             = type_metrics[(int)TYPE_PTR].align;
            type->func.@params      = (Type **)memdup(@params, params_size);
            type->func.num_params   = num_params;
            type->func.intrinsic    = intrinsic;
            type->func.has_varargs  = has_varargs;
            type->func.varargs_type = varargs_type;
            type->func.ret          = ret;
            TypeLink *new_cached = xmalloc <TypeLink>();

            new_cached->type = type;
            new_cached->next = cached;
            cached_func_types.map_put_from_uint64(key, new_cached);
            return(type);
        }
Example #23
0
 bool is_ptr_like_type(Type *type)
 {
     return(type != null && type->kind == TYPE_PTR || type->kind == TYPE_FUNC);
 }
Example #24
0
 bool is_incomplete_array_type(Type *type)
 {
     return(type != null && is_array_type(type) && type->num_elems == 0);
 }
Example #25
0
 bool is_array_type(Type *type)
 {
     return(type != null && type->kind == TYPE_ARRAY);
 }
Example #26
0
 long type_alignof(Type *type)
 {
     assert(type->kind > TYPE_COMPLETING);
     assert(IS_POW2(type->align));
     return(type->align);
 }
Example #27
0
 bool is_const_type(Type *type)
 {
     return(type != null && type->kind == TYPE_CONST);
 }
Example #28
0
 void register_typeid(Type *type)
 {
     typeid_map.map_put((void *)type->typeid, type);
 }
Example #29
0
 long type_sizeof(Type *type)
 {
     assert(type->kind > TYPE_COMPLETING);
     return(type->size);
 }
Example #30
0
 Type *aggregate_item_field_type_from_index(Type *type, int index)
 {
     assert(is_aggregate_type(type));
     assert(0 <= index && index < (int)type->aggregate.num_fields);
     return(type->aggregate.fields[index].type);
 }