source: src/ControlStruct/CaseRangeMutator.cc@ 4162aea9

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 4162aea9 was 843054c2, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

licencing: seventh groups of files

  • Property mode set to 100644
File size: 6.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// CaseRangeMutator.cc --
8//
9// Author : Rodolfo G. Esteves
10// Created On : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue May 19 13:00:28 2015
13// Update Count : 3
14//
15
16#include <list>
17#include <cassert>
18#include <cstdlib>
19#include <iterator>
20
21#include "utility.h"
22
23#include "SynTree/Statement.h"
24#include "SynTree/Expression.h"
25#include "SynTree/Constant.h"
26#include "SynTree/Type.h"
27#include "CaseRangeMutator.h"
28
29namespace ControlStruct {
30 Statement *CaseRangeMutator::mutate( ChooseStmt *chooseStmt ) {
31 // There shouldn't be any `choose' statements by now, throw an exception or something.
32 throw( 0 ) ; /* FIXME */
33 }
34
35 Statement *CaseRangeMutator::mutate( SwitchStmt *switchStmt ) {
36 std::list< Statement * > &cases = switchStmt->get_branches();
37
38 // a `for' would be more natural... all this contortions are because `replace' invalidates the iterator
39 std::list< Statement * >::iterator i = cases.begin();
40 while ( i != cases.end() ) {
41 (*i )->acceptMutator( *this );
42
43 if ( ! newCaseLabels.empty() ) {
44 std::list< Statement * > newCases;
45
46 // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) );
47
48 for ( std::list< Expression * >::iterator j = newCaseLabels.begin();
49 j != newCaseLabels.end(); j++ ) {
50 std::list<Label> emptyLabels;
51 std::list< Statement *> emptyStmts;
52 newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) );
53 } // for
54
55 if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) )
56 if ( ! currentCase->get_statements().empty() ) {
57 CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() );
58 if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases
59 // transfer the statement block ( if any ) to the new list:
60 lastCase->set_statements( currentCase->get_statements() );
61 } // if
62 std::list< Statement * >::iterator j = i; advance( j, 1 );
63 replace ( cases, i, newCases );
64 i = j;
65 newCaseLabels.clear();
66 } else
67 i++;
68 } // while
69
70 return switchStmt;
71 }
72
73 Statement *CaseRangeMutator::mutate( FallthruStmt *fallthruStmt ) {
74 //delete fallthruStmt;
75 return new NullStmt();
76 }
77
78 Statement *CaseRangeMutator::mutate( CaseStmt *caseStmt ) {
79 UntypedExpr *cond;
80 if ( ( cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) {
81 NameExpr *nmfunc;
82 if ( ( nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) {
83 if ( nmfunc->get_name() == std::string("Range") ) {
84 assert( cond->get_args().size() == 2 );
85 std::list<Expression *>::iterator i = cond->get_args().begin();
86 Expression *lo = *i, *hi = *(++i ); // "unnecessary" temporaries
87 fillRange( lo, hi );
88 } // if
89 } // if
90 } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
91 // case list
92 assert( ! tcond->get_exprs().empty() );
93 for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ )
94 newCaseLabels.push_back( *i ); // do I need to clone them?
95 } // if
96
97 std::list< Statement * > &stmts = caseStmt->get_statements();
98 mutateAll ( stmts, *this );
99
100 return caseStmt;
101 }
102
103 void CaseRangeMutator::fillRange( Expression *lo, Expression *hi ) {
104 // generate the actual range ( and check for consistency )
105 Constant *c_lo, *c_hi;
106 ConstantExpr *ce_lo, *ce_hi;
107 ce_lo = dynamic_cast< ConstantExpr * >( lo );
108 ce_hi = dynamic_cast< ConstantExpr * >( hi );
109
110 if ( ce_lo && ce_hi ) {
111 c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant();
112 } /* else {
113 if ( ! ce_lo ) ;
114 if ( ! ce_hi ) ;
115 } */
116 BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ),
117 *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() );
118
119 if ( ! ty_lo || ! ty_hi )
120 return; // one of them is not a constant
121
122 switch ( ty_lo->get_kind() ) {
123 case BasicType::Char:
124 case BasicType::UnsignedChar:
125 switch ( ty_hi->get_kind() ) {
126 case BasicType::Char:
127 case BasicType::UnsignedChar:
128 // first case, they are both printable ASCII characters represented as 'x'
129 if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) {
130 char ch_lo = ( c_lo->get_value())[1], ch_hi = ( c_hi->get_value())[1];
131
132 if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; }
133
134 for ( char c = ch_lo; c <= ch_hi; c++ ) {
135 Type::Qualifiers q;
136 Constant cnst( new BasicType( q, BasicType::Char ),
137 std::string("'") + c + std::string("'") );
138 newCaseLabels.push_back( new ConstantExpr( cnst ) );
139 } // for
140
141 return;
142 } // if
143 break;
144 default:
145 // error: incompatible constants
146 break;
147 } // switch
148 break;
149 case BasicType::ShortSignedInt:
150 case BasicType::ShortUnsignedInt:
151 case BasicType::SignedInt:
152 case BasicType::UnsignedInt:
153 case BasicType::LongSignedInt:
154 case BasicType::LongUnsignedInt:
155 case BasicType::LongLongSignedInt:
156 case BasicType::LongLongUnsignedInt:
157 switch ( ty_hi->get_kind() ) {
158 case BasicType::ShortSignedInt:
159 case BasicType::ShortUnsignedInt:
160 case BasicType::SignedInt:
161 case BasicType::UnsignedInt:
162 case BasicType::LongSignedInt:
163 case BasicType::LongUnsignedInt:
164 case BasicType::LongLongSignedInt:
165 case BasicType::LongLongUnsignedInt: {
166 int i_lo = atoi( c_lo->get_value().c_str()),
167 i_hi = atoi( c_hi->get_value().c_str());
168
169 if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; }
170
171 for ( int c = i_lo; c <= i_hi; c++ ) {
172 Type::Qualifiers q;
173 Constant cnst( new BasicType( q, ty_hi->get_kind()), // figure can't hurt (used to think in positives)
174 toString< int >( c ) );
175 newCaseLabels.push_back( new ConstantExpr( cnst ) );
176 }
177
178 return;
179 }
180 default:
181 // error: incompatible constants
182 break;
183 }
184 break;
185 default:
186 break;
187 } // switch
188
189 /* End: */{
190 // invalid range, signal a warning (it still generates the two case labels)
191 newCaseLabels.push_back( lo );
192 newCaseLabels.push_back( hi );
193 return;
194 }
195 }
196} // namespace ControlStruct
197
198// Local Variables: //
199// tab-width: 4 //
200// mode: c++ //
201// compile-command: "make install" //
202// End: //
Note: See TracBrowser for help on using the repository browser.