Changeset 81e768d for src/ResolvExpr
- Timestamp:
- Nov 28, 2024, 4:34:08 PM (10 months ago)
- Branches:
- master
- Children:
- 46c4dea
- Parents:
- f5e37a4
- Location:
- src/ResolvExpr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ResolveTypeof.cpp
rf5e37a4 r81e768d 88 88 FixArrayDimension(const ResolveContext & context) : context( context ) {} 89 89 90 const ast::ArrayType * previsit (const ast::ArrayType * arrayType) { 91 if (!arrayType->dimension) return arrayType; 92 auto mutType = mutate(arrayType); 90 template< typename PtrType > 91 const PtrType * previsitImpl( const PtrType * type ) { 92 // Note: resolving dimension expressions seems to require duplicate logic, 93 // here and Resolver.cpp: handlePtrType 94 95 if (!type->dimension) return type; 96 auto mutType = mutate(type); 93 97 auto globalSizeType = context.global.sizeType; 94 98 ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType( ast::BasicKind::LongUnsignedInt ); 95 mutType->dimension = findSingleExpression( arrayType->dimension, sizetype, context );99 mutType->dimension = findSingleExpression(type->dimension, sizetype, context ); 96 100 97 101 if (InitTweak::isConstExpr(mutType->dimension)) { … … 102 106 } 103 107 return mutType; 108 } 109 110 const ast::ArrayType * previsit (const ast::ArrayType * arrayType) { 111 return previsitImpl( arrayType ); 112 } 113 114 const ast::PointerType * previsit (const ast::PointerType * pointerType) { 115 return previsitImpl( pointerType ); 104 116 } 105 117 }; -
src/ResolvExpr/Resolver.cpp
rf5e37a4 r81e768d 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; -
src/ResolvExpr/Unify.cpp
rf5e37a4 r81e768d 292 292 if ( !array2 ) return; 293 293 294 if ( array->isVarLen != array2->isVarLen ) return; 295 if ( (array->dimension != nullptr) != (array2->dimension != nullptr) ) return; 296 297 if ( array->dimension ) { 294 // Permit cases where one side has a dimension or isVarLen, 295 // while the other side is the opposite. 296 // Acheves a wildcard-iterpretation semantics, where lack of 297 // dimension (`float a[]` or `float a[25][*]`) means 298 // "anything here is fine." 299 // Sole known case where a verbatim-match semantics is intended 300 // is typedef redefinition, for which extra checking is added 301 // in src/Validate/ReplaceTypedef.cpp. 302 303 if ( array->dimension && array2->dimension ) { 298 304 assert( array2->dimension ); 299 305 // type unification calls expression unification (mutual recursion)
Note:
See TracChangeset
for help on using the changeset viewer.