/* 
 * $Id: C-datatype.h,v 1.1 2002/02/06 16:05:00 msato 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.
 *  
 *  
 *  $
 */
/* C basic data type */

#include "C-ident.h"

/* basic data type */
typedef enum basic_data_type {
    UNDEF,	/* undefined */
    VOID,
    CHAR,
    SHORT,
    INT,
    LONG,
    LONGLONG,
    UNSIGNED_CHAR,
    UNSIGNED_SHORT,
    UNSIGNED,
    UNSIGNED_LONG,
    UNSIGNED_LONGLONG,
    FLOAT,
    DOUBLE,
    LONG_DOUBLE,
    SIGNED,
    BASIC_TYPE_END
} BASIC_DATA_TYPE;

extern char *basic_data_type_names[];

#define BASIC_DATA_TYPE_NAMES \
{ \
    "*undef*",	\
    "void",	\
    "char",	\
    "short",	\
    "int",	\
    "long",	\
    "long_long",\
    "unsigned_char", \
    "unsigned_short", \
    "unsigned", \
    "unsigned_long", \
    "unsigned_long_long", \
    "float", \
    "double", \
    "long_double",\
    "signed", \
}

#define N_BASIC_TYPE 	((int)BASIC_TYPE_END)
#define DEFAULT_TYPE	INT

typedef enum type_qualifier {
    QUAL_NONE = 0,
    QUAL_CONST,		/* const */
    QUAL_VOLATILE,	/* volatile */
    QUAL_INLINE,
    QUAL_CXX_VIRTUAL,	/* C++ */
    QUAL_CXX_FRIEND	/* C++ */
} TYPE_QUAL;

extern char *type_qualifier_names[];

#define TYPE_QUAL_NAMES \
{ \
  "*none*",\
  "const",\
  "volatile",\
  "inline",\
}

typedef struct type_descriptor {
    struct type_descriptor *link;	/* glboal linked list */
    int type_id;		/* type id (for input) */
    enum expr_code code;	/* BASIC_TYPE_NODE, ENUM_TYPE, STRUCT_TYPE,
				 * UNION_TYPE, FUNCTION_DECL, ARRAY_DECL,
				 * POINTER_DECL, ERROR  */
    unsigned int is_const:1;		/* TYPE QUALIFIER */
    unsigned int is_volatile:1;
    unsigned int is_func_proto:1;	/* declared by FUNCTION_PROTO_DECL */
    unsigned int is_referenced:1;
    unsigned int is_inline:1;	/* not implemented, just ingore decl */
    short align;		/* alignment of this type */
    int size;			/* total size in bytes */
    union {
	  BASIC_DATA_TYPE basic_type;		/* for BASIC_TYPE_NODE */
	  struct type_descriptor *ref; 		/* for xxx_DECL */
	  struct ident_descriptor *tagname;	/* FOR STRUCT, UNION */
      } p;
    union {
	  int dim;			/* dimension for ARRY_DECL */
	  expr params;			/* parameter for FUNC_DECL */
	  struct ident_descriptor *members;	/* FOR STRUCT, UNION */
	  expv moe_list;		/* FOR ENUM */
	  struct type_descriptor * master_node;	/* for volatile ENUM/STRUCT/UNION */
      } aux;
} *TYPE_DESC;

#define TYPE_DESC_CODE(tp)	((tp)->code)
#define TYPE_LINK(tp)		((tp)->link)
#define TYPE_SIZE(tp)		((tp)->size)
#define TYPE_ALIGN(tp)		((tp)->align)

#define TYPE_BASIC_TYPE(tp)	((tp)->p.basic_type)
#define TYPE_REF(tp)		((tp)->p.ref)
#define TYPE_TAG_NAME(tp)	((tp)->p.tagname)
#define TYPE_ARRAY_DIM(tp)	((tp)->aux.dim)
#define TYPE_MEMBER_LIST(tp)	(*expv_members_list(tp))
#define TYPE_FUNC_PARAMS(tp)	((tp)->aux.params)
#define TYPE_MOE_LIST(tp)	(*expv_moe_list(tp))
#define TYPE_MASTER_NODE(tp)	((tp)->aux.master_node)

#define TYPE_IS_FUNC_PROTO(tp)	((tp)->is_func_proto)
#define TYPE_IS_CONST(tp)	((tp)->is_const)
#define TYPE_IS_VOLATILE(tp)	((tp)->is_volatile)
#define TYPE_IS_INLINE(tp)	((tp)->is_inline)

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

/* predicate */
#define IS_UNDEF(tp)	\
  (TYPE_DESC_CODE(tp) == BASIC_TYPE_NODE && TYPE_BASIC_TYPE(tp) == UNDEF)
#define IS_INTEGRAL(tp)		is_integral_type(tp)
#define IS_UNSIGNED(tp)		is_unsigned_type(tp)
#define IS_FLOAT(tp)		is_float_type(tp)
#define IS_ARITHMETIC(tp)	(is_integral_type(tp)||is_float_type(tp))
#define IS_POINTER(tp)	\
  (TYPE_DESC_CODE(tp) == POINTER_DECL || TYPE_DESC_CODE(tp) == ARRAY_DECL)
#define IS_SCALAR(tp)		(IS_ARITHMETIC(tp)||IS_POINTER(tp))
#define IS_VOID(tp)	\
  (TYPE_DESC_CODE(tp) == BASIC_TYPE_NODE && TYPE_BASIC_TYPE(tp) == VOID)
#define IS_FUNCTION(tp)		(TYPE_DESC_CODE(tp) == FUNCTION_DECL)
#define IS_ARRAY(tp)		(TYPE_DESC_CODE(tp) == ARRAY_DECL)
#define IS_BASIC_TYPE(tp)	(TYPE_DESC_CODE(tp) == BASIC_TYPE_NODE)
#define IS_STRUCT(tp)		(TYPE_DESC_CODE(tp) == STRUCT_TYPE)
#define IS_UNION(tp)		(TYPE_DESC_CODE(tp) == UNION_TYPE)
#define IS_ENUM(tp)		(TYPE_DESC_CODE(tp) == ENUM_TYPE)
#define IS_COPY_NODE(tp)	((tp)->is_const || (tp->is_volatile))
