/**
 * check type is omissible, such that
 * no attributes, no memebers, no indexRanage and so on.
 *
 * FIXME:
 * shrink_type() and type_is_omissible() are quick-fix.
 * see shrink_type().
 */
int
type_is_omissible(TYPE_DESC tp, uint32_t attr, uint32_t ext)
{
    // NULL or a terminal type is not omissible.
    if (tp == NULL || TYPE_REF(tp) == NULL)
        return FALSE;
    // The struct type is not omissible.
    if (IS_STRUCT_TYPE(tp))
        return FALSE;
    // The array type is not omissible.
    if (IS_ARRAY_TYPE(tp))
        return FALSE;
    // The function type is not omissible.
    if (IS_FUNCTION_TYPE(tp))
        return FALSE;
    // Co-array is not omissible.
    if (tp->codims != NULL)
        return FALSE;
    // The type has kind, leng, or size is not omissible.
    if (TYPE_KIND(tp) != NULL ||
        TYPE_LENG(tp) != NULL ||
        TYPE_CHAR_LEN(tp) != 0) {
        return FALSE;
    }

#if 0
    // The type has attributes is not omissible.
    if (TYPE_ATTR_FLAGS(tp))
        return FALSE;
    if (TYPE_EXTATTR_FLAGS(tp))
        return FALSE;
#else
    /*
     * not omissible if this type has any attributes that is not
     * included in the given attrribute flags.
     */
    if (TYPE_ATTR_FLAGS(tp) != 0) {
        if ((attr != 0 && (attr & TYPE_ATTR_FLAGS(tp)) == 0) ||
            (attr == 0)) {
            return FALSE;
        }
    }
    if (TYPE_EXTATTR_FLAGS(tp) != 0) {
        if ((ext != 0 && (ext & TYPE_EXTATTR_FLAGS(tp)) == 0) ||
            (ext == 0)) {
            return FALSE;
        }
    }
#endif

    return TRUE;
}
Exemple #2
0
Variant::TypeId Variant::type() const
{
    const std::type_info& info = self->var.type();
    TYPE_KIND(std::string, STRING);
    TYPE_KIND(int32_t, INT32);
    TYPE_KIND(uint32_t, UINT32);
    TYPE_KIND(int64_t, INT64);
    TYPE_KIND(uint64_t, UINT64);
    TYPE_KIND(float, FLOAT);
    TYPE_KIND(double, DOUBLE);
    TYPE_KIND(char, CHAR);
    TYPE_KIND(unsigned char, UCHAR);
    TYPE_KIND(bool, BOOL);

    if(info == typeid(int)) {
        if(self->size == 4) return INT32;
        if(self->size == 8) return INT64;
    }

    if(info == typeid(long)) {
        if(self->size == 4) return INT32;
        if(self->size == 8) return INT64;
    }

    if(info == typeid(unsigned int)) {
        if(self->size == 4) return UINT32;
        if(self->size == 8) return UINT64;
    }

    if(info == typeid(unsigned long)) {
        if(self->size == 4) return UINT32;
        if(self->size == 8) return UINT64;
    }


    return EMPTY;
}
TYPE_DESC
wrap_type(TYPE_DESC tp)
{
    TYPE_DESC tq = new_type_desc();
    if (tp == tq) {
        fatal("%s: must be an malloc() problem, "
              "newly alloc'd TYPE_DESC has duplicated address.",
              __func__);
        /* not reached. */
        return NULL;
    }
    TYPE_REF(tq) = tp;
    if (IS_STRUCT_TYPE(tp)) {
        TYPE_BASIC_TYPE(tq) = TYPE_STRUCT;
    } else {
        TYPE_BASIC_TYPE(tq) = TYPE_BASIC_TYPE(tp);
        TYPE_CHAR_LEN(tq) = TYPE_CHAR_LEN(tp);
        TYPE_KIND(tq) = TYPE_KIND(tp);
        if (TYPE_IS_IMPLICIT(tp))
            TYPE_SET_IMPLICIT(tq);
    }

    return tq;
}
Exemple #4
0
static void sym_initg(Symbol sym, int tkind, int r1, int r2)	/*;sym_initg*/
{
	/* initialize the fields of a symbol used only by the code generator */
	if (tkind<=0) { /* if want to indicate type_size not defined */
		TYPE_SIZE(sym) = -1;
	}
	else {
		TYPE_KIND(sym) = tkind; /* type kind */
		TYPE_SIZE(sym) = su_size(tkind); /* storage units needed*/
	}
	S_SEGMENT(sym) = r1;
	S_OFFSET(sym) = r2;
	/* Note that the correct values of offsets for most of the standard
     * symbols are set by procedure main_data_segment() in glib.c
     */
	/* The following default value of MISC (happily) also corresponds to
     * setting CONTAINS_TASK(sym) to FALSE.
     */
	MISC(sym) = (char *) 0;
}
static TYPE_DESC
get_intrinsic_return_type(intrinsic_entry *ep, expv args, expv kindV) {
    BASIC_DATA_TYPE bType = TYPE_UNKNOWN;
    TYPE_DESC bTypeDsc = NULL;
    TYPE_DESC ret = NULL;
    expv a = NULL;
    
    if (INTR_RETURN_TYPE(ep) == INTR_TYPE_NONE) {
        return NULL;
    }

    if (INTR_RETURN_TYPE_SAME_AS(ep) >= 0) {
        /* return type is in args. */
        a = expr_list_get_n(args, INTR_RETURN_TYPE_SAME_AS(ep));
        if (!(isValidTypedExpv(a))) {
            return NULL;
        }
        ret = EXPV_TYPE(a);
    } else {
        switch (INTR_RETURN_TYPE_SAME_AS(ep)) {

            case -1 /* if not dynamic return type,
                        argument is scalar/array and
                        return type is scalar/array */ :
            case -6 /* if not dynamic return type,
                        argument is scalar/array, return
                        return type is scalar */ : {

                if (!(INTR_IS_RETURN_TYPE_DYNAMIC(ep)) &&
                    (INTR_RETURN_TYPE(ep) != INTR_TYPE_ALL_NUMERICS &&
                     INTR_RETURN_TYPE(ep) != INTR_TYPE_NUMERICS)) {
                    bType = intr_type_to_basic_type(INTR_RETURN_TYPE(ep));
                    if (bType == TYPE_UNKNOWN) {
                        fatal("invalid intrinsic return type (case -1/-6).");
                        /* not reached. */
                        return NULL;
                    } else {
                        if (kindV == NULL) {
                            ret = (bType != TYPE_CHAR) ? type_basic(bType) :
                                type_char(1);
                        } else {
                            /*
                             * Don't use BASIC_TYPE_DESC(bType) very
                             * here, since we need to set a kind to
                             * the TYPE_DESC.
                             */
                            ret = type_basic(bType);
                            TYPE_KIND(ret) = kindV;
                        }
                    }
                    ret = intr_convert_to_dimension_ifneeded(
                        ep, args, ret);
                } else {
                    expv shape = list0(LIST);
                    TYPE_DESC tp;

                    switch (INTR_OP(ep)) {

                    case INTR_ALL:
                    case INTR_ANY:
                    case INTR_MAXVAL:
                    case INTR_MINVAL:
                    case INTR_PRODUCT:
                    case INTR_SUM:
                    case INTR_COUNT:
                    {
                        /* intrinsic arguments */
                        expv array, dim;

                        array = expr_list_get_n(args, 0);
                        if (!(isValidTypedExpv(array))) {
                            return NULL;
                        }
                        tp = EXPV_TYPE(array);

                        dim = expr_list_get_n(args, 1);
                        if (!(isValidTypedExpv(dim))) {
                            return NULL;
                        }

                        /* set basic type of array type */
                        switch (INTR_OP(ep)) {
                        case INTR_ALL:
                        case INTR_ANY:
                            bType = TYPE_LOGICAL;
                            break;
                        case INTR_COUNT:
                            bType = TYPE_INT;
                            break;
                        default:
                            bType = get_basic_type(tp);
                            break;
                        }

                        if (kindV == NULL) {
                            bTypeDsc = BASIC_TYPE_DESC(bType);
                        } else {
                            bTypeDsc = type_basic(bType);
                            TYPE_KIND(bTypeDsc) = kindV;
                        }

                        dim = expv_reduce(dim, FALSE);

                        if(EXPV_CODE(dim) == INT_CONSTANT) {
                            int nDim;
                            nDim  = (int)EXPV_INT_VALUE(dim);

                            if(nDim > TYPE_N_DIM(tp) || nDim <= 0) {
                                error("value DIM of intrinsic %s "
                                      "out of range.", INTR_NAME(ep));
                                return NULL;
                            }

                            generate_contracted_shape_expr(
                                tp, shape, TYPE_N_DIM(tp) - nDim);
                        } else {
                            generate_assumed_shape_expr(
                                shape, TYPE_N_DIM(tp) - 1);
                        }
                    }
                    break;

                    case INTR_SPREAD:
                    {
                        /* intrinsic arguments */
                        expv array, dim, ncopies;

                        array = expr_list_get_n(args, 0);
                        if (!(isValidTypedExpv(array))) {
                            return NULL;
                        }
                        dim = expr_list_get_n(args, 1);
                        if (!(isValidTypedExpv(dim))) {
                            return NULL;
                        }
                        ncopies = expr_list_get_n(args, 2);
                        if (!(isValidTypedExpv(ncopies))) {
                            return NULL;
                        }

                        tp = EXPV_TYPE(array);
                        bType = get_basic_type(tp);
                        if (kindV == NULL) {
                            bTypeDsc = BASIC_TYPE_DESC(bType);
                        } else {
                            bTypeDsc = type_basic(bType);
                            TYPE_KIND(bTypeDsc) = kindV;
                        }

                        dim = expv_reduce(dim, FALSE);

                        if(EXPR_CODE(dim) == INT_CONSTANT) {
                            int nDim;
                            nDim  = (int)EXPV_INT_VALUE(dim);

                            if(nDim > (TYPE_N_DIM(tp) + 1) || nDim <= 0) {
                                error("value DIM of intrinsic %s "
                                      "out of range.", INTR_NAME(ep));
                                return NULL;
                            }

                            generate_expand_shape_expr(
                                tp, shape, ncopies, TYPE_N_DIM(tp) + 1 - nDim);
                        } else {
                            generate_assumed_shape_expr(
                                shape, TYPE_N_DIM(tp) - 1);
                        }
                    }
                    break;

                    case INTR_RESHAPE:
                    {
                        /* intrinsic arguments */
                        expv source, arg_shape;

                        source = expr_list_get_n(args, 0);
                        if (!(isValidTypedExpv(source))) {
                            return NULL;
                        }
                        arg_shape = expr_list_get_n(args, 1);
                        if (!(isValidTypedExpv(arg_shape))) {
                            return NULL;
                        }

                        tp = EXPV_TYPE(source);
                        bType = get_basic_type(tp);
                        if (kindV == NULL) {
                            bTypeDsc = BASIC_TYPE_DESC(bType);
                        } else {
                            bTypeDsc = type_basic(bType);
                            TYPE_KIND(bTypeDsc) = kindV;
                        }

                        tp = EXPV_TYPE(arg_shape);
                        if (TYPE_N_DIM(tp) != 1) {
                            error("SHAPE argument of intrinsic "
                                  "RESHAPE is not vector.");
                            return NULL;
                        }

                        /*
                         * We can't determine # of the elements in
                         * this array that represents dimension of the
                         * return type, which is identical to the
                         * reshaped array. In order to express this,
                         * we introduce a special TYPE_DESC, which is
                         * having a flag to specify that the type is
                         * generated by the reshape() intrinsic.
                         */

                        /*
                         * dummy one dimensional assumed array.
                         */
                        generate_assumed_shape_expr(shape, 2);
                        ret = compile_dimensions(bTypeDsc, shape);
                        fix_array_dimensions(ret);
                        TYPE_IS_RESHAPED(ret) = TRUE;

                        return ret;
                    }
                    break;

                    case INTR_MATMUL:
                    {
                        expv m1 = expr_list_get_n(args, 0);
                        expv m2 = expr_list_get_n(args, 1);
                        TYPE_DESC t1 = EXPV_TYPE(m1);
                        TYPE_DESC t2 = EXPV_TYPE(m2);
                        expv s1 = list0(LIST);
                        expv s2 = list0(LIST);

                        /*
                         * FIXME:
                         *	Should we use
                         *	get_binary_numeric_intrinsic_operation_type()
                         *	instead of max_type()? I think so but
                         *	not sure at this moment.
                         */
                        bType = get_basic_type(max_type(t1, t2));

                        if (kindV == NULL) {
                            bTypeDsc = BASIC_TYPE_DESC(bType);
                        } else {
                            bTypeDsc = type_basic(bType);
                            TYPE_KIND(bTypeDsc) = kindV;
                        }

                        generate_shape_expr(t1, s1);
                        generate_shape_expr(t2, s2);

                        if (TYPE_N_DIM(t1) == 2 &&
                            TYPE_N_DIM(t2) == 2) {
                            /*
                             * (n, m) * (m, k) => (n, k).
                             */
                            shape = list2(LIST,
                                          EXPR_ARG1(s1), EXPR_ARG2(s2));
                        } else if (TYPE_N_DIM(t1) == 2 &&
                                   TYPE_N_DIM(t2) == 1) {
                            /*
                             * (n, m) * (m) => (n).
                             */
                            shape = list1(LIST, EXPR_ARG1(s1));
                        } else if (TYPE_N_DIM(t1) == 1 &&
                                   TYPE_N_DIM(t2) == 2) {
                            /*
                             * (m) * (m, k) => (k).
                             */
                            shape = list1(LIST, EXPR_ARG2(s2));
                        } else {
                            error("an invalid dimension combination for "
                                  "matmul(), %d and %d.",
                                  TYPE_N_DIM(t1), TYPE_N_DIM(t2));
                            return NULL;
                        }

                        ret = compile_dimensions(bTypeDsc, shape);
                        fix_array_dimensions(ret);

                        return ret;
                    }
                    break;

                    case INTR_DOT_PRODUCT:
                    {
                        expv m1 = expr_list_get_n(args, 0);
                        expv m2 = expr_list_get_n(args, 1);
                        TYPE_DESC t1 = EXPV_TYPE(m1);
                        TYPE_DESC t2 = EXPV_TYPE(m2);

                        if (TYPE_N_DIM(t1) == 1 &&
                            TYPE_N_DIM(t2) == 1) {
                            TYPE_DESC tp =
                                get_binary_numeric_intrinsic_operation_type(
                                    t1, t2);
                            return array_element_type(tp);
                        } else {
                            error("argument(s) is not a one-dimensional "
                                  "array.");
                            return NULL;
                        }
                    }
                    break;

		    case INTR_PACK:
		    {

		      if (INTR_N_ARGS(ep) == 3){
			expv v = expr_list_get_n(args, 2);
			return EXPV_TYPE(v);
		      }
		      else {
			a = expr_list_get_n(args, 0);
			if (!(isValidTypedExpv(a))) {
			  return NULL;
			}

			bType = get_basic_type(EXPV_TYPE(a));
			bTypeDsc = BASIC_TYPE_DESC(bType);
			expr dims = list1(LIST, NULL);
			ret = compile_dimensions(bTypeDsc, dims);
			fix_array_dimensions(ret);
			return ret;
		      }
		    }
		    break;

		    case INTR_UNPACK:
		    {
			a = expr_list_get_n(args, 0);
			if (!(isValidTypedExpv(a))) {
			  return NULL;
			}
			bType = get_basic_type(EXPV_TYPE(a));
			bTypeDsc = BASIC_TYPE_DESC(bType);

			a = expr_list_get_n(args, 1);
			if (!(isValidTypedExpv(a))) {
			  return NULL;
			}
			TYPE_DESC tp = EXPV_TYPE(a);
			ret = copy_dimension(tp, bTypeDsc);
			fix_array_dimensions(ret);
			return ret;
		    }
		    break;

                    default:
                    {
                        /* not  reached ! */
                        ret = BASIC_TYPE_DESC(TYPE_GNUMERIC_ALL);
                    }

                    }

                    ret = compile_dimensions(bTypeDsc, shape);
                    fix_array_dimensions(ret);
                }

                break;
            }

            case -2: {
                /*
                 * Returns BASIC_TYPE of the first arg.
                 */
                a = expr_list_get_n(args, 0);
                if (!(isValidTypedExpv(a))) {
                    return NULL;
                }
                bType = get_basic_type(EXPV_TYPE(a));
                if (kindV == NULL) {
                    ret = BASIC_TYPE_DESC(bType);
                } else {
                    ret = type_basic(bType);
                    TYPE_KIND(ret) = kindV;
                }
                break;
            }

            case -3: {
                /*
                 * Returns single dimension array of integer having
                 * elemnets that equals to the first arg's dimension.
                 */
                /*
                 * FIXME:
                 *	No need to check kindV?? I believe we don't, though.
                 */
                bTypeDsc = BASIC_TYPE_DESC(TYPE_INT);
                TYPE_DESC tp = NULL;
                expr dims = NULL;
                int nDims = 0;
                a = expr_list_get_n(args, 0);
                if (!(isValidTypedExpv(a))) {
                    return NULL;
                }

                bTypeDsc = BASIC_TYPE_DESC(TYPE_INT);
                tp = EXPV_TYPE(a);
                nDims = TYPE_N_DIM(tp);
                dims = list1(LIST, make_int_enode(nDims));
                ret = compile_dimensions(bTypeDsc, dims);
                fix_array_dimensions(ret);

                break;
            }

            case -4:{
                /*
                 * Returns transpose of the first arg (matrix).
                 */
                TYPE_DESC tp = NULL;
                expr dims = list0(LIST);

                a = expr_list_get_n(args, 0);
                if (!(isValidTypedExpv(a))) {
                    return NULL;
                }
                tp = EXPV_TYPE(a);
                bType = get_basic_type(tp);
                if (kindV == NULL) {
                    bTypeDsc = BASIC_TYPE_DESC(bType);
                } else {
                    bTypeDsc = type_basic(bType);
                    TYPE_KIND(bTypeDsc) = kindV;
                }

                if (TYPE_N_DIM(tp) != 2) {
                    error("Dimension is not two.");
                    return NULL;
                }

                generate_reverse_dimension_expr(tp, dims);
                ret = compile_dimensions(bTypeDsc, dims);
                fix_array_dimensions(ret);

                break;
            }

            case -5: {
                /*
                 * -5 : BASIC_TYPE of return type is 'returnType' and
                 * kind of return type is same as first arg.
                 */
                int nDims = 0;
                TYPE_DESC tp = NULL;

                a = expr_list_get_n(args, 0);
                if (!(isValidTypedExpv(a))) {
                    return NULL;
                }

                tp = EXPV_TYPE(a);

                switch (INTR_OP(ep)) {
                    case INTR_AIMAG: case INTR_DIMAG: {
                        bType = get_basic_type(tp);
                        if (bType != TYPE_COMPLEX &&
                            bType != TYPE_DCOMPLEX) {
                            error("argument is not a complex type.");
                            return NULL;
                        }
                        bType = (bType == TYPE_COMPLEX) ?
                            TYPE_REAL : TYPE_DREAL;
                        break;
                    }
                    default: {
                        bType = intr_type_to_basic_type(INTR_RETURN_TYPE(ep));
                        break;
                    }
                }

                if (bType == TYPE_UNKNOWN) {
                    fatal("invalid intrinsic return type (case -5).");
                    /* not reached. */
                    return NULL;
                }
                bTypeDsc = type_basic(bType);
                TYPE_KIND(bTypeDsc) = TYPE_KIND(tp);

                if ((nDims = TYPE_N_DIM(tp)) > 0) {
                    ret = copy_dimension(tp, bTypeDsc);
                    fix_array_dimensions(ret);
                } else {
                    ret = bTypeDsc;
                }

                break;
            }

            case -7: {
                TYPE_DESC lhsTp = new_type_desc();
                TYPE_BASIC_TYPE(lhsTp) = TYPE_LHS;
                TYPE_ATTR_FLAGS(lhsTp) |= TYPE_ATTR_TARGET;
                ret = lhsTp;
                break;
            }

            case -8: {
                bType = intr_type_to_basic_type(INTR_RETURN_TYPE(ep));
                if (bType == TYPE_UNKNOWN) {
                    fatal("invalid intrinsic return type (case -8).");
                    return NULL;
                } else {
                    ret = type_basic(bType);
                }
                TYPE_SET_EXTERNAL(ret);
                break;
            }

            case -9: {
                bType = intr_type_to_basic_type(INTR_RETURN_TYPE(ep));
                ret = type_basic(bType);
                break;
            }

            default: {
                fatal("%s: Unknown return type specification.", __func__);
                break;
            }
        }
    }

    return ret;
}