Changeset 083cf31


Ignore:
Timestamp:
Jan 7, 2016, 11:28:48 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
1e9d87b
Parents:
267cb3d (diff), de91427b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge with master

Files:
2 added
56 edited

Legend:

Unmodified
Added
Removed
  • INSTALL

    r267cb3d r083cf31  
    1919  cfa-cc components.  Some components will be installed in /some/directory/bin,
    2020  others in /some/directory/lib.  If unspecified, this defaults to /usr/local.
     21  If you wish to use (a subdirectory of) your home directory, ${HOME}/some/dir
     22  works, but it is important not to put quotes around the directory path;
     23  Cforall may appear to build, but the installed version may not work properly.
    2124
    2225--with-backend-compiler=PROGRAM specifies the installed path of gcc.  It
  • configure

    r267cb3d r083cf31  
    29992999        cfa_incdir="${cfa_prefix}/include"
    30003000else
    3001         cfa_incdir=${$includedir}
     3001        cfa_incdir=${includedir}
    30023002fi
    30033003
  • configure.ac

    r267cb3d r083cf31  
    4141        cfa_incdir="${cfa_prefix}/include"
    4242else
    43         cfa_incdir=${$includedir}
     43        cfa_incdir=${includedir}
    4444fi
    4545AC_DEFINE_UNQUOTED(CFA_INCDIR, "${cfa_incdir}", [Location of include files.])
  • doc/refrat/refrat.tex

    r267cb3d r083cf31  
    112112\lstset{
    113113language=CFA,
    114 columns=fullflexible,
     114columns=flexible,
    115115basicstyle=\sf\small,
    116116tabsize=4,
    117117xleftmargin=\parindent,
    118118escapechar=@,
    119 %fancyvrb=true,
     119keepspaces=true,
    120120%showtabs=true,
    121 keepspaces=true,
    122 showtabs=true,
    123 tab=,
     121%tab=\rightarrowfill,
    124122}%
    125123
  • src/CodeGen/CodeGenerator.cc

    r267cb3d r083cf31  
    446446                output << ")";
    447447        }
     448
     449        void CodeGenerator::visit( AlignofExpr *sizeofExpr ) {
     450                // use GCC extension to avoid bumping std to C11
     451                output << "__alignof__(";
     452                if ( sizeofExpr->get_isType() ) {
     453                        output << genType( sizeofExpr->get_type(), "" );
     454                } else {
     455                        sizeofExpr->get_expr()->accept( *this );
     456                } // if
     457                output << ")";
     458        }
    448459 
    449460        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
  • src/CodeGen/CodeGenerator.h

    r267cb3d r083cf31  
    6060                virtual void visit( ConstantExpr *constantExpr );
    6161                virtual void visit( SizeofExpr *sizeofExpr );
     62                virtual void visit( AlignofExpr *alignofExpr );
    6263                virtual void visit( LogicalExpr *logicalExpr );
    6364                virtual void visit( ConditionalExpr *conditionalExpr );
  • src/GenPoly/Box.cc

    r267cb3d r083cf31  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Box.cc -- 
     7// Box.cc --
    88//
    99// Author           : Richard C. Bilson
    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 : Fri Dec 18 14:53:08 2015
     13// Update Count     : 217
    1414//
    1515
     
    2828#include "Parser/ParseNode.h"
    2929
     30#include "SynTree/Constant.h"
    3031#include "SynTree/Type.h"
    3132#include "SynTree/Expression.h"
     
    5051                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5152
     53                /// 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
    5254                class Pass1 : public PolyMutator {
    5355                  public:
     
    6062                        virtual Expression *mutate( CommaExpr *commaExpr );
    6163                        virtual Expression *mutate( ConditionalExpr *condExpr );
    62                         virtual Statement *mutate(ReturnStmt *catchStmt);
     64                        virtual Statement * mutate( ReturnStmt *returnStmt );
    6365                        virtual Type *mutate( PointerType *pointerType );
    64                         virtual Type *mutate( FunctionType *pointerType );
    65  
     66                        virtual Type * mutate( FunctionType *functionType );
     67
    6668                        virtual void doBeginScope();
    6769                        virtual void doEndScope();
     
    8890                };
    8991
     92                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    9093                class Pass2 : public PolyMutator {
    9194                  public:
    92                         Pass2();
    9395                        template< typename DeclClass >
    9496                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    101103                  private:
    102104                        void addAdapters( FunctionType *functionType );
    103  
     105
    104106                        std::map< UniqueId, std::string > adapterName;
    105107                };
    106108
     109                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
    107110                class Pass3 : public PolyMutator {
    108111                  public:
     
    148151                        // the correct thing in some situations. It's not clear to me why this wasn't working.
    149152
    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 
     153                        // if the return type or a parameter type involved polymorphic types, then the adapter will need
     154                        // to take those polymorphic types as pointers. Therefore, there can be two different functions
    152155                        // with the same mangled name, so we need to further mangle the names.
    153156                        for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
    154                                 if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {
     157                                if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
    155158                                        name << "P";
    156159                                } else {
     
    161164                        std::list< DeclarationWithType *> &paramList = function->get_parameters();
    162165                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    163                                 if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {
     166                                if ( isPolyType( (*arg)->get_type(), tyVars ) ) {
    164167                                        name << "P";
    165168                                } else {
    166                                         name << "M";                           
     169                                        name << "M";
    167170                                }
    168171                        } // for
     
    178181                }
    179182
    180                 Pass1::Pass1()
    181                         : useRetval( false ), tempNamer( "_temp" ) {
     183                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    182184                        adapters.push(AdapterMap());
    183185                }
     
    191193                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    192194                                                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    193                                                                         name = typeInst->get_name();
    194                                                                         return true;
     195                                                                        if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
     196                                                                                if ( typeInst->get_name() == typeInst2->get_name() ) {
     197                                                                                        name = typeInst->get_name();
     198                                                                                        return true;
     199                                                                                } // if
     200                                                                        } // if
    195201                                                                } // if
    196202                                                        } // if
     
    228234                                if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    229235                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    230  
     236
    231237                                        // give names to unnamed return values
    232238                                        if ( retval->get_name() == "" ) {
     
    235241                                        } // if
    236242                                } // if
    237        
     243
    238244                                FunctionType *functionType = functionDecl->get_functionType();
    239245                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
     
    260266
    261267                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    262  
     268
    263269                                scopeTyVars = oldtyVars;
    264270                                assignOps = oldassignOps;
     
    276282
    277283                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    278 ///     std::cerr << "add " << typeDecl->get_name() << "\n";
    279284                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    280285                        return Mutator::mutate( typeDecl );
     
    302307
    303308                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     309                        // pass size/align for type variables
    304310                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    305311                                ResolvExpr::EqvClass eqvClass;
     
    310316                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    311317                                                arg++;
     318                                                arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
     319                                                arg++;
    312320                                        } else {
    313321                                                throw SemanticError( "unbound type variable in application ", appExpr );
     
    315323                                } // if
    316324                        } // for
     325
     326                        // add size/align for generic types to parameter list
     327                        //assert( ! appExpr->get_function()->get_results().empty() );
     328                        if ( appExpr->get_function()->get_results().empty() ) return;
     329                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     330                        assert( funcType );
     331
     332                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
     333                        std::list< Expression* >::const_iterator fnArg = arg;
     334                        std::set< std::string > seenTypes; //< names for generic types we've seen
     335                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     336                                Type *parmType = (*fnParm)->get_type();
     337                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
     338                                        std::string sizeName = sizeofName( parmType );
     339                                        if ( seenTypes.count( sizeName ) ) continue;
     340
     341                                        assert( ! (*fnArg)->get_results().empty() );
     342                                        Type *argType = (*fnArg)->get_results().front();
     343                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
     344                                        arg++;
     345                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
     346                                        arg++;
     347
     348                                        seenTypes.insert( sizeName );
     349                                }
     350                        }
    317351                }
    318352
     
    323357                }
    324358
    325                 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    326                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    327                                 if ( env ) {
    328                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    329                                                 return isPolyType( newType, env, tyVars );
    330                                         } // if
    331                                 } // if
    332                                 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    333                                         return typeInst;
    334                                 } else {
    335                                         return 0;
    336                                 } // if
    337                         } else {
    338                                 return 0;
    339                         } // if
    340                 }
    341 
    342359                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
    343                         if ( useRetval ) {
    344                                 assert( retval );
    345                                 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    346                                 arg++;
    347                         } else {
    348                                 ObjectDecl *newObj = makeTemporary( retType->clone() );
    349                                 Expression *paramExpr = new VariableExpr( newObj );
    350                                 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
    351                                         paramExpr = new AddressExpr( paramExpr );
    352                                 } // if
    353                                 arg = appExpr->get_args().insert( arg, paramExpr );
    354                                 arg++;
    355 ///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
    356                                 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
    357                                 commaExpr->set_env( appExpr->get_env() );
    358                                 appExpr->set_env( 0 );
    359                                 return commaExpr;
    360                         } // if
    361                         return appExpr;
     360                        // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
     361                        // if ( useRetval ) {
     362                        //      assert( retval );
     363                        //      arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
     364                        //      arg++;
     365                        // } else {
     366
     367                        // Create temporary to hold return value of polymorphic function and produce that temporary as a result
     368                        // using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
     369                        // return values.
     370                        ObjectDecl *newObj = makeTemporary( retType->clone() );
     371                        Expression *paramExpr = new VariableExpr( newObj );
     372                        // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
     373                        // temporary is already boxed and can be used directly.
     374                        if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
     375                                paramExpr = new AddressExpr( paramExpr );
     376                        } // if
     377                        arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
     378                        arg++;
     379                        // Build a comma expression to call the function and emulate a normal return.
     380                        CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
     381                        commaExpr->set_env( appExpr->get_env() );
     382                        appExpr->set_env( 0 );
     383                        return commaExpr;
     384                        // } // if
     385                        // return appExpr;
    362386                }
    363387
     
    374398                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    375399                        Expression *ret = appExpr;
    376                         if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
     400                        if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    377401                                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    378402                        } // if
     
    382406                        appExpr->get_args().push_front( appExpr->get_function() );
    383407                        appExpr->set_function( new NameExpr( adapterName ) );
    384  
     408
    385409                        return ret;
    386410                }
     
    388412                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    389413                        assert( ! arg->get_results().empty() );
    390 ///   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
     414//   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
    391415                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
    392416                        if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
     
    408432                                } // if
    409433                        } // if
    410 ///   }
     434//   }
    411435                }
    412436
     
    425449
    426450                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    427 ///   std::cout << "function is ";
    428 ///   function->print( std::cout );
    429451                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    430 ///     std::cout << "parameter is ";
    431 ///     (*param)->print( std::fcout );
    432 ///     std::cout << std::endl << "argument is ";
    433 ///     (*arg)->print( std::cout );
    434452                                assert( arg != appExpr->get_args().end() );
    435453                                addCast( *arg, (*param)->get_type(), exprTyVars );
     
    466484                        // actually make the adapter type
    467485                        FunctionType *adapter = adaptee->clone();
    468                         if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     486                        if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    469487                                makeRetParm( adapter );
    470488                        } // if
     
    476494                        assert( param );
    477495                        assert( arg );
    478 ///   std::cout << "arg type is ";
    479 ///   arg->get_type()->print( std::cout );
    480 ///   std::cout << "param type is ";
    481 ///   param->get_type()->print( std::cout );
    482 ///   std::cout << " tyVars are: ";
    483 ///   printTyVarMap( std::cout, tyVars );
    484                         if ( isPolyVal( realParam->get_type(), tyVars ) ) {
    485 ///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
    486 ///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    487 ///     } else {
     496                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
     497//     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
     498//       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
     499//     } else {
    488500                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    489501                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    492504                                        return deref;
    493505                                } // if
    494 ///     }
     506//     }
    495507                        } // if
    496508                        return new VariableExpr( param );
     
    517529                        ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
    518530                        Statement *bodyStmt;
    519  
     531
    520532                        std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin();
    521533                        std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin();
     
    531543                                } // for
    532544                        } // for
    533  
     545
    534546                        std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
    535547                        std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
     
    539551                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    540552                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    541                         } else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     553                        } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    542554                                if ( (*param)->get_name() == "" ) {
    543555                                        (*param)->set_name( "_ret" );
     
    588600                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    589601                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    590                                        
     602
    591603                                        // apply substitution to type variables to figure out what the adapter's type should look like
    592604                                        assert( env );
    593605                                        env->apply( realFunction );
    594                                         mangleName = SymTab::Mangler::mangle( realFunction ); 
     606                                        mangleName = SymTab::Mangler::mangle( realFunction );
    595607                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    596608
     
    611623                } // passAdapters
    612624
    613                 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    614                         if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    615                                 return isPolyType( ptr->get_base(), env, tyVars );
    616                         } else if ( env ) {
    617                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    618                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    619                                                 return isPolyPtr( newType, env, tyVars );
    620                                         } // if
    621                                 } // if
    622                         } // if
    623                         return 0;
    624                 }
    625 
    626                 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    627                         if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    628                                 return isPolyPtr( ptr->get_base(), env, tyVars );
    629                         } else if ( env ) {
    630                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    631                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    632                                                 return isPolyPtrPtr( newType, env, tyVars );
    633                                         } // if
    634                                 } // if
    635                         } // if
    636                         return 0;
    637                 }
    638 
    639                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     625                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    640626                        NameExpr *opExpr;
    641627                        if ( isIncr ) {
     
    650636                                addAssign->get_args().push_back( appExpr->get_args().front() );
    651637                        } // if
    652                         addAssign->get_args().push_back( new NameExpr( polyName ) );
     638                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    653639                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    654640                        if ( appExpr->get_env() ) {
     
    667653                                                assert( ! appExpr->get_results().empty() );
    668654                                                assert( appExpr->get_args().size() == 2 );
    669                                                 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    670                                                 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    671                                                 assert( ! typeInst1 || ! typeInst2 ); // the arguments cannot both be polymorphic pointers
     655                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     656                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
     657                                                assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
    672658                                                UntypedExpr *ret = 0;
    673                                                 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer
     659                                                if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer
    674660                                                        ret = new UntypedExpr( new NameExpr( "?+?" ) );
    675661                                                } // if
    676                                                 if ( typeInst1 ) {
     662                                                if ( baseType1 ) {
    677663                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    678664                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    679                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     665                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    680666                                                        ret->get_args().push_back( appExpr->get_args().front() );
    681667                                                        ret->get_args().push_back( multiply );
    682                                                 } else if ( typeInst2 ) {
     668                                                } else if ( baseType2 ) {
    683669                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    684670                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    685                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     671                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    686672                                                        ret->get_args().push_back( multiply );
    687673                                                        ret->get_args().push_back( appExpr->get_args().back() );
    688674                                                } // if
    689                                                 if ( typeInst1 || typeInst2 ) {
     675                                                if ( baseType1 || baseType2 ) {
    690676                                                        ret->get_results().push_front( appExpr->get_results().front()->clone() );
    691677                                                        if ( appExpr->get_env() ) {
     
    700686                                                assert( ! appExpr->get_results().empty() );
    701687                                                assert( ! appExpr->get_args().empty() );
    702                                                 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
     688                                                if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
    703689                                                        Expression *ret = appExpr->get_args().front();
    704690                                                        delete ret->get_results().front();
     
    715701                                                assert( ! appExpr->get_results().empty() );
    716702                                                assert( appExpr->get_args().size() == 1 );
    717                                                 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     703                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
    718704                                                        Type *tempType = appExpr->get_results().front()->clone();
    719705                                                        if ( env ) {
     
    729715                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    730716                                                        } // if
    731                                                         CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
     717                                                        CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) );
    732718                                                        return new CommaExpr( firstComma, tempExpr );
    733719                                                } // if
     
    735721                                                assert( ! appExpr->get_results().empty() );
    736722                                                assert( appExpr->get_args().size() == 1 );
    737                                                 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    738                                                         return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
     723                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
     724                                                        return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
    739725                                                } // if
    740726                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    741727                                                assert( ! appExpr->get_results().empty() );
    742728                                                assert( appExpr->get_args().size() == 2 );
    743                                                 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    744                                                 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    745                                                 if ( typeInst1 && typeInst2 ) {
     729                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     730                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
     731                                                if ( baseType1 && baseType2 ) {
    746732                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    747733                                                        divide->get_args().push_back( appExpr );
    748                                                         divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     734                                                        divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    749735                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    750736                                                        if ( appExpr->get_env() ) {
     
    753739                                                        } // if
    754740                                                        return divide;
    755                                                 } else if ( typeInst1 ) {
     741                                                } else if ( baseType1 ) {
    756742                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    757743                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    758                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     744                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    759745                                                        appExpr->get_args().back() = multiply;
    760                                                 } else if ( typeInst2 ) {
     746                                                } else if ( baseType2 ) {
    761747                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    762748                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    763                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     749                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    764750                                                        appExpr->get_args().front() = multiply;
    765751                                                } // if
     
    767753                                                assert( ! appExpr->get_results().empty() );
    768754                                                assert( appExpr->get_args().size() == 2 );
    769                                                 TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
    770                                                 if ( typeInst ) {
     755                                                Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
     756                                                if ( baseType ) {
    771757                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    772758                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    773                                                         multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     759                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
    774760                                                        appExpr->get_args().back() = multiply;
    775761                                                } // if
     
    792778                        mutateAll( appExpr->get_args(), *this );
    793779                        useRetval = oldUseRetval;
    794  
     780
    795781                        assert( ! appExpr->get_function()->get_results().empty() );
    796782                        PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     
    798784                        FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
    799785                        assert( function );
    800  
     786
    801787                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
    802788                                return newExpr;
    803789                        } // if
    804  
     790
    805791                        Expression *ret = appExpr;
    806  
     792
    807793                        std::list< Expression *>::iterator arg = appExpr->get_args().begin();
    808794                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    809  
     795
    810796                        std::string typeName;
    811797                        if ( isPolyRet( function, typeName ) ) {
     
    821807                        } // if
    822808                        arg = appExpr->get_args().begin();
    823  
     809
    824810                        TyVarMap exprTyVars;
    825811                        makeTyVarMap( function, exprTyVars );
    826  
     812
    827813                        passTypeVars( appExpr, arg, exprTyVars );
    828814                        addInferredParams( appExpr, function, arg, exprTyVars );
    829815
    830816                        arg = paramBegin;
    831  
     817
    832818                        boxParams( appExpr, function, arg, exprTyVars );
    833819
     
    838824
    839825                Expression *Pass1::mutate( UntypedExpr *expr ) {
    840                         if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
     826                        if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
    841827                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    842828                                        if ( name->get_name() == "*?" ) {
     
    853839                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    854840                        assert( ! addrExpr->get_arg()->get_results().empty() );
     841
     842                        bool needs = false;
     843                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
     844                                if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
     845                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     846                                                if ( name->get_name() == "*?" ) {
     847                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
     848                                                                assert( ! appExpr->get_function()->get_results().empty() );
     849                                                                PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     850                                                                assert( pointer );
     851                                                                FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
     852                                                                assert( function );
     853                                                                needs = needsAdapter( function, scopeTyVars );
     854                                                        } // if
     855                                                } // if
     856                                        } // if
     857                                } // if
     858                        } // if
    855859                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    856                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
     860                        if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
    857861                                Expression *ret = addrExpr->get_arg();
    858862                                delete ret->get_results().front();
     
    866870                }
    867871
    868                 Statement * Pass1::mutate(ReturnStmt *retStmt) {
    869                         // by this point, a cast expr on a polymorphic return value is redundant
    870                         while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
    871                                 retStmt->set_expr( castExpr->get_arg() );
    872                                 retStmt->get_expr()->set_env( castExpr->get_env() );
    873                                 castExpr->set_env( 0 );
    874                                 castExpr->set_arg( 0 );
    875                                 delete castExpr;
    876                         }
    877                         if ( retval && retStmt->get_expr() ) {
    878                                 assert( ! retStmt->get_expr()->get_results().empty() );
    879                                 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    880 ///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    881                                         TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
    882                                         assert( typeInst );
    883                                         std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    884                                         if ( assignIter == assignOps.end() ) {
    885                                                 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
    886                                         } // if
    887                                         ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    888                                         Expression *retParm = new NameExpr( retval->get_name() );
    889                                         retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    890                                         assignExpr->get_args().push_back( retParm );
    891                                         assignExpr->get_args().push_back( retStmt->get_expr() );
    892                                         stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    893                                 } else {
    894                                         useRetval = true;
    895                                         stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
    896                                         useRetval = false;
     872                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
     873                        if ( retval && returnStmt->get_expr() ) {
     874                                assert( ! returnStmt->get_expr()->get_results().empty() );
     875                                // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
     876                                // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     877                                // by this point, a cast expr on a polymorphic return value is redundant
     878                                while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
     879                                        returnStmt->set_expr( castExpr->get_arg() );
     880                                        returnStmt->get_expr()->set_env( castExpr->get_env() );
     881                                        castExpr->set_env( 0 );
     882                                        castExpr->set_arg( 0 );
     883                                        delete castExpr;
     884                                } //while
     885                                TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
     886                                assert( typeInst );
     887                                std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     888                                if ( assignIter == assignOps.end() ) {
     889                                        throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    897890                                } // if
    898                                 retStmt->set_expr( 0 );
     891                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     892                                Expression *retParm = new NameExpr( retval->get_name() );
     893                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     894                                assignExpr->get_args().push_back( retParm );
     895                                assignExpr->get_args().push_back( returnStmt->get_expr() );
     896                                stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
     897                                // } else {
     898                                //      useRetval = true;
     899                                //      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
     900                                //      useRetval = false;
     901                                // } // if
     902                                returnStmt->set_expr( 0 );
    899903                        } else {
    900                                 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    901                         } // if
    902                         return retStmt;
     904                                returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     905                        } // if
     906                        return returnStmt;
    903907                }
    904908
     
    906910                        TyVarMap oldtyVars = scopeTyVars;
    907911                        makeTyVarMap( pointerType, scopeTyVars );
    908  
     912
    909913                        Type *ret = Mutator::mutate( pointerType );
    910  
     914
    911915                        scopeTyVars = oldtyVars;
    912916                        return ret;
     
    916920                        TyVarMap oldtyVars = scopeTyVars;
    917921                        makeTyVarMap( functionType, scopeTyVars );
    918  
     922
    919923                        Type *ret = Mutator::mutate( functionType );
    920  
     924
    921925                        scopeTyVars = oldtyVars;
    922926                        return ret;
     
    933937
    934938////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    935 
    936                 Pass2::Pass2() {}
    937939
    938940                void Pass2::addAdapters( FunctionType *functionType ) {
     
    953955                                }
    954956                        }
    955 ///  deleteAll( functions );
     957//  deleteAll( functions );
    956958                }
    957959
     
    987989                        TyVarMap oldtyVars = scopeTyVars;
    988990                        makeTyVarMap( pointerType, scopeTyVars );
    989  
     991
    990992                        Type *ret = Mutator::mutate( pointerType );
    991  
     993
    992994                        scopeTyVars = oldtyVars;
    993995                        return ret;
     
    997999                        TyVarMap oldtyVars = scopeTyVars;
    9981000                        makeTyVarMap( funcType, scopeTyVars );
    999  
     1001
     1002                        // move polymorphic return type to parameter list
    10001003                        std::string typeName;
    10011004                        if ( isPolyRet( funcType, typeName ) ) {
     
    10051008                                funcType->get_returnVals().pop_front();
    10061009                        }
    1007  
     1010
     1011                        // add size/align and assertions for type parameters to parameter list
    10081012                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    10091013                        std::list< DeclarationWithType *> inferredParams;
    1010                         ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    1011 ///   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
     1014                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1015//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10121016                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    1013                                 ObjectDecl *thisParm;
    1014                                 // add all size parameters to parameter list
     1017                                ObjectDecl *sizeParm, *alignParm;
     1018                                // add all size and alignment parameters to parameter list
    10151019                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    1016                                         thisParm = newObj->clone();
    1017                                         thisParm->set_name( (*tyParm)->get_name() );
    1018                                         last = funcType->get_parameters().insert( last, thisParm );
     1020                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     1021
     1022                                        sizeParm = newObj.clone();
     1023                                        sizeParm->set_name( sizeofName( &parmType ) );
     1024                                        last = funcType->get_parameters().insert( last, sizeParm );
     1025                                        ++last;
     1026
     1027                                        alignParm = newObj.clone();
     1028                                        alignParm->set_name( alignofName( &parmType ) );
     1029                                        last = funcType->get_parameters().insert( last, alignParm );
    10191030                                        ++last;
    10201031                                }
    10211032                                // move all assertions into parameter list
    10221033                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1023 ///      *assert = (*assert)->acceptMutator( *this );
     1034//      *assert = (*assert)->acceptMutator( *this );
    10241035                                        inferredParams.push_back( *assert );
    10251036                                }
    10261037                                (*tyParm)->get_assertions().clear();
    10271038                        }
    1028                         delete newObj;
     1039
     1040                        // add size/align for generic types to parameter list
     1041                        std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1042                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     1043                                Type *parmType = (*fnParm)->get_type();
     1044                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
     1045                                        std::string sizeName = sizeofName( parmType );
     1046                                        if ( seenTypes.count( sizeName ) ) continue;
     1047
     1048                                        ObjectDecl *sizeParm, *alignParm;
     1049                                        sizeParm = newObj.clone();
     1050                                        sizeParm->set_name( sizeName );
     1051                                        last = funcType->get_parameters().insert( last, sizeParm );
     1052                                        ++last;
     1053
     1054                                        alignParm = newObj.clone();
     1055                                        alignParm->set_name( alignofName( parmType ) );
     1056                                        last = funcType->get_parameters().insert( last, alignParm );
     1057                                        ++last;
     1058
     1059                                        seenTypes.insert( sizeName );
     1060                                }
     1061                        }
     1062
     1063                        // splice assertion parameters into parameter list
    10291064                        funcType->get_parameters().splice( last, inferredParams );
    10301065                        addAdapters( funcType );
    10311066                        mutateAll( funcType->get_returnVals(), *this );
    10321067                        mutateAll( funcType->get_parameters(), *this );
    1033  
     1068
    10341069                        scopeTyVars = oldtyVars;
    10351070                        return funcType;
     
    10421077                        TyVarMap oldtyVars = scopeTyVars;
    10431078                        makeTyVarMap( type, scopeTyVars );
    1044  
     1079
    10451080                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    10461081                        ScrubTyVars::scrub( decl, scopeTyVars );
     
    10631098
    10641099                TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1065 ///   Initializer *init = 0;
    1066 ///   std::list< Expression *> designators;
    1067 ///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1068 ///   if ( typeDecl->get_base() ) {
    1069 ///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1070 ///   }
    1071 ///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
     1100//   Initializer *init = 0;
     1101//   std::list< Expression *> designators;
     1102//   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1103//   if ( typeDecl->get_base() ) {
     1104//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
     1105//   }
     1106//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    10721107
    10731108                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     
    10781113                        TyVarMap oldtyVars = scopeTyVars;
    10791114                        makeTyVarMap( pointerType, scopeTyVars );
    1080  
     1115
    10811116                        Type *ret = Mutator::mutate( pointerType );
    1082  
     1117
    10831118                        scopeTyVars = oldtyVars;
    10841119                        return ret;
     
    10881123                        TyVarMap oldtyVars = scopeTyVars;
    10891124                        makeTyVarMap( functionType, scopeTyVars );
    1090  
     1125
    10911126                        Type *ret = Mutator::mutate( functionType );
    1092  
     1127
    10931128                        scopeTyVars = oldtyVars;
    10941129                        return ret;
     
    10971132                Statement *Pass3::mutate( DeclStmt *declStmt ) {
    10981133                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1099                                 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
     1134                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    11001135                                        // change initialization of a polymorphic value object
    11011136                                        // to allocate storage with alloca
    1102                                         TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
    1103                                         assert( typeInst );
     1137                                        Type *declType = objectDecl->get_type();
    11041138                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1105                                         alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     1139                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    11061140
    11071141                                        delete objectDecl->get_init();
  • src/GenPoly/FindFunction.h

    r267cb3d r083cf31  
    2323        typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& );
    2424
     25        /// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions`
    2526        void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
     27        /// like `findFunction`, but also replaces the function type with void ()(void)
    2628        void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
    2729} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    r267cb3d r083cf31  
    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 Dec 15 16:11:18 2015
     13// Update Count     : 13
    1414//
    1515
    1616#include "GenPoly.h"
     17
     18#include "SymTab/Mangler.h"
     19#include "SynTree/Expression.h"
    1720#include "SynTree/Type.h"
    1821
     
    2124
    2225namespace GenPoly {
    23         // A function needs an adapter if it returns a polymorphic value or if any of its
    24         // parameters have polymorphic type
    2526        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    26                 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     27                if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    2728                        return true;
    2829                } // if
    2930                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                        if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
    3132                                return true;
    3233                        } // if
     
    6667        }
    6768
    68         bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
     69        namespace {
     70                /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
     71                bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     72                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     73                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     74                                assert(paramType && "Aggregate parameters should be type expressions");
     75                                if ( isPolyType( paramType->get_type(), env ) ) return true;
     76                        }
     77                        return false;
     78                }
     79
     80                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
     81                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     82                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     83                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     84                                assert(paramType && "Aggregate parameters should be type expressions");
     85                                if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
     86                        }
     87                        return false;
     88                }
     89        }
     90
     91        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
    6992                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     93                        if ( env ) {
     94                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     95                                        return isPolyType( newType, env );
     96                                } // if
     97                        } // if
     98                        return type;
     99                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     100                        if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
     101                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     102                        if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
     103                }
     104                return 0;
     105        }
     106       
     107        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     108                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     109                        if ( env ) {
     110                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     111                                        return isPolyType( newType, tyVars, env );
     112                                } // if
     113                        } // if
    70114                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    71                                 return true;
     115                                return type;
     116                        }
     117                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     118                        if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
     119                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     120                        if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
     121                }
     122                return 0;
     123        }
     124
     125        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
     126                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     127                        return isPolyType( ptr->get_base(), env );
     128                } else if ( env ) {
     129                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     130                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     131                                        return isPolyPtr( newType, env );
     132                                } // if
    72133                        } // if
    73134                } // if
    74                 return false;
     135                return 0;
     136        }
     137       
     138        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     139                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     140                        return isPolyType( ptr->get_base(), tyVars, env );
     141                } else if ( env ) {
     142                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     143                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     144                                        return isPolyPtr( newType, tyVars, env );
     145                                } // if
     146                        } // if
     147                } // if
     148                return 0;
    75149        }
    76150
    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 );
     151        FunctionType * getFunctionType( Type *ty ) {
     152                PointerType *ptrType;
     153                if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
     154                        return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
    82155                } else {
    83                         return false;
     156                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    84157                }
    85158        }
     
    91164                os << std::endl;
    92165        }
     166
     167        std::string sizeofName( Type *ty ) {
     168                return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
     169        }
     170
     171        std::string alignofName( Type *ty ) {
     172                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
     173        }
    93174} // namespace GenPoly
    94175
  • src/GenPoly/GenPoly.h

    r267cb3d r083cf31  
    2020#include <string>
    2121#include <iostream>
     22
    2223#include "SynTree/Declaration.h"
     24#include "SynTree/TypeSubstitution.h"
    2325
    2426namespace GenPoly {
    2527        typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
    2628
     29        /// A function needs an adapter if it returns a polymorphic value or if any of its
     30        /// parameters have polymorphic type
    2731        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
     32
     33        /// true iff function has polymorphic return type
    2834        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars );
    2935        bool isPolyRet( FunctionType *function, std::string &name );
    3036        bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars );
    31 //      bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
    32         bool isPolyVal( Type *type, const TyVarMap &tyVars );
    3337
    34   // true if type variable or any number of pointers to type variable
    35   bool isPolyObj( Type *type, const TyVarMap &tyVars );
     38        /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
     39        Type *isPolyType( Type *type, const TypeSubstitution *env = 0 );
     40       
     41        /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
     42        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     43
     44        /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
     45        Type *isPolyPtr( Type *type, const TypeSubstitution *env = 0 );
     46       
     47        /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
     48        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     49
     50        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
     51        FunctionType * getFunctionType( Type *ty );
     52
     53        /// Prints type variable map
    3654        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     55
     56        /// Gets the name of the sizeof parameter for the type
     57        std::string sizeofName( Type *ty );
     58
     59        /// Gets the name of the alignof parameter for the type
     60        std::string alignofName( Type *ty );
    3761} // namespace GenPoly
    3862
  • src/GenPoly/InstantiateGeneric.cc

    r267cb3d r083cf31  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGeneric.h --
     7// InstantiateGeneric.cc --
    88//
    99// Author           : Aaron B. Moss
     
    2121
    2222#include "InstantiateGeneric.h"
    23 #include "PolyMutator.h"
     23#include "DeclMutator.h"
    2424
    2525#include "ResolvExpr/typeops.h"
     
    4444                ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    4545
    46                 /// Extracts types from a list of Expression* (which should be TypeExpr*)
    47                 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
    48                         for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
    49                                 TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    50                                 assert(param && "Aggregate parameters should be type expressions");
    51                                 params.push_back( param->get_type()->clone() );
     46                /// Extracts types from a list of TypeExpr*
     47                ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
     48                        for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
     49                                params.push_back( (*param)->get_type()->clone() );
    5250                        }
    5351                }
     
    6664
    6765                bool operator== (const ConcreteType& that) const {
     66                        if ( base != that.base ) return false;
     67
    6868                        SymTab::Indexer dummy;
    69 
    70                         if ( base != that.base ) return false;
    7169                        if ( params.size() != that.params.size() ) return false;
    7270                        for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
     
    7977                std::list< Type* > params;  ///< Instantiation parameters
    8078        };
    81 
     79       
    8280        /// Maps a concrete type to the instantiated struct type, accounting for scope
    8381        class InstantiationMap {
    84                 /// Pair of concrete type and declaration that instantiates it
    85                 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
     82                /// Instantiation of a generic type, with key information to find it
     83                struct Instantiation {
     84                        ConcreteType key;     ///< Instantiation parameters for this type
     85                        AggregateDecl *decl;  ///< Declaration of the instantiated generic type
     86
     87                        Instantiation() : key(), decl(0) {}
     88                        Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {}
     89                };
    8690                /// Map of generic types to instantiations of them
    8791                typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     
    107111                /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    108112                /// Returns NULL on none such.
    109                 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
     113                AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
    110114                        ConcreteType key(generic, params);
    111115                        // scan scopes from innermost out
     
    116120                                // look through instantiations for matches to concrete type
    117121                                for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    118                                         if ( inst->first == key ) return inst->second;
     122                                        if ( inst->key == key ) return inst->decl;
    119123                                }
    120124                        }
     
    123127                }
    124128        public:
    125                 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
    126                 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
     129                StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
     130                UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
    127131
    128132        private:
    129133                /// Adds a declaration for a concrete type to the current scope
    130                 void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
     134                void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, AggregateDecl *decl ) {
    131135                        ConcreteType key(generic, params);
    132                         scopes.back()[generic].push_back( std::make_pair( key, decl ) );
     136                        scopes.back()[generic].push_back( Instantiation( key, decl ) );
    133137                }
    134138        public:
    135                 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
    136                 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
     139                void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
     140                void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    137141        };
    138142
    139143        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    140         class Instantiate : public PolyMutator {
     144        class Instantiate : public DeclMutator {
     145                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    141146                InstantiationMap instantiations;
     147                /// Namer for concrete types
    142148                UniqueName typeNamer;
    143149
    144150        public:
    145                 Instantiate() : instantiations(), typeNamer("_conc_") {}
    146 
    147                 /// Mutates the whole translation unit, inserting new struct declarations as appropriate
    148                 void mutateAll( std::list< Declaration* >& translationUnit );
    149                
     151                Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
     152
    150153                virtual Type* mutate( StructInstType *inst );
    151154                virtual Type* mutate( UnionInstType *inst );
     155
     156//              virtual Expression* mutate( MemberExpr *memberExpr );
    152157               
    153158                virtual void doBeginScope();
    154159                virtual void doEndScope();
    155 
    156         private:
    157                 /// Adds a declaration to the current environment and the statements to add
    158                 void addDeclaration( AggregateDecl *decl ) {
    159                         std::list< Label > nolabels;
    160                         DeclStmt *stmt = new DeclStmt( nolabels, decl );
    161                         PolyMutator::stmtsToAdd.push_back( stmt );
    162                 }
    163160        };
    164161       
    165162        void instantiateGeneric( std::list< Declaration* >& translationUnit ) {
    166163                Instantiate instantiator;
    167 //              mutateAll( translationUnit, instantiator );
    168                 instantiator.mutateAll( translationUnit );
    169         }
    170 
    171         void Instantiate::mutateAll( std::list< Declaration* >& translationUnit ) {
    172                 // below copied and modified from Mutator.h:mutateAll()
    173                 SemanticError errors;
    174                 for ( std::list< Declaration* >::iterator decl = translationUnit.begin(); decl != translationUnit.end(); ++decl ) {
    175                         try {
    176                                 if ( *decl ) {
    177                                         *decl = dynamic_cast< Declaration* >( (*decl)->acceptMutator( *this ) );
    178                                         assert( *decl );
    179                                         // account for missing top-level declarations
    180                                         for ( std::list< Statement* >::const_iterator stmt = PolyMutator::stmtsToAdd.begin(); stmt != PolyMutator::stmtsToAdd.end(); ++stmt ) {
    181                                                 DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *stmt );
    182                                                 assert( declStmt );
    183                                                 translationUnit.insert( decl, declStmt->get_decl() );
    184                                         }
    185                                         PolyMutator::stmtsToAdd.clear();
    186                                 } // if
    187                         } catch( SemanticError &e ) {
    188                                 errors.append( e );
    189                         } // try
    190                 } // for
    191                 if ( ! errors.isEmpty() ) {
    192                         throw errors;
    193                 } // if
    194         }
    195 
    196         /// Substitutes types of members of in according to baseParams => params, appending the result to out
    197         void substituteMembers( const std::list< Declaration* >& in,
    198                                                         const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
     164                instantiator.mutateDeclarationList( translationUnit );
     165        }
     166
     167        /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
     168        bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
     169                bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     170
     171                // substitute concrete types for given parameters, and incomplete types for placeholders
     172                std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     173                std::list< Expression* >::const_iterator param = params.begin();
     174                for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
     175//                      switch ( (*baseParam)->get_kind() ) {
     176//                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     177                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     178                                assert(paramType && "Aggregate parameters should be type expressions");
     179                                out.push_back( paramType->clone() );
     180                                // check that the substituted type isn't a type variable itself
     181                                if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
     182                                        allConcrete = false;
     183                                }
     184//                              break;
     185//                      }
     186//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     187//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     188//                              break;
     189//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     190//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     191//                              break;
     192//                      }
     193                }
     194
     195                // if any parameters left over, not done
     196                if ( baseParam != baseParams.end() ) return false;
     197//              // if not enough parameters given, substitute remaining incomplete types for placeholders
     198//              for ( ; baseParam != baseParams.end(); ++baseParam ) {
     199//                      switch ( (*baseParam)->get_kind() ) {
     200//                      case TypeDecl::Any:    // no more substitutions here, fail early
     201//                              return false;
     202//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     203//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     204//                              break;
     205//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     206//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     207//                              break;
     208//                      }
     209//              }
     210
     211                return allConcrete;
     212        }
     213
     214        /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
     215        void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    199216                                                    std::list< Declaration* >& out ) {
    200217                // substitute types into new members
    201                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
     218                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    202219                for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    203220                        Declaration *newMember = (*member)->clone();
     
    215232                // exit early if no need for further mutation
    216233                if ( inst->get_parameters().empty() ) return inst;
     234                assert( inst->get_baseParameters() && "Base struct has parameters" );
     235
     236                // check if type can be concretely instantiated; put substitutions into typeSubs
     237                std::list< TypeExpr* > typeSubs;
     238                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     239                        deleteAll( typeSubs );
     240                        return inst;
     241                }
    217242               
    218243                // make concrete instantiation of generic type
    219                 StructDecl *concDecl = instantiations.lookup( inst );
     244                StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
    220245                if ( ! concDecl ) {
    221                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    222246                        // set concDecl to new type, insert type declaration into statements to add
    223247                        concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    224                         substituteMembers( inst->get_baseStruct()->get_members(),
    225                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    226                                                                 concDecl->get_members() );
    227                         addDeclaration( concDecl );
    228                         instantiations.insert( inst, concDecl );
     248                        substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
     249                        DeclMutator::addDeclaration( concDecl );
     250                        instantiations.insert( inst, typeSubs, concDecl );
    229251                }
    230252                StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    231253                newInst->set_baseStruct( concDecl );
     254
     255                deleteAll( typeSubs );
    232256                delete inst;
    233257                return newInst;
     
    242266                // exit early if no need for further mutation
    243267                if ( inst->get_parameters().empty() ) return inst;
    244 
     268                assert( inst->get_baseParameters() && "Base union has parameters" );
     269
     270                // check if type can be concretely instantiated; put substitutions into typeSubs
     271                std::list< TypeExpr* > typeSubs;
     272                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     273                        deleteAll( typeSubs );
     274                        return inst;
     275                }
     276               
    245277                // make concrete instantiation of generic type
    246                 UnionDecl *concDecl = instantiations.lookup( inst );
     278                UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
    247279                if ( ! concDecl ) {
    248280                        // set concDecl to new type, insert type declaration into statements to add
    249                         assert( inst->get_baseParameters() && "Base union has parameters" );
    250281                        concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    251                         substituteMembers( inst->get_baseUnion()->get_members(),
    252                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    253                                                                 concDecl->get_members() );
    254                         addDeclaration( concDecl );
    255                         instantiations.insert( inst, concDecl );
     282                        substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
     283                        DeclMutator::addDeclaration( concDecl );
     284                        instantiations.insert( inst, typeSubs, concDecl );
    256285                }
    257286                UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    258287                newInst->set_baseUnion( concDecl );
     288
     289                deleteAll( typeSubs );
    259290                delete inst;
    260291                return newInst;
    261292        }
     293
     294//      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
     295//      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
     296//              // get variable for member aggregate
     297//              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
     298//              if ( ! varExpr ) return NULL;
     299//
     300//              // get object for variable
     301//              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     302//              if ( ! objectDecl ) return NULL;
     303//
     304//              // get base declaration from object type
     305//              Type *objectType = objectDecl->get_type();
     306//              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
     307//              if ( structType ) return structType->get_baseStruct();
     308//              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
     309//              if ( unionType ) return unionType->get_baseUnion();
     310//
     311//              return NULL;
     312//      }
     313//
     314//      /// Finds the declaration with the given name, returning decls.end() if none such
     315//      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
     316//              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     317//                      if ( (*decl)->get_name() == name ) return decl;
     318//              }
     319//              return decls.end();
     320//      }
     321//     
     322//      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
     323//              // mutate, exiting early if no longer MemberExpr
     324//              Expression *expr = Mutator::mutate( memberExpr );
     325//              memberExpr = dynamic_cast< MemberExpr* >( expr );
     326//              if ( ! memberExpr ) return expr;
     327//
     328//              // get declaration of member and base declaration of member, exiting early if not found
     329//              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
     330//              if ( ! memberBase ) return memberExpr;
     331//              DeclarationWithType *memberDecl = memberExpr->get_member();
     332//              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
     333//              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
     334//              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
     335//              if ( ! baseDecl ) return memberExpr;
     336//
     337//              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
     338//              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
     339//              SymTab::Indexer dummy;
     340//              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
     341//              else return new CastExpr( memberExpr, memberDecl->get_type() );
     342//      }
    262343       
    263344        void Instantiate::doBeginScope() {
    264                 // push a new concrete type scope
     345                DeclMutator::doBeginScope();
    265346                instantiations.beginScope();
    266347        }
    267348
    268349        void Instantiate::doEndScope() {
    269                 // pop the last concrete type scope
     350                DeclMutator::doEndScope();
    270351                instantiations.endScope();
    271352        }
  • src/GenPoly/Lvalue.cc

    r267cb3d r083cf31  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 07:41:33 2015
    13 // Update Count     : 1
     12// Last Modified On : Tue Dec 15 15:33:13 2015
     13// Update Count     : 3
    1414//
    1515
     
    3535                const std::list<Label> noLabels;
    3636
     37                /// Replace uses of lvalue returns with appropriate pointers
    3738                class Pass1 : public Mutator {
    3839                  public:
     
    4647                };
    4748
     49                /// Replace declarations of lvalue returns with appropriate pointers
    4850                class Pass2 : public Visitor {
    4951                  public:
     
    120122                        if ( retval && retStmt->get_expr() ) {
    121123                                assert( ! retStmt->get_expr()->get_results().empty() );
    122                                 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
    123                                         retStmt->set_expr( castExpr->get_arg() );
    124                                         retStmt->get_expr()->set_env( castExpr->get_env() );
    125                                         castExpr->set_env( 0 );
    126                                         castExpr->set_arg( 0 );
    127                                         delete castExpr;
    128                                 } // while
    129124                                if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     125                                        // ***** Code Removal ***** because casts may be stripped already
     126
     127                                        // strip casts because not allowed to take address of cast
     128                                        // while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
     129                                        //      retStmt->set_expr( castExpr->get_arg() );
     130                                        //      retStmt->get_expr()->set_env( castExpr->get_env() );
     131                                        //      castExpr->set_env( 0 );
     132                                        //      castExpr->set_arg( 0 );
     133                                        //      delete castExpr;
     134                                        // } // while
    130135                                        retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
    131136                                } else {
  • src/GenPoly/PolyMutator.h

    r267cb3d r083cf31  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Aug 14 15:27:38 2015
    13 // Update Count     : 4
     12// Last Modified On : Tue Dec 08 15:19:05 2015
     13// Update Count     : 5
    1414//
    1515
     
    5151                virtual void doBeginScope() {}
    5252                virtual void doEndScope() {}
     53               
     54                static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    5355          protected:
    5456                void mutateStatementList( std::list< Statement* > &statements );
    5557                Statement* mutateStatement( Statement *stmt );
    5658                Expression* mutateExpression( Expression *expr );
    57                 static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    5859 
    5960                TyVarMap scopeTyVars;
  • src/GenPoly/ScrubTyVars.cc

    r267cb3d r083cf31  
    1313// Update Count     : 2
    1414//
     15
     16#include <sstream>
     17#include <string>
    1518
    1619#include "GenPoly.h"
     
    4245
    4346        Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
    44                 // sizeof( T ) => T parameter, which is the size of T
    45                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
    46                         Expression *expr = new NameExpr( typeInst->get_name() );
     47                // sizeof( T ) => _sizeof_T parameter, which is the size of T
     48                if ( Type *polyType = isPolyType( szeof->get_type() ) ) {
     49                        Expression *expr = new NameExpr( sizeofName( polyType ) );
    4750                        return expr;
    4851                } else {
    4952                        return Mutator::mutate( szeof );
     53                } // if
     54        }
     55
     56        Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
     57                // alignof( T ) => _alignof_T parameter, which is the alignment of T
     58                if ( Type *polyType = isPolyType( algnof->get_type() ) ) {
     59                        Expression *expr = new NameExpr( alignofName( polyType ) );
     60                        return expr;
     61                } else {
     62                        return Mutator::mutate( algnof );
    5063                } // if
    5164        }
  • src/GenPoly/ScrubTyVars.h

    r267cb3d r083cf31  
    1717#define _SCRUBTYVARS_H
    1818
     19#include <string>
     20
    1921#include "GenPoly.h"
    2022
     
    2628          public:
    2729                ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
    28  
     30
     31                /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars`
    2932                template< typename SynTreeClass >
    3033                static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
     34                /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable
    3135                template< typename SynTreeClass >
    3236                static SynTreeClass *scrub( SynTreeClass *target );
     
    3438                virtual Type* mutate( TypeInstType *typeInst );
    3539                Expression* mutate( SizeofExpr *szeof );
     40                Expression* mutate( AlignofExpr *algnof );
    3641                virtual Type* mutate( PointerType *pointer );
    3742          private:
  • src/GenPoly/Specialize.cc

    r267cb3d r083cf31  
    1717
    1818#include "Specialize.h"
     19#include "GenPoly.h"
    1920#include "PolyMutator.h"
    2021
     
    8788        }
    8889
    89         /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    90         FunctionType * getFunctionType( Type *ty ) {
    91                 PointerType *ptrType;
    92                 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
    93                         return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
    94                 } else {
    95                         return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    96                 }
    97         }
    98 
    9990        /// Generates a thunk that calls `actual` with type `funType` and returns its address
    10091        Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
  • src/GenPoly/module.mk

    r267cb3d r083cf31  
    2323       GenPoly/CopyParams.cc \
    2424       GenPoly/FindFunction.cc \
    25        GenPoly/InstantiateGeneric.cc
     25       GenPoly/InstantiateGeneric.cc \
     26       GenPoly/DeclMutator.cc
  • src/InitTweak/InitModel.h

    r267cb3d r083cf31  
    7272                        void visit( ConstantExpr * );
    7373                        void visit( SizeofExpr * ) { throw 0; }
     74                        void visit( AlignofExpr * ) { throw 0; }
    7475                        void visit( AttrExpr * ) { throw 0; }
    7576                        void visit( LogicalExpr * ) { throw 0; }
  • src/InitTweak/RemoveInit.cc

    r267cb3d r083cf31  
    77// RemoveInit.cc --
    88//
    9 // Author           : Rodolfo G. Esteves
     9// Author           : Rob Schluntz
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 16:39:32 2015
    13 // Update Count     : 1
     12// Last Modified On : Tue Dec 15 15:37:26 2015
     13// Update Count     : 15
    1414//
    1515
     
    2626                const std::list<Label> noLabels;
    2727        }
     28       
     29        class RemoveInit : public Mutator {
     30          public:
     31                RemoveInit();
     32                virtual ObjectDecl * mutate(ObjectDecl *objDecl);
     33                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
     34
     35                virtual Statement * mutate( ReturnStmt * returnStmt );
     36               
     37                virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
     38               
     39          protected:
     40                std::list< Statement* > stmtsToAddBefore;
     41                std::list< Statement* > stmtsToAddAfter;
     42                void mutateStatementList( std::list< Statement* > &statements );
     43
     44                std::list<DeclarationWithType*> returnVals;
     45                UniqueName tempNamer;
     46                std::string funcName;
     47        };
    2848
    2949        void tweak( std::list< Declaration * > translationUnit ) {
     
    3252        }
    3353
     54        RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
     55       
    3456        void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
    3557                for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     
    3860                        } // if
    3961                        *i = (*i)->acceptMutator( *this );
     62                        if ( ! stmtsToAddBefore.empty() ) {
     63                                statements.splice( i, stmtsToAddBefore );
     64                        } // if
    4065                } // for
    4166                if ( ! stmtsToAddAfter.empty() ) {
     
    4974        }
    5075
    51 // in the case where an object has an initializer and a polymorphic type, insert an assignment
    52 // immediately after the declaration. This will (seemingly) cause the later phases to do the right
    53 // thing with the assignment
     76        // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
     77        // declaration. This will (seemingly) cause the later phases to do the right thing with the assignment
    5478        ObjectDecl *RemoveInit::mutate( ObjectDecl *objDecl ) {
    5579                if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
     
    6387                return objDecl;
    6488        }
     89
     90        Statement *RemoveInit::mutate( ReturnStmt *returnStmt ) {
     91                // update for multiple return values
     92                assert( returnVals.size() == 0 || returnVals.size() == 1 );
     93                // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
     94                // is being returned
     95                if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
     96                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
     97                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     98                       
     99                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     100                        assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
     101                        assign->get_args().push_back( returnStmt->get_expr() );
     102                        stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
     103
     104                        returnStmt->set_expr( new VariableExpr( newObj ) );
     105                } // if
     106                return returnStmt;
     107        }
     108
     109        DeclarationWithType* RemoveInit::mutate( FunctionDecl *functionDecl ) {
     110                std::list<DeclarationWithType*> oldReturnVals = returnVals;
     111                std::string oldFuncName = funcName;
     112               
     113                FunctionType * type = functionDecl->get_functionType();
     114                returnVals = type->get_returnVals();
     115                funcName = functionDecl->get_name();
     116                DeclarationWithType * decl = Mutator::mutate( functionDecl );
     117                returnVals = oldReturnVals;
     118                funcName = oldFuncName;
     119                return decl;
     120        }
    65121} // namespace InitTweak
    66122
  • src/InitTweak/RemoveInit.h

    r267cb3d r083cf31  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 16:40:11 2015
    13 // Update Count     : 1
     12// Last Modified On : Fri Nov 27 17:00:47 2015
     13// Update Count     : 2
    1414//
    1515
     
    2727        /// Adds assignment statements for polymorphic type initializers
    2828        void tweak( std::list< Declaration * > translationUnit );
    29 
    30         class RemoveInit : public Mutator {
    31           public:
    32                 // RemoveInit();
    33                 virtual ObjectDecl *mutate(ObjectDecl *objDecl);
    34                 virtual CompoundStmt *mutate(CompoundStmt *compoundStmt);
    35           protected:
    36                 std::list< Statement* > stmtsToAddAfter;
    37                 void mutateStatementList( std::list< Statement* > &statements );
    38         };
    3929} // namespace
    4030
  • src/Makefile.in

    r267cb3d r083cf31  
    122122        GenPoly/cfa_cpp-FindFunction.$(OBJEXT) \
    123123        GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT) \
     124        GenPoly/cfa_cpp-DeclMutator.$(OBJEXT) \
    124125        InitTweak/cfa_cpp-InitModel.$(OBJEXT) \
    125126        InitTweak/cfa_cpp-InitExpander.$(OBJEXT) \
     
    348349        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    349350        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 \
     351        GenPoly/InstantiateGeneric.cc GenPoly/DeclMutator.cc \
     352        InitTweak/InitModel.cc InitTweak/InitExpander.cc \
     353        InitTweak/Mutate.cc InitTweak/Association.cc \
     354        InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \
     355        Parser/TypedefTable.cc Parser/ParseNode.cc \
     356        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     357        Parser/StatementNode.cc Parser/InitializerNode.cc \
     358        Parser/TypeData.cc Parser/LinkageSpec.cc \
     359        Parser/parseutility.cc Parser/Parser.cc \
    358360        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    359361        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    411413          esac; \
    412414        done; \
    413         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
     415        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
    414416        $(am__cd) $(top_srcdir) && \
    415           $(AUTOMAKE) --gnu src/Makefile
     417          $(AUTOMAKE) --foreign src/Makefile
    416418.PRECIOUS: Makefile
    417419Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
     
    556558        GenPoly/$(DEPDIR)/$(am__dirstamp)
    557559GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT): GenPoly/$(am__dirstamp) \
     560        GenPoly/$(DEPDIR)/$(am__dirstamp)
     561GenPoly/cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
    558562        GenPoly/$(DEPDIR)/$(am__dirstamp)
    559563InitTweak/$(am__dirstamp):
     
    785789        -rm -f GenPoly/cfa_cpp-Box.$(OBJEXT)
    786790        -rm -f GenPoly/cfa_cpp-CopyParams.$(OBJEXT)
     791        -rm -f GenPoly/cfa_cpp-DeclMutator.$(OBJEXT)
    787792        -rm -f GenPoly/cfa_cpp-FindFunction.$(OBJEXT)
    788793        -rm -f GenPoly/cfa_cpp-GenPoly.$(OBJEXT)
     
    895900@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-Box.Po@am__quote@
    896901@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-CopyParams.Po@am__quote@
     902@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po@am__quote@
    897903@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-FindFunction.Po@am__quote@
    898904@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-GenPoly.Po@am__quote@
     
    13761382@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`
    13771383
     1384GenPoly/cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc
     1385@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo -c -o GenPoly/cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
     1386@am__fastdepCXX_TRUE@   $(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po
     1387@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='GenPoly/DeclMutator.cc' object='GenPoly/cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@
     1388@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1389@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
     1390
     1391GenPoly/cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc
     1392@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo -c -o GenPoly/cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
     1393@am__fastdepCXX_TRUE@   $(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po
     1394@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='GenPoly/DeclMutator.cc' object='GenPoly/cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@
     1395@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1396@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
     1397
    13781398InitTweak/cfa_cpp-InitModel.o: InitTweak/InitModel.cc
    13791399@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/ExpressionNode.cc

    r267cb3d r083cf31  
    586586                }
    587587          case OperatorNode::AlignOf:
     588                {
     589                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
     590                                return new AlignofExpr( arg->get_decl()->buildType());
     591                        } else {
     592                                return new AlignofExpr( args.front());
     593                        } // if
     594                }
    588595          case OperatorNode::SizeOf:
    589596                {
    590 ///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
    591 
    592597                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    593598                                return new SizeofExpr( arg->get_decl()->buildType());
  • src/ResolvExpr/AlternativeFinder.cc

    r267cb3d r083cf31  
    792792        }
    793793
     794        void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
     795                if ( alignofExpr->get_isType() ) {
     796                        alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
     797                } else {
     798                        // find all alternatives for the argument to sizeof
     799                        AlternativeFinder finder( indexer, env );
     800                        finder.find( alignofExpr->get_expr() );
     801                        // find the lowest cost alternative among the alternatives, otherwise ambiguous
     802                        AltList winners;
     803                        findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
     804                        if ( winners.size() != 1 ) {
     805                                throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() );
     806                        } // if
     807                        // return the lowest cost alternative for the argument
     808                        Alternative &choice = winners.front();
     809                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     810                } // if
     811        }
     812
    794813        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    795814                // assume no polymorphism
  • src/ResolvExpr/AlternativeFinder.h

    r267cb3d r083cf31  
    5656                virtual void visit( ConstantExpr *constantExpr );
    5757                virtual void visit( SizeofExpr *sizeofExpr );
     58                virtual void visit( AlignofExpr *sizeofExpr );
    5859                virtual void visit( AttrExpr *attrExpr );
    5960                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Indexer.cc

    r267cb3d r083cf31  
    215215                } else {
    216216                        maybeAccept( sizeofExpr->get_expr(), *this );
     217                }
     218        }
     219
     220        void Indexer::visit( AlignofExpr *alignofExpr ) {
     221                acceptAllNewScope( alignofExpr->get_results(), *this );
     222                if ( alignofExpr->get_isType() ) {
     223                        maybeAccept( alignofExpr->get_type(), *this );
     224                } else {
     225                        maybeAccept( alignofExpr->get_expr(), *this );
    217226                }
    218227        }
  • src/SymTab/Indexer.h

    r267cb3d r083cf31  
    5454                virtual void visit( ConstantExpr *constantExpr );
    5555                virtual void visit( SizeofExpr *sizeofExpr );
     56                virtual void visit( AlignofExpr *alignofExpr );
    5657                virtual void visit( AttrExpr *attrExpr );
    5758                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Mangler.cc

    r267cb3d r083cf31  
    3030
    3131namespace SymTab {
    32         Mangler::Mangler( bool mangleOverridable ) : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ) {
    33         }
    34 
    35 //Mangler::Mangler( const Mangler & )
    36 //  : mangleName(), varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( isTopLevel )
    37 //{
    38 //}
     32        std::string Mangler::mangleType( Type *ty ) {
     33                Mangler mangler( false, true );
     34                maybeAccept( ty, mangler );
     35                return mangler.get_mangleName();
     36        }
     37       
     38        Mangler::Mangler( bool mangleOverridable, bool typeMode )
     39                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {}
     40               
    3941        Mangler::Mangler( const Mangler &rhs ) : mangleName() {
    4042                varNums = rhs.varNums;
     
    4244                isTopLevel = rhs.isTopLevel;
    4345                mangleOverridable = rhs.mangleOverridable;
     46                typeMode = rhs.typeMode;
    4447        }
    4548
     
    152155        void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
    153156                printQualifiers( refType );
     157
    154158                mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
    155159        }
    156160
     161        void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
     162                printQualifiers( refType );
     163
     164                std::ostringstream oldName( mangleName.str() );
     165                mangleName.clear();
     166
     167                mangleName << prefix << refType->get_name();
     168
     169                std::list< Expression* >& params = refType->get_parameters();
     170                if ( ! params.empty() ) {
     171                        mangleName << "_";
     172                        for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
     173                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     174                                assert(paramType && "Aggregate parameters should be type expressions");
     175                                maybeAccept( paramType->get_type(), *this );
     176                        }
     177                        mangleName << "_";
     178                }
     179
     180                oldName << mangleName.str().length() << mangleName.str();
     181                mangleName.str( oldName.str() );
     182        }
     183
    157184        void Mangler::visit( StructInstType *aggregateUseType ) {
    158                 mangleRef( aggregateUseType, "s" );
     185                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
     186                else mangleRef( aggregateUseType, "s" );
    159187        }
    160188
    161189        void Mangler::visit( UnionInstType *aggregateUseType ) {
    162                 mangleRef( aggregateUseType, "u" );
     190                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
     191                else mangleRef( aggregateUseType, "u" );
    163192        }
    164193
     
    209238
    210239        void Mangler::printQualifiers( Type *type ) {
     240                // skip if not including qualifiers
     241                if ( typeMode ) return;
     242               
    211243                if ( ! type->get_forall().empty() ) {
    212244                        std::list< std::string > assertionNames;
     
    227259                                varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    228260                                for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    229                                         Mangler sub_mangler( mangleOverridable );
     261                                        Mangler sub_mangler( mangleOverridable, typeMode );
    230262                                        sub_mangler.nextVarNum = nextVarNum;
    231263                                        sub_mangler.isTopLevel = false;
  • src/SymTab/Mangler.h

    r267cb3d r083cf31  
    2222
    2323namespace SymTab {
     24        /// Mangles names to a unique C identifier
    2425        class Mangler : public Visitor {
    2526          public:
     27                /// Mangle syntax tree object; primary interface to clients
    2628                template< typename SynTreeClass >
    27             static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true ); // interface to clients
     29            static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true );
     30                /// Mangle a type name; secondary interface
     31                static std::string mangleType( Type* ty );
    2832
    29 ///   using Visitor::visit;
    3033                virtual void visit( ObjectDecl *declaration );
    3134                virtual void visit( FunctionDecl *declaration );
     
    4548                std::string get_mangleName() { return mangleName.str(); }
    4649          private:
    47                 std::ostringstream mangleName;
     50                std::ostringstream mangleName;  ///< Mangled name being constructed
    4851                typedef std::map< std::string, std::pair< int, int > > VarMapType;
    49                 VarMapType varNums;
    50                 int nextVarNum;
    51                 bool isTopLevel;
    52                 bool mangleOverridable;
     52                VarMapType varNums;             ///< Map of type variables to indices
     53                int nextVarNum;                 ///< Next type variable index
     54                bool isTopLevel;                ///< Is the Mangler at the top level
     55                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     56                bool typeMode;                  ///< Produce a unique mangled name for a type
    5357 
    54                 Mangler( bool mangleOverridable );
     58                Mangler( bool mangleOverridable, bool typeMode );
    5559                Mangler( const Mangler & );
    5660 
    5761                void mangleDecl( DeclarationWithType *declaration );
    5862                void mangleRef( ReferenceToType *refType, std::string prefix );
     63                void mangleGenericRef( ReferenceToType *refType, std::string prefix );
    5964 
    6065                void printQualifiers( Type *type );
     
    6368        template< typename SynTreeClass >
    6469        std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable ) {
    65                 Mangler mangler( mangleOverridable );
     70                Mangler mangler( mangleOverridable, false );
    6671                maybeAccept( decl, mangler );
    6772                return mangler.get_mangleName();
  • src/SymTab/Validate.cc

    r267cb3d r083cf31  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Dec 18 14:32:59 2015
    13 // Update Count     : 268
     12// Last Modified On : Thu Jan 07 11:27:49 2016
     13// Update Count     : 269
    1414//
    1515
     
    8686        };
    8787
    88         /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers
     88        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    8989        class Pass1 : public Visitor {
    9090                typedef Visitor Parent;
     
    161161        };
    162162
     163        class ReturnChecker : public Visitor {
     164          public:
     165                /// Checks that return statements return nothing if their return type is void
     166                /// and return something if the return type is non-void.
     167                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
     168
     169          private:
     170                virtual void visit( FunctionDecl * functionDecl );
     171
     172                virtual void visit( ReturnStmt * returnStmt );
     173
     174                std::list< DeclarationWithType * > returnVals;
     175        };
     176
    163177        class EliminateTypedef : public Mutator {
    164178          public:
    165           EliminateTypedef() : scopeLevel( 0 ) {}
    166             /// Replaces typedefs by forward declarations
     179                EliminateTypedef() : scopeLevel( 0 ) {}
     180                /// Replaces typedefs by forward declarations
    167181                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    168182          private:
     
    209223                acceptAll( translationUnit, pass1 );
    210224                acceptAll( translationUnit, pass2 );
     225                ReturnChecker::checkFunctionReturns( translationUnit );
    211226                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    212227                acceptAll( translationUnit, pass3 );
     
    850865        }
    851866
     867        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
     868                ReturnChecker checker;
     869                acceptAll( translationUnit, checker );
     870        }
     871
     872        void ReturnChecker::visit( FunctionDecl * functionDecl ) {
     873                std::list< DeclarationWithType * > oldReturnVals = returnVals;
     874                returnVals = functionDecl->get_functionType()->get_returnVals();
     875                Visitor::visit( functionDecl );
     876                returnVals = oldReturnVals;
     877        }
     878
     879        void ReturnChecker::visit( ReturnStmt * returnStmt ) {
     880                if ( returnStmt->get_expr() == NULL && returnVals.size() != 0 ) {
     881                        throw SemanticError( "Non-void function returns no values: " , returnStmt );
     882                } else if ( returnStmt->get_expr() != NULL && returnVals.size() == 0 ) {
     883                        throw SemanticError( "void function returns values: " , returnStmt );
     884                }
     885        }
     886
     887
    852888        bool isTypedef( Declaration *decl ) {
    853889                return dynamic_cast< TypedefDecl * >( decl );
  • src/SynTree/Declaration.cc

    r267cb3d r083cf31  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 13 17:58:38 2015
    13 // Update Count     : 10
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:08:29 2015
     13// Update Count     : 12
    1414//
    1515
     
    5555}
    5656
     57std::ostream & operator<<( std::ostream & out, Declaration * decl ) {
     58        decl->print( out );
     59        return out;
     60}
     61
     62
    5763// Local Variables: //
    5864// tab-width: 4 //
  • src/SynTree/Declaration.h

    r267cb3d r083cf31  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 13 18:15:59 2015
    13 // Update Count     : 28
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:08:22 2015
     13// Update Count     : 32
    1414//
    1515
     
    259259};
    260260
     261std::ostream & operator<<( std::ostream & out, Declaration * decl );
     262
    261263#endif // DECLARATION_H
    262264
  • src/SynTree/Expression.cc

    r267cb3d r083cf31  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Sep 02 12:07:10 2015
    13 // Update Count     : 33
     12// Last Modified On : Wed Dec 09 14:10:29 2015
     13// Update Count     : 34
    1414//
    1515
     
    122122void SizeofExpr::print( std::ostream &os, int indent) const {
    123123        os << std::string( indent, ' ' ) << "Sizeof Expression on: ";
     124
     125        if (isType)
     126                type->print(os, indent + 2);
     127        else
     128                expr->print(os, indent + 2);
     129
     130        os << std::endl;
     131        Expression::print( os, indent );
     132}
     133
     134AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
     135                Expression( _aname ), expr(expr_), type(0), isType(false) {
     136        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
     137}
     138
     139AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
     140                Expression( _aname ), expr(0), type(type_), isType(true) {
     141        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
     142}
     143
     144AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
     145        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
     146}
     147
     148AlignofExpr::~AlignofExpr() {
     149        delete expr;
     150        delete type;
     151}
     152
     153void AlignofExpr::print( std::ostream &os, int indent) const {
     154        os << std::string( indent, ' ' ) << "Alignof Expression on: ";
    124155
    125156        if (isType)
     
    345376}
    346377
     378std::ostream & operator<<( std::ostream & out, Expression * expr ) {
     379        expr->print( out );
     380        return out;
     381}
     382
    347383// Local Variables: //
    348384// tab-width: 4 //
  • src/SynTree/Expression.h

    r267cb3d r083cf31  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 24 13:49:28 2015
    13 // Update Count     : 18
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:10:21 2015
     13// Update Count     : 19
    1414//
    1515
     
    2323#include "Constant.h"
    2424
     25/// Expression is the root type for all expressions
    2526class Expression {
    2627  public:
     
    4748};
    4849
    49 // ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
    50 // but subject to decay-to-pointer and type parameter renaming
    51 
     50/// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
     51/// but subject to decay-to-pointer and type parameter renaming
    5252struct ParamEntry {
    5353        ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
     
    6565typedef std::map< UniqueId, ParamEntry > InferredParams;
    6666
    67 // ApplicationExpr represents the application of a function to a set of parameters.  This is the
    68 // result of running an UntypedExpr through the expression analyzer.
    69 
     67/// ApplicationExpr represents the application of a function to a set of parameters.  This is the
     68/// result of running an UntypedExpr through the expression analyzer.
    7069class ApplicationExpr : public Expression {
    7170  public:
     
    8988};
    9089
    91 // UntypedExpr represents the application of a function to a set of parameters, but where the
    92 // particular overload for the function name has not yet been determined.  Most operators are
    93 // converted into functional form automatically, to permit operator overloading.
    94 
     90/// UntypedExpr represents the application of a function to a set of parameters, but where the
     91/// particular overload for the function name has not yet been determined.  Most operators are
     92/// converted into functional form automatically, to permit operator overloading.
    9593class UntypedExpr : public Expression {
    9694  public:
     
    118116};
    119117
    120 // this class contains a name whose meaning is still not determined
     118/// NameExpr contains a name whose meaning is still not determined
    121119class NameExpr : public Expression {
    122120  public:
     
    139137// function-call format.
    140138
    141 // AddressExpr represents a address-of expression, e.g. &e
     139/// AddressExpr represents a address-of expression, e.g. &e
    142140class AddressExpr : public Expression {
    143141  public:
     
    174172};
    175173
    176 // CastExpr represents a type cast expression, e.g. (int)e
     174/// CastExpr represents a type cast expression, e.g. (int)e
    177175class CastExpr : public Expression {
    178176  public:
     
    193191};
    194192
    195 // UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
     193/// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
    196194class UntypedMemberExpr : public Expression {
    197195  public:
     
    214212};
    215213
    216 // MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
     214/// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
    217215class MemberExpr : public Expression {
    218216  public:
     
    235233};
    236234
    237 // VariableExpr represents an expression that simply refers to the value of a named variable
     235/// VariableExpr represents an expression that simply refers to the value of a named variable
    238236class VariableExpr : public Expression {
    239237  public:
     
    253251};
    254252
    255 // ConstantExpr represents an expression that simply refers to the value of a constant
     253/// ConstantExpr represents an expression that simply refers to the value of a constant
    256254class ConstantExpr : public Expression {
    257255  public:
     
    271269};
    272270
    273 // SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
     271/// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
    274272class SizeofExpr : public Expression {
    275273  public:
     
    296294};
    297295
    298 // AttrExpr represents an @attribute expression (like sizeof, but user-defined)
     296/// AlignofExpr represents an alignof expression
     297class AlignofExpr : public Expression {
     298  public:
     299        AlignofExpr( Expression *expr, Expression *_aname = 0 );
     300        AlignofExpr( const AlignofExpr &other );
     301        AlignofExpr( Type *type, Expression *_aname = 0 );
     302        virtual ~AlignofExpr();
     303
     304        Expression *get_expr() const { return expr; }
     305        void set_expr( Expression *newValue ) { expr = newValue; }
     306        Type *get_type() const { return type; }
     307        void set_type( Type *newValue ) { type = newValue; }
     308        bool get_isType() const { return isType; }
     309        void set_isType( bool newValue ) { isType = newValue; }
     310
     311        virtual AlignofExpr *clone() const { return new AlignofExpr( *this ); }
     312        virtual void accept( Visitor &v ) { v.visit( this ); }
     313        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     314        virtual void print( std::ostream &os, int indent = 0 ) const;
     315  private:
     316        Expression *expr;
     317        Type *type;
     318        bool isType;
     319};
     320
     321/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    299322class AttrExpr : public Expression {
    300323  public:
     
    324347};
    325348
    326 // LogicalExpr represents a short-circuit boolean expression (&& or ||)
     349/// LogicalExpr represents a short-circuit boolean expression (&& or ||)
    327350class LogicalExpr : public Expression {
    328351  public:
     
    347370};
    348371
    349 // ConditionalExpr represents the three-argument conditional ( p ? a : b )
     372/// ConditionalExpr represents the three-argument conditional ( p ? a : b )
    350373class ConditionalExpr : public Expression {
    351374  public:
     
    371394};
    372395
    373 // CommaExpr represents the sequence operator ( a, b )
     396/// CommaExpr represents the sequence operator ( a, b )
    374397class CommaExpr : public Expression {
    375398  public:
     
    392415};
    393416
    394 // TupleExpr represents a tuple expression ( [a, b, c] )
     417/// TupleExpr represents a tuple expression ( [a, b, c] )
    395418class TupleExpr : public Expression {
    396419  public:
     
    410433};
    411434
    412 // SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
     435/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
    413436class SolvedTupleExpr : public Expression {
    414437  public:
     
    428451};
    429452
    430 // TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
     453/// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
    431454class TypeExpr : public Expression {
    432455  public:
     
    446469};
    447470
    448 // AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
     471/// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
    449472class AsmExpr : public Expression {
    450473  public:
     
    472495};
    473496
    474 // ValofExpr represents a GCC 'lambda expression'
     497/// ValofExpr represents a GCC 'lambda expression'
    475498class UntypedValofExpr : public Expression {
    476499  public:
     
    488511        Statement *body;
    489512};
     513
     514std::ostream & operator<<( std::ostream & out, Expression * expr );
    490515
    491516#endif // EXPRESSION_H
  • src/SynTree/Mutator.cc

    r267cb3d r083cf31  
    251251}
    252252
     253Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
     254        mutateAll( alignofExpr->get_results(), *this );
     255        if ( alignofExpr->get_isType() ) {
     256                alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) );
     257        } else {
     258                alignofExpr->set_expr( maybeMutate( alignofExpr->get_expr(), *this ) );
     259        }
     260        return alignofExpr;
     261}
     262
    253263Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    254264        mutateAll( attrExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    r267cb3d r083cf31  
    6464        virtual Expression* mutate( ConstantExpr *constantExpr );
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
     66        virtual Expression* mutate( AlignofExpr *alignofExpr );
    6667        virtual Expression* mutate( AttrExpr *attrExpr );
    6768        virtual Expression* mutate( LogicalExpr *logicalExpr );
  • src/SynTree/PointerType.cc

    r267cb3d r083cf31  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:15:16 2015
    13 // Update Count     : 2
     12// Last Modified On : Tue Dec 15 15:39:10 2015
     13// Update Count     : 5
    1414//
    1515
     
    2020PointerType::PointerType( const Type::Qualifiers &tq, Type *base )
    2121        : Type( tq ), base( base ), dimension( 0 ), isVarLen( false ), isStatic( false ) {
    22         base->set_isLvalue( false );
    2322}
    2423
    2524PointerType::PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic )
    2625        : Type( tq ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) {
    27         base->set_isLvalue( false );
    2826}
    2927
  • src/SynTree/Statement.cc

    r267cb3d r083cf31  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 25 12:19:50 2015
    13 // Update Count     : 53
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:09:34 2015
     13// Update Count     : 54
    1414//
    1515
     
    337337}
    338338
     339std::ostream & operator<<( std::ostream & out, Statement * statement ) {
     340        statement->print( out );
     341        return out;
     342}
     343
    339344// Local Variables: //
    340345// tab-width: 4 //
  • src/SynTree/Statement.h

    r267cb3d r083cf31  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 25 18:25:37 2015
    13 // Update Count     : 44
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:09:24 2015
     13// Update Count     : 46
    1414//
    1515
     
    396396};
    397397
     398std::ostream & operator<<( std::ostream & out, Statement * statement );
     399
    398400#endif // STATEMENT_H
    399401
  • src/SynTree/SynTree.h

    r267cb3d r083cf31  
    6969class ConstantExpr;
    7070class SizeofExpr;
     71class AlignofExpr;
    7172class AttrExpr;
    7273class LogicalExpr;
  • src/SynTree/Type.cc

    r267cb3d r083cf31  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul  9 16:45:13 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:08:48 2015
     13// Update Count     : 4
    1414//
    1515
     
    8080}
    8181
     82std::ostream & operator<<( std::ostream & out, Type * type ) {
     83        type->print( out );
     84        return out;
     85}
     86
    8287// Local Variables: //
    8388// tab-width: 4 //
  • src/SynTree/Type.h

    r267cb3d r083cf31  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Type.h -- 
     7// Type.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 20 12:54:09 2015
    13 // Update Count     : 15
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri Dec 18 14:46:18 2015
     13// Update Count     : 18
    1414//
    1515
     
    2323class Type {
    2424  public:
    25         struct Qualifiers { 
     25        struct Qualifiers {
    2626                Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ), isAtomic( false ), isAttribute( false ) {}
    2727                Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic, bool isAttribute ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ), isAttribute( isAttribute ) {}
    28        
     28
    2929                Qualifiers &operator+=( const Qualifiers &other );
    3030                Qualifiers &operator-=( const Qualifiers &other );
     
    3636                bool operator<( const Qualifiers &other );
    3737                bool operator>( const Qualifiers &other );
    38        
     38
    3939                bool isConst;
    4040                bool isVolatile;
     
    4343                bool isAtomic;
    4444                bool isAttribute;
    45         };     
     45        };
    4646
    4747        Type( const Qualifiers &tq );
     
    8585class BasicType : public Type {
    8686  public:
    87         enum Kind { 
     87        enum Kind {
    8888                Bool,
    8989                Char,
     
    108108                LongDoubleImaginary,
    109109                NUMBER_OF_BASIC_TYPES
    110         }; 
     110        };
    111111
    112112        static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
     
    149149  private:
    150150        Type *base;
    151        
     151
    152152        // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
    153153        Expression *dimension;
     
    188188        virtual ~FunctionType();
    189189
    190         std::list<DeclarationWithType*>& get_returnVals() { return returnVals; }
    191         std::list<DeclarationWithType*>& get_parameters() { return parameters; }
     190        std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }
     191        std::list<DeclarationWithType*> & get_parameters() { return parameters; }
    192192        bool get_isVarArgs() { return isVarArgs; }
    193193        void set_isVarArgs( bool newValue ) { isVarArgs = newValue; }
     
    217217        void set_name( std::string newValue ) { name = newValue; }
    218218        std::list< Expression* >& get_parameters() { return parameters; }
    219        
     219
    220220        virtual ReferenceToType *clone() const = 0;
    221221        virtual void accept( Visitor &v ) = 0;
     
    240240        /// Accesses generic parameters of base struct (NULL if none such)
    241241        std::list<TypeDecl*> * get_baseParameters();
    242        
     242
    243243        /// Looks up the members of this struct named "name" and places them into "foundDecls".
    244244        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    250250  private:
    251251        virtual std::string typeString() const;
    252        
     252
    253253        // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
    254254        // where the structure used in this type is actually defined
     
    267267        /// Accesses generic parameters of base union (NULL if none such)
    268268        std::list<TypeDecl*> * get_baseParameters();
    269        
     269
    270270        /// looks up the members of this union named "name" and places them into "foundDecls"
    271271        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    277277  private:
    278278        virtual std::string typeString() const;
    279        
     279
    280280        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
    281281        // where the union used in this type is actually defined
     
    310310  private:
    311311        virtual std::string typeString() const;
    312        
     312
    313313        // this member is filled in by the validate pass, which instantiates the members of the correponding
    314314        // aggregate with the actual type parameters specified for this use of the context
     
    327327        bool get_isFtype() const { return isFtype; }
    328328        void set_isFtype( bool newValue ) { isFtype = newValue; }
    329        
     329
    330330        virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
    331331        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    463463}
    464464
     465std::ostream & operator<<( std::ostream & out, Type * type );
     466
    465467#endif // TYPE_H
    466468
  • src/SynTree/Visitor.cc

    r267cb3d r083cf31  
    210210}
    211211
     212void Visitor::visit( AlignofExpr *alignofExpr ) {
     213        acceptAll( alignofExpr->get_results(), *this );
     214        if ( alignofExpr->get_isType() ) {
     215                maybeAccept( alignofExpr->get_type(), *this );
     216        } else {
     217                maybeAccept( alignofExpr->get_expr(), *this );
     218        }
     219}
     220
    212221void Visitor::visit( AttrExpr *attrExpr ) {
    213222        acceptAll( attrExpr->get_results(), *this );
  • src/SynTree/Visitor.h

    r267cb3d r083cf31  
    6464        virtual void visit( ConstantExpr *constantExpr );
    6565        virtual void visit( SizeofExpr *sizeofExpr );
     66        virtual void visit( AlignofExpr *alignofExpr );
    6667        virtual void visit( AttrExpr *attrExpr );
    6768        virtual void visit( LogicalExpr *logicalExpr );
  • src/Tuples/FlattenTuple.cc

    r267cb3d r083cf31  
    4646        void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4747        void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     48        void FlattenTuple::CollectArgs::visit( AlignofExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4849        void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4950        void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

    r267cb3d r083cf31  
    4242                        virtual void visit( ConstantExpr * );
    4343                        virtual void visit( SizeofExpr * );
     44                        virtual void visit( AlignofExpr * );
    4445                        virtual void visit( AttrExpr * );
    4546                        virtual void visit( LogicalExpr * );
  • src/driver/Makefile.in

    r267cb3d r083cf31  
    195195          esac; \
    196196        done; \
    197         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/driver/Makefile'; \
     197        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/driver/Makefile'; \
    198198        $(am__cd) $(top_srcdir) && \
    199           $(AUTOMAKE) --gnu src/driver/Makefile
     199          $(AUTOMAKE) --foreign src/driver/Makefile
    200200.PRECIOUS: Makefile
    201201Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
  • src/examples/Makefile.in

    r267cb3d r083cf31  
    191191          esac; \
    192192        done; \
    193         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/examples/Makefile'; \
     193        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/examples/Makefile'; \
    194194        $(am__cd) $(top_srcdir) && \
    195           $(AUTOMAKE) --gnu src/examples/Makefile
     195          $(AUTOMAKE) --foreign src/examples/Makefile
    196196.PRECIOUS: Makefile
    197197Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
  • src/examples/fstream_test.c

    r267cb3d r083cf31  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 27 18:13:43 2015
    13 // Update Count     : 2
     12// Last Modified On : Mon Nov 23 14:43:32 2015
     13// Update Count     : 40
    1414//
    1515
     
    2020        ifstream *sin = ifstream_stdin();
    2121        int nombre;
    22         sout << "Appuyez un nombre, s'il vous plâit:\n";
    23         sin >> &nombre;
    24         sout << "Vous avez appuyé: " << nombre << "\n";
     22        sout | "Entrez un nombre, s'il vous plaît:\n";
     23        sin  | &nombre;
     24        sout | "Vous avez entré " | nombre | " stocké à l'adresse " | &nombre | endl;
     25        sout | "nombre " | nombre | " est "
     26                 | (nombre > 0 ? "plus grand que" :
     27                   nombre == 0 ? "égal à" : "moins de")
     28                 | " zéro" | endl;
     29
     30        sout | "Entrez trois nombres, s'il vous plaît:\n";
     31        int i, j, k;
     32        sin  | &i | &j | &k;
     33        sout | "Vous avez entré " | "i:" | i | " j:" | j | " k:" | k | endl;
     34
     35        sout | 3 | ' ' | 3.5 | ' ' | 'a' | ' ' | "abc" | endl;
    2536}
    2637
  • src/examples/hello.c

    r267cb3d r083cf31  
    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 : Sun Nov 22 17:40:37 2015
     13// Update Count     : 5
    1414//
    1515
     
    1919        ofstream *sout = ofstream_stdout();
    2020        ifstream *sin = ifstream_stdin();
    21         sout << "Bonjour au monde!\n";
    22         sout << 3 << " " << 3.5 << " " << 'a' << " " << "abc" << "\n";
    23         int i, j, k;
    24         sin >> &i >> &j >> &k;
    25         sout << "i:" << i << " j:" << j << " k:" << k << "\n";
     21        sout | "Bonjour au monde!\n";
    2622}
    2723
  • src/examples/iostream.c

    r267cb3d r083cf31  
    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 : Mon Dec  7 23:08:02 2015
     13// Update Count     : 24
    1414//
    1515
     
    2121
    2222forall( dtype ostype | ostream( ostype ) )
    23 ostype * ?<<?( ostype *os, char c ) {
     23ostype * ?|?( ostype *os, char c ) {
    2424        return write( os, &c, 1 );
    25 } // ?<<?
     25} // ?|?
    2626
    2727forall( dtype ostype | ostream( ostype ) )
    28 ostype * ?<<?( ostype *os, int i ) {
     28ostype * ?|?( ostype *os, int i ) {
    2929        char buffer[32];                                                                        // larger than the largest integer
    3030        sprintf( buffer, "%d", i );
    3131        return write( os, buffer, strlen( buffer ) );
    32 } // ?<<?
     32} // ?|?
    3333
    3434forall( dtype ostype | ostream( ostype ) )
    35 ostype * ?<<?( ostype *os, double d ) {
     35ostype * ?|?( ostype *os, double d ) {
    3636        char buffer[32];                                                                        // larger than the largest double
    3737        sprintf( buffer, "%g", d );
    3838        return write( os, buffer, strlen( buffer ) );
    39 } // ?<<?
     39} // ?|?
    4040
    4141forall( dtype ostype | ostream( ostype ) )
    42 ostype * ?<<?( ostype *os, const char *cp ) {
     42ostype * ?|?( ostype *os, const char *cp ) {
    4343        return write( os, cp, strlen( cp ) );
    44 } // ?<<?
     44} // ?|?
    4545
    4646forall( dtype ostype | ostream( ostype ) )
    47 ostype * ?<<?( ostype *os, const void *p ) {
     47ostype * ?|?( ostype *os, const void *p ) {
    4848        char buffer[32];                                                                        // larger than the largest pointer
    4949        sprintf( buffer, "%p", p );
    5050        return write( os, buffer, strlen( buffer ) );
    51 } // ?<<?
     51} // ?|?
     52
     53
     54forall( dtype ostype, dtype retostype | ostream( ostype ) | ostream( retostype ) )
     55retostype * ?|?( ostype *os, retostype * (*manip)(ostype*) ) {
     56  return manip(os);
     57}
     58
     59forall( dtype ostype | ostream( ostype ) )
     60ostype * endl( ostype * os ) {
     61  os | "\n";
     62  // flush
     63  return os;
     64} // endl
    5265
    5366forall( type elt_type | writeable( elt_type ),
     
    5669void write( iterator_type begin, iterator_type end, os_type *os ) {
    5770        void print( elt_type i ) {
    58                 os << i << ' ';
     71                os | i | ' ';
    5972        }
    6073        for_each( begin, end, print );
    61 } // ?<<?
     74} // ?|?
    6275
    6376forall( type elt_type | writeable( elt_type ),
     
    6578                dtype os_type | ostream( os_type ) )
    6679void write_reverse( iterator_type begin, iterator_type end, os_type *os ) {
    67         void print( elt_type i ) {
    68                 os << i << ' ';
    69         }
     80        void print( elt_type i ) { os | i | ' '; }
    7081        for_each_reverse( begin, end, print );
    71 } // ?<<?
     82} // ?|?
    7283
    7384
    7485forall( dtype istype | istream( istype ) )
    75 istype * ?>>?( istype *is, char *cp ) {
     86istype * ?|?( istype *is, char *cp ) {
    7687        return read( is, cp, 1 );
    77 } // ?>>?
     88} // ?|?
    7889
    7990forall( dtype istype | istream( istype ) )
    80 istype * ?>>?( istype *is, int *ip ) {
     91istype * ?|?( istype *is, int *ip ) {
    8192        char cur;
    8293 
    8394        // skip some whitespace
    8495        do {
    85                 is >> &cur;
     96                is | &cur;
    8697                if ( fail( is ) || eof( is ) ) return is;
    8798        } while ( !( cur >= '0' && cur <= '9' ) );
     
    91102        while ( cur >= '0' && cur <= '9' ) {
    92103                *ip = *ip * 10 + ( cur - '0' );
    93                 is >> &cur;
     104                is | &cur;
    94105                if ( fail( is ) || eof( is ) ) return is;
    95106        }
     
    97108        unread( is, cur );
    98109        return is;
    99 } // ?>>?
     110} // ?|?
    100111
    101112// Local Variables: //
  • src/examples/iostream.h

    r267cb3d r083cf31  
    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 : Mon Nov 23 14:15:25 2015
     13// Update Count     : 17
    1414//
    1515
     
    2727
    2828context writeable( type T ) {
    29         forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, T );
     29        forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T );
    3030};
    3131
    3232// implement writable for some intrinsic types
    3333
    34 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, char );
    35 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, int );
    36 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, double );
    37 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, const char * );
    38 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, void * );
     34forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, char );
     35forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, int );
     36forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, double );
     37forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char * );
     38forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const void * );
     39
     40forall( dtype ostype, dtype retostype | ostream( ostype ) | ostream( retostype ) ) retostype * ?|?( ostype *os, retostype * (* manip)(ostype*) );
     41forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * );
    3942
    4043// writes the range [begin, end) to the given stream
     
    4952void write_reverse( iterator_type begin, iterator_type end, os_type *os );
    5053
     54//******************************************************************************
    5155
    5256context istream( dtype istype ) {
     
    5862
    5963context readable( type T ) {
    60         forall( dtype istype | istream( istype ) ) istype * ?<<?( istype *, T );
     64        forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T );
    6165};
    6266
    6367forall( dtype istype | istream( istype ) )
    64 istype * ?>>?( istype *, char * );
     68istype * ?|?( istype *, char * );
    6569
    6670forall( dtype istype | istream( istype ) )
    67 istype * ?>>?( istype *, int * );
     71istype * ?|?( istype *, int * );
    6872
    6973#endif // IOSTREAM_H
  • src/examples/sum.c

    r267cb3d r083cf31  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 28 15:09:55 2015
    13 // Update Count     : 118
     12// Last Modified On : Sat Nov 21 18:08:18 2015
     13// Update Count     : 119
    1414//
    1515
     
    5353        }
    5454        sout << "sum from " << low << " to " << High << " is "
    55                  << (int)sum( size, a ) << ", check " << (int)s << "\n";
     55                 << (int)sum( size, a ) << ", check " << (int)s << endl;
    5656
    5757        int s = 0, a[size];
     
    6262        }
    6363        sout << "sum from " << low << " to " << High << " is "
    64                  << sum( size, (int *)a ) << ", check " << (int)s << "\n";
     64                 << sum( size, (int *)a ) << ", check " << (int)s << endl;
    6565
    6666        double s = 0.0, a[size];
     
    7272        printf( "%g\n", sum( size, (double *)a ) );
    7373//      sout << "sum from " << low / 10.0 << " to " << High / 10.0 << " is "
    74 //               << sum( size, (double *)a ) << ", check " << (double)s << "\n";
     74//               << sum( size, (double *)a ) << ", check " << (double)s << endl;
    7575
    7676        float s = 0.0, a[size];
     
    8282        printf( "%g\n", sum( size, (float *)a ) );
    8383//      sout << "sum from " << low / 10.0 << " to " << High / 10.0 << " is "
    84 //               << sum( size, (float *)a ) << ", check " << (float)s << "\n";
     84//               << sum( size, (float *)a ) << ", check " << (float)s << endl;
    8585}
    8686
  • src/examples/vector_test.c

    r267cb3d r083cf31  
    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 : Tue Dec 15 16:02:56 2015
     13// Update Count     : 13
    1414//
    1515
     
    2727        int num;
    2828
    29         sout << "enter N elements and C-d on a separate line:\n";
     29        sout | "enter N elements and C-d on a separate line:" | endl;
    3030        for ( ;; ) {
    31                 sin >> &num;
     31                sin | &num;
    3232          if ( fail( sin ) || eof( sin ) ) break;
    3333                append( &vec, num );
     
    3535        // write out the numbers
    3636
    37         sout << "Array elements:\n";
     37        sout | "Array elements:" | endl;
    3838        write( begin( vec ), end( vec ), sout );
    39         sout << "\n";
     39        sout | endl;
    4040
    41         sout << "Array elements reversed:\n";
     41        sout | "Array elements reversed:" | endl;
    4242        write_reverse( begin( vec ), end( vec ), sout );
    43         sout << "\n";
     43        sout | endl;
    4444}
    4545
  • src/libcfa/Makefile.am

    r267cb3d r083cf31  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Thu Jun  4 22:49:16 2015
    14 ## Update Count     : 7
     13## Last Modified On : Wed Dec 16 22:58:17 2015
     14## Update Count     : 9
    1515###############################################################################
    1616
     
    4444
    4545libcfa-prelude.c : ${srcdir}/prelude.cf
    46         ${libdir}/cfa-cpp -l ${srcdir}/prelude.cf $@
     46        ../cfa-cpp -l ${srcdir}/prelude.cf $@  # use src/cfa-cpp as not in lib until after install
    4747
    4848libcfa-prelude.o : libcfa-prelude.c
  • src/libcfa/Makefile.in

    r267cb3d r083cf31  
    220220          esac; \
    221221        done; \
    222         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcfa/Makefile'; \
     222        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libcfa/Makefile'; \
    223223        $(am__cd) $(top_srcdir) && \
    224           $(AUTOMAKE) --gnu src/libcfa/Makefile
     224          $(AUTOMAKE) --foreign src/libcfa/Makefile
    225225.PRECIOUS: Makefile
    226226Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
     
    542542
    543543libcfa-prelude.c : ${srcdir}/prelude.cf
    544         ${libdir}/cfa-cpp -l ${srcdir}/prelude.cf $@
     544        ../cfa-cpp -l ${srcdir}/prelude.cf $@  # use src/cfa-cpp as not in lib until after install
    545545
    546546libcfa-prelude.o : libcfa-prelude.c
  • src/main.cc

    r267cb3d r083cf31  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 19 22:31:40 2015
    13 // Update Count     : 168
     12// Last Modified On : Thu Dec 17 12:59:06 2015
     13// Update Count     : 179
    1414//
    1515
     
    187187                // read in the builtins and the prelude
    188188                if ( ! nopreludep ) {                                                   // include gcc builtins
    189                         FILE * builtins = fopen( CFA_LIBDIR "/builtins.cf", "r" );
     189                        // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here.
     190                        FILE * builtins = fopen( libcfap ? "./builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" );
    190191                        if ( builtins == NULL ) {
    191192                                std::cerr << "Error: can't open builtins" << std::endl;
     
    196197
    197198                        if ( ! libcfap ) {
    198                                 // read the prelude in, if we're not generating the cfa library
     199                                // read the prelude in, if not generating the cfa library
    199200                                FILE * prelude = fopen( CFA_LIBDIR "/prelude.cf", "r" );
    200201                                if ( prelude == NULL ) {
     
    203204                                } // if
    204205                   
    205                     parse( prelude, LinkageSpec::Intrinsic );
     206                                parse( prelude, LinkageSpec::Intrinsic );
    206207                        } // if
    207208                } // if
    208209
    209                 if ( libcfap ) {
    210                         parse( input, LinkageSpec::Intrinsic );
    211                 } else {
    212                         parse( input, LinkageSpec::Cforall, grammarp );
    213                 }
     210                parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );     
    214211 
    215212                if ( parsep ) {
Note: See TracChangeset for help on using the changeset viewer.