Changeset 4d2434a
- Timestamp:
- Aug 2, 2016, 6:37:08 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 8a443f4
- Parents:
- 39f84a4
- Location:
- src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r39f84a4 r4d2434a 270 270 printDesignators( init->get_designators() ); 271 271 output << "{ "; 272 if ( init->begin _initializers() == init->end_initializers() ) {272 if ( init->begin() == init->end() ) { 273 273 // illegal to leave initializer list empty for scalar initializers, but always legal to have 0 274 274 output << "0"; 275 275 } else { 276 genCommaList( init->begin _initializers(), init->end_initializers() );276 genCommaList( init->begin(), init->end() ); 277 277 } 278 278 output << " }"; -
src/InitTweak/GenInit.cc
r39f84a4 r4d2434a 154 154 } 155 155 156 // precompute array dimension expression, because constructor generation may duplicate it, 157 // which would be incorrect if it is a side-effecting computation. 156 158 void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) { 157 159 HoistArrayDimension hoister; … … 215 217 // hands off if designated, if @=, or if extern 216 218 if ( tryConstruct( objDecl ) ) { 217 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 218 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 219 // TODO: walk initializers and generate appropriate ctor if element has initializer. 220 // Initializer could be nested (depends on the depth of the array type on the object) 221 222 std::list< Expression * > args = makeInitList( objDecl->get_init() ); 223 if ( args.empty() ) { 224 std::list< Statement * > ctor; 225 std::list< Statement * > dtor; 226 227 InitExpander srcParam( (Expression *)NULL ); 228 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 229 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 230 231 // Currently genImplicitCall produces a single Statement - a CompoundStmt 232 // which wraps everything that needs to happen. As such, it's technically 233 // possible to use a Statement ** in the above calls, but this is inherently 234 // unsafe, so instead we take the slightly less efficient route, but will be 235 // immediately informed if somehow the above assumption is broken. In this case, 236 // we could always wrap the list of statements at this point with a CompoundStmt, 237 // but it seems reasonable at the moment for this to be done by genImplicitCall 238 // itself. It is possible that genImplicitCall produces no statements (e.g. if 239 // an array type does not have a dimension). In this case, it's fine to ignore 240 // the object for the purposes of construction. 241 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 242 if ( ctor.size() == 1 ) { 243 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 244 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 245 } 246 } else { 247 // array came with an initializer list: initialize each element 248 // may have more initializers than elements in the array - need to check at each index that 249 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting 250 // computation. 251 // may have fewer initializers than elements in the array - need to default construct 252 // remaining elements. 253 // might be able to merge this with the case above. 254 255 } 256 } else { 257 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer 258 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) ); 259 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() ); 260 219 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor 220 // for each constructable object 221 std::list< Statement * > ctor; 222 std::list< Statement * > dtor; 223 224 InitExpander srcParam( objDecl->get_init() ); 225 InitExpander nullParam( (Initializer *)NULL ); 226 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 227 SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 228 229 // Currently genImplicitCall produces a single Statement - a CompoundStmt 230 // which wraps everything that needs to happen. As such, it's technically 231 // possible to use a Statement ** in the above calls, but this is inherently 232 // unsafe, so instead we take the slightly less efficient route, but will be 233 // immediately informed if somehow the above assumption is broken. In this case, 234 // we could always wrap the list of statements at this point with a CompoundStmt, 235 // but it seems reasonable at the moment for this to be done by genImplicitCall 236 // itself. It is possible that genImplicitCall produces no statements (e.g. if 237 // an array type does not have a dimension). In this case, it's fine to ignore 238 // the object for the purposes of construction. 239 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 240 if ( ctor.size() == 1 ) { 261 241 // need to remember init expression, in case no ctors exist 262 242 // if ctor does exist, want to use ctor expression instead of init 263 243 // push this decision to the resolver 264 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor ); 265 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor ); 266 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) ); 244 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 245 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 267 246 } 268 247 } -
src/InitTweak/InitTweak.cc
r39f84a4 r4d2434a 1 #include <algorithm> 1 2 #include "InitTweak.h" 2 3 #include "SynTree/Visitor.h" … … 20 21 }; 21 22 22 class Init Expander_OLD: public Visitor {23 class InitFlattener : public Visitor { 23 24 public: 24 25 virtual void visit( SingleInit * singleInit ); … … 27 28 }; 28 29 29 void Init Expander_OLD::visit( SingleInit * singleInit ) {30 void InitFlattener::visit( SingleInit * singleInit ) { 30 31 argList.push_back( singleInit->get_value()->clone() ); 31 32 } 32 33 33 void Init Expander_OLD::visit( ListInit * listInit ) {34 // xxx - for now, assume nonested list inits35 std::list<Initializer*>::iterator it = listInit->begin _initializers();36 for ( ; it != listInit->end _initializers(); ++it ) {34 void InitFlattener::visit( ListInit * listInit ) { 35 // flatten nested list inits 36 std::list<Initializer*>::iterator it = listInit->begin(); 37 for ( ; it != listInit->end(); ++it ) { 37 38 (*it)->accept( *this ); 38 39 } … … 41 42 42 43 std::list< Expression * > makeInitList( Initializer * init ) { 43 Init Expander_OLD expander;44 maybeAccept( init, expander );45 return expander.argList;44 InitFlattener flattener; 45 maybeAccept( init, flattener ); 46 return flattener.argList; 46 47 } 47 48 … … 55 56 public: 56 57 virtual std::list< Expression * > next( std::list< Expression * > & indices ) = 0; 58 virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices ) = 0; 57 59 }; 58 60 59 61 class InitImpl : public InitExpander::ExpanderImpl { 60 62 public: 61 InitImpl( Initializer * init ) { 62 if ( init ) inits.push_back( init ); 63 } 63 InitImpl( Initializer * init ) : init( init ) {} 64 64 65 65 virtual std::list< Expression * > next( std::list< Expression * > & indices ) { 66 66 // this is wrong, but just a placeholder for now 67 return ! inits.empty() ? makeInitList( inits.front() ) : std::list< Expression * >(); 68 } 67 // if ( ! flattened ) flatten( indices ); 68 // return ! inits.empty() ? makeInitList( inits.front() ) : std::list< Expression * >(); 69 return makeInitList( init ); 70 } 71 72 virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices ); 69 73 private: 70 std::list< Initializer * > inits;74 Initializer * init; 71 75 }; 72 76 … … 91 95 return ret; 92 96 } 97 98 virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices ); 93 99 private: 94 100 Expression * arg; … … 114 120 } 115 121 116 template< typename OutIterator > 117 void build( UntypedExpr * callExpr, InitExpander::IndexList::iterator idx, InitExpander::IndexList::iterator end, OutIterator out ) { 118 if ( idx == end ) return; 119 Expression * index = *idx++; 120 assert( idx != end ); 121 Expression * dimension = *idx++; 122 123 // if ( idx == end ) { 124 // // loop through list of expressions belonging to the current initializer 125 // UntypedExpr * cond = new UntypedExpr( new NameExpr( "?<?") ); 126 // cond->get_args().push_back( index->clone() ); 127 // cond->get_args().push_back( dimension->clone() ); 128 129 // UntypedExpr * call = callExpr->clone(); 130 // std::list< Expression * > args = *++expander; // xxx - need a way to indentify the end of an init list 131 // call->get_args().splice( args ); 132 133 // *out++ = new IfStmt( noLabels, cond, new ExprStmt( call ), NULL ); 134 135 // UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); 136 // increment->get_args().push_back( index->clone() ); 137 // *out++ = new ExprStmt( increment ); 138 // } else { 139 // std::list< Statement * > branches; 140 // for (...) { // loop over conditions? 141 // std::list< Statement * > stmts; 142 // build( idx, end, back_inserter( stmts ) ); 143 // CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts ); 144 // branches.push_back( caseStmt ); 145 // } 146 // *out++ = new SwitchStmt( noLabels, index->clone(), branches ); 147 // } 148 } 149 150 // generate switch statement, consuming all of expander's elements 122 void InitExpander::clearArrayIndices() { 123 indices.clear(); 124 } 125 126 namespace { 127 template< typename OutIterator > 128 void dothething( UntypedExpr * callExpr, Expression * index, Expression * dimension, Initializer * init, OutIterator out ) { 129 UntypedExpr * cond = new UntypedExpr( new NameExpr( "?<?") ); 130 cond->get_args().push_back( index->clone() ); 131 cond->get_args().push_back( dimension->clone() ); 132 133 std::list< Expression * > args = makeInitList( init ); 134 callExpr->get_args().splice( callExpr->get_args().end(), args ); 135 136 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL ); 137 138 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); 139 increment->get_args().push_back( new AddressExpr( index->clone() ) ); 140 *out++ = new ExprStmt( noLabels, increment ); 141 } 142 143 template< typename OutIterator > 144 void build( UntypedExpr * callExpr, InitExpander::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) { 145 if ( idx == idxEnd ) return; 146 Expression * index = *idx++; 147 assert( idx != idxEnd ); 148 Expression * dimension = *idx++; 149 150 if ( idx == idxEnd ) { 151 if ( ListInit * listInit = dynamic_cast< ListInit * >( init ) ) { 152 for ( Initializer * init : *listInit ) { 153 dothething( callExpr->clone(), index, dimension, init, out ); 154 } 155 } else { 156 dothething( callExpr->clone(), index, dimension, init, out ); 157 } 158 } else { 159 std::list< Statement * > branches; 160 161 unsigned long cond = 0; 162 ListInit * listInit = dynamic_cast< ListInit * >( init ); 163 if ( ! listInit ) { 164 // xxx - this shouldn't be an error, but need a way to 165 // terminate without creating output, so should catch this error 166 throw SemanticError( "unbalanced list initializers" ); 167 } 168 for ( Initializer * init : *listInit ) { 169 Expression * condition; 170 // check for designations 171 // if ( init-> ) { 172 condition = new ConstantExpr( Constant::from_ulong( cond ) ); 173 ++cond; 174 // } else { 175 // condition = // ... take designation 176 // cond = // ... take designation+1 177 // } 178 std::list< Statement * > stmts; 179 build( callExpr, idx, idxEnd, init, back_inserter( stmts ) ); 180 CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts ); 181 branches.push_back( caseStmt ); 182 } 183 *out++ = new SwitchStmt( noLabels, index->clone(), branches ); 184 } 185 } 186 } 187 188 // if array came with an initializer list: initialize each element 189 // may have more initializers than elements in the array - need to check at each index that 190 // we haven't exceeded size. 191 // may have fewer initializers than elements in the array - need to default construct 192 // remaining elements. 193 // To accomplish this, generate switch statement, consuming all of expander's elements 194 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 195 if ( ! init ) return NULL; 196 std::list< Statement * > results; 197 build( dst, indices.begin(), indices.end(), init, back_inserter( results ) ); 198 assert( results.size() <= 1 ); 199 if ( results.empty() ) { 200 return NULL; 201 } else { 202 init = NULL; // init was consumed in creating the list init 203 return results.front(); 204 } 205 return ! results.empty() ? results.front() : NULL; 206 } 207 208 Statement * ExprImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 209 return NULL; 210 } 211 151 212 Statement * InitExpander::buildListInit( UntypedExpr * dst ) { 152 std::list< Statement * > results; 153 build( dst, indices.begin(), indices.end(), back_inserter( results ) ); 154 assert( results.size() <= 1 ); 155 return ! results.empty() ? results.front() : NULL; 213 return expander->buildListInit( dst, indices ); 156 214 } 157 215 … … 164 222 } 165 223 224 class CallFinder : public Visitor { 225 public: 226 typedef Visitor Parent; 227 CallFinder( const std::list< std::string > & names ) : names( names ) {} 228 229 virtual void visit( ApplicationExpr * appExpr ) { 230 handleCallExpr( appExpr ); 231 } 232 233 virtual void visit( UntypedExpr * untypedExpr ) { 234 handleCallExpr( untypedExpr ); 235 } 236 237 std::list< Expression * > * matches; 238 private: 239 const std::list< std::string > names; 240 241 template< typename CallExpr > 242 void handleCallExpr( CallExpr * expr ) { 243 Parent::visit( expr ); 244 std::string fname = getFunctionName( expr ); 245 if ( std::find( names.begin(), names.end(), fname ) != names.end() ) { 246 matches->push_back( expr ); 247 } 248 } 249 }; 250 251 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) { 252 static CallFinder finder( std::list< std::string >{ "?{}", "^?{}" } ); 253 finder.matches = &matches; 254 maybeAccept( stmt, finder ); 255 } 256 166 257 Expression * getCtorDtorCall( Statement * stmt ) { 167 if ( stmt == NULL ) return NULL; 168 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) { 169 return exprStmt->get_expr(); 170 } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) { 171 // could also be a compound statement with a loop, in the case of an array 172 if( compoundStmt->get_kids().size() == 2 ) { 173 // loop variable and loop 174 ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() ); 175 assert( forStmt && forStmt->get_body() ); 176 return getCtorDtorCall( forStmt->get_body() ); 177 } else if ( compoundStmt->get_kids().size() == 1 ) { 178 // should be the call statement, but in any case there's only one option 179 return getCtorDtorCall( compoundStmt->get_kids().front() ); 180 } else { 181 assert( false && "too many statements in compoundStmt for getCtorDtorCall" ); 182 } 183 } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) { 184 return getCtorDtorCall( impCtorDtorStmt->get_callStmt() ); 185 } else { 186 // should never get here 187 assert( false && "encountered unknown call statement" ); 188 } 189 } 258 std::list< Expression * > matches; 259 collectCtorDtorCalls( stmt, matches ); 260 assert( matches.size() <= 1 ); 261 return matches.size() == 1 ? matches.front() : NULL; 262 } 263 190 264 namespace { 191 265 VariableExpr * getCalledFunction( ApplicationExpr * appExpr ) { 192 266 assert( appExpr ); 267 // xxx - it's possible this can be other things, e.g. MemberExpr, so this is insufficient 193 268 return dynamic_cast< VariableExpr * >( appExpr->get_function() ); 194 269 } … … 206 281 207 282 bool isInstrinsicSingleArgCallStmt( Statement * stmt ) { 208 Expression * callExpr = getCtorDtorCall( stmt ); 209 if ( ! callExpr ) return false; 210 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 211 assert( ! appExpr->get_function()->get_results().empty() ); 212 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() ); 213 assert( funcType ); 214 return funcType->get_parameters().size() == 1; 215 } 216 return false; 283 std::list< Expression * > callExprs; 284 collectCtorDtorCalls( stmt, callExprs ); 285 // if ( callExprs.empty() ) return false; // xxx - do I still need this check? 286 return std::all_of( callExprs.begin(), callExprs.end(), []( Expression * callExpr ){ 287 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 288 assert( ! appExpr->get_function()->get_results().empty() ); 289 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() ); 290 assert( funcType ); 291 return funcType->get_parameters().size() == 1; 292 } 293 return false; 294 }); 217 295 } 218 296 -
src/InitTweak/InitTweak.h
r39f84a4 r4d2434a 43 43 bool isInstrinsicSingleArgCallStmt( Statement * expr ); 44 44 45 /// get all Ctor/Dtor call expressions from a Statement 46 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ); 47 45 48 /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call 46 49 Expression * getCtorDtorCall( Statement * stmt ); … … 78 81 Statement * buildListInit( UntypedExpr * callExpr ); 79 82 void addArrayIndex( Expression * index, Expression * dimension ); 83 void clearArrayIndices(); 80 84 81 85 class ExpanderImpl; -
src/ResolvExpr/Resolver.cc
r39f84a4 r4d2434a 54 54 virtual void visit( BranchStmt *branchStmt ); 55 55 virtual void visit( ReturnStmt *returnStmt ); 56 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );57 56 58 57 virtual void visit( SingleInit *singleInit ); … … 436 435 437 436 void Resolver::visit( ListInit * listInit ) { 438 InitIterator iter = listInit->begin _initializers();439 InitIterator end = listInit->end _initializers();437 InitIterator iter = listInit->begin(); 438 InitIterator end = listInit->end(); 440 439 441 440 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { … … 539 538 ctorInit->set_ctor( NULL ); 540 539 } 541 if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ ctor() ) ) {540 if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) { 542 541 delete ctorInit->get_dtor(); 543 542 ctorInit->set_dtor( NULL ); 544 543 } 545 }546 547 void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {548 // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).549 // Do this through a cast expression to greatly simplify the code.550 Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );551 assert( callExpr );552 Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );553 554 // the first argument will always be &<expr>555 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );556 assert( addrExpr );557 558 // need to find the type of the first argument. In the case of an array,559 // need to remove one ArrayType layer from the type for each subscript expression.560 Expression * addressee = addrExpr->get_arg();561 int numLayers = 0;562 while ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( addressee ) ) {563 assert( InitTweak::getFunctionName( untypedExpr ) == "?[?]" );564 addressee = InitTweak::getCallArg( untypedExpr, 0 );565 numLayers++;566 }567 assert( addressee->get_results().size() == 1 );568 Type * type = addressee->get_results().front();569 for ( int i = 0; i < numLayers; i++ ) {570 type = InitTweak::getPointerBase( type );571 assert( type && "Expected pointer or array type. May have generated too many ?[?] calls." );572 }573 574 // cast to T* with qualifiers removed.575 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument576 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever577 // remove lvalue as a qualifier, this can change to578 // type->get_qualifiers() = Type::Qualifiers();579 assert( type );580 type = type->clone();581 type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);582 type = new PointerType( Type::Qualifiers(), type );583 constructee = new CastExpr( constructee, type );584 585 // finally, resolve the ctor/dtor586 impCtorDtorStmt->get_callStmt()->accept( *this );587 544 } 588 545 } // namespace ResolvExpr -
src/SymTab/Autogen.h
r39f84a4 r4d2434a 37 37 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 38 38 template< typename OutputIterator > 39 void genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward = true );39 void genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true ); 40 40 41 41 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 42 42 template< typename OutputIterator > 43 void genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out ) {43 void genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 44 44 // want to be able to generate assignment, ctor, and dtor generically, 45 45 // so fname is either ?=?, ?{}, or ^?{} … … 47 47 48 48 // do something special for unnamed members 49 fExpr->get_args().push_back( new AddressExpr( dstParam ) ); 49 dstParam = new AddressExpr( dstParam ); 50 if ( addCast ) { 51 // cast to T* with qualifiers removed, so that qualified objects can be constructed 52 // and destructed with the same functions as non-qualified objects. 53 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 54 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 55 // remove lvalue as a qualifier, this can change to 56 // type->get_qualifiers() = Type::Qualifiers(); 57 assert( type ); 58 Type * castType = type->clone(); 59 castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 60 castType->set_isLvalue( true ); // xxx - might not need this 61 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 62 } 63 fExpr->get_args().push_back( dstParam ); 50 64 51 65 Statement * listInit = srcParam.buildListInit( fExpr ); … … 56 70 std::list< Expression * > args = *++srcParam; 57 71 fExpr->get_args().splice( fExpr->get_args().end(), args ); 58 /* if ( srcParam ) { 59 // xxx - 60 // make srcParam more complicated 61 // if srcParam contains 62 fExpr->get_args().push_back( srcParam ); 63 } 64 */ 72 65 73 *out++ = new ExprStmt( noLabels, fExpr ); 74 75 srcParam.clearArrayIndices(); 66 76 } 67 77 … … 69 79 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 70 80 template< typename OutputIterator > 71 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool forward = true ) {81 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) { 72 82 static UniqueName indexName( "_index" ); 73 83 … … 124 134 // for stmt's body, eventually containing call 125 135 CompoundStmt * body = new CompoundStmt( noLabels ); 126 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), forward );136 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 127 137 128 138 // block containing for stmt and index variable … … 136 146 137 147 template< typename OutputIterator > 138 void genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward ) {148 void genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 139 149 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 140 genArrayCall( srcParam, dstParam, fname, out, at, forward );150 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 141 151 } else { 142 genScalarCall( srcParam, dstParam, fname, out );152 genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 143 153 } 144 154 } … … 155 165 if ( isUnnamedBitfield( obj ) ) return; 156 166 167 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ); 157 168 std::list< Statement * > stmts; 158 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), forward );169 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward ); 159 170 160 171 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call … … 162 173 if ( stmts.size() == 1 ) { 163 174 Statement * callStmt = stmts.front(); 164 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) )) {175 if ( addCast ) { 165 176 // implicitly generated ctor/dtor calls should be wrapped 166 177 // so that later passes are aware they were generated. -
src/SynTree/Initializer.h
r39f84a4 r4d2434a 93 93 std::list<Initializer*> &get_initializers() { return initializers; } 94 94 95 std::list<Initializer*>::iterator begin_initializers() { return initializers.begin(); } 96 std::list<Initializer*>::iterator end_initializers() { return initializers.end(); } 95 typedef std::list<Initializer*>::iterator iterator; 96 iterator begin() { return initializers.begin(); } 97 iterator end() { return initializers.end(); } 97 98 98 99 virtual ListInit *clone() const { return new ListInit( *this ); }
Note: See TracChangeset
for help on using the changeset viewer.