/* 
 * $Id: F-datatype.h,v 1.16 2000/12/09 04:30:54 m-hirano Exp $
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */

/* f77 data types */
typedef enum datatype {
    TYPE_UNKNOWN=0,	/* undef or pointer */
    TYPE_SHORT,	/* 1 */
    TYPE_INT,	/* 2 */
    TYPE_REAL,	/* 3 */
    TYPE_DREAL,	/* 4 */
    TYPE_COMPLEX,	/* 5 */
    TYPE_DCOMPLEX,	/* 6 */
    TYPE_LOGICAL,	/* 7 */
    TYPE_CHAR,	/* 8 */
    TYPE_SUBR,	/* 9 */
    TYPE_LONGLONG,	/* 10 'interger*8' */
    TYPE_QREAL,	/* 11 'real*16' */
    TYPE_ARRAY,  /* extended */
    TYPE_EQBLK,	/* equivalence block */
    TYPE_FUNCTION, /* function */
    TYPE_END
} BASIC_DATA_TYPE;

#define N_BASIC_TYPES ((int)TYPE_END)

extern char *basic_type_names[];
#ifdef ENABLE_QREAL
#define BASIC_TYPE_NAMES \
{ \
 "*undef*",	\
 "short",	\
 "integer",	\
 "real",	\
 "double_real",	\
 "complex",	\
 "double_complex",\
 "logical",	\
 "character",	\
 "subroutine",	\
 "longlong",	\
 "quad_real",	\
 "*array*",	\
 "*equivalence*", \
 "*function*",\
}
#else
#define BASIC_TYPE_NAMES \
{ \
 "*undef*",	\
 "short",	\
 "integer",	\
 "real",	\
 "double_real",	\
 "complex",	\
 "double_complex",\
 "logical",	\
 "character",	\
 "subroutine",	\
 "longlong",	\
 "*array*",	\
 "*equivalence*",\
 "*function*",\
}
#endif /* ENABLE_QREAL */

/* FORTRAN type descriptor */
/* FORTRAN does not have nested data structure */
/* pointer type, TYPE_UNKNOWN and ref != NULL */
/* array type, TYPE_ARRAY && ref != NULL */
typedef struct type_descriptor
{
    struct type_descriptor *link;	/* global linked list */
    struct type_descriptor *ref;	/* if not NULL, reference to other */
    BASIC_DATA_TYPE basic_type;
    char is_referenced;
    char n_dim;			/* dimension (max 7) */
    char dim_fixed;		/* fixed or not */
    char dim_fixing;
    int size;			/* array size. if TYPE_CHAR, size is length */
    expv dim_size;
    expv dim_upper,dim_lower;
    void *equivId;
} *TYPE_DESC;

extern TYPE_DESC basic_type_desc[];
#define BASIC_TYPE_DESC(t) basic_type_desc[(int)t]

#define TYPE_LINK(tp)		((tp)->link)
#define TYPE_REF(tp)		((tp)->ref)
#define TYPE_BASIC_TYPE(tp) 	((tp)->basic_type)

#define TYPE_N_DIM(tp)		((tp)->n_dim)
#define TYPE_DIM_FIXED(tp)	((tp)->dim_fixed)
#define TYPE_DIM_FIXING(tp)	((tp)->dim_fixing)
#define TYPE_DIM_SIZE(tp)	((tp)->dim_size)
#define TYPE_DIM_UPPER(tp)	((tp)->dim_upper)
#define TYPE_DIM_LOWER(tp)	((tp)->dim_lower)

#define TYPE_CHAR_LEN(tp) 	((tp)->size)
#define TYPE_ARRAY_SIZE(tp) 	((tp)->size)

#define TYPE_EQUIV_ID(tp)	((tp)->equivId)

#define CHAR_UNKNOWN_LEN (-1)

#define IS_ARRAY_TYPE(tp)   ((tp) != NULL && TYPE_BASIC_TYPE(tp) == TYPE_ARRAY)
#define IS_ELEMENT_TYPE(tp) ((tp) != NULL && (tp)->ref == NULL)
#define IS_FUNCTION_TYPE(tp)   \
((tp) != NULL && TYPE_BASIC_TYPE(tp) == TYPE_FUNCTION)

/* misc. macros */
#define IS_COMPLEX(tp)	\
((tp) != NULL && \
 (TYPE_BASIC_TYPE(tp) == TYPE_COMPLEX || TYPE_BASIC_TYPE(tp) == TYPE_DCOMPLEX))
#ifdef ENABLE_QREAL
#define IS_REAL(tp)	\
((tp) != NULL && \
 (TYPE_BASIC_TYPE(tp) == TYPE_REAL || TYPE_BASIC_TYPE(tp) == TYPE_DREAL || \
  TYPE_BASIC_TYPE(tp) == TYPE_QREAL))
#else
#define IS_REAL(tp)	\
((tp) != NULL && \
 (TYPE_BASIC_TYPE(tp) == TYPE_REAL || TYPE_BASIC_TYPE(tp) == TYPE_DREAL))
#endif /* ENABLE_QREAL */
#define IS_INT(tp)	\
((tp) != NULL && \
 (TYPE_BASIC_TYPE(tp) == TYPE_SHORT || TYPE_BASIC_TYPE(tp) == TYPE_INT || \
  TYPE_BASIC_TYPE(tp) == TYPE_LONGLONG))
#define IS_NUMERIC(tp)	\
((tp) != NULL && (IS_COMPLEX(tp)||IS_REAL(tp)||IS_INT(tp)))
#define IS_CHAR(tp) 	((tp) != NULL && (TYPE_BASIC_TYPE(tp) == TYPE_CHAR))
#define IS_LOGICAL(tp) 	((tp) != NULL && (TYPE_BASIC_TYPE(tp) == TYPE_LOGICAL))
#define IS_SUBR(tp)	((tp) != NULL && (TYPE_BASIC_TYPE(tp) == TYPE_SUBR))

#define IS_INT_CONST_V(v) (IS_INT(EXPV_TYPE(v)) && expr_is_constant(v))
#define IS_REAL_CONST_V(v) (IS_REAL(EXPV_TYPE(v)) && expr_is_constant(v))
#define IS_COMPLEX_CONST_V(v) (IS_COMPLEX(EXPV_TYPE(v)) && expr_is_constant(v))

#define IS_NUMERIC_CONST_V(v)	\
((IS_INT_CONST_V(v)) || (IS_REAL_CONST_V(v)) || (IS_COMPLEX_CONST_V(v)))

/* machine dependent parameter */
extern int type_LOGICAL_SIZE;
extern char *type_LOGICAL_NAME;
extern int type_POINTER_SIZE, type_POINTER_ALIGN;


