Changeset cce9429 for src/InitTweak
- Timestamp:
- Dec 13, 2016, 6:42:39 PM (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:
- 1aa4b71
- Parents:
- 31f379c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r31f379c rcce9429 46 46 ReturnFixer(); 47 47 48 using GenPoly::PolyMutator::mutate; 48 typedef GenPoly::PolyMutator Parent; 49 using Parent::mutate; 49 50 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override; 50 51 virtual Statement * mutate( ReturnStmt * returnStmt ) override; … … 142 143 // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address 143 144 // is being returned 145 // Note: under the assumption that assignments return *this, checking for ?=? here is an optimization, since it shouldn't be necessary to copy construct `this`. This is a temporary optimization until reference types are added, at which point this should be removed, along with the analogous optimization in copy constructor generation. 144 146 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue() ) { 145 // ensure return value is not destructed by explicitly creating 146 // an empty SingleInit node wherein maybeConstruct is false 147 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), new ListInit( std::list<Initializer*>(), noDesignators, false ) ); 148 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 149 150 // and explicitly create the constructor expression separately 147 // explicitly construct the return value using the return expression and the retVal object 148 assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() ); 151 149 UntypedExpr *construct = new UntypedExpr( new NameExpr( "?{}" ) ); 152 construct->get_args().push_back( new AddressExpr( new VariableExpr( newObj) ) );150 construct->get_args().push_back( new AddressExpr( new VariableExpr( returnVals.front() ) ) ); 153 151 construct->get_args().push_back( returnStmt->get_expr() ); 154 152 stmtsToAdd.push_back(new ExprStmt(noLabels, construct)); 155 153 156 returnStmt->set_expr( new VariableExpr( newObj ) ); 154 // return the retVal object 155 returnStmt->set_expr( new VariableExpr( returnVals.front() ) ); 157 156 } // if 158 157 return returnStmt; … … 160 159 161 160 DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) { 162 // xxx - need to handle named return values - this pass may need to happen163 // after resolution? the ordering is tricky because return statements must be164 // constructed - the simplest way to do that (while also handling multiple165 // returns) is to structure the returnVals into a tuple, as done here.166 // however, if the tuple return value is structured before resolution,167 // it's difficult to resolve named return values, since the name is lost168 // in conversion to a tuple. this might be easiest to deal with169 // after reference types are added, as it may then be possible to170 // uniformly move named return values to the parameter list directly171 161 ValueGuard< FunctionType * > oldFtype( ftype ); 172 162 ValueGuard< std::string > oldFuncName( funcName ); 173 163 174 164 ftype = functionDecl->get_functionType(); 175 std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();176 if ( retVals.size() > 1 ) {177 TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );178 ObjectDecl * newRet = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );179 retVals.clear();180 retVals.push_back( newRet );181 }182 165 funcName = functionDecl->get_name(); 183 DeclarationWithType * decl = Mutator::mutate( functionDecl ); 184 return decl; 166 return Parent::mutate( functionDecl ); 185 167 } 186 168
Note: See TracChangeset
for help on using the changeset viewer.