/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)lab.c 1.5 10/14/80";
* Label enters the definitions
* of the label declaration part
register struct nl
*p
, *lp
;
if (parts
[ cbn
] & (CPRT
|TPRT
|VPRT
|RPRT
)){
error("Label declarations should precede const, type, var and routine declarations");
if (parts
[ cbn
] & LPRT
) {
error("All labels should be declared in one label part");
for (ll
= r
; ll
!= NIL
; ll
= ll
[2]) {
p
= enter(defnl(ll
[1], LABEL
, 0, l
));
* Get the label for the eventual target
p
->nl_flags
|= (NFORWD
|NMOD
);
p
->value
[NL_GOLEV
] = NOTYET
;
* This operator is between
* the bodies of two procedures
* and provides a target for
* gotos for this label via TRA.
put2(O_GOTO
| cbn
<<8+INDX
, p
->value
[1]);
* labels have to be .globl otherwise /lib/c2 may
* throw them away if they aren't used in the function
for ( i
= 1 ; i
< cbn
; i
++ ) {
sprintf( starthere
, EXTFORMAT
, enclosing
[ i
] );
starthere
+= strlen( enclosing
[ i
] ) + 1;
sprintf( starthere
, EXTFORMAT
, p
-> symbol
);
starthere
+= strlen( p
-> symbol
) + 1;
if ( starthere
>= &extname
[ BUFSIZ
] ) {
panic( "lab decl namelength" );
putprintf( " .globl " , 1 );
putprintf( NAMEFORMAT
, 0 , extname
);
stabglabel( extname
, line
);
pPointer Labels
= LabelDCopy( r
);
pDEF( PorFHeader
[ nesting
] ).PorFLabels
= Labels
;
* we get a statement "goto label"
* and generates the needed tra.
* call goto to unwind the stack to the destination level
putleaf( P2ICON
, 0 , 0 , ADDTYPE( P2FTN
| P2INT
, P2PTR
)
putLV( DISPLAYNAME
, 0 , bn
* sizeof( struct dispsave
)
putdot( filename
, line
);
for ( i
= 1 ; i
< bn
; i
++ ) {
sprintf( starthere
, EXTFORMAT
, enclosing
[ i
] );
starthere
+= strlen( enclosing
[ i
] ) + 1;
sprintf( starthere
, EXTFORMAT
, p
-> symbol
);
starthere
+= strlen( p
-> symbol
) + 1;
if ( starthere
>= &extname
[ BUFSIZ
] ) {
panic( "goto namelength" );
putprintf( " jbr " , 1 );
putprintf( NAMEFORMAT
, 0 , extname
);
if (p
->nl_flags
& NFORWD
) {
if (p
->value
[NL_GOLEV
] == NOTYET
) {
p
->value
[NL_GOLEV
] = level
;
p
->value
[NL_GOLINE
] = line
;
if (p
->value
[NL_GOLEV
] == DEAD
) {
error("Goto %s is into a structured statement", p
->symbol
);
* Labeled is called when a label
* definition is encountered, and
* marks that it has been found and
* patches the associated GOTO generated
error("Label %s not defined in correct block", s
);
if ((p
->nl_flags
& NFORWD
) == 0) {
error("Label %s redefined", s
);
for ( i
= 1 ; i
< bn
; i
++ ) {
sprintf( starthere
, EXTFORMAT
, enclosing
[ i
] );
starthere
+= strlen( enclosing
[ i
] ) + 1;
sprintf( starthere
, EXTFORMAT
, p
-> symbol
);
starthere
+= strlen( p
-> symbol
) + 1;
if ( starthere
>= &extname
[ BUFSIZ
] ) {
panic( "labeled namelength" );
putprintf( NAMEFORMAT
, 1 , extname
);
if (p
->value
[NL_GOLEV
] != NOTYET
)
if (p
->value
[NL_GOLEV
] < level
) {
error("Goto %s from line %d is into a structured statement", s
, p
->value
[NL_GOLINE
]);
p
->value
[NL_GOLEV
] = level
;