Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r4573e3c reada3cf  
    3232#include "Common/UniqueName.h"           // for UniqueName
    3333#include "Common/utility.h"              // for toString
     34#include "DeclMutator.h"                 // for DeclMutator
    3435#include "FindFunction.h"                // for findFunction, findAndReplace...
    3536#include "GenPoly/ErasableScopedMap.h"   // for ErasableScopedMap<>::const_i...
     
    3839#include "Lvalue.h"                      // for generalizedLvalue
    3940#include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
     41#include "PolyMutator.h"                 // for PolyMutator
    4042#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4143#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    6062                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6163
    62                 class BoxPass {
    63                 protected:
    64                         BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
    65                         TyVarMap scopeTyVars;
     64                /// Adds layout-generation functions to polymorphic types
     65                class LayoutFunctionBuilder final : public DeclMutator {
     66                        unsigned int functionNesting;  // current level of nested functions
     67                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;
    6674                };
    6775
    68                 /// Adds layout-generation functions to polymorphic types
    69                 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
    70                         unsigned int functionNesting = 0;  // current level of nested functions
    71                 public:
    72                         void previsit( FunctionDecl *functionDecl );
    73                         void previsit( StructDecl *structDecl );
    74                         void previsit( UnionDecl *unionDecl );
    75                 };
    76 
    7776                /// 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
    78                 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
     77                class Pass1 final : public PolyMutator {
    7978                  public:
    8079                        Pass1();
    8180
    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();
     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;
    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                 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 );
     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;
    141149
    142150                  private:
     
    150158                /// * Calculates polymorphic offsetof expressions from offset array
    151159                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    152                 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     160                class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    153161                public:
    154162                        PolyGenericCalculator();
     
    189197                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    190198                        UniqueName bufNamer;                           ///< Namer for VLA buffers
     199                        TyVarMap scopeTyVars;
    191200                };
    192201
    193202                /// 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.
    194                 struct Pass3 final : public BoxPass, public WithGuards {
     203                class Pass3 final : public PolyMutator {
     204                  public:
    195205                        template< typename DeclClass >
    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 );
     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:
    206218                };
    207219        } // anonymous namespace
     
    235247
    236248        void box( std::list< Declaration *>& translationUnit ) {
    237                 PassVisitor<LayoutFunctionBuilder> layoutBuilder;
    238                 PassVisitor<Pass1> pass1;
    239                 PassVisitor<Pass2> pass2;
     249                LayoutFunctionBuilder layoutBuilder;
     250                Pass1 pass1;
     251                Pass2 pass2;
    240252                PassVisitor<PolyGenericCalculator> polyCalculator;
    241                 PassVisitor<Pass3> pass3;
    242 
    243                 acceptAll( translationUnit, layoutBuilder );
    244                 mutateAll( translationUnit, pass1 );
    245                 mutateAll( translationUnit, pass2 );
     253                Pass3 pass3;
     254
     255                layoutBuilder.mutateDeclarationList( translationUnit );
     256                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     257                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    246258                mutateAll( translationUnit, polyCalculator );
    247                 mutateAll( translationUnit, pass3 );
     259                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    248260        }
    249261
    250262        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    251263
    252         void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
    253                 visit_children = false;
    254                 maybeAccept( functionDecl->get_functionType(), *visitor );
     264        DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
     265                functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    255266                ++functionNesting;
    256                 maybeAccept( functionDecl->get_statements(), *visitor );
     267                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    257268                --functionNesting;
     269                return functionDecl;
    258270        }
    259271
     
    344356        }
    345357
    346         void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {
     358        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    347359                // do not generate layout function for "empty" tag structs
    348                 visit_children = false;
    349                 if ( structDecl->get_members().empty() ) return;
     360                if ( structDecl->get_members().empty() ) return structDecl;
    350361
    351362                // get parameters that can change layout, exiting early if none
    352363                std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    353                 if ( otypeParams.empty() ) return;
     364                if ( otypeParams.empty() ) return structDecl;
    354365
    355366                // build layout function signature
     
    402413                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    403414
    404                 declsToAddAfter.push_back( layoutDecl );
     415                addDeclarationAfter( layoutDecl );
     416                return structDecl;
    405417        }
    406418
    407         void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {
     419        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    408420                // do not generate layout function for "empty" tag unions
    409                 visit_children = false;
    410                 if ( unionDecl->get_members().empty() ) return;
     421                if ( unionDecl->get_members().empty() ) return unionDecl;
    411422
    412423                // get parameters that can change layout, exiting early if none
    413424                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    414                 if ( otypeParams.empty() ) return;
     425                if ( otypeParams.empty() ) return unionDecl;
    415426
    416427                // build layout function signature
     
    445456                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    446457
    447                 declsToAddAfter.push_back( layoutDecl );
     458                addDeclarationAfter( layoutDecl );
     459                return unionDecl;
    448460        }
    449461
     
    489501                Pass1::Pass1() : tempNamer( "_temp" ) {}
    490502
    491                 void Pass1::premutate( FunctionDecl *functionDecl ) {
     503                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    492504                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    493505                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    494                                 GuardScope( scopeTyVars );
    495                                 GuardValue( retval );
     506                                doBeginScope();
     507                                scopeTyVars.beginScope();
     508
     509                                DeclarationWithType *oldRetval = retval;
    496510
    497511                                // process polymorphic return value
    498512                                retval = nullptr;
    499                                 FunctionType *functionType = functionDecl->type;
    500                                 if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) {
    501                                         retval = functionType->returnVals.front();
     513                                if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) {
     514                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    502515
    503516                                        // give names to unnamed return values
    504                                         if ( retval->name == "" ) {
    505                                                 retval->name = "_retparm";
    506                                                 retval->linkage = LinkageSpec::C;
     517                                        if ( retval->get_name() == "" ) {
     518                                                retval->set_name( "_retparm" );
     519                                                retval->set_linkage( LinkageSpec::C );
    507520                                        } // if
    508521                                } // if
    509522
    510                                 makeTyVarMap( functionType, scopeTyVars );
    511 
    512                                 std::list< DeclarationWithType *> &paramList = functionType->parameters;
     523                                FunctionType *functionType = functionDecl->get_functionType();
     524                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
     525
     526                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    513527                                std::list< FunctionType *> functions;
    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 ) {
     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 ) {
    516530                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    517531                                        } // for
     
    528542                                        } // if
    529543                                } // for
     544
     545                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
     546
     547                                scopeTyVars.endScope();
     548                                retval = oldRetval;
     549                                doEndScope();
    530550                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    531551                        } // if
    532                 }
    533 
    534                 void Pass1::premutate( TypeDecl *typeDecl ) {
     552                        return functionDecl;
     553                }
     554
     555                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    535556                        addToTyVarMap( typeDecl, scopeTyVars );
    536                 }
    537 
    538                 void Pass1::premutate( CommaExpr *commaExpr ) {
     557                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
     558                }
     559
     560                Expression *Pass1::mutate( CommaExpr *commaExpr ) {
    539561                        // Attempting to find application expressions that were mutated by the copy constructor passes
    540562                        // to use an explicit return variable, so that the variable can be reused as a parameter to the
     
    552574                                }
    553575                        }
     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
    554588                }
    555589
     
    600634
    601635                        // add size/align for generic types to parameter list
    602                         if ( ! appExpr->get_function()->result ) return;
     636                        if ( ! appExpr->get_function()->has_result() ) return;
    603637                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
    604638                        assert( funcType );
     
    625659                ObjectDecl *Pass1::makeTemporary( Type *type ) {
    626660                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
    627                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     661                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    628662                        return newObj;
    629663                }
     
    714748
    715749                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    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();
     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();
    735753                                if ( env ) env->apply( newType );
    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 ) );
     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
    744784                        } // 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;
    765785                }
    766786
     
    769789                /// this gets rid of warnings from gcc.
    770790                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    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 ) ) {
     791                        if ( getFunctionType( formal ) ) {
    774792                                Type * newType = formal->clone();
    775793                                newType = ScrubTyVars::scrub( newType, tyVars );
     
    779797
    780798                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    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() );
     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() );
    783801                                addCast( *arg, (*param)->get_type(), exprTyVars );
    784802                                boxParam( (*param)->get_type(), *arg, exprTyVars );
     
    789807                        std::list< Expression *>::iterator cur = arg;
    790808                        for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    791                                 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
     809                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    792810                                        InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    793                                         assertf( inferParam != appExpr->get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
     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" );
    794815                                        Expression *newExpr = inferParam->second.expr->clone();
    795816                                        addCast( newExpr, (*assert)->get_type(), tyVars );
     
    801822
    802823                void makeRetParm( FunctionType *funcType ) {
    803                         DeclarationWithType *retParm = funcType->returnVals.front();
     824                        DeclarationWithType *retParm = funcType->get_returnVals().front();
    804825
    805826                        // make a new parameter that is a pointer to the type of the old return value
     
    814835                        // actually make the adapter type
    815836                        FunctionType *adapter = adaptee->clone();
     837//                      if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    816838                        if ( isDynRet( adapter, tyVars ) ) {
    817839                                makeRetParm( adapter );
     
    939961                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    940962                                                adapter = answer.first;
    941                                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
     963                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    942964                                        } // if
    943965                                        assert( adapter != adapters.end() );
     
    977999                                if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    9781000                                        if ( varExpr->get_var()->get_name() == "?[?]" ) {
    979                                                 assert( appExpr->result );
     1001                                                assert( appExpr->has_result() );
    9801002                                                assert( appExpr->get_args().size() == 2 );
    9811003                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
     
    10111033                                                } // if
    10121034                                        } else if ( varExpr->get_var()->get_name() == "*?" ) {
    1013                                                 assert( appExpr->result );
     1035                                                assert( appExpr->has_result() );
    10141036                                                assert( ! appExpr->get_args().empty() );
    10151037                                                if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10281050                                                } // if
    10291051                                        } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
    1030                                                 assert( appExpr->result );
     1052                                                assert( appExpr->has_result() );
    10311053                                                assert( appExpr->get_args().size() == 1 );
    10321054                                                if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10481070                                                } // if
    10491071                                        } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
    1050                                                 assert( appExpr->result );
     1072                                                assert( appExpr->has_result() );
    10511073                                                assert( appExpr->get_args().size() == 1 );
    10521074                                                if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10541076                                                } // if
    10551077                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    1056                                                 assert( appExpr->result );
     1078                                                assert( appExpr->has_result() );
    10571079                                                assert( appExpr->get_args().size() == 2 );
    10581080                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
     
    10801102                                                } // if
    10811103                                        } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
    1082                                                 assert( appExpr->result );
     1104                                                assert( appExpr->has_result() );
    10831105                                                assert( appExpr->get_args().size() == 2 );
    10841106                                                Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env );
     
    10961118                }
    10971119
    1098                 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
     1120                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    10991121                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11001122                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    11021124                        // }
    11031125                        // std::cerr << "\n";
    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() );
     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() );
    11081132
    11091133                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    11581182                }
    11591183
    1160                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
    1161                         if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1162                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
     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() ) ) {
    11631187                                        if ( name->get_name() == "*?" ) {
    1164                                                 Expression *ret = expr->args.front();
    1165                                                 expr->args.clear();
     1188                                                Expression *ret = expr->get_args().front();
     1189                                                expr->get_args().clear();
    11661190                                                delete expr;
    1167                                                 return ret;
     1191                                                return ret->acceptMutator( *this );
    11681192                                        } // if
    11691193                                } // if
    11701194                        } // if
    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() );
     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() );
    11771200
    11781201                        bool needs = false;
    11791202                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    1180                                 if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
     1203                                if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    11811204                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    11821205                                                if ( name->get_name() == "*?" ) {
    11831206                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    1184                                                                 assert( appExpr->get_function()->result );
     1207                                                                assert( appExpr->get_function()->has_result() );
    11851208                                                                FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    11861209                                                                assert( function );
     
    11931216                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    11941217                        // out of the if condition.
    1195                         addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
     1218                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    11961219                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    11971220                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     
    12081231                }
    12091232
    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;
     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() ) );
    12151240                        } // if
    1216                 }
    1217 
    1218                 void Pass1::premutate( PointerType *pointerType ) {
    1219                         GuardScope( scopeTyVars );
     1241                        return returnStmt;
     1242                }
     1243
     1244                Type * Pass1::mutate( PointerType *pointerType ) {
     1245                        scopeTyVars.beginScope();
    12201246                        makeTyVarMap( pointerType, scopeTyVars );
    1221                 }
    1222 
    1223                 void Pass1::premutate( FunctionType *functionType ) {
    1224                         GuardScope( 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();
    12251256                        makeTyVarMap( functionType, scopeTyVars );
    1226                 }
    1227 
    1228                 void Pass1::beginScope() {
     1257
     1258                        Type *ret = Mutator::mutate( functionType );
     1259
     1260                        scopeTyVars.endScope();
     1261                        return ret;
     1262                }
     1263
     1264                void Pass1::doBeginScope() {
    12291265                        adapters.beginScope();
    12301266                }
    12311267
    1232                 void Pass1::endScope() {
     1268                void Pass1::doEndScope() {
    12331269                        adapters.endScope();
    12341270                }
     
    12571293                }
    12581294
    1259                 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
     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 ) );
    12601304                        FunctionType * ftype = functionDecl->get_functionType();
    12611305                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
     
    12811325                }
    12821326
    1283                 void Pass2::premutate( StructDecl * ) {
     1327                ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
     1328                        return handleDecl( objectDecl );
     1329                }
     1330
     1331                template< typename AggDecl >
     1332                AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
    12841333                        // prevent tyVars from leaking into containing scope
    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 ) {
     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 ) {
    12991353                        addToTyVarMap( typeDecl, scopeTyVars );
    1300                 }
    1301 
    1302                 void Pass2::premutate( PointerType *pointerType ) {
    1303                         GuardScope( 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();
    13041367                        makeTyVarMap( pointerType, scopeTyVars );
    1305                 }
    1306 
    1307                 void Pass2::premutate( FunctionType *funcType ) {
    1308                         GuardScope( 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
    13091378                        makeTyVarMap( funcType, scopeTyVars );
    13101379
     
    13451414                                // move all assertions into parameter list
    13461415                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
     1416//      *assert = (*assert)->acceptMutator( *this );
    13471417                                        // assertion parameters may not be used in body, pass along with unused attribute.
    13481418                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     
    13801450                                                }
    13811451                                        }
     1452
    13821453                                        seenTypes.insert( typeName );
    13831454                                }
     
    13871458                        funcType->get_parameters().splice( last, inferredParams );
    13881459                        addAdapters( funcType );
     1460                        mutateAll( funcType->get_returnVals(), *this );
     1461                        mutateAll( funcType->get_parameters(), *this );
     1462
     1463                        scopeTyVars.endScope();
     1464                        return funcType;
    13891465                }
    13901466
     
    13921468
    13931469                PolyGenericCalculator::PolyGenericCalculator()
    1394                         : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
     1470                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
    13951471
    13961472                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     
    17531829
    17541830                template< typename DeclClass >
    1755                 void Pass3::handleDecl( DeclClass * decl, Type * type ) {
    1756                         GuardScope( scopeTyVars );
     1831                DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
     1832                        scopeTyVars.beginScope();
    17571833                        makeTyVarMap( type, scopeTyVars );
     1834
     1835                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1836                        // ScrubTyVars::scrub( decl, scopeTyVars );
    17581837                        ScrubTyVars::scrubAll( decl );
    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 );
     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() );
    17711853                }
    17721854
    17731855                /// Strips the members from a generic aggregate
    1774                 void stripGenericMembers(AggregateDecl * decl) {
    1775                         if ( ! decl->parameters.empty() ) decl->members.clear();
    1776                 }
    1777 
    1778                 void Pass3::premutate( StructDecl * structDecl ) {
     1856                void stripGenericMembers(AggregateDecl* decl) {
     1857                        if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
     1858                }
     1859
     1860                Declaration *Pass3::mutate( StructDecl *structDecl ) {
    17791861                        stripGenericMembers( structDecl );
    1780                 }
    1781 
    1782                 void Pass3::premutate( UnionDecl * unionDecl ) {
     1862                        return structDecl;
     1863                }
     1864
     1865                Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
    17831866                        stripGenericMembers( unionDecl );
    1784                 }
    1785 
    1786                 void Pass3::premutate( TypeDecl * typeDecl ) {
     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
    17871879                        addToTyVarMap( typeDecl, scopeTyVars );
    1788                 }
    1789 
    1790                 void Pass3::premutate( PointerType * pointerType ) {
    1791                         GuardScope( scopeTyVars );
     1880                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
     1881                }
     1882
     1883                Type * Pass3::mutate( PointerType *pointerType ) {
     1884                        scopeTyVars.beginScope();
    17921885                        makeTyVarMap( pointerType, scopeTyVars );
    1793                 }
    1794 
    1795                 void Pass3::premutate( FunctionType * functionType ) {
    1796                         GuardScope( 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();
    17971895                        makeTyVarMap( functionType, scopeTyVars );
     1896
     1897                        Type *ret = Mutator::mutate( functionType );
     1898
     1899                        scopeTyVars.endScope();
     1900                        return ret;
    17981901                }
    17991902        } // anonymous namespace
Note: See TracChangeset for help on using the changeset viewer.