⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cctype.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	CCTYPE.C - Type checking and conversion during parsing
**
**	(c) Copyright Ken Harrenstien 1989
**		All changes after v.123, 4-Jun-1988
**	(c) Copyright Ken Harrenstien, SRI International 1985, 1986
**		All changes after v.41, 8-Aug-1985 (complete re-write)
*/

#include "cc.h"

/* Imported functions */
extern NODE *evalexpr(NODE *);				/* CCEVAL */
extern NODE *ndef(int op, TYPE *t, int f, NODE *l, NODE *r);	/* CCNODE */
extern NODE *ndeftl(int op, TYPE *t, NODE *l);		/* CCNODE */
extern NODE *ndeficonst(INT val);			/* CCNODE */
extern TYPE *findtype(int, TYPE *), *findutype(TYPE *), 
	 *findqtype(TYPE *, INT);			/* CCSYM */
extern TYPE *tcomposite(TYPE *, TYPE *);		/* CCSYM */
extern int cmputype(TYPE *, TYPE *);			/* CCSYM */

/* Exported functions */
NODE *convcast(TYPE *, NODE *), *convbinary(NODE *), 
	    *convunary(NODE *), *convarrfn(NODE *),
	    *convasgn(TYPE *, NODE *), *convfunarg(NODE *), 
	    *convnullcomb(NODE *), *convvoidptr(NODE *);
TYPE *convfparam(TYPE *), *convternaryt(NODE *);

/* Internal functions and vars */
static int cast_op(TYPE *, TYPE *);
static int nisnull(NODE **);
static int convisnull(NODE *);
static NODE *ndefcast(int, TYPE *, NODE *);
static void convboth(NODE *, TYPE *);
static NODE *convxboth(NODE *, TYPE *);
#if 0
static void convboth();
static NODE *convxboth();
static int cast_op();
static int nisnull();
static int convisnull();
static NODE *ndefcast();
#endif

#if 0

	How cast conversions and definitions are set up:

CCSYM.H: defines (as enums) all of the cast conversions supported.
	These CAST_ operation values are entered in convtab[]
	and used in N_CAST parse-tree nodes.

Next page: Maps from all possible C conversions into the ones actually
	supported.

Cast conversions must be supported in 3 places:
	(1) here in CCTYPE, which controls parsing semantics of cast exprs.
	(2) in CCEVAL which does compile-time evaluation of constants.
	(3) in CCGEN2 which generates code for run-time conversions.
There is also CCDUMP (to examine parse trees) which is rarely invoked.

The CONVTAB table, plus cast_op(), does two things.  In addition to
specifying whether a given cast is legal, it also specifies the general
nature of the cast.  The evaluator and generator must decide for themselves
how to best derive explicit actions from both this general hint and the
exact type values provided in the N_CAST node.  This allows the parser
to remain relatively independent of the evaluator/generator.  Note that
whenever an exact and unique value is needed for a specific cast, the
"castidx" macro can be used (e.g. in switch statements) to derive this.

/* The following definitions list all of the possible cast conversions
** which are legal in C.  They are grouped by target type, just as for
** the type conversion table in CCTYPE.
*/

	/* All conversions to TS_VOID are allowed. */
	CAST_VOID	/* Value is discarded in all cases. */

	/* No conversions to TS_FUNCT are allowed. */
	/* No conversions to TS_ARRAY are allowed. */

	/* The only conversion to TS_STRUCT is the trivial one. */
	/* The only conversion to TS_UNION  is the trivial one. */
	CAST_TRIV	/* Permit "conversion" only if types identical */

	/* Conversions to TS_PTR.  Lots of checking involved. */
	/* Pointer subtype conversions.  A pointer may have
	** any subtype, including "void" in ANSI C.
	** This means there are N different
	** pointer subtypes which may be converted into any of the other
	** N subtypes.  We'll let the code generation worry about it
	** and punt with "pointer to pointer".
	** Conversions from void, struct/union, enum or floats are illegal.
	*/
	CAST_FN_PF	/* Function -> Pointer to Function */
	CAST_AR_PA	/* Array -> Pointer to 1st Array element */
	CAST_PT_PT	/* Pointer to a Type -> Pointer to another Type */
	CAST_IT_PT	/* Integer type -> Pointer type */

	/* Conversions to TS_ENUM.  All others are illegal. */
	CAST_EN_EN	/* Enum to Enum.  (may wish to check tags) */
	CAST_IT_EN	/* Integer to Enum */

	/* Conversions to TS_FLOAT, TS_DOUBLE, TS_LNGDBL */
	CAST_FP_FP	/* Floating to Floating */
	CAST_IT_FP	/* Integer to Floating */

	/* Conversions to Integer types */
	CAST_IT_IT	/* from Integer Type */
	CAST_FP_IT	/* from Floating-Point type */
	CAST_EN_IT	/* from ENumeration type */
	CAST_PT_IT	/* from Pointer Type */

#endif

