Changeset 491bb81 for src/ControlStruct
- Timestamp:
- May 12, 2022, 9:30:38 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- e5628db
- Parents:
- 7675f58
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/ControlStruct/MultiLevelExit.cpp ¶
r7675f58 r491bb81 229 229 // Labels on different stmts require different approaches to access 230 230 switch ( stmt->kind ) { 231 231 case BranchStmt::Goto: 232 232 return stmt; 233 234 235 236 237 238 239 240 241 233 case BranchStmt::Continue: 234 case BranchStmt::Break: { 235 bool isContinue = stmt->kind == BranchStmt::Continue; 236 // Handle unlabeled break and continue. 237 if ( stmt->target.empty() ) { 238 if ( isContinue ) { 239 targetEntry = findEnclosingControlStructure( isContinueTarget ); 240 } else { 241 if ( enclosing_control_structures.empty() ) { 242 242 SemanticError( stmt->location, 243 243 "'break' outside a loop, 'switch', or labelled block" ); 244 245 246 247 248 249 250 251 244 } 245 targetEntry = findEnclosingControlStructure( isBreakTarget ); 246 } 247 // Handle labeled break and continue. 248 } else { 249 // Lookup label in table to find attached control structure. 250 targetEntry = findEnclosingControlStructure( 251 [ targetStmt = target_table.at(stmt->target) ](auto entry){ 252 252 return entry.stmt == targetStmt; 253 254 255 256 257 253 } ); 254 } 255 // Ensure that selected target is valid. 256 if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) { 257 SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"), 258 258 " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), 259 259 stmt->originalTarget ) ); 260 261 262 263 264 265 266 267 268 269 270 271 272 273 260 } 261 break; 262 } 263 // handle fallthrough in case/switch stmts 264 case BranchStmt::FallThrough: { 265 targetEntry = findEnclosingControlStructure( isFallthroughTarget ); 266 // Check that target is valid. 267 if ( targetEntry == enclosing_control_structures.rend() ) { 268 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" ); 269 } 270 if ( ! stmt->target.empty() ) { 271 // Labelled fallthrough: target must be a valid fallthough label. 272 if ( ! fallthrough_labels.count( stmt->target ) ) { 273 SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ", 274 274 stmt->originalTarget ) ); 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 275 } 276 return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget ); 277 } 278 break; 279 } 280 case BranchStmt::FallThroughDefault: { 281 targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget ); 282 283 // Check if in switch or choose statement. 284 if ( targetEntry == enclosing_control_structures.rend() ) { 285 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" ); 286 } 287 288 // Check if switch or choose has default clause. 289 auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt ); 290 bool foundDefault = false; 291 for ( auto caseStmt : switchStmt->cases ) { 292 if ( caseStmt->isDefault() ) { 293 foundDefault = true; 294 break; 295 } 296 } 297 if ( ! foundDefault ) { 298 SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'" 299 "control structure with a 'default' clause" ); 300 } 301 break; 302 } 303 default: 304 304 assert( false ); 305 305 } … … 308 308 Label exitLabel( CodeLocation(), "" ); 309 309 switch ( stmt->kind ) { 310 310 case BranchStmt::Break: 311 311 assert( ! targetEntry->useBreakExit().empty() ); 312 312 exitLabel = targetEntry->useBreakExit(); 313 313 break; 314 314 case BranchStmt::Continue: 315 315 assert( ! targetEntry->useContExit().empty() ); 316 316 exitLabel = targetEntry->useContExit(); 317 317 break; 318 318 case BranchStmt::FallThrough: 319 319 assert( ! targetEntry->useFallExit().empty() ); 320 320 exitLabel = targetEntry->useFallExit(); 321 321 break; 322 322 case BranchStmt::FallThroughDefault: 323 323 assert( ! targetEntry->useFallDefaultExit().empty() ); 324 324 exitLabel = targetEntry->useFallDefaultExit(); … … 328 328 } 329 329 break; 330 330 default: 331 331 assert(0); 332 332 }
Note: See TracChangeset
for help on using the changeset viewer.