Changeset 491bb81
- Timestamp:
 - May 12, 2022, 9:30:38 AM (3 years ago)
 - Branches:
 - ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
 - Children:
 - e5628db
 - Parents:
 - 7675f58
 - Location:
 - src
 - Files:
 - 
      
- 2 edited
 
- 
          
  AST/Stmt.hpp (modified) (2 diffs)
 - 
          
  ControlStruct/MultiLevelExit.cpp (modified) (3 diffs)
 
 
Legend:
- Unmodified
 - Added
 - Removed
 
- 
      
src/AST/Stmt.hpp
r7675f58 r491bb81 58 58 // cannot be, they are sub-types of this type, for organization. 59 59 60 StmtClause( const CodeLocation & loc )60 StmtClause( const CodeLocation & loc ) 61 61 : ParseNode(loc) {} 62 62 … … 396 396 class WaitForClause final : public StmtClause { 397 397 public: 398 ptr<Expr> target_func;399 std::vector<ptr<Expr>> target_args;400 ptr<Stmt> stmt;401 ptr<Expr> cond;402 403 WaitForClause( const CodeLocation & loc )398 ptr<Expr> target_func; 399 std::vector<ptr<Expr>> target_args; 400 ptr<Stmt> stmt; 401 ptr<Expr> cond; 402 403 WaitForClause( const CodeLocation & loc ) 404 404 : StmtClause( loc ) {} 405 405 406 406 const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); } 407 407 private: 408 WaitForClause * clone() const override { return new WaitForClause{ *this }; }409 MUTATE_FRIEND408 WaitForClause * clone() const override { return new WaitForClause{ *this }; } 409 MUTATE_FRIEND 410 410 }; 411 411  - 
      
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.