1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)lab.c 1.14 11/10/82"; 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 static bool label_order = FALSE; 24 static bool label_seen = FALSE; 25 #ifdef PC 26 char extname[ BUFSIZ ]; 27 #endif PC 28 #ifndef PI0 29 register *ll; 30 register struct nl *p, *lp; 31 32 lp = NIL; 33 #else 34 send(REVLAB, r); 35 #endif 36 if ( ! progseen ) { 37 level1(); 38 } 39 line = l; 40 #ifndef PI1 41 if (parts[ cbn ] & (CPRT|TPRT|VPRT|RPRT)){ 42 if ( opt( 's' ) ) { 43 standard(); 44 error("Label declarations should precede const, type, var and routine declarations"); 45 } else { 46 if ( !label_order ) { 47 label_order = TRUE; 48 warning(); 49 error("Label declarations should precede const, type, var and routine declarations"); 50 } 51 } 52 } 53 if (parts[ cbn ] & LPRT) { 54 if ( opt( 's' ) ) { 55 standard(); 56 error("All labels should be declared in one label part"); 57 } else { 58 if ( !label_seen ) { 59 label_seen = TRUE; 60 warning(); 61 error("All labels should be declared in one label part"); 62 } 63 } 64 } 65 parts[ cbn ] |= LPRT; 66 #endif 67 #ifndef PI0 68 for (ll = r; ll != NIL; ll = ll[2]) { 69 l = getlab(); 70 p = enter(defnl(ll[1], LABEL, 0, l)); 71 /* 72 * Get the label for the eventual target 73 */ 74 p->value[1] = getlab(); 75 p->chain = lp; 76 p->nl_flags |= (NFORWD|NMOD); 77 p->value[NL_GOLEV] = NOTYET; 78 p->value[NL_ENTLOC] = l; 79 lp = p; 80 # ifdef OBJ 81 /* 82 * This operator is between 83 * the bodies of two procedures 84 * and provides a target for 85 * gotos for this label via TRA. 86 */ 87 putlab(l); 88 /* put(2, O_GOTO | cbn<<8+INDX, (long)p->value[1]); */ 89 put(2, O_GOTO | cbn<<8, (long)p->value[1]); 90 # endif OBJ 91 # ifdef PC 92 /* 93 * labels have to be .globl otherwise /lib/c2 may 94 * throw them away if they aren't used in the function 95 * which defines them. 96 */ 97 extlabname( extname , p -> symbol , cbn ); 98 putprintf( " .globl %s" , 0 , extname ); 99 if ( cbn == 1 ) { 100 stabglabel( extname , line ); 101 } 102 # endif PC 103 } 104 gotos[cbn] = lp; 105 # ifdef PTREE 106 { 107 pPointer Labels = LabelDCopy( r ); 108 109 pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; 110 } 111 # endif PTREE 112 #endif 113 } 114 115 #ifndef PI0 116 /* 117 * Gotoop is called when 118 * we get a statement "goto label" 119 * and generates the needed tra. 120 */ 121 gotoop(s) 122 char *s; 123 { 124 register struct nl *p; 125 #ifdef PC 126 char extname[ BUFSIZ ]; 127 #endif PC 128 129 gocnt++; 130 p = lookup(s); 131 if (p == NIL) 132 return (NIL); 133 # ifdef OBJ 134 put(2, O_TRA4, (long)p->value[NL_ENTLOC]); 135 # endif OBJ 136 # ifdef PC 137 if ( cbn != bn ) { 138 /* 139 * Close all active files between top of stack and 140 * frame at the destination level. Then call longjmp 141 * to unwind the stack to the destination level. 142 */ 143 putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 144 , "_PCLOSE" ); 145 putRV( DISPLAYNAME , 0 , 146 bn * sizeof( struct dispsave ) + sizeof ( char * ) , 147 NGLOBAL , P2PTR | P2INT ); 148 if ( bn > 1 ) { 149 p = lookup( enclosing[ bn - 1 ] ); 150 sprintf( extname, "LF%d+%d", p -> value[ NL_ENTLOC ] 151 , sizeof( int ) ); 152 putleaf( P2ICON , 0 , 0 , P2INT , extname ); 153 p = lookup(s); 154 } else { 155 putleaf( P2ICON , DPOFF1 + sizeof( int ) , 0 , P2INT , 0 ); 156 } 157 putop( P2MINUS , P2PTR | P2CHAR ); 158 putop( P2CALL , P2INT ); 159 putdot( filename , line ); 160 putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 161 , "_longjmp" ); 162 putLV( 0 , bn , GOTOENVOFFSET , NLOCAL , P2PTR|P2STRTY ); 163 extlabname( extname , p -> symbol , bn ); 164 putLV( extname , 0 , 0 , NGLOBAL , P2PTR|P2STRTY ); 165 putop( P2LISTOP , P2INT ); 166 putop( P2CALL , P2INT ); 167 putdot( filename , line ); 168 } else { 169 extlabname( extname , p -> symbol , bn ); 170 /* 171 * this is a jmp because it's a jump to a global 172 * and the assembler doesn't change jbr's into jmp's 173 * if the destination is a global symbol. 174 */ 175 putprintf( " jmp %s" , 0 , extname ); 176 } 177 # endif PC 178 if (bn == cbn) 179 if (p->nl_flags & NFORWD) { 180 if (p->value[NL_GOLEV] == NOTYET) { 181 p->value[NL_GOLEV] = level; 182 p->value[NL_GOLINE] = line; 183 } 184 } else 185 if (p->value[NL_GOLEV] == DEAD) { 186 recovered(); 187 error("Goto %s is into a structured statement", p->symbol); 188 } 189 } 190 191 /* 192 * Labeled is called when a label 193 * definition is encountered, and 194 * marks that it has been found and 195 * patches the associated GOTO generated 196 * by gotoop. 197 */ 198 labeled(s) 199 char *s; 200 { 201 register struct nl *p; 202 #ifdef PC 203 char extname[ BUFSIZ ]; 204 #endif PC 205 206 p = lookup(s); 207 if (p == NIL) 208 return (NIL); 209 if (bn != cbn) { 210 error("Label %s not defined in correct block", s); 211 return; 212 } 213 if ((p->nl_flags & NFORWD) == 0) { 214 error("Label %s redefined", s); 215 return; 216 } 217 p->nl_flags &= ~NFORWD; 218 # ifdef OBJ 219 patch4(p->value[NL_ENTLOC]); 220 # endif OBJ 221 # ifdef PC 222 extlabname( extname , p -> symbol , bn ); 223 putprintf( "%s:" , 0 , extname ); 224 # endif PC 225 if (p->value[NL_GOLEV] != NOTYET) 226 if (p->value[NL_GOLEV] < level) { 227 recovered(); 228 error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]); 229 } 230 p->value[NL_GOLEV] = level; 231 } 232 #endif 233 234 #ifdef PC 235 /* 236 * construct the long name of a label based on it's static nesting. 237 * into a caller-supplied buffer (that should be about BUFSIZ big). 238 */ 239 extlabname( buffer , name , level ) 240 char buffer[]; 241 char *name; 242 int level; 243 { 244 char *starthere; 245 int i; 246 247 starthere = &buffer[0]; 248 for ( i = 1 ; i < level ; i++ ) { 249 sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 250 starthere += strlen( enclosing[ i ] ) + 1; 251 } 252 sprintf( starthere , EXTFORMAT , "" ); 253 starthere += 1; 254 sprintf( starthere , LABELFORMAT , name ); 255 starthere += strlen( name ) + 1; 256 if ( starthere >= &buffer[ BUFSIZ ] ) { 257 panic( "extlabname" ); 258 } 259 } 260 #endif PC 261