/* $Id: type.h,v 1.57 2012/02/17 14:17:00 vrsieh Exp $ 
 *
 * Copyright (C) 2008-2009 FAUcc Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#ifndef __TYPE_H_INCLUDED
#define __TYPE_H_INCLUDED

#include "setup.h"

struct type {
	enum type_type {
		TYPE_NONE,

		TYPE_ELIPSIS,

		TYPE_VOID,
		TYPE_VA_LIST,

		TYPE_INT8,
		TYPE_UINT8,
		TYPE_INT16,
		TYPE_UINT16,
		TYPE_INT32,
		TYPE_UINT32,
		TYPE_INT64,
		TYPE_UINT64,

		TYPE_FLOAT32,
		TYPE_FLOAT64,
		TYPE_FLOAT80,

		TYPE_STRUCT,
		TYPE_UNION,
		TYPE_ENUM,

		TYPE_POINTER,
		TYPE_ARRAY,
		TYPE_FUNCTION,

		TYPE_MAX,
	} type;

	struct type *declarator;

	/* Pointer */
	// struct type *declarator;

	/* Array */
	struct expr *dimension;
	// struct type *declarator;

	/* Function */
	struct scope *parameter;
	// struct type *declarator;

	/* Type Specifier */
	const char *identifier;
	struct scope *scope; /* for struct/union */

	unsigned int mod_const;
	unsigned int mod_volatile;
	unsigned int attr_aligned;
	unsigned int attr_packed;

	struct type *addrof;
	struct type *constof;
	struct type *volatileof;
	struct type *pureof;
};

extern const char *type_info[];

extern void
type_rename_structunionenum(struct type *t, enum type_type type,
		const char *old, const char *new);

extern void
type_rename_type(struct type *t, const char *old, const char *new);

extern int
type_is_type_spec(struct type *dor);
extern int
type_is_void(struct type *t);
extern int
type_is_integer(struct type *t);
extern int
type_is_struct(struct type *t);
extern int
type_is_union(struct type *t);
extern int
type_is_ptrdiff(struct type *t);
extern int
type_is_pointer(struct type *t);
extern int
type_is_array(struct type *t);
extern int
type_is_function(struct type *t);

extern int
type_equal(struct type *t0, struct type *t1);

extern void
type_align_size(struct scope *scope, struct type *t,
		unsigned int *alignp, unsigned int *sizep);
extern unsigned int
type_sizeof(struct scope *scope, struct type *t);
extern unsigned int
type_offsetof(struct scope *scope, struct type *t, const char *mem);

extern struct expr *
type_dimension_get(struct type *abs_decl);
extern struct scope *
type_parameter_get(struct type *abs_decl);

extern struct type *
type_new(void);
extern struct type *
type_type_spec(void);

extern struct type *
type_gen(enum type_type type);

extern struct type *
type_void(void);

extern struct type *
type_int8(void);
extern struct type *
type_uint8(void);
extern struct type *
type_int16(void);
extern struct type *
type_uint16(void);
extern struct type *
type_int32(void);
extern struct type *
type_uint32(void);
extern struct type *
type_int64(void);
extern struct type *
type_uint64(void);

extern struct type *
type_float32(void);
extern struct type *
type_float64(void);
extern struct type *
type_float80(void);

extern struct type *
type_signed_char(void);
extern struct type *
type_unsigned_char(void);
extern struct type *
type_char(void);
extern struct type *
type_short_int(void);
extern struct type *
type_unsigned_short_int(void);
extern struct type *
type_int(void);
extern struct type *
type_unsigned_int(void);
extern struct type *
type_long_int(void);
extern struct type *
type_unsigned_long_int(void);
extern struct type *
type_long_long_int(void);
extern struct type *
type_unsigned_long_long_int(void);
extern struct type *
type_ptrdiff(void);
extern struct type *
type_uintptr_t(void);
extern struct type *
type_float(void);
extern struct type *
type_double(void);
extern struct type *
type_long_double(void);
extern struct type *
type_const_char_pointer(void);
extern struct type *
type_const_char_array(unsigned int dim);

extern struct type *
type_add_pointer(struct type *dor, int const_volatile);
extern struct type *
type_add_array(struct type *dor, struct expr *dimension);
extern struct type *
type_add_function(struct type *dor, struct scope *parameter);
extern struct type *
type_add_user(struct type *dor, struct type *dor_user);

extern struct type *
type_const(struct type *t);
extern struct type *
type_volatile(struct type *t);
extern struct type *
type_aligned(struct scope *scope, struct type *t, unsigned int aligned);
extern struct type *
type_packed(struct scope *scope, struct type *t);
extern struct type *
type_pure(struct type *t);

extern struct type *
type_amphersand(struct type *t);
extern struct type *
type_star(struct type *t);
extern struct type *
type_array_access(struct type *t);
extern struct type *
type_call(struct type *t);

extern struct type *
type_add(struct type *t0, struct type *t1);
extern struct type *
type_sub(struct type *t0, struct type *t1);
extern struct type *
type_arithmetic(struct type *t0, struct type *t1);

extern struct type *
type_pointer_to_ptrdiff(struct type *t);

extern void
type_free(struct type *ad);

#endif /* __TYPE_H_INCLUDED */
