📄 decl.c
字号:
/*
* 68K/386 32-bit C compiler.
*
* copyright (c) 1997, David Lindauer
*
* This compiler is intended for educational use. It may not be used
* for profit without the express written consent of the author.
*
* It may be freely redistributed, as long as this notice remains intact
* and either the original sources or derived sources
* are distributed along with any executables derived from the originals.
*
* The author is not responsible for any damages that may arise from use
* of this software, either idirect or consequential.
*
* v1.35 March 1997
* David Lindauer, gclind01@starbase.spd.louisville.edu
*
* Credits to Mathew Brandt for original K&R C compiler
*
*/
/*
* handle ALL declarative statements
*/
#include <stdio.h>
#include <limits.h>
#include "expr.h"
#include "c.h"
#include "errors.h"
extern int stdinttype,stdunstype,stdintsize, stdldoublesize,stdaddrsize;
extern int strucadd,strucmod;
extern char laststr[];
extern int global_flag;
extern TABLE gsyms,lsyms;
extern SNODE *cbautoinithead;
extern int prm_packing;
extern int prm_revbits;
extern int prm_68020;
extern int prm_ansi;
extern HASHREC **globalhash;
extern SYM *currentfunc;
extern int prm_cplusplus;
extern char * tn_unnamed;
extern TYP stdconst;
extern enum e_sym lastst;
extern char lastid[];
extern int block_nesting;
extern long nextlabel;
char *Cstr = "C";
TABLE *active_table; /* This is so enums will not be put in structre tabs */
int mangleflag;
int skm_declopenpa[] = { semicolon, comma,openpa, eq,0 };
int skm_declclosepa[] = { semicolon, comma,closepa, eq,0 };
int skm_declclosebr[] = { comma,closebr, eq,0 };
int skm_declend[] = { semicolon, comma, end, eq,0 };
int skm_decl[] = {semicolon,kw_int, kw_long, kw_short, kw_char, kw_float,
kw_double, kw_struct, kw_union, kw_enum, kw_unsigned, kw_signed, kw_auto,
kw_extern, kw_static, kw_register, kw_typedef, id, kw_void, 0 };
TYP *head = 0;
TYP *tail = 0;
char declid[100];
TABLE tagtable = {0,0};
int ispascal;
static SYM *lastdecl;
static int pcount=0;
static int bittype = -1;
static int curbit = 0;
static int curofs = 0;
static int manglelevel;
static int intflag;
void declini(void)
/*
* init
*/
{
bittype = -1;
head = tail = 0;
declid[0] = 0;
tagtable.head = tagtable.tail = 0;
pcount = 0;
mangleflag = TRUE;
}
int imax(int i,int j)
{ return (i > j) ? i : j;
}
char *litlate(char *s)
{ char *p;
p = xalloc(strlen(s) + 1);
strcpy(p,s);
return p;
}
TYP *maketype(int bt,int siz)
/*
* Create a type list entry
*/
{ TYP *tp;
tp = xalloc(sizeof(TYP));
tp->val_flag = 0;
tp->bits = tp->startbit = -1;
tp->size = siz;
tp->type = bt;
tp->sname = 0;
tp->cflags = 0;
tp->uflags = 0;
tp->lst.head = tp->lst.tail = 0;
tp->tdef = 0;
return tp;
}
TYP *cponetype(TYP *t)
/*
* Copy a entry
*/
{ TYP *tp;
tp = xalloc(sizeof(TYP));
tp->type = t->type;
tp->val_flag = t->val_flag;
tp->cflags = t->cflags;
tp->bits = t->bits;
tp->startbit = t->startbit;
tp->size = t->size;
tp->lst = t->lst;
tp->btp = t->btp;
tp->sname = t->sname;
tp->uflags = t->uflags;
tp->tdef = t->tdef;
return tp;
}
TYP *copytype(TYP *itp, int flags)
/*
* copy a type tree
*/
{
TYP *head, *tail,*x=itp;
while (x->type == bt_pointer)
x = x->btp;
if (x->type == bt_struct || x->type == bt_union)
if (!x->lst.head) {
itp->cflags = flags;
return head = tail = itp;
}
head = tail = cponetype(itp);
while (itp->type == bt_pointer) {
tail = tail->btp = cponetype(itp->btp);
itp = itp->btp;
}
if (itp->type == bt_func || itp->type == bt_ptrfunc || itp->type == bt_ifunc) {
tail->btp = cponetype(itp->btp);
}
else {
tail->cflags |= flags;
}
return head;
}
void decl(TABLE *table)
/*
* parse the declare keywords and create a basic type
*/
{
int tp;
SYM *sp;
int flags = 0;
while (lastst == kw_const || lastst == kw_volatile) {
if (lastst == kw_const)
flags |= DF_CONST;
else
flags |= DF_VOL;
getsym();
}
switch (lastst) {
case kw_void:
head = tail = maketype(bt_void,0);
getsym();
break;
case kw_char:
head = tail = maketype(bt_char,1);
getsym();
break;
case kw_short:
getsym();
tp = bt_short;
if (lastst == kw_unsigned) {
tp = bt_unsignedshort;
getsym();
}
if (lastst == kw_int)
getsym();
head = tail = maketype(tp,2);
break;
case kw_int:
head = tail = maketype(stdinttype,stdintsize);
getsym();
break;
case kw_unsigned:
getsym();
switch (lastst) {
case kw_char:
getsym();
head = tail = maketype(bt_unsignedchar,1);
break;
case kw_short:
getsym();
if (lastst == kw_int)
getsym();
head = tail = maketype(bt_unsignedshort,2);
break;
case kw_long:
getsym();
if (lastst == kw_long) {
getsym();
generror(ERR_LONGLONG,0,0);
}
if (lastst == kw_int)
getsym();
head = tail = maketype(bt_unsigned,4);
break;
case kw_int:
getsym();
default:
head = tail = maketype(stdunstype,stdintsize);
break;
}
break;
case kw_signed:
getsym();
switch (lastst) {
case kw_char:
getsym();
head = tail = maketype(bt_char,1);
break;
case kw_short:
getsym();
if (lastst == kw_int)
getsym();
head = tail = maketype(bt_short,2);
break;
case kw_long:
getsym();
if (lastst == kw_long) {
getsym();
generror(ERR_LONGLONG,0,0);
}
if (lastst == kw_int)
getsym();
head = tail = maketype(bt_long,4);
break;
case kw_int:
getsym();
default:
head = tail = maketype(stdinttype,stdintsize);
break;
}
break;
case id: /* no type declarator */
if ((sp = gsearch(lastid)) != 0 && sp->storage_class == sc_type) {
head = tail = copytype(sp->tp,flags);
getsym();
}
else
head = tail = maketype(bt_long,4);
break;
case kw_float:
head = tail = maketype(bt_float,4);
getsym();
break;
case kw_long:
getsym();
if (lastst==kw_double) {
getsym();
head = tail = maketype(bt_longdouble,stdldoublesize);
break;
}
if (lastst==kw_float) {
getsym();
head = tail = maketype(bt_double,8);
break;
}
if (lastst == kw_long) {
getsym();
generror(ERR_LONGLONG,0,0);
}
tp = bt_long;
if (lastst == kw_unsigned) {
tp = bt_unsigned;
getsym();
}
if (lastst == kw_long) {
getsym();
generror(ERR_LONGLONG,0,0);
}
if (lastst == kw_int)
getsym();
head = tail = maketype(tp,4);
break;
case kw_double:
head = tail = maketype(bt_double,8);
getsym();
break;
case kw_enum:
getsym();
declenum(table);
break;
case kw_struct:
getsym();
declstruct(table, bt_struct,flags);
break;
case kw_union:
getsym();
declstruct(table, bt_union,flags);
break;
}
head->cflags |= flags;
head->uflags |= UF_CANASSIGN;
}
void decl1(void)
/*
* Modifiers that could occur BEFORE the name of the var
*/
{ TYP *temp1, *temp2, *temp3, *temp4;
lp:
switch (lastst) {
case kw_const:
head->cflags |= DF_CONST;
getsym();
goto lp;
case kw_volatile:
head->cflags |= DF_VOL;
getsym();
goto lp;
case kw__pascal:
ispascal = TRUE;
getsym();
goto lp;
case id:
strcpy(declid,lastid);
getsym();
decl2();
break;
case and:
#ifdef CPLUSPLUS
if (prm_cplusplus) {
getsym();
if (prm_cplusplus) {
decl1();
if (head->type == bt_ref || head->type == bt_pointer)
generror(ERR_CANTREF,0,0);
else {
temp1 = maketype(bt_ref,4);
temp1->btp = head;
head = temp1;
if (tail == NULL)
tail = head;
}
}
else
generror(ERR_NOREF,0,0);
}
else
#endif
{
decl2();
break;
}
break;
case star:
head->uflags &= ~UF_CANASSIGN;
temp1 = maketype(bt_pointer,4);
temp1->btp = head;
head = temp1;
head->uflags |= UF_CANASSIGN;
if(tail == NULL)
tail = head;
getsym();
decl1();
break;
case openpa:
getsym();
temp1 = head;
temp2 = tail;
/* Check here for function pointer */
if (lastst == star) {
getsym();
{
head = tail = maketype(bt_ptrfunc,4);
head->btp = temp1;
decl1();
if (needpunc(closepa,skm_declclosepa)) {
char temp[40];
/* in case we have a pointer type in
* parenthesis
* Isn't C grand? */
if (lastst != openpa) {
/* change the pointerfunc to a pointer */
if (head->type == bt_ptrfunc)
head->type = bt_pointer;
else {
temp3 = head;
while (temp3->type != bt_ptrfunc)
temp3 = temp3->btp;
temp3->type = bt_pointer;
}
tail = temp2;
decl2();
break;
}
strcpy(temp,declid);
if (head->type == bt_func) {
declid[0] = 0;
temp1 = head;
head = head->btp;
}
else
temp1 = 0;
getsym();
declfuncarg(intflag);
if (temp1) {
strcpy(declid,temp);
temp1->btp = head;
head = temp1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -