|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)lab.c 1.5 10/14/80";
4:
5: #include "whoami.h"
6: #include "0.h"
7: #include "tree.h"
8: #include "opcode.h"
9: #include "objfmt.h"
10: #ifdef PC
11: # include "pc.h"
12: # include "pcops.h"
13: #endif PC
14:
15: /*
16: * Label enters the definitions
17: * of the label declaration part
18: * into the namelist.
19: */
20: label(r, l)
21: int *r, l;
22: {
23: #ifndef PI0
24: register *ll;
25: register struct nl *p, *lp;
26:
27: lp = NIL;
28: #else
29: send(REVLAB, r);
30: #endif
31: if ( ! progseen ) {
32: level1();
33: }
34: line = l;
35: #ifndef PI1
36: if (parts[ cbn ] & (CPRT|TPRT|VPRT|RPRT)){
37: if ( opt( 's' ) ) {
38: standard();
39: } else {
40: warning();
41: }
42: error("Label declarations should precede const, type, var and routine declarations");
43: }
44: if (parts[ cbn ] & LPRT) {
45: if ( opt( 's' ) ) {
46: standard();
47: } else {
48: warning();
49: }
50: error("All labels should be declared in one label part");
51: }
52: parts[ cbn ] |= LPRT;
53: #endif
54: #ifndef PI0
55: for (ll = r; ll != NIL; ll = ll[2]) {
56: l = getlab();
57: p = enter(defnl(ll[1], LABEL, 0, l));
58: /*
59: * Get the label for the eventual target
60: */
61: p->value[1] = getlab();
62: p->chain = lp;
63: p->nl_flags |= (NFORWD|NMOD);
64: p->value[NL_GOLEV] = NOTYET;
65: p->entloc = l;
66: lp = p;
67: # ifdef OBJ
68: /*
69: * This operator is between
70: * the bodies of two procedures
71: * and provides a target for
72: * gotos for this label via TRA.
73: */
74: putlab(l);
75: put2(O_GOTO | cbn<<8+INDX, p->value[1]);
76: # endif OBJ
77: # ifdef PC
78: /*
79: * labels have to be .globl otherwise /lib/c2 may
80: * throw them away if they aren't used in the function
81: * which defines them.
82: */
83: {
84: char extname[ BUFSIZ ];
85: char *starthere;
86: int i;
87:
88: starthere = &extname[0];
89: for ( i = 1 ; i < cbn ; i++ ) {
90: sprintf( starthere , EXTFORMAT , enclosing[ i ] );
91: starthere += strlen( enclosing[ i ] ) + 1;
92: }
93: sprintf( starthere , EXTFORMAT , p -> symbol );
94: starthere += strlen( p -> symbol ) + 1;
95: if ( starthere >= &extname[ BUFSIZ ] ) {
96: panic( "lab decl namelength" );
97: }
98: putprintf( " .globl " , 1 );
99: putprintf( NAMEFORMAT , 0 , extname );
100: if ( cbn == 1 ) {
101: stabglabel( extname , line );
102: }
103: }
104: # endif PC
105: }
106: gotos[cbn] = lp;
107: # ifdef PTREE
108: {
109: pPointer Labels = LabelDCopy( r );
110:
111: pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels;
112: }
113: # endif PTREE
114: #endif
115: }
116:
117: #ifndef PI0
118: /*
119: * Gotoop is called when
120: * we get a statement "goto label"
121: * and generates the needed tra.
122: */
123: gotoop(s)
124: char *s;
125: {
126: register struct nl *p;
127:
128: gocnt++;
129: p = lookup(s);
130: if (p == NIL)
131: return (NIL);
132: # ifdef OBJ
133: put2(O_TRA4, p->entloc);
134: # endif OBJ
135: # ifdef PC
136: if ( cbn != bn ) {
137: /*
138: * call goto to unwind the stack to the destination level
139: */
140: putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
141: , "_GOTO" );
142: putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave )
143: , P2PTR | P2INT );
144: putop( P2CALL , P2INT );
145: putdot( filename , line );
146: }
147: {
148: char extname[ BUFSIZ ];
149: char *starthere;
150: int i;
151:
152: starthere = &extname[0];
153: for ( i = 1 ; i < bn ; i++ ) {
154: sprintf( starthere , EXTFORMAT , enclosing[ i ] );
155: starthere += strlen( enclosing[ i ] ) + 1;
156: }
157: sprintf( starthere , EXTFORMAT , p -> symbol );
158: starthere += strlen( p -> symbol ) + 1;
159: if ( starthere >= &extname[ BUFSIZ ] ) {
160: panic( "goto namelength" );
161: }
162: putprintf( " jbr " , 1 );
163: putprintf( NAMEFORMAT , 0 , extname );
164: }
165: # endif PC
166: if (bn == cbn)
167: if (p->nl_flags & NFORWD) {
168: if (p->value[NL_GOLEV] == NOTYET) {
169: p->value[NL_GOLEV] = level;
170: p->value[NL_GOLINE] = line;
171: }
172: } else
173: if (p->value[NL_GOLEV] == DEAD) {
174: recovered();
175: error("Goto %s is into a structured statement", p->symbol);
176: }
177: }
178:
179: /*
180: * Labeled is called when a label
181: * definition is encountered, and
182: * marks that it has been found and
183: * patches the associated GOTO generated
184: * by gotoop.
185: */
186: labeled(s)
187: char *s;
188: {
189: register struct nl *p;
190:
191: p = lookup(s);
192: if (p == NIL)
193: return (NIL);
194: if (bn != cbn) {
195: error("Label %s not defined in correct block", s);
196: return;
197: }
198: if ((p->nl_flags & NFORWD) == 0) {
199: error("Label %s redefined", s);
200: return;
201: }
202: p->nl_flags &= ~NFORWD;
203: # ifdef OBJ
204: patch4(p->entloc);
205: # endif OBJ
206: # ifdef PC
207: {
208: char extname[ BUFSIZ ];
209: char *starthere;
210: int i;
211:
212: starthere = &extname[0];
213: for ( i = 1 ; i < bn ; i++ ) {
214: sprintf( starthere , EXTFORMAT , enclosing[ i ] );
215: starthere += strlen( enclosing[ i ] ) + 1;
216: }
217: sprintf( starthere , EXTFORMAT , p -> symbol );
218: starthere += strlen( p -> symbol ) + 1;
219: if ( starthere >= &extname[ BUFSIZ ] ) {
220: panic( "labeled namelength" );
221: }
222: putprintf( NAMEFORMAT , 1 , extname );
223: putprintf( ":" , 0 );
224: }
225: # endif PC
226: if (p->value[NL_GOLEV] != NOTYET)
227: if (p->value[NL_GOLEV] < level) {
228: recovered();
229: error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]);
230: }
231: p->value[NL_GOLEV] = level;
232: }
233: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.