/* CONVTAB - Conversion table.
**	This table attempts to be relatively machine independent by only
** indicating the general nature of the conversion required for a particular
** cast.  It is indexed by use of the "castidx" macro.
**
** The value of convtab[castidx(from,to)] will specify the general kind
** of conversion that the code generator will have to apply.
** There are certain special values
** which indicate errors or a need for further checking.
** WARNING!!! If the ordering of the TS_ values defined in CCSYM.H is
** changed, this table needs to be changed too!!
**	Note that most self-to-self integer conversions, such as long to
** long, have CAST_NONE.  However, both bitfields and chars have the general
** CAST_IT_IT type instead, because the size of bitfields can vary, and
** because KCC has a special feature which allows the size of chars to
** also vary.
*/
static char
convtab[TS_MAX*TS_MAX] = {
/* 18 basic types, plus 2 internal (bitfields) */
/* Vo Fn Ar St Un Pt En Fl Db LD SB SC SS SI SL UB UC US UI UL */
/*	Void, Funct, Array,
**	Struct, Union, Pointer, Enum,
**	Float, Double, Long Double,
**	Signed   Bitfield, Char, Short, Int, Long,
**	Unsigned Bitfield, Char, Short, Int, Long
*/

/* Conversions to TS_VOID.  All such conversions are allowed. */
	CAST_VOID,CAST_VOID,CAST_VOID,
	CAST_VOID,CAST_VOID,CAST_VOID,CAST_VOID,
	CAST_VOID,CAST_VOID,CAST_VOID,
	CAST_VOID,CAST_VOID,CAST_VOID,CAST_VOID,CAST_VOID,
	CAST_VOID,CAST_VOID,CAST_VOID,CAST_VOID,CAST_VOID,

/* Conversions to TS_FUNCT.  No such conversion is allowed. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,

/* Conversions to TS_ARRAY.  No such conversion is allowed. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,

/* Conversions to TS_STRUCT.  Only the trivial conversion is allowed. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_TRIV ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,	/* Check it out. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,

/* Conversions to TS_UNION.  Only the trivial conversion is allowed. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_TRIV ,CAST_ILL  ,CAST_ILL  ,	/* Check it out. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,

/* Conversions to TS_PTR.  Lots of checking involved. */
	CAST_ILL  ,CAST_FN_PF,CAST_AR_PA,		/* OK from Fn and Ar */
	CAST_ILL  ,CAST_ILL  ,CAST_PT_PT,CAST_ILL  ,	/* Ptr to ptr */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_IT_PT,CAST_IT_PT,CAST_IT_PT,CAST_IT_PT,CAST_IT_PT,	/* Ints to */
	CAST_IT_PT,CAST_IT_PT,CAST_IT_PT,CAST_IT_PT,CAST_IT_PT,	/* ptrs */

/* Conversions to TS_ENUM.  Only enum and integer source allowed. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_EN_EN,	/* Maybe check tags. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_IT_EN,CAST_IT_EN,CAST_IT_EN,CAST_IT_EN,CAST_IT_EN,	/* Ints to */
	CAST_IT_EN,CAST_IT_EN,CAST_IT_EN,CAST_IT_EN,CAST_IT_EN,	/* enums */

/* Conversions to TS_FLOAT. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_NONE ,CAST_FP_FP,CAST_FP_FP,		/* float to float */
	CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,	/* Ints to */
	CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,	/* float */

/* Conversions to TS_DOUBLE. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_FP_FP,CAST_NONE ,CAST_FP_FP,		/* float to float */
	CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,	/* Ints to */
	CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,	/* float */

/* Conversions to TS_LNGDBL. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_FP_FP,CAST_FP_FP,CAST_NONE ,		/* float to float */
	CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,	/* Ints to */
	CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,CAST_IT_FP,	/* float */

/* Conversions to TS_BITF. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_CHAR. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_SHORT. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_NONE ,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_INT. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_NONE ,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_LONG. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_NONE ,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_UBITF. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_UCHAR. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_USHORT. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_NONE ,CAST_IT_IT,CAST_IT_IT,	/* ints */

/* Conversions to TS_UINT. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_NONE ,CAST_IT_IT,	/* ints */

/* Conversions to TS_ULONG. */
	CAST_ILL  ,CAST_ILL  ,CAST_ILL  ,
	CAST_ILL  ,CAST_ILL  ,CAST_PT_IT,CAST_EN_IT,
	CAST_FP_IT,CAST_FP_IT,CAST_FP_IT,		/* Floats to integer */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,	/* Ints to */
	CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_IT_IT,CAST_NONE ,	/* ints */
};

/* Pointer representation conversion table
**	A C pointer can have several different representations or formats
** depending on what it is pointing to.  We handle this by defining a
** PTRREP_ value for each possible format, and assuming that
** all possible formats are encompassed by pointers to each of the
** possible TS_ values.  This allows us to quickly determine pointer
** format and identify any conversions that are necessary.
**
** PCONVTAB is indexed by the first subtype T (as in "pointer to T").
**	The exception is "pointer to array of T" which becomes
**	"pointer to T" iteratively.
*/

#if 0	/* Commented out for now */

enum ptrspec {
	PTRREP_WD,	/* Pointer to word */
	PTRREP_CH,	/* Pointer to normal char */
	PTRREP_MAX,	/* Max # of pointer rep types */
	PTRREP_CH7,	/* Pointer to 7-bit char */
	PTRREP_ILL,	/* Illegal */
};

static ptyptab[20] = {
 /* 18 basic types */
/* Vo Fn Ar St Un Pt En Fl Db SB SC SS SI SL UB UC US UI UL */
	PTRREP_ILL,	/* (void *) illegal at moment, until ANSI comes */
	PTRREP_WD,	/* function addr */
	PTRREP_ILL,	/* No ptrs to array - should be caught earlier */
	PTRREP_WD,	/* (struct foo *) */
	PTRREP_WD,	/* (union foo *) */
	PTRREP_WD,	/* (type **) */
	PTRREP_WD,	/* (enum foo *) */
	PTRREP_WD,	/* (float *) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -