Changeset d9a0e76 for translator/ControlStruct/CaseRangeMutator.cc
- Timestamp:
- Dec 16, 2014, 9:41:50 PM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 17cd4eb
- Parents:
- 3848e0e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
translator/ControlStruct/CaseRangeMutator.cc
r3848e0e rd9a0e76 13 13 14 14 namespace ControlStruct { 15 16 Statement* CaseRangeMutator::mutate(ChooseStmt *chooseStmt) 17 { 18 /* There shouldn't be any `choose' statements by now, throw an exception or something. */ 19 throw( 0 ) ; /* FIXME */ 20 } 21 22 Statement* CaseRangeMutator::mutate(SwitchStmt *switchStmt) 23 { 24 std::list< Statement * > &cases = switchStmt->get_branches(); 25 26 // a `for' would be more natural... all this contortions are because `replace' invalidates the iterator 27 std::list< Statement * >::iterator i = cases.begin(); 28 while ( i != cases.end() ) { 29 (*i)->acceptMutator( *this ); 30 31 if ( ! newCaseLabels.empty() ) { 32 std::list< Statement * > newCases; 33 34 // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) ); 35 36 for ( std::list< Expression * >::iterator j = newCaseLabels.begin(); 37 j != newCaseLabels.end(); j++ ) { 38 std::list<Label> emptyLabels; 39 std::list< Statement *> emptyStmts; 40 newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) ); 41 } 42 43 if( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) ) 44 if ( !currentCase->get_statements().empty() ) { 45 CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() ); 46 if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases 47 // transfer the statement block (if any) to the new list: 48 lastCase->set_statements( currentCase->get_statements() ); 49 } 50 std::list< Statement * >::iterator j = i; advance( j, 1 ); 51 replace ( cases, i, newCases ); 52 i = j; 53 newCaseLabels.clear(); 54 } else 55 i++; 15 Statement *CaseRangeMutator::mutate(ChooseStmt *chooseStmt) { 16 /* There shouldn't be any `choose' statements by now, throw an exception or something. */ 17 throw( 0 ) ; /* FIXME */ 56 18 } 57 19 58 return switchStmt;59 } 20 Statement *CaseRangeMutator::mutate(SwitchStmt *switchStmt) { 21 std::list< Statement * > &cases = switchStmt->get_branches(); 60 22 61 Statement* CaseRangeMutator::mutate(FallthruStmt *fallthruStmt) 62 { 63 //delete fallthruStmt; 64 return new NullStmt(); 65 } 23 // a `for' would be more natural... all this contortions are because `replace' invalidates the iterator 24 std::list< Statement * >::iterator i = cases.begin(); 25 while ( i != cases.end() ) { 26 (*i)->acceptMutator( *this ); 66 27 67 Statement* CaseRangeMutator::mutate(CaseStmt *caseStmt) 68 { 69 UntypedExpr *cond; 70 if ( (cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) { 71 NameExpr *nmfunc; 72 if ( (nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) { 73 if ( nmfunc->get_name() == std::string("Range") ) { 74 assert( cond->get_args().size() == 2 ); 75 std::list<Expression *>::iterator i = cond->get_args().begin(); 76 Expression *lo = *i, *hi = *(++i); // "unnecessary" temporaries 77 fillRange( lo, hi); 78 } 79 } 80 } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) { 81 // case list 82 assert( ! tcond->get_exprs().empty() ); 83 for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ ) 84 newCaseLabels.push_back( *i ); // do I need to clone them? 28 if ( ! newCaseLabels.empty() ) { 29 std::list< Statement * > newCases; 30 31 // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) ); 32 33 for ( std::list< Expression * >::iterator j = newCaseLabels.begin(); 34 j != newCaseLabels.end(); j++ ) { 35 std::list<Label> emptyLabels; 36 std::list< Statement *> emptyStmts; 37 newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) ); 38 } 39 40 if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) ) 41 if ( ! currentCase->get_statements().empty() ) { 42 CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() ); 43 if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases 44 // transfer the statement block (if any) to the new list: 45 lastCase->set_statements( currentCase->get_statements() ); 46 } 47 std::list< Statement * >::iterator j = i; advance( j, 1 ); 48 replace ( cases, i, newCases ); 49 i = j; 50 newCaseLabels.clear(); 51 } else 52 i++; 53 } // while 54 55 return switchStmt; 85 56 } 86 57 87 std::list< Statement * > &stmts = caseStmt->get_statements(); 88 mutateAll ( stmts, *this ); 89 90 return caseStmt; 91 } 92 93 void CaseRangeMutator::fillRange(Expression *lo, Expression *hi) { 94 // generate the actual range (and check for consistency) 95 Constant *c_lo, *c_hi; 96 ConstantExpr *ce_lo, *ce_hi; 97 ce_lo = dynamic_cast< ConstantExpr * >( lo ); 98 ce_hi = dynamic_cast< ConstantExpr * >( hi ); 99 100 if ( ce_lo && ce_hi ) { 101 c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant(); 102 } /* else { 103 if ( !ce_lo ) ; 104 if ( !ce_hi ) ; 105 } */ 106 BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ), 107 *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() ); 108 109 if( !ty_lo || !ty_hi ) 110 return; // one of them is not a constant 111 112 113 switch( ty_lo->get_kind() ) { 114 case BasicType::Char: 115 case BasicType::UnsignedChar: 116 switch( ty_hi->get_kind() ) 117 { 118 case BasicType::Char: 119 case BasicType::UnsignedChar: 120 // first case, they are both printable ASCII characters represented as 'x' 121 if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) { 122 char ch_lo = (c_lo->get_value())[1], ch_hi = (c_hi->get_value())[1]; 123 124 if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; } 125 126 for( char c = ch_lo; c <= ch_hi; c++ ){ 127 Type::Qualifiers q; 128 Constant cnst( new BasicType(q, BasicType::Char), 129 std::string("'") + c + std::string("'") ); 130 newCaseLabels.push_back( new ConstantExpr( cnst ) ); 131 } 132 133 return; 134 } 135 break; 136 default: 137 // error: incompatible constants 138 break; 139 } 140 break; 141 case BasicType::ShortSignedInt: 142 case BasicType::ShortUnsignedInt: 143 case BasicType::SignedInt: 144 case BasicType::UnsignedInt: 145 case BasicType::LongSignedInt: 146 case BasicType::LongUnsignedInt: 147 case BasicType::LongLongSignedInt: 148 case BasicType::LongLongUnsignedInt: 149 switch( ty_hi->get_kind() ) 150 { 151 case BasicType::ShortSignedInt: 152 case BasicType::ShortUnsignedInt: 153 case BasicType::SignedInt: 154 case BasicType::UnsignedInt: 155 case BasicType::LongSignedInt: 156 case BasicType::LongUnsignedInt: 157 case BasicType::LongLongSignedInt: 158 case BasicType::LongLongUnsignedInt: { 159 int i_lo = atoi(c_lo->get_value().c_str()), 160 i_hi = atoi(c_hi->get_value().c_str()); 161 162 if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; } 163 164 for( int c = i_lo; c <= i_hi; c++ ){ 165 Type::Qualifiers q; 166 Constant cnst( new BasicType(q, ty_hi->get_kind()), // figure can't hurt (used to think in positives) 167 toString< int >( c ) ); 168 newCaseLabels.push_back( new ConstantExpr( cnst ) ); 169 } 170 171 return; 172 } 173 default: 174 // error: incompatible constants 175 break; 176 } 177 break; 178 default: 179 break; 58 Statement *CaseRangeMutator::mutate(FallthruStmt *fallthruStmt) { 59 //delete fallthruStmt; 60 return new NullStmt(); 180 61 } 181 62 182 /* End: */{ 183 // invalid range, signal a warning (it still generates the two case labels) 184 newCaseLabels.push_back( lo ); 185 newCaseLabels.push_back( hi ); 186 return; 63 Statement *CaseRangeMutator::mutate(CaseStmt *caseStmt) { 64 UntypedExpr *cond; 65 if ( (cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) { 66 NameExpr *nmfunc; 67 if ( (nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) { 68 if ( nmfunc->get_name() == std::string("Range") ) { 69 assert( cond->get_args().size() == 2 ); 70 std::list<Expression *>::iterator i = cond->get_args().begin(); 71 Expression *lo = *i, *hi = *(++i); // "unnecessary" temporaries 72 fillRange( lo, hi); 73 } 74 } 75 } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) { 76 // case list 77 assert( ! tcond->get_exprs().empty() ); 78 for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ ) 79 newCaseLabels.push_back( *i ); // do I need to clone them? 80 } // if 81 82 std::list< Statement * > &stmts = caseStmt->get_statements(); 83 mutateAll ( stmts, *this ); 84 85 return caseStmt; 187 86 } 188 }189 87 88 void CaseRangeMutator::fillRange(Expression *lo, Expression *hi) { 89 // generate the actual range (and check for consistency) 90 Constant *c_lo, *c_hi; 91 ConstantExpr *ce_lo, *ce_hi; 92 ce_lo = dynamic_cast< ConstantExpr * >( lo ); 93 ce_hi = dynamic_cast< ConstantExpr * >( hi ); 94 95 if ( ce_lo && ce_hi ) { 96 c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant(); 97 } /* else { 98 if ( ! ce_lo ) ; 99 if ( ! ce_hi ) ; 100 } */ 101 BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ), 102 *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() ); 103 104 if ( ! ty_lo || ! ty_hi ) 105 return; // one of them is not a constant 106 107 switch ( ty_lo->get_kind() ) { 108 case BasicType::Char: 109 case BasicType::UnsignedChar: 110 switch ( ty_hi->get_kind() ){ 111 case BasicType::Char: 112 case BasicType::UnsignedChar: 113 // first case, they are both printable ASCII characters represented as 'x' 114 if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) { 115 char ch_lo = (c_lo->get_value())[1], ch_hi = (c_hi->get_value())[1]; 116 117 if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; } 118 119 for( char c = ch_lo; c <= ch_hi; c++ ){ 120 Type::Qualifiers q; 121 Constant cnst( new BasicType(q, BasicType::Char), 122 std::string("'") + c + std::string("'") ); 123 newCaseLabels.push_back( new ConstantExpr( cnst ) ); 124 } 125 126 return; 127 } 128 break; 129 default: 130 // error: incompatible constants 131 break; 132 } 133 break; 134 case BasicType::ShortSignedInt: 135 case BasicType::ShortUnsignedInt: 136 case BasicType::SignedInt: 137 case BasicType::UnsignedInt: 138 case BasicType::LongSignedInt: 139 case BasicType::LongUnsignedInt: 140 case BasicType::LongLongSignedInt: 141 case BasicType::LongLongUnsignedInt: 142 switch ( ty_hi->get_kind() ) { 143 case BasicType::ShortSignedInt: 144 case BasicType::ShortUnsignedInt: 145 case BasicType::SignedInt: 146 case BasicType::UnsignedInt: 147 case BasicType::LongSignedInt: 148 case BasicType::LongUnsignedInt: 149 case BasicType::LongLongSignedInt: 150 case BasicType::LongLongUnsignedInt: { 151 int i_lo = atoi(c_lo->get_value().c_str()), 152 i_hi = atoi(c_hi->get_value().c_str()); 153 154 if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; } 155 156 for( int c = i_lo; c <= i_hi; c++ ){ 157 Type::Qualifiers q; 158 Constant cnst( new BasicType(q, ty_hi->get_kind()), // figure can't hurt (used to think in positives) 159 toString< int >( c ) ); 160 newCaseLabels.push_back( new ConstantExpr( cnst ) ); 161 } 162 163 return; 164 } 165 default: 166 // error: incompatible constants 167 break; 168 } 169 break; 170 default: 171 break; 172 } // switch 173 174 /* End: */{ 175 // invalid range, signal a warning (it still generates the two case labels) 176 newCaseLabels.push_back( lo ); 177 newCaseLabels.push_back( hi ); 178 return; 179 } 180 } 190 181 } // namespace ControlStruct
Note: See TracChangeset
for help on using the changeset viewer.