Changeset a724ac1
- Timestamp:
- Jun 12, 2017, 3:38:07 PM (6 years ago)
- Branches:
- aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 1bc9dcb
- Parents:
- 82ff5845 (diff), 465ed18 (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. - Files:
-
- 1 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/working/exception/design.txt
r82ff5845 ra724ac1 1 1 Design of Exceptions and EHM in Cforall: 2 2 3 Currently this is a combination of ideas and big questions that still have to 4 be addressed. It also includes some other error handling options, how they 5 interact and compare to exceptions. 3 4 Exception Instances: 5 Currently, exceptions are integers (like errno). 6 7 They are planned to be the new "tagged structures", which allows them to 8 exist in a simple hierarchy which shared functionality throughout. However 9 the tagged structures are not yet implemented so that will wait. 10 11 A single built in exception is at the top of the hierarchy and all other 12 exceptions are its children. When you match against an exception, you match 13 for an exception and its children, so the top of the hierarchy is used as a 14 catch-all option. 15 16 The shared functionality across exceptions has not been finalized, but will 17 probably include things like human readable descriptions and default handlers. 6 18 7 19 8 What is an Exception: 20 Throwing: 21 There are currently two kinds of throws, "throw" for termination and 22 "throwResume" for resumption. Both keywords can be used to create a throw 23 statement. The kind of throw decides what handlers may catch the exception 24 and weither control flow can return to the throw site. 9 25 10 In other words what do we throw? What is matched against, how does it carry 11 data with it? A very important question that has not been answered. 26 Syntax 27 "throw" exception ";" 28 "throwResume" exception ";" 12 29 13 Option 1: Strutures 30 Non-local throws are allowed for resumption only. A target is an object with 31 a stack, with which it may propagate and handle the exception. 14 32 15 Considering the current state of Cforall the most natural form of the 16 exception would likely be a struture, implementing a trait repersenting the 17 minimum features of an exception. This has many advantages, including arbitray 18 fields, some polymorphism and it matches exceptations of many current systems. 33 Syntax 34 "throwResume" exception "_At" target ";" 19 35 20 The main issue with this is matching, without OOP inheritance there is no 21 exception hierarchy. Meaning all handling has to happen on the exact exception 22 without the ease of grouping parents. There are several ways to attempt to 23 recover this. 24 25 The first is with conditional matching (a check after the type has been 26 matched) which allows for matching particular values of a known type. However 27 this does not dynamically expand and requires an extra step (as opposed to 28 mearly allowing one). I would not recomend this as the primary method. 29 30 Second is to try and use type casts/conversions to create an implicate 31 hierachy, so that a catch clause catches anything of the given type or 32 anything that converts to the given type. 33 34 Plan9 (from what I know of it) would be a powerful tool here. Even with it, 35 creating a hierarchy of types at runtime might be too expencive. Esecially 36 since they are less likely to be tree like at that point. 37 38 Option 2: Tags 39 40 The other option is to introduce a new construct into the language. A tag 41 repersents a type of exception, it is not a structure or variable (or even 42 a normal type). It may be usable in some of those contexts. 43 44 Tags can declare an existing tag as its parent. Tags can be caught by handlers 45 that catch their parents. (There is a single base_exception that all other 46 exceptions are children of eventually.) This allows for grouping of exceptions 47 that repersent similar errors. 48 49 Tags should also have some assotiated data, where and on what did the error 50 occur. Keeping with the otherness of exception tags and allowing them to be 51 expanded, using a parameter list. Each exception can have a list of paramters 52 given to it on a throw. Each tag would have a declared list of parameters 53 (which could be treated more like a set of fields as well). Child tags must 54 use their parent's list as a prefix to their own, so that the parameters can 55 be accessed when the child tag is matched against the parent. 56 57 Option N: ... 58 59 This list is not complete. 36 Termination throws unwind the stack until a handler is reached, control moves 37 onwards from the end of the handler. Resumption throws do not unwind, if a 38 handler is found and control will return to the throw after the exception is 39 handled. 60 40 61 41 62 Seperating Termination and Resumption: 42 Catching: 43 The catch and handle of an exception is preformed with a try statement, which 44 also can have finally clauses to exceute on exit from the scope. 63 45 64 Differentating the types of exceptions based on exception would be hard with 65 exceptions as structures. It is possible with exceptions as tags by having 66 two base exceptions, one for each type of throw. However recompining them 67 to dual types would be harder. 46 Syntax 47 "try" 48 try-block 49 ( ("catch" | "catchResume") 50 "(" exception_type [identifier] [";" conditional_expression] ")" 51 catch-block 52 )* 53 ("finally" 54 finally-block 55 )? 68 56 69 Reguardless, using different keywords would also be useful for clarity, even 70 if it does not add functality. Using the C++ like keywords would be a good 71 base. Resumption exceptions could use a different set (ex. raise->handle) or 72 use resume as a qualifier on the existing statements. 57 Either at least 1 handler clause or the finally clasue must be given on each 58 try block. Each handler clause handles 1 of the two types of throws. Each 59 handler also specifies a type of exception it handles, and will handle all 60 children exceptions as well. In addition, a conditional expression which, if 61 included, must be true for the handler to catch the exception. 62 63 The two types of handlers may be intermixed. Multiple handlers catching the 64 same type may also be used, to allow for fallbacks on false conditionals. 73 65 74 66 75 Conditional Matching:67 Implementation Overview: 76 68 77 A possible useful feature, it allows for arbitrary checks on a catch block 78 instead of merely matching a type. However there are few use cases that 79 cannot be avoided with proper use of a type hierarchy, and this shrinks even 80 further with a good use of re-throws.69 The implementation has two main parts. The first is just a collection of the 70 support definitions we need, the data types and functions used within the 71 exception handling code. Second is a translation from Cforall code to C code 72 that uses those definitions to throw, catch and handle exceptions. 81 73 82 Also it assumes one sweep, that might also be a problem. But might also give 83 it an advantage over re-throws. 74 Termination handlers call a specially annotated function, passing it inner 75 functions that act as the varius sub-blocks. Termination throws use the 76 unwind library that checks the underlying code for those annotations. Each 77 time one is found some magic is used to check for a matching handler, if one 78 is found control goes to the special function which excecutes the handler and 79 returns. 80 81 Resumption handlers maintain a linked list of stack allocated nodes that have 82 the handler functions attached. Throwing a resumption exception traverses this 83 list, and calls each handler, the handlers handle the exception if they can 84 and return if they did or not. 85 86 Finally clauses just use stack cleanup to force a nested function, which has 87 the code from the finally clause, to execute when we leave that section. 84 88 85 89 86 Alternative s: Implicate Handlers &Return Unions90 Alternative Error Handling: Return Unions 87 91 88 Both act as a kind of local version of an exception. Implicate handlers act as 89 resumption exceptions and return unions like termination exceptions. By local 90 I mean they work well at one or two levels of calls, but do not cover N levels 91 as cleanly. 92 Return unions (Maybe and Result), are types that can encode a success or 93 other result in a single value. Maybe stores a value or nothing, Result stores 94 a value or an error. 92 95 93 Implicate handles require a growing number of function pointers (which should 94 not be used very often) to be passed to functions, creating and additional 95 preformance cost. Return unions have to be checked and handled at every level, 96 which has some preformance cost, but also can significantly clutter code. 97 Proper tools can help with the latter. 96 For errors that are usually handled quite close to where they occur, these 97 can replace exceptions. 98 98 99 However, they may work better at that local level as they do not require stack 100 walking or unwinding. In addition they are closer to regular control flow and 101 are easier to staticly check. So even if they can't replace exceptions 102 (directly) they may still be worth using together. 103 104 For instance, consider the Python iterator interface. It uses a single 105 function, __next__, to access the next value and to signal the end of the 106 sequence. If a value is returned, it is the next value, if the StopIteration 107 exception is thrown the sequence has finished. 108 109 However almost every use of an iterator will add a try-except block around the 110 call site (possibly through for or next) to catch and handle the exception 111 immediately, ignoring the advantages of more distant exception handling. 112 113 In this case it may be cleaner to use a Maybe for both cases (as in Rust) 114 which gives similar results without having to jump to the exception handler. 115 This will likely handle the error case more efficiently and the success case a 116 bit less so. 117 118 It also mixes the error and regular control flow, which can hurt readablity, 119 but very little if the handling is simple, for instance providing a default 120 value. Similarly, if the error (or alternate outcome) is common enough 121 encoding it in the function signature may be good commuication. 99 They tend to be faster and require similar or less amounts of code to handle. 100 However they can slow down the normal path with some extra conditionals and 101 can mix the normal and exceptional control flow path. If handling the error 102 is simple, and happens relatively frequently, this might be prefered but in 103 other cases it just hurts speed and readability. 122 104 123 105 In short, these errors seem to be more effective when errors are likely and … … 125 107 be handled locally, might be better off using these instead of exceptions. 126 108 127 Also the implicate handlers and return unions could use exceptions as well. 128 For instance, a useful default might handler might be to throw an exception, 129 seaching up the stack for a solution if one is not locally provided. 130 131 Or here is a possible helper for unpacking a Result value: 109 Also the return unions could use exceptions as well. Getting the improper 110 side of a return union might throw an exception. Or we can provide helpers 111 for results withe exceptions as in: 132 112 forall(otype T, otype E | exception(E)) 133 113 T get_or_throw (Result(T, E) * this) { 134 if ( is_success(this)) {135 return get_ success(this);114 if (has_value(this)) { 115 return get_value(this); 136 116 } else { 137 throw get_ failure(this);117 throw get_error(this); 138 118 } 139 119 } 140 So they can feed off of each other. -
src/CodeGen/CodeGenerator.cc
r82ff5845 ra724ac1 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 10 14:45:00 201713 // Update Count : 48 412 // Last Modified On : Thu Jun 8 16:00:00 2017 13 // Update Count : 485 14 14 // 15 15 … … 908 908 } 909 909 910 void CodeGenerator::visit( ThrowStmt * throwStmt ) { 911 assertf( ! genC, "Throw statements should not reach code generation." ); 912 913 output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ? 914 "throw" : "throwResume"); 915 if (throwStmt->get_expr()) { 916 output << " "; 917 throwStmt->get_expr()->accept( *this ); 918 } 919 if (throwStmt->get_target()) { 920 output << " _At "; 921 throwStmt->get_target()->accept( *this ); 922 } 923 output << ";"; 924 } 925 910 926 void CodeGenerator::visit( WhileStmt * whileStmt ) { 911 927 if ( whileStmt->get_isDoWhile() ) { -
src/CodeGen/CodeGenerator.h
r82ff5845 ra724ac1 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 10 10:57:00 201713 // Update Count : 5 112 // Last Modified On : Thu Jun 8 15:48:00 2017 13 // Update Count : 52 14 14 // 15 15 … … 91 91 virtual void visit( BranchStmt * ); 92 92 virtual void visit( ReturnStmt * ); 93 virtual void visit( ThrowStmt * ); 93 94 virtual void visit( WhileStmt * ); 94 95 virtual void visit( ForStmt * ); -
src/Parser/ParseNode.h
r82ff5845 ra724ac1 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:28:16 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Mar 17 15:42:18201713 // Update Count : 77 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 12 13:00:00 2017 13 // Update Count : 779 14 14 // 15 15 … … 393 393 Statement * build_return( ExpressionNode * ctl ); 394 394 Statement * build_throw( ExpressionNode * ctl ); 395 Statement * build_resume( ExpressionNode * ctl ); 396 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target ); 395 397 Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt ); 396 Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false);398 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body ); 397 399 Statement * build_finally( StatementNode * stmt ); 398 400 Statement * build_compound( StatementNode * first ); -
src/Parser/StatementNode.cc
r82ff5845 ra724ac1 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 14:59:41 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Feb 2 22:16:40 201713 // Update Count : 32 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 12 13:03:00 2017 13 // Update Count : 329 14 14 // 15 15 … … 152 152 return new ReturnStmt( noLabels, exps.size() > 0 ? exps.back() : nullptr ); 153 153 } 154 154 155 Statement *build_throw( ExpressionNode *ctl ) { 155 156 std::list< Expression * > exps; 156 157 buildMoveList( ctl, exps ); 157 158 assertf( exps.size() < 2, "This means we are leaking memory"); 158 return new ReturnStmt( noLabels, !exps.empty() ? exps.back() : nullptr, true ); 159 return new ThrowStmt( noLabels, ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 160 } 161 162 Statement *build_resume( ExpressionNode *ctl ) { 163 std::list< Expression * > exps; 164 buildMoveList( ctl, exps ); 165 assertf( exps.size() < 2, "This means we are leaking memory"); 166 return new ThrowStmt( noLabels, ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 167 } 168 169 Statement *build_resume_at( ExpressionNode *ctl, ExpressionNode *target ) { 170 std::list< Expression * > exps; 171 buildMoveList( ctl, exps ); 172 assertf( exps.size() < 2, "This means we are leaking memory"); 173 return new ThrowStmt( noLabels, ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 159 174 } 160 175 … … 166 181 return new TryStmt( noLabels, tryBlock, branches, finallyBlock ); 167 182 } 168 Statement *build_catch( DeclarationNode *decl, StatementNode *stmt, bool catchAny ) {169 std::list< Statement * > branches; 170 buildMoveList< Statement, StatementNode >( stmt, branches );171 assert( branches.size() == 1 ); 172 return new CatchStmt( noLabels, maybeMoveBuild< Declaration >(decl), branches.front(), catchAny);183 Statement *build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body ) { 184 std::list< Statement * > branches; 185 buildMoveList< Statement, StatementNode >( body, branches ); 186 assert( branches.size() == 1 ); 187 return new CatchStmt( noLabels, kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() ); 173 188 } 174 189 Statement *build_finally( StatementNode *stmt ) { -
src/Parser/parser.yy
r82ff5845 ra724ac1 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 25 15:21:59201713 // Update Count : 2 39812 // Last Modified On : Mon Jun 12 12:59:00 2017 13 // Update Count : 2402 14 14 // 15 15 … … 193 193 %type<sn> case_value_list case_label case_label_list 194 194 %type<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list 195 %type<sn> handler_listhandler_clause finally_clause195 %type<sn> /* handler_list */ handler_clause finally_clause 196 196 197 197 // declarations … … 931 931 { $$ = new StatementNode( build_throw( $2 ) ); } 932 932 | THROWRESUME assignment_expression_opt ';' // handles reresume 933 { $$ = new StatementNode( build_ throw( $2 ) ); }933 { $$ = new StatementNode( build_resume( $2 ) ); } 934 934 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 935 { $$ = new StatementNode( build_ throw( $2) ); }935 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } 936 936 ; 937 937 938 938 exception_statement: 939 TRY compound_statement handler_ list939 TRY compound_statement handler_clause 940 940 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); } 941 941 | TRY compound_statement finally_clause 942 942 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); } 943 | TRY compound_statement handler_ listfinally_clause943 | TRY compound_statement handler_clause finally_clause 944 944 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); } 945 945 ; 946 946 947 handler_list:948 handler_clause949 // ISO/IEC 9899:1999 Section 15.3(6 ) If present, a "..." handler shall be the last handler for its try block.950 | CATCH '(' ELLIPSIS ')' compound_statement951 { $$ = new StatementNode( build_catch( 0, $5, true ) ); }952 | handler_clause CATCH '(' ELLIPSIS ')' compound_statement953 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); }954 | CATCHRESUME '(' ELLIPSIS ')' compound_statement955 { $$ = new StatementNode( build_catch( 0, $5, true ) ); }956 | handler_clause CATCHRESUME '(' ELLIPSIS ')' compound_statement957 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); }958 ;947 //handler_list: 948 // handler_clause 949 // // ISO/IEC 9899:1999 Section 15.3(6 ) If present, a "..." handler shall be the last handler for its try block. 950 // | CATCH '(' ELLIPSIS ')' compound_statement 951 // { $$ = new StatementNode( build_catch( 0, $5, true ) ); } 952 // | handler_clause CATCH '(' ELLIPSIS ')' compound_statement 953 // { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); } 954 // | CATCHRESUME '(' ELLIPSIS ')' compound_statement 955 // { $$ = new StatementNode( build_catch( 0, $5, true ) ); } 956 // | handler_clause CATCHRESUME '(' ELLIPSIS ')' compound_statement 957 // { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); } 958 // ; 959 959 960 960 handler_clause: 961 961 CATCH '(' push push exception_declaration pop ')' compound_statement pop 962 { $$ = new StatementNode( build_catch( $5, $8 ) ); }962 { $$ = new StatementNode( build_catch( CatchStmt::Terminate, $5, nullptr, $8 ) ); } 963 963 | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop 964 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $6, $9 ) ) ); }964 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, $6, nullptr, $9 ) ) ); } 965 965 | CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop 966 { $$ = new StatementNode( build_catch( $5, $8 ) ); }966 { $$ = new StatementNode( build_catch( CatchStmt::Resume, $5, nullptr, $8 ) ); } 967 967 | handler_clause CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop 968 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $6, $9 ) ) ); }968 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Resume, $6, nullptr, $9 ) ) ); } 969 969 ; 970 970 -
src/ResolvExpr/Unify.cc
r82ff5845 ra724ac1 683 683 684 684 template< typename Iterator1, typename Iterator2 > 685 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode,const SymTab::Indexer &indexer ) {685 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 686 686 auto get_type = [](Type * t) { return t; }; 687 687 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { … … 733 733 flatten( flat2.get(), back_inserter( types2 ) ); 734 734 735 result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode,indexer );735 result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, indexer ); 736 736 } // if 737 737 } -
src/SynTree/Mutator.cc
r82ff5845 ra724ac1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 30 16:45:19201713 // Update Count : 2 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Mar 8 16:36:00 2017 13 // Update Count : 23 14 14 // 15 15 … … 153 153 } 154 154 155 Statement *Mutator::mutate( ThrowStmt *throwStmt ) { 156 throwStmt->set_expr( maybeMutate( throwStmt->get_expr(), *this ) ); 157 throwStmt->set_target( maybeMutate( throwStmt->get_target(), *this ) ); 158 return throwStmt; 159 } 160 155 161 Statement *Mutator::mutate( TryStmt *tryStmt ) { 156 162 tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); -
src/SynTree/Mutator.h
r82ff5845 ra724ac1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Feb 9 14:23:23201713 // Update Count : 1 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Jun 8 15:45:00 2017 13 // Update Count : 14 14 14 // 15 15 #include <cassert> … … 46 46 virtual Statement* mutate( BranchStmt *branchStmt ); 47 47 virtual Statement* mutate( ReturnStmt *returnStmt ); 48 virtual Statement* mutate( TryStmt *returnStmt ); 48 virtual Statement* mutate( ThrowStmt *throwStmt ); 49 virtual Statement* mutate( TryStmt *tryStmt ); 49 50 virtual Statement* mutate( CatchStmt *catchStmt ); 50 51 virtual Statement* mutate( FinallyStmt *catchStmt ); -
src/SynTree/Statement.cc
r82ff5845 ra724ac1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Aug 12 13:58:48 201613 // Update Count : 6 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 12 10:37:00 2017 13 // Update Count : 64 14 14 // 15 15 … … 101 101 } 102 102 103 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr , bool throwP ) : Statement( labels ), expr( _expr ), isThrow( throwP) {}104 105 ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) , isThrow( other.isThrow ){}103 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr ) : Statement( labels ), expr( _expr ) {} 104 105 ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {} 106 106 107 107 ReturnStmt::~ReturnStmt() { … … 110 110 111 111 void ReturnStmt::print( std::ostream &os, int indent ) const { 112 os << string ( isThrow? "Throw":"Return" ) << "Statement, returning: ";112 os << "Return Statement, returning: "; 113 113 if ( expr != 0 ) { 114 114 os << endl << string( indent+2, ' ' ); … … 287 287 } 288 288 289 ThrowStmt::ThrowStmt( std::list<Label> labels, Kind kind, Expression * expr, Expression * target ) : 290 Statement( labels ), kind(kind), expr(expr), target(target) { 291 assertf(Resume == kind || nullptr == target, "Non-local termination throw is not accepted." ); 292 } 293 294 ThrowStmt::ThrowStmt( const ThrowStmt &other ) : 295 Statement ( other ), kind( other.kind ), expr( maybeClone( other.expr ) ), target( maybeClone( other.target ) ) { 296 } 297 298 ThrowStmt::~ThrowStmt() { 299 delete expr; 300 delete target; 301 } 302 303 void ThrowStmt::print( std::ostream &os, int indent) const { 304 if ( target ) { 305 os << "Non-Local "; 306 } 307 os << "Throw Statement, raising: "; 308 expr->print(os, indent + 4); 309 if ( target ) { 310 os << "At: "; 311 target->print(os, indent + 4); 312 } 313 } 314 289 315 TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &_handlers, FinallyStmt *_finallyBlock ) : 290 316 Statement( labels ), block( tryBlock ), handlers( _handlers ), finallyBlock( _finallyBlock ) { … … 318 344 } 319 345 320 CatchStmt::CatchStmt( std::list<Label> labels, Declaration *_decl, Statement *_body, bool catchAny ) :321 Statement( labels ), decl ( _decl ), body( _body ), catchRest ( catchAny ) {346 CatchStmt::CatchStmt( std::list<Label> labels, Kind _kind, Declaration *_decl, Expression *_cond, Statement *_body ) : 347 Statement( labels ), kind ( _kind ), decl ( _decl ), cond ( _cond ), body( _body ) { 322 348 } 323 349 324 350 CatchStmt::CatchStmt( const CatchStmt & other ) : 325 Statement( other ), decl ( maybeClone( other.decl ) ), body( maybeClone( other.body ) ), catchRest ( other.catchRest) {351 Statement( other ), kind ( other.kind ), decl ( maybeClone( other.decl ) ), cond ( maybeClone( other.cond ) ), body( maybeClone( other.body ) ) { 326 352 } 327 353 … … 332 358 333 359 void CatchStmt::print( std::ostream &os, int indent ) const { 334 os << "Catch Statement" << endl;360 os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl; 335 361 336 362 os << string( indent, ' ' ) << "... catching" << endl; … … 338 364 decl->printShort( os, indent + 4 ); 339 365 os << endl; 340 } else if ( catchRest ) 341 os << string( indent + 4 , ' ' ) << "the rest" << endl; 366 } 342 367 else 343 368 os << string( indent + 4 , ' ' ) << ">>> Error: this catch clause must have a declaration <<<" << endl; -
src/SynTree/Statement.h
r82ff5845 ra724ac1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Aug 12 13:57:46 201613 // Update Count : 6 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 12 13:35:00 2017 13 // Update Count : 67 14 14 // 15 15 … … 57 57 private: 58 58 std::list<Statement*> kids; 59 }; 60 61 class NullStmt : public CompoundStmt { 62 public: 63 NullStmt(); 64 NullStmt( std::list<Label> labels ); 65 66 virtual NullStmt *clone() const { return new NullStmt( *this ); } 67 virtual void accept( Visitor &v ) { v.visit( this ); } 68 virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); } 69 virtual void print( std::ostream &os, int indent = 0 ) const; 70 71 private: 59 72 }; 60 73 … … 261 274 class ReturnStmt : public Statement { 262 275 public: 263 ReturnStmt( std::list<Label> labels, Expression *expr , bool throwP = false);276 ReturnStmt( std::list<Label> labels, Expression *expr ); 264 277 ReturnStmt( const ReturnStmt &other ); 265 278 virtual ~ReturnStmt(); … … 274 287 private: 275 288 Expression *expr; 276 bool isThrow; 277 }; 278 279 280 class NullStmt : public CompoundStmt { 281 public: 282 NullStmt(); 283 NullStmt( std::list<Label> labels ); 284 285 virtual NullStmt *clone() const { return new NullStmt( *this ); } 286 virtual void accept( Visitor &v ) { v.visit( this ); } 287 virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); } 288 virtual void print( std::ostream &os, int indent = 0 ) const; 289 290 private: 289 }; 290 291 class ThrowStmt : public Statement { 292 public: 293 enum Kind { Terminate, Resume }; 294 295 ThrowStmt( std::list<Label> labels, Kind kind, Expression * expr, Expression * target = nullptr ); 296 ThrowStmt( const ThrowStmt &other ); 297 virtual ~ThrowStmt(); 298 299 Kind get_kind() { return kind; } 300 Expression * get_expr() { return expr; } 301 void set_expr( Expression * newExpr ) { expr = newExpr; } 302 Expression * get_target() { return target; } 303 void set_target( Expression * newTarget ) { target = newTarget; } 304 305 virtual ThrowStmt *clone() const { return new ThrowStmt( *this ); } 306 virtual void accept( Visitor &v ) { v.visit( this ); } 307 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 308 virtual void print( std::ostream &os, int indent = 0 ) const; 309 private: 310 Kind kind; 311 Expression * expr; 312 Expression * target; 291 313 }; 292 314 … … 317 339 class CatchStmt : public Statement { 318 340 public: 319 CatchStmt( std::list<Label> labels, Declaration *decl, Statement *body, bool catchAny = false ); 341 enum Kind { Terminate, Resume }; 342 343 CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl, 344 Expression *cond, Statement *body ); 320 345 CatchStmt( const CatchStmt &other ); 321 346 virtual ~CatchStmt(); 322 347 348 Kind get_kind() { return kind; } 323 349 Declaration *get_decl() { return decl; } 324 350 void set_decl( Declaration *newValue ) { decl = newValue; } 325 351 Expression *get_cond() { return cond; } 352 void set_cond( Expression *newCond ) { cond = newCond; } 326 353 Statement *get_body() { return body; } 327 354 void set_body( Statement *newValue ) { body = newValue; } … … 333 360 334 361 private: 362 Kind kind; 335 363 Declaration *decl; 364 Expression *cond; 336 365 Statement *body; 337 bool catchRest;338 366 }; 339 367 -
src/SynTree/SynTree.h
r82ff5845 ra724ac1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Feb 9 14:23:49201713 // Update Count : 811 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Jun 8 17:00:00 2017 13 // Update Count : 9 14 14 // 15 15 … … 51 51 class BranchStmt; 52 52 class ReturnStmt; 53 class ThrowStmt; 53 54 class TryStmt; 54 55 class CatchStmt; -
src/SynTree/Visitor.cc
r82ff5845 ra724ac1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 30 16:45:25201713 // Update Count : 2 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Jun 8 16:31:00 2017 13 // Update Count : 25 14 14 // 15 15 … … 129 129 } 130 130 131 void Visitor::visit( ThrowStmt * throwStmt ) { 132 maybeAccept( throwStmt->get_expr(), *this ); 133 maybeAccept( throwStmt->get_target(), *this ); 134 } 135 131 136 void Visitor::visit( TryStmt *tryStmt ) { 132 137 maybeAccept( tryStmt->get_block(), *this ); -
src/SynTree/Visitor.h
r82ff5845 ra724ac1 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 3 08:58:00 201713 // Update Count : 1 012 // Last Modified On : Thr Jun 08 15:45:00 2017 13 // Update Count : 11 14 14 // 15 15 … … 49 49 virtual void visit( BranchStmt *branchStmt ); 50 50 virtual void visit( ReturnStmt *returnStmt ); 51 virtual void visit( ThrowStmt *throwStmt ); 51 52 virtual void visit( TryStmt *tryStmt ); 52 53 virtual void visit( CatchStmt *catchStmt ); -
tools/cfa.nanorc
r82ff5845 ra724ac1 33 33 ## Update/Redistribute 34 34 # GCC builtins 35 ##color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__" 35 color cyan "__attribute__[[:space:]]*\(\([^()]*(\([^()]*\)[^()]*)*\)\)" 36 ##color cyan "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__" 36 37 37 38 # Preprocesser Directives
Note: See TracChangeset
for help on using the changeset viewer.