Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    reada3cf r4573e3c  
    3232#include "Common/UniqueName.h"           // for UniqueName
    3333#include "Common/utility.h"              // for toString
    34 #include "DeclMutator.h"                 // for DeclMutator
    3534#include "FindFunction.h"                // for findFunction, findAndReplace...
    3635#include "GenPoly/ErasableScopedMap.h"   // for ErasableScopedMap<>::const_i...
     
    3938#include "Lvalue.h"                      // for generalizedLvalue
    4039#include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
    41 #include "PolyMutator.h"                 // for PolyMutator
    4240#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4341#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    6260                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6361
     62                class BoxPass {
     63                protected:
     64                        BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
     65                        TyVarMap scopeTyVars;
     66                };
     67
    6468                /// Adds layout-generation functions to polymorphic types
    65                 class LayoutFunctionBuilder final : public DeclMutator {
    66                         unsigned int functionNesting;  // current level of nested functions
     69                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
     70                        unsigned int functionNesting = 0;  // current level of nested functions
    6771                public:
    68                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    69 
    70                         using DeclMutator::mutate;
    71                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    72                         virtual Declaration *mutate( StructDecl *structDecl ) override;
    73                         virtual Declaration *mutate( UnionDecl *unionDecl ) override;
     72                        void previsit( FunctionDecl *functionDecl );
     73                        void previsit( StructDecl *structDecl );
     74                        void previsit( UnionDecl *unionDecl );
    7475                };
    7576
    7677                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    77                 class Pass1 final : public PolyMutator {
     78                class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7879                  public:
    7980                        Pass1();
    8081
    81                         using PolyMutator::mutate;
    82                         virtual Expression *mutate( ApplicationExpr *appExpr ) override;
    83                         virtual Expression *mutate( AddressExpr *addrExpr ) override;
    84                         virtual Expression *mutate( UntypedExpr *expr ) override;
    85                         virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override;
    86                         virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    87                         virtual Expression *mutate( CommaExpr *commaExpr ) override;
    88                         virtual Expression *mutate( ConditionalExpr *condExpr ) override;
    89                         virtual Statement * mutate( ReturnStmt *returnStmt ) override;
    90                         virtual Type *mutate( PointerType *pointerType ) override;
    91                         virtual Type * mutate( FunctionType *functionType ) override;
    92 
    93                         virtual void doBeginScope() override;
    94                         virtual void doEndScope() override;
     82                        void premutate( FunctionDecl * functionDecl );
     83                        void premutate( TypeDecl * typeDecl );
     84                        void premutate( CommaExpr * commaExpr );
     85                        Expression * postmutate( ApplicationExpr * appExpr );
     86                        Expression * postmutate( UntypedExpr *expr );
     87                        void premutate( AddressExpr * addrExpr );
     88                        Expression * postmutate( AddressExpr * addrExpr );
     89                        void premutate( ReturnStmt * returnStmt );
     90                        void premutate( PointerType * pointerType );
     91                        void premutate( FunctionType * functionType );
     92
     93                        void beginScope();
     94                        void endScope();
    9595                  private:
    9696                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
     
    129129                /// * Moves polymorphic returns in function types to pointer-type parameters
    130130                /// * adds type size and assertion parameters to parameter lists
    131                 class Pass2 final : public PolyMutator {
    132                   public:
    133                         template< typename DeclClass >
    134                         DeclClass *handleDecl( DeclClass *decl );
    135                         template< typename AggDecl >
    136                         AggDecl * handleAggDecl( AggDecl * aggDecl );
    137 
    138                         typedef PolyMutator Parent;
    139                         using Parent::mutate;
    140                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    141                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    142                         virtual StructDecl *mutate( StructDecl *structDecl ) override;
    143                         virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
    144                         virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
    145                         virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    146                         virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
    147                         virtual Type *mutate( PointerType *pointerType ) override;
    148                         virtual Type *mutate( FunctionType *funcType ) override;
     131                struct Pass2 final : public BoxPass, public WithGuards {
     132                        void handleAggDecl();
     133
     134                        DeclarationWithType * postmutate( FunctionDecl *functionDecl );
     135                        void premutate( StructDecl *structDecl );
     136                        void premutate( UnionDecl *unionDecl );
     137                        void premutate( TraitDecl *unionDecl );
     138                        void premutate( TypeDecl *typeDecl );
     139                        void premutate( PointerType *pointerType );
     140                        void premutate( FunctionType *funcType );
    149141
    150142                  private:
     
    158150                /// * Calculates polymorphic offsetof expressions from offset array
    159151                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    160                 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     152                class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    161153                public:
    162154                        PolyGenericCalculator();
     
    197189                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    198190                        UniqueName bufNamer;                           ///< Namer for VLA buffers
    199                         TyVarMap scopeTyVars;
    200191                };
    201192
    202193                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
    203                 class Pass3 final : public PolyMutator {
    204                   public:
     194                struct Pass3 final : public BoxPass, public WithGuards {
    205195                        template< typename DeclClass >
    206                         DeclClass *handleDecl( DeclClass *decl, Type *type );
    207 
    208                         using PolyMutator::mutate;
    209                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    210                         virtual Declaration *mutate( StructDecl *structDecl ) override;
    211                         virtual Declaration *mutate( UnionDecl *unionDecl ) override;
    212                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    213                         virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
    214                         virtual TypeDecl *mutate( TypeDecl *objectDecl ) override;
    215                         virtual Type *mutate( PointerType *pointerType ) override;
    216                         virtual Type *mutate( FunctionType *funcType ) override;
    217                   private:
     196                        void handleDecl( DeclClass * decl, Type * type );
     197
     198                        void premutate( ObjectDecl * objectDecl );
     199                        void premutate( FunctionDecl * functionDecl );
     200                        void premutate( TypedefDecl * typedefDecl );
     201                        void premutate( StructDecl * structDecl );
     202                        void premutate( UnionDecl * unionDecl );
     203                        void premutate( TypeDecl * typeDecl );
     204                        void premutate( PointerType * pointerType );
     205                        void premutate( FunctionType * funcType );
    218206                };
    219207        } // anonymous namespace
     
    247235
    248236        void box( std::list< Declaration *>& translationUnit ) {
    249                 LayoutFunctionBuilder layoutBuilder;
    250                 Pass1 pass1;
    251                 Pass2 pass2;
     237                PassVisitor<LayoutFunctionBuilder> layoutBuilder;
     238                PassVisitor<Pass1> pass1;
     239                PassVisitor<Pass2> pass2;
    252240                PassVisitor<PolyGenericCalculator> polyCalculator;
    253                 Pass3 pass3;
    254 
    255                 layoutBuilder.mutateDeclarationList( translationUnit );
    256                 mutateTranslationUnit/*All*/( translationUnit, pass1 );
    257                 mutateTranslationUnit/*All*/( translationUnit, pass2 );
     241                PassVisitor<Pass3> pass3;
     242
     243                acceptAll( translationUnit, layoutBuilder );
     244                mutateAll( translationUnit, pass1 );
     245                mutateAll( translationUnit, pass2 );
    258246                mutateAll( translationUnit, polyCalculator );
    259                 mutateTranslationUnit/*All*/( translationUnit, pass3 );
     247                mutateAll( translationUnit, pass3 );
    260248        }
    261249
    262250        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    263251
    264         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    265                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     252        void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
     253                visit_children = false;
     254                maybeAccept( functionDecl->get_functionType(), *visitor );
    266255                ++functionNesting;
    267                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     256                maybeAccept( functionDecl->get_statements(), *visitor );
    268257                --functionNesting;
    269                 return functionDecl;
    270258        }
    271259
     
    356344        }
    357345
    358         Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
     346        void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {
    359347                // do not generate layout function for "empty" tag structs
    360                 if ( structDecl->get_members().empty() ) return structDecl;
     348                visit_children = false;
     349                if ( structDecl->get_members().empty() ) return;
    361350
    362351                // get parameters that can change layout, exiting early if none
    363352                std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    364                 if ( otypeParams.empty() ) return structDecl;
     353                if ( otypeParams.empty() ) return;
    365354
    366355                // build layout function signature
     
    413402                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    414403
    415                 addDeclarationAfter( layoutDecl );
    416                 return structDecl;
     404                declsToAddAfter.push_back( layoutDecl );
    417405        }
    418406
    419         Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
     407        void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {
    420408                // do not generate layout function for "empty" tag unions
    421                 if ( unionDecl->get_members().empty() ) return unionDecl;
     409                visit_children = false;
     410                if ( unionDecl->get_members().empty() ) return;
    422411
    423412                // get parameters that can change layout, exiting early if none
    424413                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    425                 if ( otypeParams.empty() ) return unionDecl;
     414                if ( otypeParams.empty() ) return;
    426415
    427416                // build layout function signature
     
    456445                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    457446
    458                 addDeclarationAfter( layoutDecl );
    459                 return unionDecl;
     447                declsToAddAfter.push_back( layoutDecl );
    460448        }
    461449
     
    501489                Pass1::Pass1() : tempNamer( "_temp" ) {}
    502490
    503                 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
     491                void Pass1::premutate( FunctionDecl *functionDecl ) {
    504492                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    505493                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506                                 doBeginScope();
    507                                 scopeTyVars.beginScope();
    508 
    509                                 DeclarationWithType *oldRetval = retval;
     494                                GuardScope( scopeTyVars );
     495                                GuardValue( retval );
    510496
    511497                                // process polymorphic return value
    512498                                retval = nullptr;
    513                                 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) {
    514                                         retval = functionDecl->get_functionType()->get_returnVals().front();
     499                                FunctionType *functionType = functionDecl->type;
     500                                if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) {
     501                                        retval = functionType->returnVals.front();
    515502
    516503                                        // give names to unnamed return values
    517                                         if ( retval->get_name() == "" ) {
    518                                                 retval->set_name( "_retparm" );
    519                                                 retval->set_linkage( LinkageSpec::C );
     504                                        if ( retval->name == "" ) {
     505                                                retval->name = "_retparm";
     506                                                retval->linkage = LinkageSpec::C;
    520507                                        } // if
    521508                                } // if
    522509
    523                                 FunctionType *functionType = functionDecl->get_functionType();
    524                                 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    525 
    526                                 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     510                                makeTyVarMap( functionType, scopeTyVars );
     511
     512                                std::list< DeclarationWithType *> &paramList = functionType->parameters;
    527513                                std::list< FunctionType *> functions;
    528                                 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    529                                         for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     514                                for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {
     515                                        for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    530516                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    531517                                        } // for
     
    542528                                        } // if
    543529                                } // for
    544 
    545                                 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    546 
    547                                 scopeTyVars.endScope();
    548                                 retval = oldRetval;
    549                                 doEndScope();
    550530                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    551531                        } // if
    552                         return functionDecl;
    553                 }
    554 
    555                 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
     532                }
     533
     534                void Pass1::premutate( TypeDecl *typeDecl ) {
    556535                        addToTyVarMap( typeDecl, scopeTyVars );
    557                         return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    558                 }
    559 
    560                 Expression *Pass1::mutate( CommaExpr *commaExpr ) {
     536                }
     537
     538                void Pass1::premutate( CommaExpr *commaExpr ) {
    561539                        // Attempting to find application expressions that were mutated by the copy constructor passes
    562540                        // to use an explicit return variable, so that the variable can be reused as a parameter to the
     
    574552                                }
    575553                        }
    576 
    577                         commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
    578                         commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
    579                         return commaExpr;
    580                 }
    581 
    582                 Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
    583                         condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
    584                         condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
    585                         condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
    586                         return condExpr;
    587 
    588554                }
    589555
     
    634600
    635601                        // add size/align for generic types to parameter list
    636                         if ( ! appExpr->get_function()->has_result() ) return;
     602                        if ( ! appExpr->get_function()->result ) return;
    637603                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
    638604                        assert( funcType );
     
    659625                ObjectDecl *Pass1::makeTemporary( Type *type ) {
    660626                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
    661                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     627                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    662628                        return newObj;
    663629                }
     
    748714
    749715                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    750                         assertf( arg->has_result(), "arg does not have result: %s", toString( arg ).c_str() );
    751                         if ( isPolyType( param, exprTyVars ) ) {
    752                                 Type * newType = arg->get_result()->clone();
     716                        assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
     717                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
     718
     719                        if ( arg->result->get_lvalue() ) {
     720                                // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
     721                                // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
     722                                //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
     723                                //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
     724                                //              return;
     725                                //      }
     726                                // }
     727                                arg =  generalizedLvalue( new AddressExpr( arg ) );
     728                                if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
     729                                        // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
     730                                        arg = new CastExpr( arg, param->clone() );
     731                                }
     732                        } else {
     733                                // use type computed in unification to declare boxed variables
     734                                Type * newType = param->clone();
    753735                                if ( env ) env->apply( newType );
    754                                 std::unique_ptr<Type> manager( newType );
    755                                 if ( isPolyType( newType ) ) {
    756                                         // if the argument's type is polymorphic, we don't need to box again!
    757                                         return;
    758                                 } else if ( arg->get_result()->get_lvalue() ) {
    759                                         // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
    760                                         // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
    761                                         //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
    762                                         //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
    763                                         //              return;
    764                                         //      }
    765                                         // }
    766                                         arg =  generalizedLvalue( new AddressExpr( arg ) );
    767                                         if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
    768                                                 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
    769                                                 arg = new CastExpr( arg, param->clone() );
    770                                         }
    771                                 } else {
    772                                         // use type computed in unification to declare boxed variables
    773                                         Type * newType = param->clone();
    774                                         if ( env ) env->apply( newType );
    775                                         ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
    776                                         newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    777                                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    778                                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    779                                         assign->get_args().push_back( new VariableExpr( newObj ) );
    780                                         assign->get_args().push_back( arg );
    781                                         stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
    782                                         arg = new AddressExpr( new VariableExpr( newObj ) );
    783                                 } // if
     736                                ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );
     737                                newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
     738                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     739                                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
     740                                assign->get_args().push_back( new VariableExpr( newObj ) );
     741                                assign->get_args().push_back( arg );
     742                                stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
     743                                arg = new AddressExpr( new VariableExpr( newObj ) );
    784744                        } // if
     745                }
     746
     747                // find instances of polymorphic type parameters
     748                struct PolyFinder {
     749                        const TyVarMap * tyVars = nullptr;
     750                        bool found = false;
     751
     752                        void previsit( TypeInstType * t ) {
     753                                if ( isPolyType( t, *tyVars ) ) {
     754                                        found = true;
     755                                }
     756                        }
     757                };
     758
     759                // true if there is an instance of a polymorphic type parameter in t
     760                bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {
     761                        PassVisitor<PolyFinder> finder;
     762                        finder.pass.tyVars = &tyVars;
     763                        maybeAccept( t, finder );
     764                        return finder.pass.found;
    785765                }
    786766
     
    789769                /// this gets rid of warnings from gcc.
    790770                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    791                         if ( getFunctionType( formal ) ) {
     771                        // type contains polymorphism, but isn't exactly a polytype, in which case it
     772                        // has some real actual type (e.g. unsigned int) and casting to void * is wrong
     773                        if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {
    792774                                Type * newType = formal->clone();
    793775                                newType = ScrubTyVars::scrub( newType, tyVars );
     
    797779
    798780                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    799                         for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    800                                 assertf( arg != appExpr->get_args().end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
     781                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg ) {
     782                                assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
    801783                                addCast( *arg, (*param)->get_type(), exprTyVars );
    802784                                boxParam( (*param)->get_type(), *arg, exprTyVars );
     
    807789                        std::list< Expression *>::iterator cur = arg;
    808790                        for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    809                                 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     791                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    810792                                        InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    811                                         if ( inferParam == appExpr->get_inferParams().end() ) {
    812                                                 std::cerr << "looking for assertion: " << (*assert) << std::endl << appExpr << std::endl;
    813                                         }
    814                                         assertf( inferParam != appExpr->get_inferParams().end(), "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
     793                                        assertf( inferParam != appExpr->get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
    815794                                        Expression *newExpr = inferParam->second.expr->clone();
    816795                                        addCast( newExpr, (*assert)->get_type(), tyVars );
     
    822801
    823802                void makeRetParm( FunctionType *funcType ) {
    824                         DeclarationWithType *retParm = funcType->get_returnVals().front();
     803                        DeclarationWithType *retParm = funcType->returnVals.front();
    825804
    826805                        // make a new parameter that is a pointer to the type of the old return value
     
    835814                        // actually make the adapter type
    836815                        FunctionType *adapter = adaptee->clone();
    837 //                      if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    838816                        if ( isDynRet( adapter, tyVars ) ) {
    839817                                makeRetParm( adapter );
     
    961939                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    962940                                                adapter = answer.first;
    963                                                 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     941                                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
    964942                                        } // if
    965943                                        assert( adapter != adapters.end() );
     
    999977                                if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    1000978                                        if ( varExpr->get_var()->get_name() == "?[?]" ) {
    1001                                                 assert( appExpr->has_result() );
     979                                                assert( appExpr->result );
    1002980                                                assert( appExpr->get_args().size() == 2 );
    1003981                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
     
    10331011                                                } // if
    10341012                                        } else if ( varExpr->get_var()->get_name() == "*?" ) {
    1035                                                 assert( appExpr->has_result() );
     1013                                                assert( appExpr->result );
    10361014                                                assert( ! appExpr->get_args().empty() );
    10371015                                                if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10501028                                                } // if
    10511029                                        } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
    1052                                                 assert( appExpr->has_result() );
     1030                                                assert( appExpr->result );
    10531031                                                assert( appExpr->get_args().size() == 1 );
    10541032                                                if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10701048                                                } // if
    10711049                                        } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
    1072                                                 assert( appExpr->has_result() );
     1050                                                assert( appExpr->result );
    10731051                                                assert( appExpr->get_args().size() == 1 );
    10741052                                                if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10761054                                                } // if
    10771055                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    1078                                                 assert( appExpr->has_result() );
     1056                                                assert( appExpr->result );
    10791057                                                assert( appExpr->get_args().size() == 2 );
    10801058                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
     
    11021080                                                } // if
    11031081                                        } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
    1104                                                 assert( appExpr->has_result() );
     1082                                                assert( appExpr->result );
    11051083                                                assert( appExpr->get_args().size() == 2 );
    11061084                                                Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env );
     
    11181096                }
    11191097
    1120                 Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
     1098                Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
    11211099                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11221100                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    11241102                        // }
    11251103                        // std::cerr << "\n";
    1126                         appExpr->get_function()->acceptMutator( *this );
    1127                         mutateAll( appExpr->get_args(), *this );
    1128 
    1129                         assert( appExpr->get_function()->has_result() );
    1130                         FunctionType * function = getFunctionType( appExpr->get_function()->get_result() );
    1131                         assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() );
     1104
     1105                        assert( appExpr->function->result );
     1106                        FunctionType * function = getFunctionType( appExpr->function->result );
     1107                        assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
    11321108
    11331109                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    11821158                }
    11831159
    1184                 Expression *Pass1::mutate( UntypedExpr *expr ) {
    1185                         if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    1186                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     1160                Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1161                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
     1162                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    11871163                                        if ( name->get_name() == "*?" ) {
    1188                                                 Expression *ret = expr->get_args().front();
    1189                                                 expr->get_args().clear();
     1164                                                Expression *ret = expr->args.front();
     1165                                                expr->args.clear();
    11901166                                                delete expr;
    1191                                                 return ret->acceptMutator( *this );
     1167                                                return ret;
    11921168                                        } // if
    11931169                                } // if
    11941170                        } // if
    1195                         return PolyMutator::mutate( expr );
    1196                 }
    1197 
    1198                 Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    1199                         assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
     1171                        return expr;
     1172                }
     1173
     1174                void Pass1::premutate( AddressExpr * ) { visit_children = false; }
     1175                Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
     1176                        assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() );
    12001177
    12011178                        bool needs = false;
    12021179                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    1203                                 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
     1180                                if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    12041181                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    12051182                                                if ( name->get_name() == "*?" ) {
    12061183                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    1207                                                                 assert( appExpr->get_function()->has_result() );
     1184                                                                assert( appExpr->get_function()->result );
    12081185                                                                FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    12091186                                                                assert( function );
     
    12161193                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    12171194                        // out of the if condition.
    1218                         addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
     1195                        addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
    12191196                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    12201197                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     
    12311208                }
    12321209
    1233                 Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    1234                         if ( retval && returnStmt->get_expr() ) {
    1235                                 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
    1236                                 delete returnStmt->get_expr();
    1237                                 returnStmt->set_expr( 0 );
    1238                         } else {
    1239                                 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     1210                void Pass1::premutate( ReturnStmt *returnStmt ) {
     1211                        if ( retval && returnStmt->expr ) {
     1212                                assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() );
     1213                                delete returnStmt->expr;
     1214                                returnStmt->expr = nullptr;
    12401215                        } // if
    1241                         return returnStmt;
    1242                 }
    1243 
    1244                 Type * Pass1::mutate( PointerType *pointerType ) {
    1245                         scopeTyVars.beginScope();
     1216                }
     1217
     1218                void Pass1::premutate( PointerType *pointerType ) {
     1219                        GuardScope( scopeTyVars );
    12461220                        makeTyVarMap( pointerType, scopeTyVars );
    1247 
    1248                         Type *ret = Mutator::mutate( pointerType );
    1249 
    1250                         scopeTyVars.endScope();
    1251                         return ret;
    1252                 }
    1253 
    1254                 Type * Pass1::mutate( FunctionType *functionType ) {
    1255                         scopeTyVars.beginScope();
     1221                }
     1222
     1223                void Pass1::premutate( FunctionType *functionType ) {
     1224                        GuardScope( scopeTyVars );
    12561225                        makeTyVarMap( functionType, scopeTyVars );
    1257 
    1258                         Type *ret = Mutator::mutate( functionType );
    1259 
    1260                         scopeTyVars.endScope();
    1261                         return ret;
    1262                 }
    1263 
    1264                 void Pass1::doBeginScope() {
     1226                }
     1227
     1228                void Pass1::beginScope() {
    12651229                        adapters.beginScope();
    12661230                }
    12671231
    1268                 void Pass1::doEndScope() {
     1232                void Pass1::endScope() {
    12691233                        adapters.endScope();
    12701234                }
     
    12931257                }
    12941258
    1295                 template< typename DeclClass >
    1296                 DeclClass * Pass2::handleDecl( DeclClass *decl ) {
    1297                         DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) );
    1298 
    1299                         return ret;
    1300                 }
    1301 
    1302                 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
    1303                         functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
     1259                DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
    13041260                        FunctionType * ftype = functionDecl->get_functionType();
    13051261                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
     
    13251281                }
    13261282
    1327                 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
    1328                         return handleDecl( objectDecl );
    1329                 }
    1330 
    1331                 template< typename AggDecl >
    1332                 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
     1283                void Pass2::premutate( StructDecl * ) {
    13331284                        // prevent tyVars from leaking into containing scope
    1334                         scopeTyVars.beginScope();
    1335                         Parent::mutate( aggDecl );
    1336                         scopeTyVars.endScope();
    1337                         return aggDecl;
    1338                 }
    1339 
    1340                 StructDecl * Pass2::mutate( StructDecl *aggDecl ) {
    1341                         return handleAggDecl( aggDecl );
    1342                 }
    1343 
    1344                 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) {
    1345                         return handleAggDecl( aggDecl );
    1346                 }
    1347 
    1348                 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
    1349                         return handleAggDecl( aggDecl );
    1350                 }
    1351 
    1352                 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
     1285                        GuardScope( scopeTyVars );
     1286                }
     1287
     1288                void Pass2::premutate( UnionDecl * ) {
     1289                        // prevent tyVars from leaking into containing scope
     1290                        GuardScope( scopeTyVars );
     1291                }
     1292
     1293                void Pass2::premutate( TraitDecl * ) {
     1294                        // prevent tyVars from leaking into containing scope
     1295                        GuardScope( scopeTyVars );
     1296                }
     1297
     1298                void Pass2::premutate( TypeDecl *typeDecl ) {
    13531299                        addToTyVarMap( typeDecl, scopeTyVars );
    1354                         if ( typeDecl->get_base() ) {
    1355                                 return handleDecl( typeDecl );
    1356                         } else {
    1357                                 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) );
    1358                         }
    1359                 }
    1360 
    1361                 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) {
    1362                         return handleDecl( typedefDecl );
    1363                 }
    1364 
    1365                 Type * Pass2::mutate( PointerType *pointerType ) {
    1366                         scopeTyVars.beginScope();
     1300                }
     1301
     1302                void Pass2::premutate( PointerType *pointerType ) {
     1303                        GuardScope( scopeTyVars );
    13671304                        makeTyVarMap( pointerType, scopeTyVars );
    1368 
    1369                         Type *ret = Parent::mutate( pointerType );
    1370 
    1371                         scopeTyVars.endScope();
    1372                         return ret;
    1373                 }
    1374 
    1375                 Type *Pass2::mutate( FunctionType *funcType ) {
    1376                         scopeTyVars.beginScope();
    1377 
     1305                }
     1306
     1307                void Pass2::premutate( FunctionType *funcType ) {
     1308                        GuardScope( scopeTyVars );
    13781309                        makeTyVarMap( funcType, scopeTyVars );
    13791310
     
    14141345                                // move all assertions into parameter list
    14151346                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1416 //      *assert = (*assert)->acceptMutator( *this );
    14171347                                        // assertion parameters may not be used in body, pass along with unused attribute.
    14181348                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     
    14501380                                                }
    14511381                                        }
    1452 
    14531382                                        seenTypes.insert( typeName );
    14541383                                }
     
    14581387                        funcType->get_parameters().splice( last, inferredParams );
    14591388                        addAdapters( funcType );
    1460                         mutateAll( funcType->get_returnVals(), *this );
    1461                         mutateAll( funcType->get_parameters(), *this );
    1462 
    1463                         scopeTyVars.endScope();
    1464                         return funcType;
    14651389                }
    14661390
     
    14681392
    14691393                PolyGenericCalculator::PolyGenericCalculator()
    1470                         : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
     1394                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
    14711395
    14721396                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     
    18291753
    18301754                template< typename DeclClass >
    1831                 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
    1832                         scopeTyVars.beginScope();
     1755                void Pass3::handleDecl( DeclClass * decl, Type * type ) {
     1756                        GuardScope( scopeTyVars );
    18331757                        makeTyVarMap( type, scopeTyVars );
    1834 
    1835                         DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    1836                         // ScrubTyVars::scrub( decl, scopeTyVars );
    18371758                        ScrubTyVars::scrubAll( decl );
    1838 
    1839                         scopeTyVars.endScope();
    1840                         return ret;
    1841                 }
    1842 
    1843                 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) {
    1844                         return handleDecl( objectDecl, objectDecl->get_type() );
    1845                 }
    1846 
    1847                 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) {
    1848                         return handleDecl( functionDecl, functionDecl->get_functionType() );
    1849                 }
    1850 
    1851                 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) {
    1852                         return handleDecl( typedefDecl, typedefDecl->get_base() );
     1759                }
     1760
     1761                void Pass3::premutate( ObjectDecl * objectDecl ) {
     1762                        handleDecl( objectDecl, objectDecl->type );
     1763                }
     1764
     1765                void Pass3::premutate( FunctionDecl * functionDecl ) {
     1766                        handleDecl( functionDecl, functionDecl->type );
     1767                }
     1768
     1769                void Pass3::premutate( TypedefDecl * typedefDecl ) {
     1770                        handleDecl( typedefDecl, typedefDecl->base );
    18531771                }
    18541772
    18551773                /// Strips the members from a generic aggregate
    1856                 void stripGenericMembers(AggregateDecl* decl) {
    1857                         if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
    1858                 }
    1859 
    1860                 Declaration *Pass3::mutate( StructDecl *structDecl ) {
     1774                void stripGenericMembers(AggregateDecl * decl) {
     1775                        if ( ! decl->parameters.empty() ) decl->members.clear();
     1776                }
     1777
     1778                void Pass3::premutate( StructDecl * structDecl ) {
    18611779                        stripGenericMembers( structDecl );
    1862                         return structDecl;
    1863                 }
    1864 
    1865                 Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
     1780                }
     1781
     1782                void Pass3::premutate( UnionDecl * unionDecl ) {
    18661783                        stripGenericMembers( unionDecl );
    1867                         return unionDecl;
    1868                 }
    1869 
    1870                 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1871 //   Initializer *init = 0;
    1872 //   std::list< Expression *> designators;
    1873 //   addToTyVarMap( typeDecl, scopeTyVars );
    1874 //   if ( typeDecl->get_base() ) {
    1875 //     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1876 //   }
    1877 //   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    1878 
     1784                }
     1785
     1786                void Pass3::premutate( TypeDecl * typeDecl ) {
    18791787                        addToTyVarMap( typeDecl, scopeTyVars );
    1880                         return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    1881                 }
    1882 
    1883                 Type * Pass3::mutate( PointerType *pointerType ) {
    1884                         scopeTyVars.beginScope();
     1788                }
     1789
     1790                void Pass3::premutate( PointerType * pointerType ) {
     1791                        GuardScope( scopeTyVars );
    18851792                        makeTyVarMap( pointerType, scopeTyVars );
    1886 
    1887                         Type *ret = Mutator::mutate( pointerType );
    1888 
    1889                         scopeTyVars.endScope();
    1890                         return ret;
    1891                 }
    1892 
    1893                 Type * Pass3::mutate( FunctionType *functionType ) {
    1894                         scopeTyVars.beginScope();
     1793                }
     1794
     1795                void Pass3::premutate( FunctionType * functionType ) {
     1796                        GuardScope( scopeTyVars );
    18951797                        makeTyVarMap( functionType, scopeTyVars );
    1896 
    1897                         Type *ret = Mutator::mutate( functionType );
    1898 
    1899                         scopeTyVars.endScope();
    1900                         return ret;
    19011798                }
    19021799        } // anonymous namespace
Note: See TracChangeset for help on using the changeset viewer.