Changes in / [0ddb713:9ed3237]


Ignore:
Location:
src
Files:
6 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r0ddb713 r9ed3237  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Dec 02 11:52:37 2015
    13 // Update Count     : 201
     12// Last Modified On : Tue Aug 11 16:22:35 2015
     13// Update Count     : 89
    1414//
    1515
     
    4747        namespace {
    4848                const std::list<Label> noLabels;
    49 
    50                 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5149
    5250                class Pass1 : public PolyMutator {
     
    8078                        ObjectDecl *makeTemporary( Type *type );
    8179
    82                         typedef std::map< std::string, DeclarationWithType *> AdapterMap;
     80                        typedef std::map< std::string, FunctionDecl *> AdapterMap;
    8381                        std::map< std::string, DeclarationWithType *> assignOps;
    8482                        std::stack< AdapterMap > adapters;
     
    142140
    143141        namespace {
    144                 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {
    145                         std::stringstream name;
    146 
    147                         // NOTE: this function previously used isPolyObj, which failed to produce
    148                         // the correct thing in some situations. It's not clear to me why this wasn't working.
    149 
    150                         // if the return type or a parameter type involved polymorphic types, then the adapter will need
    151                         // to take those polymorphic types as pointers. Therefore, there can be two different functions
    152                         // with the same mangled name, so we need to further mangle the names.
    153                         for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
    154                                 if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {
    155                                         name << "P";
    156                                 } else {
    157                                         name << "M";
    158                                 }
    159                         }
    160                         name << "_";
    161                         std::list< DeclarationWithType *> &paramList = function->get_parameters();
    162                         for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    163                                 if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {
    164                                         name << "P";
    165                                 } else {
    166                                         name << "M";                           
    167                                 }
    168                         } // for
    169                         return name.str();
    170                 }
    171 
    172                 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {
    173                         return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );
    174                 }
    175 
    176142                std::string makeAdapterName( const std::string &mangleName ) {
    177143                        return "_adapter" + mangleName;
    178144                }
    179145
     146                bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
     147                        bool doTransform = false;
     148                        if ( ! function->get_returnVals().empty() ) {
     149                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) {
     150       
     151                                        // figure out if the return type is specified by a type parameter
     152                                        for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
     153                                                if ( (*tyVar)->get_name() == typeInst->get_name() ) {
     154                                                        doTransform = true;
     155                                                        name = typeInst->get_name();
     156                                                        break;
     157                                                } // if
     158                                        } // for
     159                                        if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
     160                                                doTransform = true;
     161                                        } // if
     162                                } // if
     163                        } // if
     164                        return doTransform;
     165                }
     166
     167                bool isPolyRet( FunctionType *function, std::string &name ) {
     168                        TyVarMap dummyTyVars;
     169                        return isPolyRet( function, name, dummyTyVars );
     170                }
     171
     172                bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) {
     173                        std::string dummyString;
     174                        return isPolyRet( function, dummyString, otherTyVars );
     175                }
     176
    180177                Pass1::Pass1()
    181178                        : useRetval( false ), tempNamer( "_temp" ) {
    182                         adapters.push(AdapterMap());
    183                 }
    184 
    185                 // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be)
     179                }
     180
    186181                bool checkAssignment( DeclarationWithType *decl, std::string &name ) {
    187182                        if ( decl->get_name() == "?=?" ) {
     
    203198
    204199                void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
    205                         // what if a nested function uses an assignment operator?
    206                         // assignOps.clear();
     200                        assignOps.clear();
    207201                        for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    208202                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     
    216210
    217211                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    218                         if ( functionDecl->get_statements() ) {         // empty routine body ?
    219                                 doBeginScope();
     212                        if ( functionDecl->get_statements() ) {
    220213                                TyVarMap oldtyVars = scopeTyVars;
    221                                 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;
    222214                                DeclarationWithType *oldRetval = retval;
    223215                                bool oldUseRetval = useRetval;
    224 
    225                                 // process polymorphic return value
     216       
    226217                                retval = 0;
    227218                                std::string typeName;
     
    236227                                } // if
    237228       
    238                                 FunctionType *functionType = functionDecl->get_functionType();
     229                                scopeTyVars.clear();
     230///     std::cerr << "clear\n";
    239231                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    240232                                findAssignOps( functionDecl->get_functionType()->get_forall() );
    241 
    242                                 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    243                                 std::list< FunctionType *> functions;
    244                                 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    245                                         for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    246                                                 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    247                                         } // for
    248                                 } // for
    249                                 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    250                                         findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    251                                 } // for
    252                                 AdapterMap & adapters = Pass1::adapters.top();
    253                                 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    254                                         std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
    255                                         if ( adapters.find( mangleName ) == adapters.end() ) {
    256                                                 std::string adapterName = makeAdapterName( mangleName );
    257                                                 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) ) );
    258                                         } // if
    259                                 } // for
    260 
    261233                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    262234 
    263235                                scopeTyVars = oldtyVars;
    264                                 assignOps = oldassignOps;
    265                                 // std::cerr << "end FunctionDecl: ";
    266                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    267                                 //      std::cerr << i->first << " ";
    268                                 // }
    269                                 // std::cerr << "\n";
     236///     std::cerr << "end FunctionDecl: ";
     237///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     238///       std::cerr << i->first << " ";
     239///     }
     240///     std::cerr << "\n";
    270241                                retval = oldRetval;
    271242                                useRetval = oldUseRetval;
    272                                 doEndScope();
     243                                // doEndScope();
    273244                        } // if
    274245                        return functionDecl;
     
    377348                                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    378349                        } // if
    379                         std::string mangleName = mangleAdapterName( function, tyVars );
     350                        std::string mangleName = SymTab::Mangler::mangle( function );
    380351                        std::string adapterName = makeAdapterName( mangleName );
    381352
     
    486457///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    487458///     } else {
    488                                 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    489                                         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    490                                         deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    491                                         deref->get_results().push_back( arg->get_type()->clone() );
    492                                         return deref;
    493                                 } // if
     459                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     460                                deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     461                                deref->get_results().push_back( arg->get_type()->clone() );
     462                                return deref;
    494463///     }
    495464                        } // if
     
    575544                        } // for
    576545
    577                         // parameter function types for which an appropriate adapter has been generated.  we cannot use the types
    578                         // after applying substitutions, since two different parameter types may be unified to the same type
     546                        // parameter function types for which an appropriate adapter has been generated.
     547                        // we cannot use the types after applying substitutions, since two different
     548                        // parameter types may be unified to the same type
    579549                        std::set< std::string > adaptersDone;
    580550
     
    584554                                std::string mangleName = SymTab::Mangler::mangle( realFunction );
    585555
    586                                 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
    587                                 // pre-substitution parameter function type.
     556                                // only attempt to create an adapter or pass one as a parameter if we haven't
     557                                // already done so for this pre-substitution parameter function type.
    588558                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
     559                                        std::string mangleName = SymTab::Mangler::mangle( realFunction );
    589560                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    590561                                       
    591                                         // apply substitution to type variables to figure out what the adapter's type should look like
     562                                        // apply substitution to type variables to figure out what the
     563                                        // adapter's type should look like
    592564                                        assert( env );
    593565                                        env->apply( realFunction );
    594                                         mangleName = SymTab::Mangler::mangle( realFunction );
    595                                         mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    596 
    597                                         AdapterMap & adapters = Pass1::adapters.top();
    598                                         AdapterMap::iterator adapter = adapters.find( mangleName );
    599                                         if ( adapter == adapters.end() ) {
    600                                                 // adapter has not been created yet in the current scope, so define it
    601                                                 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    602                                                 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    603                                                 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     566                                        mangleName = SymTab::Mangler::mangle( realFunction );
     567
     568                                        if ( needsAdapter( realFunction, exprTyVars, true ) ) {
     569                                                // the function still contains type variables, which means we are in a polymorphic
     570                                                // context and the adapter function is a parameter - call the parameter and don't
     571                                                // create a new adapter.
     572                                                appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) );
     573                                        } else {
     574                                                if ( isPolyRet( originalFunction, exprTyVars ) ) {
     575                                                        // if the return type involved polymorphic types, then
     576                                                        // the adapter will need to take those polymorphic types
     577                                                        // as pointers. Therefore, there can be two different
     578                                                        // functions with the same mangled name, so we need two adapter map
     579                                                        // stacks and also we need the mangled names to be different.
     580                                                        mangleName += "polyret_";
     581                                                }
     582
     583                                                AdapterMap & adapters = Pass1::adapters.top();
     584                                                AdapterMap::iterator adapter = adapters.find( mangleName );
     585                                                if ( adapter == adapters.end() ) {
     586                                                        // adapter has not been created yet in the current scope, so define it
     587                                                        FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
     588                                                        adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) );
     589                                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     590                                                } // if
     591                                                assert( adapter != adapters.end() );
     592
     593                                                // add the appropriate adapter as a parameter
     594                                                appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
    604595                                        } // if
    605                                         assert( adapter != adapters.end() );
    606 
    607                                         // add the appropriate adapter as a parameter
    608                                         appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
    609596                                } // if
    610597                        } // for
    611                 } // passAdapters
     598                }
    612599
    613600                TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
     
    669656                                                TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    670657                                                TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    671                                                 assert( ! typeInst1 || ! typeInst2 );  // the arguments cannot both be polymorphic pointers
     658                                                assert( ! typeInst1 || ! typeInst2 );
    672659                                                UntypedExpr *ret = 0;
    673                                                 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer
     660                                                if ( typeInst1 || typeInst2 ) {
    674661                                                        ret = new UntypedExpr( new NameExpr( "?+?" ) );
    675662                                                } // if
     
    782769
    783770                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    784                         // std::cerr << "mutate appExpr: ";
    785                         // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    786                         //      std::cerr << i->first << " ";
    787                         // }
    788                         // std::cerr << "\n";
     771///    std::cerr << "mutate appExpr: ";
     772///    for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     773///       std::cerr << i->first << " ";
     774///    }
     775///    std::cerr << "\n";
    789776                        bool oldUseRetval = useRetval;
    790777                        useRetval = false;
     
    812799                                ret = addPolyRetParam( appExpr, function, typeName, arg );
    813800                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    814                                 // std::cerr << "needs adapter: ";
    815                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    816                                 //      std::cerr << i->first << " ";
    817                                 // }
    818                                 // std::cerr << "\n";
     801///    std::cerr << "needs adapter: ";
     802///    for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     803///       std::cerr << i->first << " ";
     804///    }
     805///    std::cerr << "\n";
    819806                                // change the application so it calls the adapter rather than the passed function
    820807                                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     
    867854
    868855                Statement * Pass1::mutate(ReturnStmt *retStmt) {
    869                         // by this point, a cast expr on a polymorphic return value is redundant
     856                        // a cast expr on a polymorphic return value is either redundant or invalid
    870857                        while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
    871858                                retStmt->set_expr( castExpr->get_arg() );
     
    924911
    925912                void Pass1::doBeginScope() {
    926                         // push a copy of the current map
    927                         adapters.push(adapters.top());
     913                        // actually, maybe this could (should?) push
     914                        // a copy of the current map
     915                        adapters.push(AdapterMap());
    928916                }
    929917
     
    946934                        std::set< std::string > adaptersDone;
    947935                        for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    948                                 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     936                                std::string mangleName = SymTab::Mangler::mangle( *funType );
    949937                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    950938                                        std::string adapterName = makeAdapterName( mangleName );
     
    10121000                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    10131001                                ObjectDecl *thisParm;
    1014                                 // add all size parameters to parameter list
    10151002                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    10161003                                        thisParm = newObj->clone();
     
    10191006                                        ++last;
    10201007                                }
    1021                                 // move all assertions into parameter list
    10221008                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    10231009///      *assert = (*assert)->acceptMutator( *this );
  • src/GenPoly/Box.h

    r0ddb713 r9ed3237  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 17:24:01 2015
    13 // Update Count     : 5
     12// Last Modified On : Tue May 19 07:32:33 2015
     13// Update Count     : 2
    1414//
    1515
  • src/GenPoly/GenPoly.cc

    r0ddb713 r9ed3237  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Nov 24 15:23:08 2015
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:37:46 2015
     13// Update Count     : 1
    1414//
    1515
     
    2121
    2222namespace GenPoly {
    23         // A function needs an adapter if it returns a polymorphic value or if any of its
    24         // parameters have polymorphic type
    25         bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    26                 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    27                         return true;
    28                 } // if
    29                 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
    30                         if ( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
    31                                 return true;
    32                         } // if
    33                 } // for
    34                 return false;
     23        // interface functions
     24        bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
     25                return isPolyVal( type, tyVars, false );
    3526        }
    3627
    37         bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
    38                 bool doTransform = false;
    39                 if ( ! function->get_returnVals().empty() ) {
    40                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) {
    41        
    42                                 // figure out if the return type is specified by a type parameter
    43                                 for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
    44                                         if ( (*tyVar)->get_name() == typeInst->get_name() ) {
    45                                                 doTransform = true;
    46                                                 name = typeInst->get_name();
    47                                                 break;
    48                                         } // if
    49                                 } // for
    50                                 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
    51                                         doTransform = true;
    52                                 } // if
    53                         } // if
    54                 } // if
    55                 return doTransform;
     28        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 
     29                return needsAdapter( adaptee, tyVars, false );
    5630        }
    5731
    58         bool isPolyRet( FunctionType *function, std::string &name ) {
    59                 TyVarMap dummyTyVars;
    60                 return isPolyRet( function, name, dummyTyVars );
    61         }
    62 
    63         bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) {
    64                 std::string dummyString;
    65                 return isPolyRet( function, dummyString, otherTyVars );
    66         }
    67 
    68         bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
    69                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     32        bool isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars ) {
     33                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    7034                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    7135                                return true;
    7236                        } // if
     37                        return considerAllTyVars;
    7338                } // if
    7439                return false;
    7540        }
    7641
    77         bool isPolyObj( Type *type, const TyVarMap &tyVars ) {
    78                 if ( isPolyVal( type, tyVars ) ) {
    79                         return true;
    80                 } else if ( PointerType *pt = dynamic_cast<PointerType*>( type ) ) {
    81                         return isPolyObj( pt->get_base(), tyVars );
    82                 } else {
    83                         return false;
    84                 }
     42        // A function needs an adapter if it returns a polymorphic value or if any of its
     43        // parameters have polymorphic type
     44        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars ) {
     45                bool needsAdapter = false;
     46                if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars, considerAllTyVars ) ) {
     47                        needsAdapter = true;
     48                } // if
     49                for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); ! needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) {
     50                        if ( isPolyVal( (*innerArg)->get_type(), tyVars, considerAllTyVars ) ) {
     51                                needsAdapter = true;
     52                        } // if
     53                } // for
     54                return needsAdapter;
    8555        }
    8656
  • src/GenPoly/GenPoly.h

    r0ddb713 r9ed3237  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Nov 24 15:24:38 2015
    13 // Update Count     : 6
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:38:34 2015
     13// Update Count     : 1
    1414//
    1515
     
    2525        typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
    2626
     27        // considerAllTyVars allows ignoring the contents of the TyVarMap parameter, for the situations where
     28        // it is important only that a TypeInstType node exists.
     29
    2730        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
    28         bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars );
    29         bool isPolyRet( FunctionType *function, std::string &name );
    30         bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars );
    31 //      bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
     31        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars );
     32        bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
    3233        bool isPolyVal( Type *type, const TyVarMap &tyVars );
    33 
    34   // true if type variable or any number of pointers to type variable
    35   bool isPolyObj( Type *type, const TyVarMap &tyVars );
     34        bool isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars );
    3635        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
    3736} // namespace GenPoly
  • src/GenPoly/module.mk

    r0ddb713 r9ed3237  
    2222       GenPoly/Specialize.cc \
    2323       GenPoly/CopyParams.cc \
    24        GenPoly/FindFunction.cc \
    25        GenPoly/InstantiateGeneric.cc
     24       GenPoly/FindFunction.cc
  • src/Makefile.in

    r0ddb713 r9ed3237  
    121121        GenPoly/cfa_cpp-CopyParams.$(OBJEXT) \
    122122        GenPoly/cfa_cpp-FindFunction.$(OBJEXT) \
    123         GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    124123        InitTweak/cfa_cpp-InitModel.$(OBJEXT) \
    125124        InitTweak/cfa_cpp-InitExpander.$(OBJEXT) \
     
    348347        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    349348        GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    350         GenPoly/InstantiateGeneric.cc InitTweak/InitModel.cc \
    351         InitTweak/InitExpander.cc InitTweak/Mutate.cc \
    352         InitTweak/Association.cc InitTweak/RemoveInit.cc \
    353         Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
    354         Parser/ParseNode.cc Parser/DeclarationNode.cc \
    355         Parser/ExpressionNode.cc Parser/StatementNode.cc \
    356         Parser/InitializerNode.cc Parser/TypeData.cc \
    357         Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
     349        InitTweak/InitModel.cc InitTweak/InitExpander.cc \
     350        InitTweak/Mutate.cc InitTweak/Association.cc \
     351        InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \
     352        Parser/TypedefTable.cc Parser/ParseNode.cc \
     353        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     354        Parser/StatementNode.cc Parser/InitializerNode.cc \
     355        Parser/TypeData.cc Parser/LinkageSpec.cc \
     356        Parser/parseutility.cc Parser/Parser.cc \
    358357        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    359358        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    554553        GenPoly/$(DEPDIR)/$(am__dirstamp)
    555554GenPoly/cfa_cpp-FindFunction.$(OBJEXT): GenPoly/$(am__dirstamp) \
    556         GenPoly/$(DEPDIR)/$(am__dirstamp)
    557 GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT): GenPoly/$(am__dirstamp) \
    558555        GenPoly/$(DEPDIR)/$(am__dirstamp)
    559556InitTweak/$(am__dirstamp):
     
    787784        -rm -f GenPoly/cfa_cpp-FindFunction.$(OBJEXT)
    788785        -rm -f GenPoly/cfa_cpp-GenPoly.$(OBJEXT)
    789         -rm -f GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT)
    790786        -rm -f GenPoly/cfa_cpp-Lvalue.$(OBJEXT)
    791787        -rm -f GenPoly/cfa_cpp-PolyMutator.$(OBJEXT)
     
    897893@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-FindFunction.Po@am__quote@
    898894@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-GenPoly.Po@am__quote@
    899 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Po@am__quote@
    900895@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-Lvalue.Po@am__quote@
    901896@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-PolyMutator.Po@am__quote@
     
    13621357@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    13631358
    1364 GenPoly/cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
    1365 @am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
    1366 @am__fastdepCXX_TRUE@   $(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Po
    1367 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='GenPoly/InstantiateGeneric.cc' object='GenPoly/cfa_cpp-InstantiateGeneric.o' libtool=no @AMDEPBACKSLASH@
    1368 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1369 @am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
    1370 
    1371 GenPoly/cfa_cpp-InstantiateGeneric.obj: GenPoly/InstantiateGeneric.cc
    1372 @am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-InstantiateGeneric.obj -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
    1373 @am__fastdepCXX_TRUE@   $(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/cfa_cpp-InstantiateGeneric.Po
    1374 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='GenPoly/InstantiateGeneric.cc' object='GenPoly/cfa_cpp-InstantiateGeneric.obj' libtool=no @AMDEPBACKSLASH@
    1375 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1376 @am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
    1377 
    13781359InitTweak/cfa_cpp-InitModel.o: InitTweak/InitModel.cc
    13791360@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/cfa_cpp-InitModel.o -MD -MP -MF InitTweak/$(DEPDIR)/cfa_cpp-InitModel.Tpo -c -o InitTweak/cfa_cpp-InitModel.o `test -f 'InitTweak/InitModel.cc' || echo '$(srcdir)/'`InitTweak/InitModel.cc
  • src/Parser/TypeData.cc

    r0ddb713 r9ed3237  
    799799          case DeclarationNode::Struct:
    800800                at = new StructDecl( aggregate->name );
    801                 buildForall( aggregate->params, at->get_parameters() );
    802801                break;
    803802          case DeclarationNode::Union:
    804803                at = new UnionDecl( aggregate->name );
    805                 buildForall( aggregate->params, at->get_parameters() );
    806804                break;
    807805          case DeclarationNode::Context:
    808806                at = new ContextDecl( aggregate->name );
    809                 buildList( aggregate->params, at->get_parameters() );
    810807                break;
    811808          default:
    812809                assert( false );
    813810        } // switch
    814 //      buildList( aggregate->params, at->get_parameters() );
     811        buildList( aggregate->params, at->get_parameters() );
    815812        buildList( aggregate->fields, at->get_members() );
    816813
  • src/ResolvExpr/Unify.cc

    r0ddb713 r9ed3237  
    6161
    6262                template< typename RefType > void handleRefType( RefType *inst, Type *other );
    63                 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
    6463
    6564                bool result;
     
    497496
    498497        template< typename RefType >
    499         void Unify::handleRefType( RefType *inst, Type *other ) {
    500                 // check that other type is compatible and named the same
     498        void Unify::handleRefType( RefType *inst, Type *other ) { 
    501499                RefType *otherStruct = dynamic_cast< RefType* >( other );
    502500                result = otherStruct && inst->get_name() == otherStruct->get_name();
    503         }
    504 
    505         template< typename RefType >
    506         void Unify::handleGenericRefType( RefType *inst, Type *other ) {
    507                 // Check that other type is compatible and named the same
    508                 handleRefType( inst, other );
    509                 if ( ! result ) return;
    510                 // Check that parameters of types unify, if any
    511                 std::list< Expression* > params = inst->get_parameters();
    512                 std::list< Expression* > otherParams = ((RefType*)other)->get_parameters();
    513 
    514                 std::list< Expression* >::const_iterator it = params.begin(), jt = otherParams.begin();
    515                 for ( ; it != params.end() && jt != otherParams.end(); ++it, ++jt ) {
    516                         TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    517                         assert(param && "Aggregate parameters should be type expressions");
    518                         TypeExpr *otherParam = dynamic_cast< TypeExpr* >(*jt);
    519                         assert(otherParam && "Aggregate parameters should be type expressions");
    520 
    521                         if ( ! unifyExact( param->get_type(), otherParam->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode(false, false), indexer ) ) {
    522                                 result = false;
    523                                 return;
    524                         }
    525                 }
    526                 result = ( it == params.end() && jt == otherParams.end() );
    527         }
     501        } 
    528502
    529503        void Unify::visit(StructInstType *structInst) {
    530                 handleGenericRefType( structInst, type2 );
     504                handleRefType( structInst, type2 );
    531505        }
    532506
    533507        void Unify::visit(UnionInstType *unionInst) {
    534                 handleGenericRefType( unionInst, type2 );
     508                handleRefType( unionInst, type2 );
    535509        }
    536510
  • src/SymTab/Validate.cc

    r0ddb713 r9ed3237  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Nov 20 16:33:52 2015
    13 // Update Count     : 201
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Aug 11 16:59:35 2015
     13// Update Count     : 196
    1414//
    1515
     
    126126        };
    127127
    128         class AutogenerateRoutines : public Visitor {
     128        class AddStructAssignment : public Visitor {
    129129          public:
    130130                /// Generates assignment operators for aggregate types as required
    131                 static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     131                static void addStructAssignment( std::list< Declaration * > &translationUnit );
    132132
    133133                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     
    152152                virtual void visit( CatchStmt *catchStmt );
    153153
    154                 AutogenerateRoutines() : functionNesting( 0 ) {}
     154                AddStructAssignment() : functionNesting( 0 ) {}
    155155          private:
    156156                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     
    196196                acceptAll( translationUnit, pass1 );
    197197                acceptAll( translationUnit, pass2 );
    198                 AutogenerateRoutines::autogenerateRoutines( translationUnit );
     198                // need to collect all of the assignment operators prior to
     199                // this point and only generate assignment operators if one doesn't exist
     200                AddStructAssignment::addStructAssignment( translationUnit );
    199201                acceptAll( translationUnit, pass3 );
    200202        }
     
    500502        static const std::list< std::string > noLabels;
    501503
    502         void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    503                 AutogenerateRoutines visitor;
     504        void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) {
     505                AddStructAssignment visitor;
    504506                acceptAndAdd( translationUnit, visitor, false );
    505507        }
     
    625627        }
    626628
    627         /// Clones a reference type, replacing any parameters it may have with a clone of the provided list
    628         template< typename GenericInstType >
    629         GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
    630                 GenericInstType *clone = refType->clone();
    631                 clone->get_parameters().clear();
    632                 cloneAll( params, clone->get_parameters() );
    633                 return clone;
    634         }
    635629
    636630        Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    637631                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    638 
    639                 // Make function polymorphic in same parameters as generic struct, if applicable
    640                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    641                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    642                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    643                         TypeDecl *typeParam = (*param)->clone();
    644                         assignType->get_forall().push_back( typeParam );
    645                         structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    646                 }
    647  
    648                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     632 
     633                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    649634                assignType->get_returnVals().push_back( returnVal );
    650635 
    651                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
     636                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    652637                assignType->get_parameters().push_back( dstParam );
    653638 
    654                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     639                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    655640                assignType->get_parameters().push_back( srcParam );
    656641
     
    688673        Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
    689674                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    690 
    691                 // Make function polymorphic in same parameters as generic union, if applicable
    692                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    693                 std::list< Expression* > unionParams;  // List of matching parameters to put on types
    694                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    695                         TypeDecl *typeParam = (*param)->clone();
    696                         assignType->get_forall().push_back( typeParam );
    697                         unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    698                 }
    699  
    700                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     675 
     676                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    701677                assignType->get_returnVals().push_back( returnVal );
    702678 
    703                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
     679                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    704680                assignType->get_parameters().push_back( dstParam );
    705681 
    706                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     682                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    707683                assignType->get_parameters().push_back( srcParam );
    708684 
     
    715691                copy->get_args().push_back( new VariableExpr( dstParam ) );
    716692                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    717                 copy->get_args().push_back( new SizeofExpr( cloneWithParams( refType, unionParams ) ) );
     693                copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
    718694
    719695                assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
     
    723699        }
    724700
    725         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
     701        void AddStructAssignment::visit( EnumDecl *enumDecl ) {
    726702                if ( ! enumDecl->get_members().empty() ) {
    727703                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    732708        }
    733709
    734         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
     710        void AddStructAssignment::visit( StructDecl *structDecl ) {
    735711                if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    736                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    737                         structInst.set_baseStruct( structDecl );
    738                         declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
     712                        StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
     713                        structInst->set_baseStruct( structDecl );
     714                        declsToAdd.push_back( makeStructAssignment( structDecl, structInst, functionNesting ) );
    739715                        structsDone.insert( structDecl->get_name() );
    740716                } // if
    741717        }
    742718
    743         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     719        void AddStructAssignment::visit( UnionDecl *unionDecl ) {
    744720                if ( ! unionDecl->get_members().empty() ) {
    745                         UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    746                         unionInst.set_baseUnion( unionDecl );
    747                         declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
    748                 } // if
    749         }
    750 
    751         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     721                        UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
     722                        unionInst->set_baseUnion( unionDecl );
     723                        declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst, functionNesting ) );
     724                } // if
     725        }
     726
     727        void AddStructAssignment::visit( TypeDecl *typeDecl ) {
    752728                CompoundStmt *stmts = 0;
    753729                TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
     
    777753        }
    778754
    779         void AutogenerateRoutines::visit( FunctionType *) {
     755        void AddStructAssignment::visit( FunctionType *) {
    780756                // ensure that we don't add assignment ops for types defined as part of the function
    781757        }
    782758
    783         void AutogenerateRoutines::visit( PointerType *) {
     759        void AddStructAssignment::visit( PointerType *) {
    784760                // ensure that we don't add assignment ops for types defined as part of the pointer
    785761        }
    786762
    787         void AutogenerateRoutines::visit( ContextDecl *) {
     763        void AddStructAssignment::visit( ContextDecl *) {
    788764                // ensure that we don't add assignment ops for types defined as part of the context
    789765        }
    790766
    791767        template< typename StmtClass >
    792         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
     768        inline void AddStructAssignment::visitStatement( StmtClass *stmt ) {
    793769                std::set< std::string > oldStructs = structsDone;
    794770                addVisit( stmt, *this );
     
    796772        }
    797773
    798         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
     774        void AddStructAssignment::visit( FunctionDecl *functionDecl ) {
    799775                maybeAccept( functionDecl->get_functionType(), *this );
    800776                acceptAll( functionDecl->get_oldDecls(), *this );
     
    804780        }
    805781
    806         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
     782        void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
    807783                visitStatement( compoundStmt );
    808784        }
    809785
    810         void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
     786        void AddStructAssignment::visit( IfStmt *ifStmt ) {
    811787                visitStatement( ifStmt );
    812788        }
    813789
    814         void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
     790        void AddStructAssignment::visit( WhileStmt *whileStmt ) {
    815791                visitStatement( whileStmt );
    816792        }
    817793
    818         void AutogenerateRoutines::visit( ForStmt *forStmt ) {
     794        void AddStructAssignment::visit( ForStmt *forStmt ) {
    819795                visitStatement( forStmt );
    820796        }
    821797
    822         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
     798        void AddStructAssignment::visit( SwitchStmt *switchStmt ) {
    823799                visitStatement( switchStmt );
    824800        }
    825801
    826         void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
     802        void AddStructAssignment::visit( ChooseStmt *switchStmt ) {
    827803                visitStatement( switchStmt );
    828804        }
    829805
    830         void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
     806        void AddStructAssignment::visit( CaseStmt *caseStmt ) {
    831807                visitStatement( caseStmt );
    832808        }
    833809
    834         void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
     810        void AddStructAssignment::visit( CatchStmt *cathStmt ) {
    835811                visitStatement( cathStmt );
    836812        }
  • src/SynTree/Mutator.h

    r0ddb713 r9ed3237  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 22:26:16 2015
    13 // Update Count     : 8
     12// Last Modified On : Thu Jul 23 23:24:18 2015
     13// Update Count     : 7
    1414//
    1515#include <cassert>
     
    103103inline TreeType *maybeMutate( TreeType *tree, MutatorType &mutator ) {
    104104        if ( tree ) {
    105                 TreeType *newnode = dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) );
     105                TreeType *newnode = dynamic_cast< TreeType* >( tree->acceptMutator( mutator ) );
    106106                assert( newnode );
    107107                return newnode;
  • src/SynTree/ReferenceToType.cc

    r0ddb713 r9ed3237  
    5959std::string StructInstType::typeString() const { return "struct"; }
    6060
    61 std::list<TypeDecl*>* StructInstType::get_baseParameters() {
    62         if ( ! baseStruct ) return NULL;
    63         return &baseStruct->get_parameters();
    64 }
    65 
    6661void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    6762        assert( baseStruct );
     
    7065
    7166std::string UnionInstType::typeString() const { return "union"; }
    72 
    73 std::list<TypeDecl*>* UnionInstType::get_baseParameters() {
    74         if ( ! baseUnion ) return NULL;
    75         return &baseUnion->get_parameters();
    76 }
    7767
    7868void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
  • src/SynTree/Type.h

    r0ddb713 r9ed3237  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 20 12:54:09 2015
    13 // Update Count     : 15
     12// Last Modified On : Thu Jul  9 16:46:15 2015
     13// Update Count     : 14
    1414//
    1515
     
    201201        std::list<DeclarationWithType*> parameters;
    202202
    203         // Does the function accept a variable number of arguments following the arguments specified in the parameters list.
    204         // This could be because of
     203        // does the function accept a variable number of arguments following the arguments
     204        // specified in the parameters list.    This could be because of
    205205        // - an ellipsis in a prototype declaration
    206206        // - an unprototyped declaration
     
    237237        StructDecl *get_baseStruct() const { return baseStruct; }
    238238        void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
    239 
    240         /// Accesses generic parameters of base struct (NULL if none such)
    241         std::list<TypeDecl*> * get_baseParameters();
    242        
    243         /// Looks up the members of this struct named "name" and places them into "foundDecls".
    244         /// Clones declarations into "foundDecls", caller responsible for freeing
     239       
     240        // a utility function
    245241        void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const;
    246242
     
    264260        UnionDecl *get_baseUnion() const { return baseUnion; }
    265261        void set_baseUnion( UnionDecl *newValue ) { baseUnion = newValue; }
    266 
    267         /// Accesses generic parameters of base union (NULL if none such)
    268         std::list<TypeDecl*> * get_baseParameters();
    269        
    270         /// looks up the members of this union named "name" and places them into "foundDecls"
    271         /// Clones declarations into "foundDecls", caller responsible for freeing
     262       
     263        // a utility function
    272264        void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const;
    273265
  • src/SynTree/TypeSubstitution.cc

    r0ddb713 r9ed3237  
    126126Type *TypeSubstitution::handleType( TypeClass *type ) {
    127127        BoundVarsType oldBoundVars( boundVars );
    128         // bind type variables from forall-qualifiers
    129128        if ( freeOnly ) {
    130129                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    131130                        boundVars.insert( (*tyvar )->get_name() );
    132                 } // for
    133         } // if
    134         Type *ret = Mutator::mutate( type );
    135         boundVars = oldBoundVars;
    136         return ret;
    137 }
    138 
    139 template< typename TypeClass >
    140 Type *TypeSubstitution::handleAggregateType( TypeClass *type ) {
    141         BoundVarsType oldBoundVars( boundVars );
    142         // bind type variables from forall-qualifiers
    143         if ( freeOnly ) {
    144                 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    145                         boundVars.insert( (*tyvar )->get_name() );
    146                 } // for
    147         } // if
    148         // bind type variables from generic type instantiations
    149         std::list< TypeDecl* > *baseParameters = type->get_baseParameters();
    150         if ( baseParameters && ! type->get_parameters().empty() ) {
    151                 for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {
    152                         boundVars.insert( (*tyvar)->get_name() );
    153131                } // for
    154132        } // if
     
    179157
    180158Type * TypeSubstitution::mutate( StructInstType *aggregateUseType ) {
    181         return handleAggregateType( aggregateUseType );
     159        return handleType( aggregateUseType );
    182160}
    183161
    184162Type * TypeSubstitution::mutate( UnionInstType *aggregateUseType ) {
    185         return handleAggregateType( aggregateUseType );
     163        return handleType( aggregateUseType );
    186164}
    187165
  • src/SynTree/TypeSubstitution.h

    r0ddb713 r9ed3237  
    5858        virtual Type* mutate(TypeInstType *aggregateUseType);
    5959        virtual Expression* mutate(NameExpr *nameExpr);
    60 
    61         /// Records type variable bindings from forall-statements
     60       
    6261        template< typename TypeClass > Type *handleType( TypeClass *type );
    63         /// Records type variable bindings from forall-statements and instantiations of generic types
    64         template< typename TypeClass > Type *handleAggregateType( TypeClass *type );
    6562       
    6663        virtual Type* mutate(VoidType *basicType);
  • src/examples/Makefile.am

    r0ddb713 r9ed3237  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Fri Nov 20 16:03:46 2015
    14 ## Update Count     : 24
     13## Last Modified On : Thu Jun  4 23:13:10 2015
     14## Update Count     : 22
    1515###############################################################################
    1616
     
    1919CC = @CFA_BINDIR@/cfa
    2020
    21 noinst_PROGRAMS = fstream_test vector_test # build but do not install
    22 fstream_test_SOURCES = iostream.c fstream.c fstream_test.c iterator.c
     21noinst_PROGRAMS = fstream_test vector_test
     22fstream_test_SOURCES = iostream.c fstream.c fstream_test.c
    2323vector_test_SOURCES = vector_int.c fstream.c iostream.c array.c iterator.c vector_test.c
  • src/examples/Makefile.in

    r0ddb713 r9ed3237  
    4949PROGRAMS = $(noinst_PROGRAMS)
    5050am_fstream_test_OBJECTS = iostream.$(OBJEXT) fstream.$(OBJEXT) \
    51         fstream_test.$(OBJEXT) iterator.$(OBJEXT)
     51        fstream_test.$(OBJEXT)
    5252fstream_test_OBJECTS = $(am_fstream_test_OBJECTS)
    5353fstream_test_LDADD = $(LDADD)
     
    176176top_builddir = @top_builddir@
    177177top_srcdir = @top_srcdir@
    178 fstream_test_SOURCES = iostream.c fstream.c fstream_test.c iterator.c
     178fstream_test_SOURCES = iostream.c fstream.c fstream_test.c
    179179vector_test_SOURCES = vector_int.c fstream.c iostream.c array.c iterator.c vector_test.c
    180180all: all-am
  • src/examples/fstream.c

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 22:43:31 2015
    13 // Update Count     : 4
     12// Last Modified On : Wed May 27 18:12:33 2015
     13// Update Count     : 2
    1414//
    1515
     
    3030                fwrite( data, size, 1, os->file );
    3131                os->fail = ferror( os->file );
    32         } // if
     32        }
    3333        return os;
    34 } // write
     34}
    3535
    3636int fail( ofstream *os ) {
    3737        return os->fail;
    38 } // fail
     38}
    3939
    4040static ofstream *make_ofstream() {
     
    4242        new_stream->fail = 0;
    4343        return new_stream;
    44 } // make_ofstream
     44}
    4545
    4646ofstream *ofstream_stdout() {
     
    4848        stdout_stream->file = stdout;
    4949        return stdout_stream;
    50 } // ofstream_stdout
     50}
    5151
    5252ofstream *ofstream_stderr() {
     
    5454        stderr_stream->file = stderr;
    5555        return stderr_stream;
    56 } // ofstream_stderr
     56}
    5757
    5858ofstream *ofstream_fromfile( const char *name ) {
  • src/examples/hello.c

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 20 16:02:50 2015
    13 // Update Count     : 3
     12// Last Modified On : Wed May 27 18:14:58 2015
     13// Update Count     : 1
    1414//
    1515
     
    2828// Local Variables: //
    2929// tab-width: 4 //
    30 // compile-command: "cfa hello.c fstream.o iostream.o iterator.o" //
     30// compile-command: "cfa hello.c fstream.o iostream.o" //
    3131// End: //
  • src/examples/iostream.c

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 20 13:19:19 2015
    13 // Update Count     : 9
     12// Last Modified On : Wed May 27 18:18:13 2015
     13// Update Count     : 2
    1414//
    1515
     
    1717extern "C" {
    1818#include <stdio.h>
    19 #include <string.h>                                                                             // strlen
     19//#include <string.h>
     20//#include <ctype.h>
     21        typedef long unsigned int size_t;
     22        size_t strlen(const char *s);
    2023}
    2124
     
    2326ostype * ?<<?( ostype *os, char c ) {
    2427        return write( os, &c, 1 );
    25 } // ?<<?
     28}
    2629
    2730forall( dtype ostype | ostream( ostype ) )
    2831ostype * ?<<?( ostype *os, int i ) {
    29         char buffer[32];                                                                        // larger than the largest integer
     32        char buffer[20];      // larger than the largest integer
    3033        sprintf( buffer, "%d", i );
    3134        return write( os, buffer, strlen( buffer ) );
    32 } // ?<<?
     35}
    3336
    3437forall( dtype ostype | ostream( ostype ) )
    3538ostype * ?<<?( ostype *os, double d ) {
    36         char buffer[32];                                                                        // larger than the largest double
     39        char buffer[32];      // larger than the largest double
    3740        sprintf( buffer, "%g", d );
    3841        return write( os, buffer, strlen( buffer ) );
    39 } // ?<<?
     42}
    4043
    4144forall( dtype ostype | ostream( ostype ) )
    4245ostype * ?<<?( ostype *os, const char *cp ) {
    4346        return write( os, cp, strlen( cp ) );
    44 } // ?<<?
    45 
    46 forall( dtype ostype | ostream( ostype ) )
    47 ostype * ?<<?( ostype *os, const void *p ) {
    48         char buffer[32];                                                                        // larger than the largest pointer
    49         sprintf( buffer, "%p", p );
    50         return write( os, buffer, strlen( buffer ) );
    51 } // ?<<?
    52 
    53 forall( type elt_type | writeable( elt_type ),
    54                 type iterator_type | iterator( iterator_type, elt_type ),
    55                 dtype os_type | ostream( os_type ) )
    56 void write( iterator_type begin, iterator_type end, os_type *os ) {
    57         void print( elt_type i ) {
    58                 os << i << ' ';
    59         }
    60         for_each( begin, end, print );
    61 } // ?<<?
    62 
    63 forall( type elt_type | writeable( elt_type ),
    64                 type iterator_type | iterator( iterator_type, elt_type ),
    65                 dtype os_type | ostream( os_type ) )
    66 void write_reverse( iterator_type begin, iterator_type end, os_type *os ) {
    67         void print( elt_type i ) {
    68                 os << i << ' ';
    69         }
    70         for_each_reverse( begin, end, print );
    71 } // ?<<?
    72 
     47}
    7348
    7449forall( dtype istype | istream( istype ) )
    7550istype * ?>>?( istype *is, char *cp ) {
    7651        return read( is, cp, 1 );
    77 } // ?>>?
     52}
    7853
    7954forall( dtype istype | istream( istype ) )
     
    9772        unread( is, cur );
    9873        return is;
    99 } // ?>>?
     74}
    10075
    10176// Local Variables: //
  • src/examples/iostream.h

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 17:56:51 2015
    13 // Update Count     : 5
     12// Last Modified On : Wed May 27 18:18:46 2015
     13// Update Count     : 1
    1414//
    1515
    1616#ifndef IOSTREAM_H
    1717#define IOSTREAM_H
    18 
    19 #include "iterator.h"
    2018
    2119typedef unsigned long streamsize_type;
     
    3634forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, double );
    3735forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, const char * );
    38 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, void * );
    39 
    40 // writes the range [begin, end) to the given stream
    41 forall( type elt_type | writeable( elt_type ),
    42                 type iterator_type | iterator( iterator_type, elt_type ),
    43                 dtype os_type | ostream( os_type ) )
    44 void write( iterator_type begin, iterator_type end, os_type *os );
    45 
    46 forall( type elt_type | writeable( elt_type ),
    47                 type iterator_type | iterator( iterator_type, elt_type ),
    48                 dtype os_type | ostream( os_type ) )
    49 void write_reverse( iterator_type begin, iterator_type end, os_type *os );
    5036
    5137
  • src/examples/iterator.c

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 17:54:37 2015
    13 // Update Count     : 24
     12// Last Modified On : Wed May 27 18:41:41 2015
     13// Update Count     : 3
    1414//
    1515
    1616#include "iterator.h"
    1717
    18 forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
    19 void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) ) {
    20         for ( iterator_type i = begin; i != end; ++i ) {
    21                 func( *i );
     18/// forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
     19/// void
     20/// for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) )
     21/// {
     22///   iterator_type i;
     23///   for ( i = begin; i != end; ++i ) {
     24///      func( *i );
     25///   }
     26/// }
     27
     28forall( type elt_type | writeable( elt_type ),
     29                type iterator_type | iterator( iterator_type, elt_type ),
     30                dtype os_type | ostream( os_type ) )
     31void write_all( iterator_type begin, iterator_type end, os_type *os ) {
     32        iterator_type i;
     33        for ( i = begin; i != end; ++i ) {
     34                os << *i << ' ';
    2235        }
    2336}
    2437
    25 forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
    26 void for_each_reverse( iterator_type begin, iterator_type end, void (*func)( elt_type ) ) {
    27         for ( iterator_type i = end; i != begin; ) {
     38forall( type elt_type | writeable( elt_type ),
     39                type iterator_type | iterator( iterator_type, elt_type ),
     40                dtype os_type | ostream( os_type ) )
     41void write_reverse( iterator_type begin, iterator_type end, os_type *os ) {
     42        iterator_type i; // "= end;" does not work
     43        i = end;
     44        do {
    2845                --i;
    29                 func( *i );
    30         }
     46                os << *i << ' ';
     47        } while ( i != begin );
    3148}
    3249
  • src/examples/iterator.h

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 17:58:28 2015
    13 // Update Count     : 6
     12// Last Modified On : Wed May 27 18:41:57 2015
     13// Update Count     : 3
    1414//
    1515
    1616#ifndef ITERATOR_H
    1717#define ITERATOR_H
     18
     19#include "iostream.h"
    1820
    1921// An iterator can be used to traverse a data structure.
     
    3234};
    3335
    34 context iterator_for( type iterator_type, type collection_type, type elt_type | iterator( iterator_type, elt_type ) ) {
     36context iterator_for ( type iterator_type, type collection_type, type elt_type | iterator( iterator_type, elt_type ) ) {
    3537//      [ iterator_type begin, iterator_type end ] get_iterators( collection_type );
    3638        iterator_type begin( collection_type );
     
    4143void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) );
    4244
    43 forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
    44 void for_each_reverse( iterator_type begin, iterator_type end, void (*func)( elt_type ) );
     45// writes the range [begin, end) to the given stream
     46forall( type elt_type | writeable( elt_type ),
     47                type iterator_type | iterator( iterator_type, elt_type ),
     48                dtype os_type | ostream( os_type ) )
     49void write_all( iterator_type begin, iterator_type end, os_type *os );
     50
     51forall( type elt_type | writeable( elt_type ),
     52                type iterator_type | iterator( iterator_type, elt_type ),
     53                dtype os_type | ostream( os_type ) )
     54void write_reverse( iterator_type begin, iterator_type end, os_type *os );
    4555
    4656#endif // ITERATOR_H
  • src/examples/vector_test.c

    r0ddb713 r9ed3237  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 17:54:34 2015
    13 // Update Count     : 9
     12// Last Modified On : Wed May 27 18:42:55 2015
     13// Update Count     : 2
    1414//
    1515
     
    2929        sout << "enter N elements and C-d on a separate line:\n";
    3030        for ( ;; ) {
    31                 sin >> &num;
     31        sin >> &num;
    3232          if ( fail( sin ) || eof( sin ) ) break;
    33                 append( &vec, num );
     33        append( &vec, num );
    3434        }
    3535        // write out the numbers
    3636
    3737        sout << "Array elements:\n";
    38         write( begin( vec ), end( vec ), sout );
     38//      write_all( begin( vec ), end( vec ), sout );
     39//      sout << "\n";
     40        for ( int index = 0; index <= last( vec ); index += 1 ) {
     41        sout << vec[ index ] << " ";
     42        }
    3943        sout << "\n";
    40 
     44#if 1
    4145        sout << "Array elements reversed:\n";
    4246        write_reverse( begin( vec ), end( vec ), sout );
    4347        sout << "\n";
     48#endif
    4449}
     50
     51// ../bin/cfa vector_test.c fstream.o iostream.o vector_int.o iterator.o array.o
    4552
    4653// Local Variables: //
  • src/libcfa/prelude.cf

    r0ddb713 r9ed3237  
    77// Author           : Glen Ditchfield
    88// Created On       : Sat Nov 29 07:23:41 2014
    9 // Last Modified By : Rob Schluntz
    10 // Last Modified On : Thu Nov 19 11:09:47 2015
    11 // Update Count     : 76
     9// Last Modified By : Peter A. Buhr
     10// Last Modified On : Tue Jun  9 14:43:47 2015
     11// Update Count     : 75
    1212//
    1313
  • src/main.cc

    r0ddb713 r9ed3237  
    99// Author           : Richard C. Bilson
    1010// Created On       : Fri May 15 23:12:02 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 22:31:40 2015
    13 // Update Count     : 168
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jul 30 16:08:18 2015
     13// Update Count     : 167
    1414//
    1515
     
    2424#include "SynTree/Declaration.h"
    2525#include "SynTree/Visitor.h"
    26 #include "GenPoly/InstantiateGeneric.h"
    2726#include "GenPoly/Lvalue.h"
    2827#include "GenPoly/Specialize.h"
     
    227226                } // if
    228227
    229                 // add the assignment statement after the initialization of a type parameter
     228                // add the assignment statement after the
     229                // initialization of a type parameter
    230230                OPTPRINT( "validate" )
    231231                SymTab::validate( translationUnit, symtabp );
     
    268268                }
    269269
    270                 OPTPRINT( "instantiateGeneric" )
    271                 GenPoly::instantiateGeneric( translationUnit );
    272270                OPTPRINT( "copyParams" );
    273271                GenPoly::copyParams( translationUnit );
Note: See TracChangeset for help on using the changeset viewer.