Changeset 509ec82 for src/ResolvExpr/Resolver.cpp
- Timestamp:
- Dec 1, 2024, 9:04:12 PM (10 months ago)
- Branches:
- master
- Children:
- eae8b37
- Parents:
- 3e2e9b2 (diff), 1c0a3a4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cpp
r3e2e9b2 r509ec82 494 494 } 495 495 496 // Returns a version of `ty`, with some detail redacted. 497 // `ty` is that of a parameter or return of `functionDecl`. 498 // Redaction: 499 // - concerns the dimension expression, when `ty` is a pointer or array 500 // - prevents escape of variables bound by other parameter declarations 501 // - replaces the whole dimension with `*` if it uses such a variable 502 // - produces the caller's view of `functionDecl`, where `ty` is from the callee/body's view 503 // Example 1 504 // functionDecl: void f( int n, float a[][5][n + 1] ); 505 // outcome: f : void (*)( int , float [][5][*] ), redaction on deepest ArrayType 506 // Example 2 507 // functionDecl: void f( int n, float a[n] ); 508 // outcome: f : void (*)( int , float [*] ), redaction on PointerType 509 // Example 3 510 // in scope: int n; 511 // functionDecl: void f( float a[][n] ); 512 // outcome: f : void (*)( float [][n] ), no redaction 513 static const ast::Type * redactBoundDimExprs( 514 const ast::Type * ty, 515 const ast::FunctionDecl * functionDecl 516 ); 517 struct UsesParams { 518 const ast::FunctionDecl * functionDecl; 519 UsesParams( const ast::FunctionDecl * functionDecl ) : functionDecl(functionDecl) {} 520 bool result = false; 521 void postvisit( const ast::VariableExpr * e ) { 522 for ( auto p : functionDecl->params ) { 523 if ( p.get() == e->var ) result = true; 524 } 525 } 526 }; 527 struct Redactor { 528 const ast::FunctionDecl * functionDecl; 529 Redactor( const ast::FunctionDecl * functionDecl ) : functionDecl(functionDecl) {} 530 template< typename PtrType > 531 const PtrType * postvisitImpl( const PtrType * type ) { 532 if ( type->dimension && ast::Pass<UsesParams>::read( type->dimension.get(), functionDecl ) ) { 533 // PtrType * newtype = ast::shallowCopy( type ); 534 // newtype->dimension = nullptr; 535 // type = newtype; 536 auto mutType = mutate(type); 537 mutType->dimension = nullptr; 538 type = mutType; 539 } 540 return type; 541 } 542 543 const ast::ArrayType * postvisit (const ast::ArrayType * arrayType) { 544 return postvisitImpl( arrayType ); 545 } 546 547 const ast::PointerType * postvisit (const ast::PointerType * pointerType) { 548 return postvisitImpl( pointerType ); 549 } 550 }; 551 static const ast::Type * redactBoundDimExprs( 552 const ast::Type * ty, 553 const ast::FunctionDecl * functionDecl 554 ) { 555 if ( ast::Pass<UsesParams>::read( ty, functionDecl ) ) { 556 ast::Type * newty = ast::deepCopy( ty ); 557 ast::Pass<Redactor> visitor(functionDecl); 558 ty = newty->accept(visitor); 559 } 560 return ty; 561 } 562 496 563 const ast::FunctionDecl * Resolver::previsit( const ast::FunctionDecl * functionDecl ) { 497 564 GuardValue( functionReturn ); … … 534 601 param = fixObjectType(param.strict_as<ast::ObjectDecl>(), context); 535 602 symtab.addId(param); 536 paramTypes.emplace_back(param->get_type()); 603 auto exportParamT = redactBoundDimExprs( param->get_type(), mutDecl ); 604 paramTypes.emplace_back( exportParamT ); 537 605 } 538 606 for (auto & ret : mutDecl->returns) { 539 607 ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), context); 540 returnTypes.emplace_back(ret->get_type()); 608 auto exportRetT = redactBoundDimExprs( ret->get_type(), mutDecl ); 609 returnTypes.emplace_back( exportRetT ); 541 610 } 542 611 // since function type in decl is just a view of param types, need to update that as well … … 699 768 template< typename PtrType > 700 769 const PtrType * handlePtrType( const PtrType * type, const ResolveContext & context ) { 770 // Note: resolving dimension expressions seems to require duplicate logic, 771 // here and ResolveTypeof.cpp:fixArrayType. 701 772 if ( type->dimension ) { 702 773 const ast::Type * sizeType = context.global.sizeType.get(); … … 704 775 assertf(dimension->env->empty(), "array dimension expr has nonempty env"); 705 776 dimension.get_and_mutate()->env = nullptr; 706 ast::mutate_field( type, &PtrType::dimension, dimension );777 type = ast::mutate_field( type, &PtrType::dimension, dimension ); 707 778 } 708 779 return type;
Note:
See TracChangeset
for help on using the changeset viewer.