Changeset e5628db for src/ControlStruct
- Timestamp:
- May 12, 2022, 3:10:58 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 8060b2b, f835806
- Parents:
- f75e25b (diff), 491bb81 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/ControlStruct
- Files:
-
- 2 edited
-
LabelGeneratorNew.hpp (modified) (1 diff)
-
MultiLevelExit.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelGeneratorNew.hpp
rf75e25b re5628db 18 18 #include <string> // for string 19 19 20 classCodeLocation;20 struct CodeLocation; 21 21 22 22 namespace ast { -
src/ControlStruct/MultiLevelExit.cpp
rf75e25b re5628db 18 18 #include "AST/Pass.hpp" 19 19 #include "AST/Stmt.hpp" 20 #include "Common/CodeLocationTools.hpp" 20 21 #include "LabelGeneratorNew.hpp" 21 22 … … 228 229 // Labels on different stmts require different approaches to access 229 230 switch ( stmt->kind ) { 230 case BranchStmt::Goto:231 case BranchStmt::Goto: 231 232 return stmt; 232 case BranchStmt::Continue:233 case BranchStmt::Break: {234 bool isContinue = stmt->kind == BranchStmt::Continue;235 // Handle unlabeled break and continue.236 if ( stmt->target.empty() ) {237 if ( isContinue ) {238 targetEntry = findEnclosingControlStructure( isContinueTarget );239 } else {240 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() ) { 241 242 SemanticError( stmt->location, 242 243 "'break' outside a loop, 'switch', or labelled block" ); 243 }244 targetEntry = findEnclosingControlStructure( isBreakTarget );245 }246 // Handle labeled break and continue.247 } else {248 // Lookup label in table to find attached control structure.249 targetEntry = findEnclosingControlStructure(250 [ 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){ 251 252 return entry.stmt == targetStmt; 252 } );253 }254 // Ensure that selected target is valid.255 if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {256 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'"), 257 258 " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), 258 259 stmt->originalTarget ) ); 259 }260 break;261 }262 // handle fallthrough in case/switch stmts263 case BranchStmt::FallThrough: {264 targetEntry = findEnclosingControlStructure( isFallthroughTarget );265 // Check that target is valid.266 if ( targetEntry == enclosing_control_structures.rend() ) {267 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );268 }269 if ( ! stmt->target.empty() ) {270 // Labelled fallthrough: target must be a valid fallthough label.271 if ( ! fallthrough_labels.count( stmt->target ) ) {272 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: ", 273 274 stmt->originalTarget ) ); 274 }275 return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget );276 }277 break;278 }279 case BranchStmt::FallThroughDefault: {280 targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );281 282 // Check if in switch or choose statement.283 if ( targetEntry == enclosing_control_structures.rend() ) {284 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );285 }286 287 // Check if switch or choose has default clause.288 auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );289 bool foundDefault = false;290 for ( auto caseStmt : switchStmt->cases ) {291 if ( caseStmt->isDefault() ) {292 foundDefault = true;293 break;294 }295 }296 if ( ! foundDefault ) {297 SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"298 "control structure with a 'default' clause" );299 }300 break;301 }302 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: 303 304 assert( false ); 304 305 } … … 307 308 Label exitLabel( CodeLocation(), "" ); 308 309 switch ( stmt->kind ) { 309 case BranchStmt::Break:310 case BranchStmt::Break: 310 311 assert( ! targetEntry->useBreakExit().empty() ); 311 312 exitLabel = targetEntry->useBreakExit(); 312 313 break; 313 case BranchStmt::Continue:314 case BranchStmt::Continue: 314 315 assert( ! targetEntry->useContExit().empty() ); 315 316 exitLabel = targetEntry->useContExit(); 316 317 break; 317 case BranchStmt::FallThrough:318 case BranchStmt::FallThrough: 318 319 assert( ! targetEntry->useFallExit().empty() ); 319 320 exitLabel = targetEntry->useFallExit(); 320 321 break; 321 case BranchStmt::FallThroughDefault:322 case BranchStmt::FallThroughDefault: 322 323 assert( ! targetEntry->useFallDefaultExit().empty() ); 323 324 exitLabel = targetEntry->useFallDefaultExit(); … … 327 328 } 328 329 break; 329 default:330 default: 330 331 assert(0); 331 332 } … … 633 634 Pass<MultiLevelExitCore> visitor( labelTable ); 634 635 const CompoundStmt * ret = stmt->accept( visitor ); 635 return ret; 636 // There are some unset code locations slipping in, possibly by Labels. 637 const Node * node = localFillCodeLocations( ret->location, ret ); 638 return strict_dynamic_cast<const CompoundStmt *>( node ); 636 639 } 637 640 } // namespace ControlStruct
Note:
See TracChangeset
for help on using the changeset viewer.