Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cpp

    r81e768d red96731  
    494494}
    495495
    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 
    563496const ast::FunctionDecl * Resolver::previsit( const ast::FunctionDecl * functionDecl ) {
    564497        GuardValue( functionReturn );
     
    601534                        param = fixObjectType(param.strict_as<ast::ObjectDecl>(), context);
    602535                        symtab.addId(param);
    603                         auto exportParamT = redactBoundDimExprs( param->get_type(), mutDecl );
    604                         paramTypes.emplace_back( exportParamT );
     536                        paramTypes.emplace_back(param->get_type());
    605537                }
    606538                for (auto & ret : mutDecl->returns) {
    607539                        ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), context);
    608                         auto exportRetT = redactBoundDimExprs( ret->get_type(), mutDecl );
    609                         returnTypes.emplace_back( exportRetT );
     540                        returnTypes.emplace_back(ret->get_type());
    610541                }
    611542                // since function type in decl is just a view of param types, need to update that as well
     
    768699template< typename PtrType >
    769700const PtrType * handlePtrType( const PtrType * type, const ResolveContext & context ) {
    770         // Note: resolving dimension expressions seems to require duplicate logic,
    771         // here and ResolveTypeof.cpp:fixArrayType.
    772701        if ( type->dimension ) {
    773702                const ast::Type * sizeType = context.global.sizeType.get();
     
    775704                assertf(dimension->env->empty(), "array dimension expr has nonempty env");
    776705                dimension.get_and_mutate()->env = nullptr;
    777                 type = ast::mutate_field( type, &PtrType::dimension, dimension );
     706                ast::mutate_field( type, &PtrType::dimension, dimension );
    778707        }
    779708        return type;
Note: See TracChangeset for help on using the changeset viewer.