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
-
src/ControlStruct/MultiLevelExit.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/MultiLevelExit.cpp
r7675f58 r491bb81 229 229 // Labels on different stmts require different approaches to access 230 230 switch ( stmt->kind ) { 231 case BranchStmt::Goto:231 case BranchStmt::Goto: 232 232 return stmt; 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() ) {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 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){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 // Ensure that selected target is valid.256 if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {257 SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),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 break;262 }263 // handle fallthrough in case/switch stmts264 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: ",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 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: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 case BranchStmt::Break:310 case BranchStmt::Break: 311 311 assert( ! targetEntry->useBreakExit().empty() ); 312 312 exitLabel = targetEntry->useBreakExit(); 313 313 break; 314 case BranchStmt::Continue:314 case BranchStmt::Continue: 315 315 assert( ! targetEntry->useContExit().empty() ); 316 316 exitLabel = targetEntry->useContExit(); 317 317 break; 318 case BranchStmt::FallThrough:318 case BranchStmt::FallThrough: 319 319 assert( ! targetEntry->useFallExit().empty() ); 320 320 exitLabel = targetEntry->useFallExit(); 321 321 break; 322 case BranchStmt::FallThroughDefault:322 case BranchStmt::FallThroughDefault: 323 323 assert( ! targetEntry->useFallDefaultExit().empty() ); 324 324 exitLabel = targetEntry->useFallDefaultExit(); … … 328 328 } 329 329 break; 330 default:330 default: 331 331 assert(0); 332 332 }
Note:
See TracChangeset
for help on using the changeset viewer.