- Timestamp:
- Sep 21, 2023, 10:15:58 PM (16 months ago)
- Branches:
- master
- Children:
- 62c6cfa
- Parents:
- c1e66d9 (diff), 5a1ae14 (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
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Util.cpp
rc1e66d9 rdeda7e6 104 104 } 105 105 assertf( false, "Member not found." ); 106 } 107 108 template<typename node_t> 109 void oneOfExprOrType( const node_t * node ) { 110 if ( node->expr ) { 111 assertf( node->expr && !node->type, "Exactly one of expr or type should be set." ); 112 } else { 113 assertf( !node->expr && node->type, "Exactly one of expr or type should be set." ); 114 } 106 115 } 107 116 … … 152 161 } 153 162 163 void previsit( const SizeofExpr * node ) { 164 previsit( (const ParseNode *)node ); 165 oneOfExprOrType( node ); 166 } 167 168 void previsit( const AlignofExpr * node ) { 169 previsit( (const ParseNode *)node ); 170 oneOfExprOrType( node ); 171 } 172 154 173 void previsit( const StructInstType * node ) { 155 174 previsit( (const Node *)node ); … … 181 200 /// referring to is in scope by the structural rules of code. 182 201 // Any escapes marked with a bug should be removed once the bug is fixed. 202 // This is a separate pass because of it changes the visit pattern and 203 // must always be run on the entire translation unit. 183 204 struct InScopeCore : public ast::WithShortCircuiting { 184 205 ScopedSet<DeclWithType const *> typedDecls; -
src/ControlStruct/MultiLevelExit.cpp
rc1e66d9 rdeda7e6 10 10 // Created On : Mon Nov 1 13:48:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 6 12:00:00 202313 // Update Count : 3 512 // Last Modified On : Fri Sep 8 17:04:00 2023 13 // Update Count : 36 14 14 // 15 15 … … 27 27 28 28 namespace { 29 30 /// The return context is used to remember if returns are allowed and if 31 /// not, why not. It is the nearest local control flow blocking construct. 32 enum ReturnContext { 33 MayReturn, 34 InTryWithHandler, 35 InResumeHandler, 36 InTerminateHandler, 37 InFinally, 38 }; 29 39 30 40 class Entry { … … 126 136 void previsit( const TryStmt * ); 127 137 void postvisit( const TryStmt * ); 138 void previsit( const CatchClause * ); 128 139 void previsit( const FinallyClause * ); 129 140 … … 134 145 vector<Entry> enclosing_control_structures; 135 146 Label break_label; 136 bool inFinally;147 ReturnContext ret_context; 137 148 138 149 template<typename LoopNode> … … 144 155 const list<ptr<Stmt>> & kids, bool caseClause ); 145 156 157 void enterSealedContext( ReturnContext ); 158 146 159 template<typename UnaryPredicate> 147 160 auto findEnclosingControlStructure( UnaryPredicate pred ) { … … 157 170 MultiLevelExitCore::MultiLevelExitCore( const LabelToStmt & lt ) : 158 171 target_table( lt ), break_label( CodeLocation(), "" ), 159 inFinally( false)172 ret_context( ReturnContext::MayReturn ) 160 173 {} 161 174 … … 488 501 489 502 void MultiLevelExitCore::previsit( const ReturnStmt * stmt ) { 490 if ( inFinally ) { 491 SemanticError( stmt->location, "'return' may not appear in a finally clause" ); 492 } 503 char const * context; 504 switch ( ret_context ) { 505 case ReturnContext::MayReturn: 506 return; 507 case ReturnContext::InTryWithHandler: 508 context = "try statement with a catch clause"; 509 break; 510 case ReturnContext::InResumeHandler: 511 context = "catchResume clause"; 512 break; 513 case ReturnContext::InTerminateHandler: 514 context = "catch clause"; 515 break; 516 case ReturnContext::InFinally: 517 context = "finally clause"; 518 break; 519 default: 520 assert(0); 521 } 522 SemanticError( stmt->location, toString( "'return' may not appear in a ", context ) ); 493 523 } 494 524 … … 500 530 GuardAction([this](){ enclosing_control_structures.pop_back(); } ); 501 531 } 532 533 // Try statements/try blocks are only sealed with a termination handler. 534 for ( auto clause : stmt->handlers ) { 535 if ( ast::Terminate == clause->kind ) { 536 return enterSealedContext( ReturnContext::InTryWithHandler ); 537 } 538 } 502 539 } 503 540 … … 512 549 } 513 550 551 void MultiLevelExitCore::previsit( const CatchClause * clause ) { 552 ReturnContext context = ( ast::Terminate == clause->kind ) 553 ? ReturnContext::InTerminateHandler : ReturnContext::InResumeHandler; 554 enterSealedContext( context ); 555 } 556 514 557 void MultiLevelExitCore::previsit( const FinallyClause * ) { 515 GuardAction([this, old = std::move( enclosing_control_structures)](){ enclosing_control_structures = std::move(old); }); 516 enclosing_control_structures = vector<Entry>(); 517 GuardValue( inFinally ) = true; 558 enterSealedContext( ReturnContext::InFinally ); 518 559 } 519 560 … … 617 658 } 618 659 660 void MultiLevelExitCore::enterSealedContext( ReturnContext enter_context ) { 661 GuardAction([this, old = std::move(enclosing_control_structures)](){ enclosing_control_structures = std::move(old); }); 662 enclosing_control_structures = vector<Entry>(); 663 GuardValue( ret_context ) = enter_context; 664 } 665 619 666 } // namespace 620 667 -
src/GenPoly/GenPoly.cc
rc1e66d9 rdeda7e6 48 48 } 49 49 50 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env) { 51 for (auto ¶m : params) { 52 auto paramType = param.strict_as<ast::TypeExpr>(); 53 if (isPolyType(paramType->type, env)) return true; 50 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env ) { 51 for ( auto ¶m : params ) { 52 auto paramType = param.as<ast::TypeExpr>(); 53 assertf( paramType, "Aggregate parameters should be type expressions" ); 54 if ( isPolyType( paramType->type, env ) ) return true; 54 55 } 55 56 return false; … … 62 63 assertf(paramType, "Aggregate parameters should be type expressions"); 63 64 if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true; 65 } 66 return false; 67 } 68 69 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TypeVarMap & typeVars, const ast::TypeSubstitution * env ) { 70 for ( auto & param : params ) { 71 auto paramType = param.as<ast::TypeExpr>(); 72 assertf( paramType, "Aggregate parameters should be type expressions" ); 73 if ( isPolyType( paramType->type, typeVars, env ) ) return true; 64 74 } 65 75 return false; … … 185 195 } 186 196 187 const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {188 type = replaceTypeInst( type, env );189 190 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {191 if ( tyVars.contains( typeInst->typeString() ) ) return type;192 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {193 return isPolyType( arrayType->base, env );194 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {195 if ( hasPolyParams( structType->params, env ) ) return type;196 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {197 if ( hasPolyParams( unionType->params, env ) ) return type;198 }199 return nullptr;200 }201 202 197 const ast::Type * isPolyType( const ast::Type * type, 203 198 const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) { … … 207 202 if ( typeVars.contains( *inst ) ) return type; 208 203 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 209 return isPolyType( array->base, subst );204 return isPolyType( array->base, typeVars, subst ); 210 205 } else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) { 211 if ( hasPolyParams( sue->params, subst ) ) return type;206 if ( hasPolyParams( sue->params, typeVars, subst ) ) return type; 212 207 } else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) { 213 if ( hasPolyParams( sue->params, subst ) ) return type;208 if ( hasPolyParams( sue->params, typeVars, subst ) ) return type; 214 209 } 215 210 return nullptr;
Note: See TracChangeset
for help on using the changeset viewer.