* Handles processing of declarations,
* except for top-level processing of
* Process a sequence of declaration statements
while (getkeywords(&sclass
, &typer
)) {
offset
= declare(sclass
, &typer
, offset
);
return(offset
+align(INT
, offset
, 0));
* Read the keywords introducing a declaration statement
* Store back the storage class, and fill in the type
* entry, which looks like a hash table entry.
register skw
, tkw
, longf
;
int o
, isadecl
, ismos
, unsignf
;
ismos
= skw
==MOS
||skw
==MOU
;
mosflg
= ismos
&& isadecl
;
if (o
==NAME
&& csym
->hclass
==TYPEDEF
&& tkw
<0) {
tptr
->hsubsp
= csym
->hsubsp
;
tptr
->hstrp
= csym
->hstrp
;
switch (o
==KEYW
? cval
: -1) {
if (skw
==ARG
&& cval
==REG
)
error("Conflict in storage class");
tptr
->hstrp
= strdec(ismos
, cval
);
skw
= blklev
==0? DEFXTRN
: AUTO
;
error("Misplaced 'unsigned'");
error("Misplaced 'long'");
* Process a structure, union, or enum declaration; a subroutine
register struct hshtab
*ssym
;
struct hshtab
**savememlist
;
struct hshtab
*mems
[NMEMS
];
if ((o
=symbol())==NAME
) {
if (o
==LBRACE
&& ssym
->hblklev
<blklev
)
ssym
->strp
= gblock(sizeof(*strp
));
ssym
->strp
->memlist
= NULL
;
if (ssym
->hclass
!= tagkind
)
strp
= gblock(sizeof(*strp
));
if (ssym
->hclass
!=tagkind
)
error("Bad structure/union/enum name");
declare(ENUM
, &typer
, 0);
elsize
= declist(kind
==UNION
?MOU
:MOS
);
error("%.8s redeclared", ssym
->name
);
strp
->memlist
= gblock((memlist
-mems
)*sizeof(*memlist
));
for (o
=0; &mems
[o
] != memlist
; o
++)
strp
->memlist
[o
] = mems
[o
];
if ((o
= symbol()) != RBRACE
)
* Process a comma-separated list of declarators
declare(askw
, tptr
, offset
)
register int skw
, isunion
;
if ((peeksym
=symbol()) == SEMI
) {
if (skw
==ENUM
&& (peeksym
=symbol())==RBRACE
) {
o
= decl1(skw
, tptr
, isunion
?0:offset
, NULL
);
} while ((o
=symbol()) == COMMA
);
if (o
!=SEMI
&& (o
!=RPARN
|| skw
!=ARG1
))
* Process a single declarator
decl1(askw
, atptr
, offset
, absname
)
struct hshtab
*atptr
, *absname
;
int t1
, chkoff
, a
, elsize
;
register struct hshtab
*dsym
;
register struct hshtab
*tptr
;
if (((peeksym
=symbol())==SEMI
|| peeksym
==RPARN
) && absname
==NULL
)
if (peeksym
==COLON
&& skw
==MOS
) {
elsize
= align(tptr
->htype
, offset
, t1
);
t1
= getype(&dim
, absname
);
dim
.dimens
[dim
.rank
++] = tptr
->hsubsp
[a
++];
type
= tptr
->htype
& ~TYPE
;
type
= type
<<TYLEN
| (t1
& XTYPE
);
type
=| tptr
->htype
&TYPE
;
if (dsym
->hblklev
< blklev
)
dp
= gblock(dim
.rank
*sizeof(dim
.rank
));
for (a
=0; a
<dim
.rank
; a
++) {
if ((t1
= dp
[a
] = dim
.dimens
[a
])
&& (dsym
->htype
&XTYPE
) == ARRAY
&& dsym
->subsp
[a
] && t1
!=dsym
->subsp
[a
])
if ((type
&XTYPE
) == FUNC
) {
if ((skw
!=EXTERN
&& skw
!=TYPEDEF
) && absname
==NULL
)
error("Bad func. storage class");
|| ((skw
==ARG
||skw
==AREG
) && dsym
->hclass
==ARG1
)
|| (skw
==EXTERN
&& dsym
->hclass
==EXTERN
&& dsym
->htype
==type
)))
if (skw
==MOS
&& dsym
->hclass
==MOS
&& dsym
->htype
==type
)
if (dsym
->hclass
&& (dsym
->htype
&TYPE
)==STRUCT
&& (type
&TYPE
)==STRUCT
)
if (dsym
->hstrp
!= tptr
->hstrp
) {
error("Warning: structure redeclaration");
dsym
->hstrp
= tptr
->hstrp
;
if ((peeksym
= symbol())==COLON
) {
a
= align(type
, offset
, t1
);
if (dsym
->hflag
&FFIELD
) {
if (dsym
->hstrp
->bitoffs
!=bitoffs
|| dsym
->hstrp
->flen
!=t1
)
dsym
->hstrp
= gblock(sizeof(*fldp
));
dsym
->hstrp
->bitoffs
= bitoffs
;
a
= align(type
, offset
, 0);
error("Too many structure members");
*memlist
++ = &structhole
;
if (chkoff
&& dsym
->hoffset
!= offset
)
if ((dsym
->hoffset
= goodreg(dsym
)) < 0)
if ((a
=symbol())!=COMMA
&& a
!=SEMI
&& a
!=RBRACE
)
autolen
=- rlength(dsym
);
/* dsym->hoffset = autolen; */
/* autolen =+ rlength(dsym); */
/* if (autolen > maxauto) */
} else if (skw
==STATIC
) {
outcode("BBN", DATA
, LABEL
, isn
++);
if (cinit(dsym
, 1, STATIC
) & ALIGN
)
outcode("BBNBN", BSS
, LABEL
, isn
++, SSPACE
, rlength(dsym
));
} else if (skw
==REG
&& isinit
)
error("Illegal enumeration %.8s", dsym
->name
);
elsize
= dsym
->hoffset
-offset
+1;
* Push down an outer-block declaration
* after redeclaration in an inner block.
register struct phshtab
*sp
, *nsp
;
nsp
= gblock(sizeof(*nsp
));
maxdecl
= funcbase
= curbase
;
sp
->hflag
=& (FKEYW
|FMOS
);
* Copy the non-name part of a symbol
register struct phshtab
*rs1
, *rs2
;
rs1
->hclass
= rs2
->hclass
;
rs1
->hoffset
= rs2
->hoffset
;
rs1
->hsubsp
= rs2
->hsubsp
;
rs1
->hblklev
= rs2
->hblklev
;
rs1
->hpdown
= rs2
->hpdown
;
* Read a declarator and get the implied type
static struct hshtab argtype
;
register struct hshtab
*ds
;
register struct tdim
*dimp
;
type
= getype(dimp
, absname
);
return(type
<<TYLEN
| PTR
);
if (absname
==NULL
|| nextchar()!=')') {
type
= getype(dimp
, absname
);
if ((o
=symbol()) != RPARN
)
declare(ARG1
, &argtype
, 0);
if ((o
=symbol()) != RPARN
)
type
= type
<<TYLEN
| FUNC
;
if ((o
=symbol()) != RBRACK
) {
if ((o
=symbol())!=RBRACK
)
dimp
->dimens
[dimp
->rank
++] = cval
;
type
= type
<<TYLEN
| ARRAY
;
* More bits required for type than allowed.
error("Type is too complicated");
* Enforce alignment restrictions in structures,
* including bit-field considerations.
align(type
, offset
, aflen
)
a
=+ (NBPC
+bitoffs
-1) / NBPC
;
if (type
==INT
|| type
==UNSIGN
) {
if (flen
+bitoffs
> NBPW
) {
if (flen
+bitoffs
> NBPC
) {
error("Bad type for field");
* Complain about syntax error in declaration
error("Declaration syntax");
* Complain about a redeclaration
error("%.8s redeclared", defsym
->name
);
* Determine if a variable is suitable for storage in
* a register; if so return the register number
* Special dispensation for unions
if (type
==STRUCT
&& length(hp
)<=SZINT
)
if ((type
!=INT
&& type
!=CHAR
&& type
!=UNSIGN
&& (type
&XTYPE
)==0)
|| (type
&XTYPE
)>PTR
|| regvar
<3)