Changes in src/ResolvExpr/CurrentObject.cc [c6b4432:2908f08]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CurrentObject.cc
rc6b4432 r2908f08 41 41 42 42 namespace ast { 43 /// Iterates members of a type by initializer. 44 class MemberIterator { 45 public: 46 virtual ~MemberIterator() {} 47 48 /// Internal set position based on iterator ranges. 49 virtual void setPosition( 50 std::deque< ptr< Expr > >::const_iterator it, 51 std::deque< ptr< Expr > >::const_iterator end ) = 0; 52 53 /// Walks the current object using the given designators as a guide. 54 void setPosition( const std::deque< ptr< Expr > > & designators ) { 55 setPosition( designators.begin(), designators.end() ); 56 } 57 58 /// Retrieve the list of possible (Type,Designation) pairs for the 59 /// current position in the current object. 60 virtual std::deque< InitAlternative > operator* () const = 0; 61 62 /// True if the iterator is not currently at the end. 63 virtual operator bool() const = 0; 64 65 /// Moves the iterator by one member in the current object. 66 virtual MemberIterator & bigStep() = 0; 67 68 /// Moves the iterator by one member in the current subobject. 69 virtual MemberIterator & smallStep() = 0; 70 71 /// The type of the current object. 72 virtual const Type * getType() = 0; 73 74 /// The type of the current subobject. 75 virtual const Type * getNext() = 0; 76 77 /// Helper for operator*; aggregates must add designator to each init 78 /// alternative, but adding designators in operator* creates duplicates. 79 virtual std::deque< InitAlternative > first() const = 0; 80 }; 81 82 /// create a new MemberIterator that traverses a type correctly 83 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); 84 85 /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry 86 class SimpleIterator final : public MemberIterator { 87 CodeLocation location; 88 const Type * type = nullptr; 89 public: 90 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} 91 92 void setPosition( 93 std::deque< ptr< Expr > >::const_iterator begin, 94 std::deque< ptr< Expr > >::const_iterator end 95 ) override { 96 if ( begin != end ) { 97 SemanticError( location, "Un-designated initializer given non-empty designator" ); 98 } 99 } 100 101 std::deque< InitAlternative > operator* () const override { return first(); } 102 103 operator bool() const override { return type; } 104 105 SimpleIterator & bigStep() override { return smallStep(); } 106 SimpleIterator & smallStep() override { 107 type = nullptr; // empty on increment because no members 108 return *this; 109 } 110 111 const Type * getType() override { return type; } 112 113 const Type * getNext() override { return type; } 114 115 std::deque< InitAlternative > first() const override { 116 if ( type ) return { InitAlternative{ type, new Designation{ location } } }; 117 return {}; 118 } 119 }; 120 121 /// Iterates over an indexed type: 122 class IndexIterator : public MemberIterator { 123 protected: 124 CodeLocation location; 125 size_t index = 0; 126 size_t size = 0; 127 std::unique_ptr<MemberIterator> memberIter; 128 public: 129 IndexIterator( const CodeLocation & loc, size_t size ) : 130 location( loc ), size( size ) 131 {} 132 133 void setPosition( const Expr * expr ) { 134 // need to permit integer-constant-expressions, including: integer constants, 135 // enumeration constants, character constants, sizeof expressions, alignof expressions, 136 // cast expressions 137 138 auto arg = eval( expr ); 139 assertf( arg.hasKnownValue, "Non-evaluable expression made it to IndexIterator" ); 140 index = arg.knownValue; 141 142 // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { 143 // try { 144 // index = constExpr->intValue(); 145 // } catch ( SemanticErrorException & ) { 146 // SemanticError( expr, "Constant expression of non-integral type in array designator: " ); 147 // } 148 // } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) { 149 // setPosition( castExpr->arg ); 150 // } else if ( dynamic_cast< const SizeofExpr * >( expr ) || dynamic_cast< const AlignofExpr * >( expr ) ) { 151 // index = 0; 152 // } else { 153 // assertf( false, "2 bad designator given to ArrayIterator: %s", toString( expr ).c_str() ); 154 // } 155 } 156 157 void setPosition( 158 std::deque<ast::ptr<ast::Expr>>::const_iterator begin, 159 std::deque<ast::ptr<ast::Expr>>::const_iterator end 160 ) override { 161 if ( begin == end ) return; 162 163 setPosition( *begin ); 164 memberIter->setPosition( ++begin, end ); 165 } 166 167 std::deque< InitAlternative > operator* () const override { return first(); } 168 169 operator bool() const override { return index < size; } 170 }; 171 172 /// Iterates over the members of array types: 173 class ArrayIterator final : public IndexIterator { 174 const ArrayType * array = nullptr; 175 const Type * base = nullptr; 176 177 size_t getSize( const Expr * expr ) { 178 auto res = eval( expr ); 179 if ( !res.hasKnownValue ) { 180 SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) ); 181 } 182 return res.knownValue; 183 } 184 185 public: 186 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) : 187 IndexIterator( loc, getSize( at->dimension) ), 188 array( at ), base( at->base ) { 189 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 190 memberIter.reset( createMemberIterator( loc, base ) ); 191 if ( at->isVarLen ) { 192 SemanticError( location, at, "VLA initialization does not support @=: " ); 193 } 194 } 195 196 ArrayIterator & bigStep() override { 197 PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 198 ++index; 199 memberIter.reset( index < size ? createMemberIterator( location, base ) : nullptr ); 200 return *this; 201 } 202 203 ArrayIterator & smallStep() override { 204 PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 205 if ( memberIter ) { 206 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; ) 207 memberIter->smallStep(); 208 if ( *memberIter ) { 209 PRINT( std::cerr << "has valid member iter" << std::endl; ) 210 return *this; 211 } 212 } 213 return bigStep(); 214 } 215 216 const Type * getType() override { return array; } 217 218 const Type * getNext() override { return base; } 219 220 std::deque< InitAlternative > first() const override { 221 PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 222 if ( memberIter && *memberIter ) { 223 std::deque< InitAlternative > ret = memberIter->first(); 224 for ( InitAlternative & alt : ret ) { 225 alt.designation.get_and_mutate()->designators.emplace_front( ConstantExpr::from_ulong( location, index ) ); 226 } 227 return ret; 228 } 229 return {}; 230 } 231 }; 232 233 class AggregateIterator : public MemberIterator { 234 protected: 235 using MemberList = std::vector< ptr< Decl > >; 236 237 CodeLocation location; 238 std::string kind; // for debug 239 std::string name; 240 const Type * inst; 241 const MemberList & members; 242 MemberList::const_iterator curMember; 243 bool atbegin = true; // false at first {small,big}Step 244 const Type * curType = nullptr; 245 std::unique_ptr< MemberIterator > memberIter = nullptr; 246 TypeSubstitution sub; 247 248 bool init() { 249 PRINT( std::cerr << "--init()--" << members.size() << std::endl; ) 250 if ( curMember != members.end() ) { 251 if ( auto field = curMember->as< ObjectDecl >() ) { 252 PRINT( std::cerr << "incremented to field: " << field << std::endl; ) 253 curType = field->get_type(); 254 memberIter.reset( createMemberIterator( location, curType ) ); 255 return true; 256 } 257 } 258 return false; 259 } 260 261 AggregateIterator( 262 const CodeLocation & loc, const std::string k, const std::string & n, const Type * i, 263 const MemberList & ms ) 264 : location( loc ), kind( k ), name( n ), inst( i ), members( ms ), curMember( ms.begin() ), 265 sub( genericSubstitution( i ) ) { 266 PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; ) 267 init(); 268 } 269 270 public: 271 void setPosition( 272 std::deque< ptr< Expr > >::const_iterator begin, 273 std::deque< ptr< Expr > >::const_iterator end 274 ) final { 275 if ( begin == end ) return; 276 277 if ( auto varExpr = begin->as< VariableExpr >() ) { 278 for ( curMember = members.begin(); curMember != members.end(); ++curMember ) { 279 if ( *curMember != varExpr->var ) continue; 280 281 ++begin; 282 283 memberIter.reset( createMemberIterator( location, varExpr->result ) ); 284 curType = varExpr->result; 285 atbegin = curMember == members.begin() && begin == end; 286 memberIter->setPosition( begin, end ); 287 return; 288 } 289 assertf( false, "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() ); 290 } else { 291 assertf( false, "1 bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() ); 292 } 293 } 294 295 std::deque< InitAlternative > operator* () const final { 296 if ( memberIter && *memberIter ) { 297 std::deque< InitAlternative > ret = memberIter->first(); 298 PRINT( std::cerr << "sub: " << sub << std::endl; ) 299 for ( InitAlternative & alt : ret ) { 300 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 301 alt.designation.get_and_mutate()->designators.emplace_front( 302 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 303 // need to substitute for generic types so that casts are to concrete types 304 alt.type = shallowCopy(alt.type.get()); 305 PRINT( std::cerr << " type is: " << alt.type; ) 306 sub.apply( alt.type ); // also apply to designation?? 307 PRINT( std::cerr << " ==> " << alt.type << std::endl; ) 308 } 309 return ret; 310 } 311 return {}; 312 } 313 314 AggregateIterator & smallStep() final { 315 PRINT( std::cerr << "smallStep in " << kind << std::endl; ) 316 atbegin = false; 317 if ( memberIter ) { 318 PRINT( std::cerr << "has member iter, incrementing..." << std::endl; ) 319 memberIter->smallStep(); 320 if ( *memberIter ) { 321 PRINT( std::cerr << "success!" << std::endl; ) 322 return *this; 323 } 324 } 325 return bigStep(); 326 } 327 328 AggregateIterator & bigStep() override = 0; 329 330 const Type * getType() final { return inst; } 331 332 const Type * getNext() final { 333 bool hasMember = memberIter && *memberIter; 334 return hasMember ? memberIter->getType() : nullptr; 335 } 336 337 std::deque< InitAlternative > first() const final { 338 std::deque< InitAlternative > ret; 339 PRINT( std::cerr << "first " << kind << std::endl; ) 340 if ( memberIter && *memberIter ) { 341 PRINT( std::cerr << "adding children" << std::endl; ) 342 ret = memberIter->first(); 343 for ( InitAlternative & alt : ret ) { 344 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 345 alt.designation.get_and_mutate()->designators.emplace_front( 346 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 347 } 348 } 349 if ( atbegin ) { 350 // only add self if at the very beginning of the structure 351 PRINT( std::cerr << "adding self" << std::endl; ) 352 ret.emplace_front( inst, new Designation{ location } ); 43 44 /// Iterates members of a type by initializer. 45 class MemberIterator { 46 public: 47 virtual ~MemberIterator() {} 48 49 /// Internal set position based on iterator ranges. 50 virtual void setPosition( 51 std::deque< ptr< Expr > >::const_iterator it, 52 std::deque< ptr< Expr > >::const_iterator end ) = 0; 53 54 /// Walks the current object using the given designators as a guide. 55 void setPosition( const std::deque< ptr< Expr > > & designators ) { 56 setPosition( designators.begin(), designators.end() ); 57 } 58 59 /// Retrieve the list of possible (Type,Designation) pairs for the 60 /// current position in the current object. 61 virtual std::deque< InitAlternative > operator* () const = 0; 62 63 /// True if the iterator is not currently at the end. 64 virtual operator bool() const = 0; 65 66 /// Moves the iterator by one member in the current object. 67 virtual MemberIterator & bigStep() = 0; 68 69 /// Moves the iterator by one member in the current subobject. 70 virtual MemberIterator & smallStep() = 0; 71 72 /// The type of the current object. 73 virtual const Type * getType() = 0; 74 75 /// The type of the current subobject. 76 virtual const Type * getNext() = 0; 77 78 /// Helper for operator*; aggregates must add designator to each init 79 /// alternative, but adding designators in operator* creates duplicates. 80 virtual std::deque< InitAlternative > first() const = 0; 81 }; 82 83 namespace { 84 85 /// create a new MemberIterator that traverses a type correctly 86 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); 87 88 /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry 89 class SimpleIterator final : public MemberIterator { 90 CodeLocation location; 91 const Type * type = nullptr; 92 public: 93 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} 94 95 void setPosition( 96 std::deque< ptr< Expr > >::const_iterator begin, 97 std::deque< ptr< Expr > >::const_iterator end 98 ) override { 99 if ( begin != end ) { 100 SemanticError( location, "Un-designated initializer given non-empty designator" ); 101 } 102 } 103 104 std::deque< InitAlternative > operator* () const override { return first(); } 105 106 operator bool() const override { return type; } 107 108 SimpleIterator & bigStep() override { return smallStep(); } 109 SimpleIterator & smallStep() override { 110 type = nullptr; // empty on increment because no members 111 return *this; 112 } 113 114 const Type * getType() override { return type; } 115 116 const Type * getNext() override { return type; } 117 118 std::deque< InitAlternative > first() const override { 119 if ( type ) return { InitAlternative{ type, new Designation{ location } } }; 120 return {}; 121 } 122 }; 123 124 /// Iterates over an indexed type: 125 class IndexIterator : public MemberIterator { 126 protected: 127 CodeLocation location; 128 size_t index = 0; 129 size_t size = 0; 130 std::unique_ptr<MemberIterator> memberIter; 131 public: 132 IndexIterator( const CodeLocation & loc, size_t size ) : 133 location( loc ), size( size ) 134 {} 135 136 void setPosition( const Expr * expr ) { 137 // need to permit integer-constant-expressions, including: integer constants, 138 // enumeration constants, character constants, sizeof expressions, alignof expressions, 139 // cast expressions 140 141 auto arg = eval( expr ); 142 assertf( arg.hasKnownValue, "Non-evaluable expression made it to IndexIterator" ); 143 index = arg.knownValue; 144 145 // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { 146 // try { 147 // index = constExpr->intValue(); 148 // } catch ( SemanticErrorException & ) { 149 // SemanticError( expr, "Constant expression of non-integral type in array designator: " ); 150 // } 151 // } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) { 152 // setPosition( castExpr->arg ); 153 // } else if ( dynamic_cast< const SizeofExpr * >( expr ) || dynamic_cast< const AlignofExpr * >( expr ) ) { 154 // index = 0; 155 // } else { 156 // assertf( false, "2 bad designator given to ArrayIterator: %s", toString( expr ).c_str() ); 157 // } 158 } 159 160 void setPosition( 161 std::deque<ast::ptr<ast::Expr>>::const_iterator begin, 162 std::deque<ast::ptr<ast::Expr>>::const_iterator end 163 ) override { 164 if ( begin == end ) return; 165 166 setPosition( *begin ); 167 memberIter->setPosition( ++begin, end ); 168 } 169 170 std::deque< InitAlternative > operator* () const override { return first(); } 171 172 operator bool() const override { return index < size; } 173 }; 174 175 /// Iterates over the members of array types: 176 class ArrayIterator final : public IndexIterator { 177 const ArrayType * array = nullptr; 178 const Type * base = nullptr; 179 180 size_t getSize( const Expr * expr ) { 181 auto res = eval( expr ); 182 if ( !res.hasKnownValue ) { 183 SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) ); 184 } 185 return res.knownValue; 186 } 187 188 public: 189 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) : 190 IndexIterator( loc, getSize( at->dimension) ), 191 array( at ), base( at->base ) { 192 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 193 memberIter.reset( createMemberIterator( loc, base ) ); 194 if ( at->isVarLen ) { 195 SemanticError( location, at, "VLA initialization does not support @=: " ); 196 } 197 } 198 199 ArrayIterator & bigStep() override { 200 PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 201 ++index; 202 memberIter.reset( index < size ? createMemberIterator( location, base ) : nullptr ); 203 return *this; 204 } 205 206 ArrayIterator & smallStep() override { 207 PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 208 if ( memberIter ) { 209 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; ) 210 memberIter->smallStep(); 211 if ( *memberIter ) { 212 PRINT( std::cerr << "has valid member iter" << std::endl; ) 213 return *this; 214 } 215 } 216 return bigStep(); 217 } 218 219 const Type * getType() override { return array; } 220 221 const Type * getNext() override { return base; } 222 223 std::deque< InitAlternative > first() const override { 224 PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 225 if ( memberIter && *memberIter ) { 226 std::deque< InitAlternative > ret = memberIter->first(); 227 for ( InitAlternative & alt : ret ) { 228 alt.designation.get_and_mutate()->designators.emplace_front( ConstantExpr::from_ulong( location, index ) ); 353 229 } 354 230 return ret; 355 231 } 356 }; 357 358 class StructIterator final : public AggregateIterator { 359 public: 360 StructIterator( const CodeLocation & loc, const StructInstType * inst ) 361 : AggregateIterator( loc, "StructIterator", inst->name, inst, inst->base->members ) {} 362 363 operator bool() const override { 364 return curMember != members.end() || (memberIter && *memberIter); 365 } 366 367 StructIterator & bigStep() override { 368 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 369 atbegin = false; 370 memberIter = nullptr; 371 curType = nullptr; 372 while ( curMember != members.end() ) { 373 ++curMember; 374 if ( init() ) return *this; 375 } 376 return *this; 377 } 378 }; 379 380 class UnionIterator final : public AggregateIterator { 381 public: 382 UnionIterator( const CodeLocation & loc, const UnionInstType * inst ) 383 : AggregateIterator( loc, "UnionIterator", inst->name, inst, inst->base->members ) {} 384 385 operator bool() const override { return memberIter && *memberIter; } 386 387 UnionIterator & bigStep() override { 388 // unions only initialize one member 389 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 390 atbegin = false; 391 memberIter = nullptr; 392 curType = nullptr; 393 curMember = members.end(); 394 return *this; 395 } 396 }; 397 398 /// Iterates across the positions in a tuple: 399 class TupleIterator final : public IndexIterator { 400 ast::TupleType const * const tuple; 401 402 const ast::Type * typeAtIndex() const { 403 assert( index < size ); 404 return tuple->types[ index ].get(); 405 } 406 407 public: 408 TupleIterator( const CodeLocation & loc, const TupleType * type ) 409 : IndexIterator( loc, type->size() ), tuple( type ) { 410 PRINT( std::cerr << "Creating tuple iterator: " << type << std::endl; ) 411 memberIter.reset( createMemberIterator( loc, typeAtIndex() ) ); 412 } 413 414 TupleIterator & bigStep() override { 415 ++index; 416 memberIter.reset( index < size ? 417 createMemberIterator( location, typeAtIndex() ) : nullptr ); 418 return *this; 419 } 420 421 TupleIterator & smallStep() override { 422 if ( memberIter ) { 423 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; ) 424 memberIter->smallStep(); 425 if ( !memberIter ) { 426 PRINT( std::cerr << "has valid member iter" << std::endl; ) 427 return *this; 428 } 429 } 430 return bigStep(); 431 } 432 433 const ast::Type * getType() override { 434 return tuple; 435 } 436 437 const ast::Type * getNext() override { 438 bool hasMember = memberIter && *memberIter; 439 return hasMember ? memberIter->getType() : nullptr; 440 } 441 442 std::deque< InitAlternative > first() const override { 443 PRINT( std::cerr << "first in TupleIterator (" << index << "/" << size << ")" << std::endl; ) 444 if ( memberIter && *memberIter ) { 445 std::deque< InitAlternative > ret = memberIter->first(); 446 for ( InitAlternative & alt : ret ) { 447 alt.designation.get_and_mutate()->designators.emplace_front( 448 ConstantExpr::from_ulong( location, index ) ); 449 } 450 return ret; 451 } 452 return {}; 453 } 454 }; 455 456 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) { 457 if ( auto aggr = dynamic_cast< const BaseInstType * >( type ) ) { 458 if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) { 459 assert( sit->base ); 460 return new StructIterator{ loc, sit }; 461 } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) { 462 assert( uit->base ); 463 return new UnionIterator{ loc, uit }; 464 } else { 465 assertf( 466 dynamic_cast< const EnumInstType * >( type ) 467 || dynamic_cast< const TypeInstType * >( type ), 468 "Encountered unhandled BaseInstType in createMemberIterator: %s", 469 toString( type ).c_str() ); 470 return new SimpleIterator{ loc, type }; 471 } 472 } else if ( auto at = dynamic_cast< const ArrayType * >( type ) ) { 473 return new ArrayIterator{ loc, at }; 474 } else if ( auto tt = dynamic_cast< const TupleType * >( type ) ) { 475 return new TupleIterator{ loc, tt }; 232 return {}; 233 } 234 }; 235 236 class AggregateIterator : public MemberIterator { 237 protected: 238 using MemberList = std::vector< ptr< Decl > >; 239 240 CodeLocation location; 241 std::string kind; // for debug 242 std::string name; 243 const Type * inst; 244 const MemberList & members; 245 MemberList::const_iterator curMember; 246 bool atbegin = true; // false at first {small,big}Step 247 const Type * curType = nullptr; 248 std::unique_ptr< MemberIterator > memberIter = nullptr; 249 TypeSubstitution sub; 250 251 bool init() { 252 PRINT( std::cerr << "--init()--" << members.size() << std::endl; ) 253 if ( curMember != members.end() ) { 254 if ( auto field = curMember->as< ObjectDecl >() ) { 255 PRINT( std::cerr << "incremented to field: " << field << std::endl; ) 256 curType = field->get_type(); 257 memberIter.reset( createMemberIterator( location, curType ) ); 258 return true; 259 } 260 } 261 return false; 262 } 263 264 AggregateIterator( 265 const CodeLocation & loc, const std::string k, const std::string & n, const Type * i, 266 const MemberList & ms ) 267 : location( loc ), kind( k ), name( n ), inst( i ), members( ms ), curMember( ms.begin() ), 268 sub( genericSubstitution( i ) ) { 269 PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; ) 270 init(); 271 } 272 273 public: 274 void setPosition( 275 std::deque< ptr< Expr > >::const_iterator begin, 276 std::deque< ptr< Expr > >::const_iterator end 277 ) final { 278 if ( begin == end ) return; 279 280 if ( auto varExpr = begin->as< VariableExpr >() ) { 281 for ( curMember = members.begin(); curMember != members.end(); ++curMember ) { 282 if ( *curMember != varExpr->var ) continue; 283 284 ++begin; 285 286 memberIter.reset( createMemberIterator( location, varExpr->result ) ); 287 curType = varExpr->result; 288 atbegin = curMember == members.begin() && begin == end; 289 memberIter->setPosition( begin, end ); 290 return; 291 } 292 assertf( false, "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() ); 476 293 } else { 294 assertf( false, "1 bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() ); 295 } 296 } 297 298 std::deque< InitAlternative > operator* () const final { 299 if ( memberIter && *memberIter ) { 300 std::deque< InitAlternative > ret = memberIter->first(); 301 PRINT( std::cerr << "sub: " << sub << std::endl; ) 302 for ( InitAlternative & alt : ret ) { 303 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 304 alt.designation.get_and_mutate()->designators.emplace_front( 305 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 306 // need to substitute for generic types so that casts are to concrete types 307 alt.type = shallowCopy(alt.type.get()); 308 PRINT( std::cerr << " type is: " << alt.type; ) 309 sub.apply( alt.type ); // also apply to designation?? 310 PRINT( std::cerr << " ==> " << alt.type << std::endl; ) 311 } 312 return ret; 313 } 314 return {}; 315 } 316 317 AggregateIterator & smallStep() final { 318 PRINT( std::cerr << "smallStep in " << kind << std::endl; ) 319 atbegin = false; 320 if ( memberIter ) { 321 PRINT( std::cerr << "has member iter, incrementing..." << std::endl; ) 322 memberIter->smallStep(); 323 if ( *memberIter ) { 324 PRINT( std::cerr << "success!" << std::endl; ) 325 return *this; 326 } 327 } 328 return bigStep(); 329 } 330 331 AggregateIterator & bigStep() override = 0; 332 333 const Type * getType() final { return inst; } 334 335 const Type * getNext() final { 336 bool hasMember = memberIter && *memberIter; 337 return hasMember ? memberIter->getType() : nullptr; 338 } 339 340 std::deque< InitAlternative > first() const final { 341 std::deque< InitAlternative > ret; 342 PRINT( std::cerr << "first " << kind << std::endl; ) 343 if ( memberIter && *memberIter ) { 344 PRINT( std::cerr << "adding children" << std::endl; ) 345 ret = memberIter->first(); 346 for ( InitAlternative & alt : ret ) { 347 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 348 alt.designation.get_and_mutate()->designators.emplace_front( 349 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 350 } 351 } 352 if ( atbegin ) { 353 // only add self if at the very beginning of the structure 354 PRINT( std::cerr << "adding self" << std::endl; ) 355 ret.emplace_front( inst, new Designation{ location } ); 356 } 357 return ret; 358 } 359 }; 360 361 class StructIterator final : public AggregateIterator { 362 public: 363 StructIterator( const CodeLocation & loc, const StructInstType * inst ) 364 : AggregateIterator( loc, "StructIterator", inst->name, inst, inst->base->members ) {} 365 366 operator bool() const override { 367 return curMember != members.end() || (memberIter && *memberIter); 368 } 369 370 StructIterator & bigStep() override { 371 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 372 atbegin = false; 373 memberIter = nullptr; 374 curType = nullptr; 375 while ( curMember != members.end() ) { 376 ++curMember; 377 if ( init() ) return *this; 378 } 379 return *this; 380 } 381 }; 382 383 class UnionIterator final : public AggregateIterator { 384 public: 385 UnionIterator( const CodeLocation & loc, const UnionInstType * inst ) 386 : AggregateIterator( loc, "UnionIterator", inst->name, inst, inst->base->members ) {} 387 388 operator bool() const override { return memberIter && *memberIter; } 389 390 UnionIterator & bigStep() override { 391 // unions only initialize one member 392 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 393 atbegin = false; 394 memberIter = nullptr; 395 curType = nullptr; 396 curMember = members.end(); 397 return *this; 398 } 399 }; 400 401 /// Iterates across the positions in a tuple: 402 class TupleIterator final : public IndexIterator { 403 ast::TupleType const * const tuple; 404 405 const ast::Type * typeAtIndex() const { 406 assert( index < size ); 407 return tuple->types[ index ].get(); 408 } 409 410 public: 411 TupleIterator( const CodeLocation & loc, const TupleType * type ) 412 : IndexIterator( loc, type->size() ), tuple( type ) { 413 PRINT( std::cerr << "Creating tuple iterator: " << type << std::endl; ) 414 memberIter.reset( createMemberIterator( loc, typeAtIndex() ) ); 415 } 416 417 TupleIterator & bigStep() override { 418 ++index; 419 memberIter.reset( index < size ? 420 createMemberIterator( location, typeAtIndex() ) : nullptr ); 421 return *this; 422 } 423 424 TupleIterator & smallStep() override { 425 if ( memberIter ) { 426 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; ) 427 memberIter->smallStep(); 428 if ( !memberIter ) { 429 PRINT( std::cerr << "has valid member iter" << std::endl; ) 430 return *this; 431 } 432 } 433 return bigStep(); 434 } 435 436 const ast::Type * getType() override { 437 return tuple; 438 } 439 440 const ast::Type * getNext() override { 441 bool hasMember = memberIter && *memberIter; 442 return hasMember ? memberIter->getType() : nullptr; 443 } 444 445 std::deque< InitAlternative > first() const override { 446 PRINT( std::cerr << "first in TupleIterator (" << index << "/" << size << ")" << std::endl; ) 447 if ( memberIter && *memberIter ) { 448 std::deque< InitAlternative > ret = memberIter->first(); 449 for ( InitAlternative & alt : ret ) { 450 alt.designation.get_and_mutate()->designators.emplace_front( 451 ConstantExpr::from_ulong( location, index ) ); 452 } 453 return ret; 454 } 455 return {}; 456 } 457 }; 458 459 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) { 460 if ( auto aggr = dynamic_cast< const BaseInstType * >( type ) ) { 461 if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) { 462 assert( sit->base ); 463 return new StructIterator{ loc, sit }; 464 } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) { 465 assert( uit->base ); 466 return new UnionIterator{ loc, uit }; 467 } else { 468 assertf( 469 dynamic_cast< const EnumInstType * >( type ) 470 || dynamic_cast< const TypeInstType * >( type ), 471 "Encountered unhandled BaseInstType in createMemberIterator: %s", 472 toString( type ).c_str() ); 477 473 return new SimpleIterator{ loc, type }; 478 474 } 479 } 480 481 CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() { 482 objStack.emplace_back( new SimpleIterator{ loc, type } ); 483 } 484 485 const Designation * CurrentObject::findNext( const Designation * designation ) { 486 using DesignatorChain = std::deque< ptr< Expr > >; 487 PRINT( std::cerr << "___findNext" << std::endl; ) 488 489 // find all the d's 490 std::vector< DesignatorChain > desigAlts{ {} }, newDesigAlts; 491 std::deque< const Type * > curTypes{ objStack.back()->getType() }, newTypes; 492 for ( const Expr * expr : designation->designators ) { 493 PRINT( std::cerr << "____untyped: " << expr << std::endl; ) 494 auto dit = desigAlts.begin(); 495 496 for ( const Type * t : curTypes ) { 497 assert( dit != desigAlts.end() ); 498 DesignatorChain & d = *dit; 499 if ( auto nexpr = dynamic_cast< const NameExpr *>( expr ) ) { 500 PRINT( std::cerr << "____actual: " << t << std::endl; ) 501 if ( auto refType = dynamic_cast< const BaseInstType * >( t ) ) { 502 // concatenate identical field names 503 for ( const Decl * mem : refType->lookup( nexpr->name ) ) { 504 if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) { 505 PRINT( std::cerr << "____alt: " << field->type << std::endl; ) 506 DesignatorChain d2 = d; 507 d2.emplace_back( new VariableExpr{ expr->location, field } ); 508 newDesigAlts.emplace_back( std::move( d2 ) ); 509 newTypes.emplace_back( field->type ); 510 } 511 } 512 } else if ( auto at = dynamic_cast< const ArrayType * >( t ) ) { 513 auto nexpr = dynamic_cast< const NameExpr *>( expr ); 514 for ( const Decl * mem : refType->lookup( nexpr->name ) ) { 515 if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) { 516 DesignatorChain d2 = d; 517 d2.emplace_back( new VariableExpr{ expr->location, field } ); 518 newDesigAlts.emplace_back( std::move( d2 ) ); 519 newTypes.emplace_back( at->base ); 520 } 475 } else if ( auto at = dynamic_cast< const ArrayType * >( type ) ) { 476 return new ArrayIterator{ loc, at }; 477 } else if ( auto tt = dynamic_cast< const TupleType * >( type ) ) { 478 return new TupleIterator{ loc, tt }; 479 } else { 480 return new SimpleIterator{ loc, type }; 481 } 482 } 483 484 } // namespace 485 486 CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() { 487 objStack.emplace_back( new SimpleIterator{ loc, type } ); 488 } 489 490 const Designation * CurrentObject::findNext( const Designation * designation ) { 491 using DesignatorChain = std::deque< ptr< Expr > >; 492 PRINT( std::cerr << "___findNext" << std::endl; ) 493 494 // find all the d's 495 std::vector< DesignatorChain > desigAlts{ {} }, newDesigAlts; 496 std::deque< const Type * > curTypes{ objStack.back()->getType() }, newTypes; 497 for ( const Expr * expr : designation->designators ) { 498 PRINT( std::cerr << "____untyped: " << expr << std::endl; ) 499 auto dit = desigAlts.begin(); 500 501 for ( const Type * t : curTypes ) { 502 assert( dit != desigAlts.end() ); 503 DesignatorChain & d = *dit; 504 if ( auto nexpr = dynamic_cast< const NameExpr *>( expr ) ) { 505 PRINT( std::cerr << "____actual: " << t << std::endl; ) 506 if ( auto refType = dynamic_cast< const BaseInstType * >( t ) ) { 507 // concatenate identical field names 508 for ( const Decl * mem : refType->lookup( nexpr->name ) ) { 509 if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) { 510 PRINT( std::cerr << "____alt: " << field->type << std::endl; ) 511 DesignatorChain d2 = d; 512 d2.emplace_back( new VariableExpr{ expr->location, field } ); 513 newDesigAlts.emplace_back( std::move( d2 ) ); 514 newTypes.emplace_back( field->type ); 521 515 } 522 516 } 523 524 ++dit; 525 } else { 526 if ( auto at = dynamic_cast< const ArrayType * >( t ) ) { 527 PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; ) 528 d.emplace_back( expr ); 529 newDesigAlts.emplace_back( d ); 530 newTypes.emplace_back( at->base ); 517 } else if ( auto at = dynamic_cast< const ArrayType * >( t ) ) { 518 auto nexpr = dynamic_cast< const NameExpr *>( expr ); 519 for ( const Decl * mem : refType->lookup( nexpr->name ) ) { 520 if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) { 521 DesignatorChain d2 = d; 522 d2.emplace_back( new VariableExpr{ expr->location, field } ); 523 newDesigAlts.emplace_back( std::move( d2 ) ); 524 newTypes.emplace_back( at->base ); 525 } 531 526 } 532 527 } 533 } 534 535 // reset queue 536 desigAlts = std::move( newDesigAlts ); 537 newDesigAlts.clear(); 538 curTypes = std::move( newTypes ); 539 newTypes.clear(); 540 assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%zu) and current types (%zu) out of sync", desigAlts.size(), curTypes.size() ); 541 } 542 543 if ( desigAlts.size() > 1 ) { 544 SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") ); 545 } else if ( desigAlts.empty() ) { 546 SemanticError( designation, "No reasonable alternatives for designation: " ); 547 } 548 549 DesignatorChain & d = desigAlts.back(); 550 PRINT( for ( Expression * expr : d ) { 551 std::cerr << "____desig: " << expr << std::endl; 552 } ) // for 553 assertf( ! curTypes.empty(), "empty designator chosen"); 554 555 // set new designators 556 assertf( ! objStack.empty(), "empty object stack when setting designation" ); 557 Designation * actualDesignation = 558 new Designation{ designation->location, DesignatorChain{d} }; 559 objStack.back()->setPosition( d ); // destroys d 560 return actualDesignation; 561 } 562 563 void CurrentObject::setNext( const Designation * designation ) { 564 PRINT( std::cerr << "____setNext" << designation << std::endl; ) 565 assertf( ! objStack.empty(), "obj stack empty in setNext" ); 566 objStack.back()->setPosition( designation->designators ); 567 } 568 569 void CurrentObject::increment() { 570 PRINT( std::cerr << "____increment" << std::endl; ) 571 if ( objStack.empty() ) return; 528 529 ++dit; 530 } else { 531 if ( auto at = dynamic_cast< const ArrayType * >( t ) ) { 532 PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; ) 533 d.emplace_back( expr ); 534 newDesigAlts.emplace_back( d ); 535 newTypes.emplace_back( at->base ); 536 } 537 } 538 } 539 540 // reset queue 541 desigAlts = std::move( newDesigAlts ); 542 newDesigAlts.clear(); 543 curTypes = std::move( newTypes ); 544 newTypes.clear(); 545 assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%zu) and current types (%zu) out of sync", desigAlts.size(), curTypes.size() ); 546 } 547 548 if ( desigAlts.size() > 1 ) { 549 SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") ); 550 } else if ( desigAlts.empty() ) { 551 SemanticError( designation, "No reasonable alternatives for designation: " ); 552 } 553 554 DesignatorChain & d = desigAlts.back(); 555 PRINT( for ( Expression * expr : d ) { 556 std::cerr << "____desig: " << expr << std::endl; 557 } ) // for 558 assertf( ! curTypes.empty(), "empty designator chosen"); 559 560 // set new designators 561 assertf( ! objStack.empty(), "empty object stack when setting designation" ); 562 Designation * actualDesignation = 563 new Designation{ designation->location, DesignatorChain{d} }; 564 objStack.back()->setPosition( d ); // destroys d 565 return actualDesignation; 566 } 567 568 void CurrentObject::setNext( const Designation * designation ) { 569 PRINT( std::cerr << "____setNext" << designation << std::endl; ) 570 assertf( ! objStack.empty(), "obj stack empty in setNext" ); 571 objStack.back()->setPosition( designation->designators ); 572 } 573 574 void CurrentObject::increment() { 575 PRINT( std::cerr << "____increment" << std::endl; ) 576 if ( objStack.empty() ) return; 577 PRINT( std::cerr << *objStack.back() << std::endl; ) 578 objStack.back()->smallStep(); 579 } 580 581 void CurrentObject::enterListInit( const CodeLocation & loc ) { 582 PRINT( std::cerr << "____entering list init" << std::endl; ) 583 assertf( ! objStack.empty(), "empty obj stack entering list init" ); 584 const ast::Type * type = objStack.back()->getNext(); 585 assert( type ); 586 objStack.emplace_back( createMemberIterator( loc, type ) ); 587 } 588 589 void CurrentObject::exitListInit() { 590 PRINT( std::cerr << "____exiting list init" << std::endl; ) 591 assertf( ! objStack.empty(), "objstack empty" ); 592 objStack.pop_back(); 593 if ( ! objStack.empty() ) { 572 594 PRINT( std::cerr << *objStack.back() << std::endl; ) 573 objStack.back()->smallStep(); 574 } 575 576 void CurrentObject::enterListInit( const CodeLocation & loc ) { 577 PRINT( std::cerr << "____entering list init" << std::endl; ) 578 assertf( ! objStack.empty(), "empty obj stack entering list init" ); 579 const ast::Type * type = objStack.back()->getNext(); 580 assert( type ); 581 objStack.emplace_back( createMemberIterator( loc, type ) ); 582 } 583 584 void CurrentObject::exitListInit() { 585 PRINT( std::cerr << "____exiting list init" << std::endl; ) 586 assertf( ! objStack.empty(), "objstack empty" ); 587 objStack.pop_back(); 588 if ( ! objStack.empty() ) { 589 PRINT( std::cerr << *objStack.back() << std::endl; ) 590 objStack.back()->bigStep(); 591 } 592 } 593 594 std::deque< InitAlternative > CurrentObject::getOptions() { 595 PRINT( std::cerr << "____getting current options" << std::endl; ) 596 assertf( ! objStack.empty(), "objstack empty in getOptions" ); 597 return **objStack.back(); 598 } 599 600 const Type * CurrentObject::getCurrentType() { 601 PRINT( std::cerr << "____getting current type" << std::endl; ) 602 assertf( ! objStack.empty(), "objstack empty in getCurrentType" ); 603 return objStack.back()->getNext(); 604 } 605 } 595 objStack.back()->bigStep(); 596 } 597 } 598 599 std::deque< InitAlternative > CurrentObject::getOptions() { 600 PRINT( std::cerr << "____getting current options" << std::endl; ) 601 assertf( ! objStack.empty(), "objstack empty in getOptions" ); 602 return **objStack.back(); 603 } 604 605 const Type * CurrentObject::getCurrentType() { 606 PRINT( std::cerr << "____getting current type" << std::endl; ) 607 assertf( ! objStack.empty(), "objstack empty in getCurrentType" ); 608 return objStack.back()->getNext(); 609 } 610 611 } // namespace ast 606 612 607 613 // Local Variables: //
Note: See TracChangeset
for help on using the changeset viewer.