Changeset 65660bd for src/Tuples/TupleExpansion.cc
- Timestamp:
- Sep 22, 2016, 8:14:56 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, 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:
- ac9ca96
- Parents:
- 1132b62
- git-author:
- Rob Schluntz <rschlunt@…> (09/21/16 23:43:37)
- git-committer:
- Rob Schluntz <rschlunt@…> (09/22/16 08:14:56)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleExpansion.cc
r1132b62 r65660bd 49 49 50 50 virtual Type * mutate( TupleType * tupleType ); 51 virtual Type * mutate( FunctionType * ftype );52 51 53 52 virtual CompoundStmt * mutate( CompoundStmt * stmt ) { … … 119 118 delete assnExpr; 120 119 return new StmtExpr( compoundStmt ); 121 }122 123 Type * TupleTypeReplacer::mutate( FunctionType * ftype ) {124 // replace multiple-returning functions with functions which return a tuple125 if ( ftype->get_returnVals().size() > 1 ) {126 TupleType * tupleType = safe_dynamic_cast<TupleType *>( ResolvExpr::extractResultType( ftype ) );127 ObjectDecl * retVal = new ObjectDecl( "__tuple_ret", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, tupleType, nullptr );128 // xxx - replace all uses of return vals with appropriate tuple index expr129 deleteAll( ftype->get_returnVals() );130 ftype->get_returnVals().clear();131 ftype->get_returnVals().push_back( retVal );132 }133 return Parent::mutate( ftype );134 120 } 135 121 … … 167 153 } 168 154 155 Expression * replaceTupleExpr( Type * result, const std::list< Expression * > & exprs ) { 156 if ( result->isVoid() ) { 157 // void result - don't need to produce a value for cascading - just output a chain of comma exprs 158 assert( ! exprs.empty() ); 159 std::list< Expression * >::const_iterator iter = exprs.begin(); 160 Expression * expr = *iter++; 161 for ( ; iter != exprs.end(); ++iter ) { 162 expr = new CommaExpr( expr, *iter ); 163 } 164 return expr; 165 } else { 166 // typed tuple expression - produce a compound literal which performs each of the expressions 167 // as a distinct part of its initializer - the produced compound literal may be used as part of 168 // another expression 169 std::list< Initializer * > inits; 170 for ( Expression * expr : exprs ) { 171 inits.push_back( new SingleInit( expr ) ); 172 } 173 return new CompoundLiteralExpr( result, new ListInit( inits ) ); 174 } 175 } 176 169 177 Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) { 170 assert( tupleExpr->get_result() ); 171 std::list< Initializer * > inits; 172 for ( Expression * expr : tupleExpr->get_exprs() ) { 173 inits.push_back( new SingleInit( expr ) ); 174 } 175 return new CompoundLiteralExpr( tupleExpr->get_result(), new ListInit( inits ) ); 176 } 177 178 TupleType * makeTupleType( const std::list< Expression * > & exprs ) { 178 Type * result = tupleExpr->get_result(); 179 std::list< Expression * > exprs = tupleExpr->get_exprs(); 180 assert( result ); 181 182 tupleExpr->set_result( nullptr ); 183 tupleExpr->get_exprs().clear(); 184 delete tupleExpr; 185 186 return replaceTupleExpr( result, exprs ); 187 } 188 189 Type * makeTupleType( const std::list< Expression * > & exprs ) { 190 // produce the TupleType which aggregates the types of the exprs 179 191 TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, false) ); 180 192 Type::Qualifiers &qualifiers = tupleType->get_qualifiers(); 181 193 for ( Expression * expr : exprs ) { 182 194 assert( expr->get_result() ); 195 if ( expr->get_result()->isVoid() ) { 196 // if the type of any expr is void, the type of the entire tuple is void 197 delete tupleType; 198 return new VoidType( Type::Qualifiers() ); 199 } 183 200 Type * type = expr->get_result()->clone(); 184 201 tupleType->get_types().push_back( type ); 202 // the qualifiers on the tuple type are the qualifiers that exist on all component types 185 203 qualifiers &= type->get_qualifiers(); 186 204 } // for 187 205 return tupleType; 206 } 207 208 namespace { 209 /// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure 210 class ImpurityDetector : public Visitor { 211 public: 212 typedef Visitor Parent; 213 virtual void visit( ApplicationExpr * appExpr ) { maybeImpure = true; } 214 virtual void visit( UntypedExpr * untypedExpr ) { maybeImpure = true; } 215 bool maybeImpure = false; 216 }; 217 } // namespace 218 219 bool maybeImpure( Expression * expr ) { 220 ImpurityDetector detector; 221 expr->accept( detector ); 222 return detector.maybeImpure; 188 223 } 189 224 } // namespace Tuples
Note: See TracChangeset
for help on using the changeset viewer.