Changeset 579263a for src


Ignore:
Timestamp:
Jun 26, 2017, 4:48:35 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
bb1cd95
Parents:
e4d829b (diff), 2a7b3ca (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 branch 'master' into designations

Conflicts:

src/InitTweak/FixInit.cc
src/SymTab/Autogen.h
src/SynTree/Initializer.cc
src/SynTree/Initializer.h
src/Tuples/TupleExpansion.cc

Location:
src
Files:
13 added
1 deleted
74 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    re4d829b r579263a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed May 10 14:45:00 2017
    13 // Update Count     : 484
     12// Last Modified On : Thu Jun  8 16:00:00 2017
     13// Update Count     : 485
    1414//
    1515
     
    112112
    113113        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
    114 
    115         CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp )
    116                         : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) {
    117                 //output << std::string( init );
    118         }
    119 
    120         CodeGenerator::CodeGenerator( std::ostream & os, char * init, int indentation, bool infunp )
    121                         : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) {
    122                 //output << std::string( init );
    123         }
    124114
    125115        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
     
    932922        }
    933923
     924        void CodeGenerator::visit( ThrowStmt * throwStmt ) {
     925                assertf( ! genC, "Throw statements should not reach code generation." );
     926
     927                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
     928                           "throw" : "throwResume");
     929                if (throwStmt->get_expr()) {
     930                        output << " ";
     931                        throwStmt->get_expr()->accept( *this );
     932                }
     933                if (throwStmt->get_target()) {
     934                        output << " _At ";
     935                        throwStmt->get_target()->accept( *this );
     936                }
     937                output << ";";
     938        }
     939
    934940        void CodeGenerator::visit( WhileStmt * whileStmt ) {
    935941                if ( whileStmt->get_isDoWhile() ) {
  • src/CodeGen/CodeGenerator.h

    re4d829b r579263a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed May 10 10:57:00 2017
    13 // Update Count     : 51
     12// Last Modified On : Thu Jun  8 15:48:00 2017
     13// Update Count     : 52
    1414//
    1515
     
    9292                virtual void visit( BranchStmt * );
    9393                virtual void visit( ReturnStmt * );
     94                virtual void visit( ThrowStmt * );
    9495                virtual void visit( WhileStmt * );
    9596                virtual void visit( ForStmt * );
  • src/CodeGen/FixNames.cc

    re4d829b r579263a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 07:50:30 2017
    13 // Update Count     : 16
     12// Last Modified On : Wed Jun 21 14:22:59 2017
     13// Update Count     : 19
    1414//
    1515
     
    114114                                throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl);
    115115                        }
    116                         functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), "0") ) ) );
     116                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) );
    117117                        CodeGen::FixMain::registerMain( functionDecl );
    118118                }
  • src/Common/PassVisitor.h

    re4d829b r579263a  
    1212#include "SynTree/Expression.h"
    1313#include "SynTree/Constant.h"
     14#include "SynTree/TypeSubstitution.h"
    1415
    1516#include "PassVisitor.proto.h"
     
    1819// Templated visitor type
    1920// To use declare a PassVisitor< YOUR VISITOR TYPE >
    20 // The visitor type should specify the previsit/postvisit for types that are desired.
     21// The visitor type should specify the previsit/postvisit/premutate/postmutate for types that are desired.
     22// Note: previsit/postvisit/premutate/postmutate must be **public** members
     23//
     24// Several additional features are available through inheritance
     25// | WithTypeSubstitution - provides polymorphic TypeSubstitution * env for the current expression
     26// | WithStmtsToAdd       - provides the ability to insert statements before or after the current statement by adding new statements into
     27//                          stmtsToAddBefore or stmtsToAddAfter respectively.
     28// | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children
     29// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
     30//                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
    2131//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    2232template< typename pass_type >
    2333class PassVisitor final : public Visitor, public Mutator {
    2434public:
    25         PassVisitor() = default;
    2635
    2736        template< typename... Args >
    2837        PassVisitor(Args &&... args)
    2938                : pass( std::forward<Args>( args )... )
    30         {}
     39        {
     40                typedef PassVisitor<pass_type> this_t;
     41                this_t * const * visitor = visitor_impl(pass, 0);
     42                if(visitor) {
     43                        *const_cast<this_t **>( visitor ) = this;
     44                }
     45        }
    3146
    3247        virtual ~PassVisitor() = default;
     
    5469        virtual void visit( BranchStmt *branchStmt ) override final;
    5570        virtual void visit( ReturnStmt *returnStmt ) override final;
     71        virtual void visit( ThrowStmt *throwStmt ) override final;
    5672        virtual void visit( TryStmt *tryStmt ) override final;
    5773        virtual void visit( CatchStmt *catchStmt ) override final;
     
    85101        virtual void visit( ConstructorExpr * ctorExpr ) override final;
    86102        virtual void visit( CompoundLiteralExpr *compLitExpr ) override final;
    87         virtual void visit( UntypedValofExpr *valofExpr ) override final;
    88103        virtual void visit( RangeExpr *rangeExpr ) override final;
    89104        virtual void visit( UntypedTupleExpr *tupleExpr ) override final;
    90105        virtual void visit( TupleExpr *tupleExpr ) override final;
    91106        virtual void visit( TupleIndexExpr *tupleExpr ) override final;
    92         virtual void visit( MemberTupleExpr *tupleExpr ) override final;
    93107        virtual void visit( TupleAssignExpr *assignExpr ) override final;
    94108        virtual void visit( StmtExpr * stmtExpr ) override final;
     
    140154        virtual Statement* mutate( BranchStmt *branchStmt ) override final;
    141155        virtual Statement* mutate( ReturnStmt *returnStmt ) override final;
     156        virtual Statement* mutate( ThrowStmt *throwStmt ) override final;
    142157        virtual Statement* mutate( TryStmt *returnStmt ) override final;
    143158        virtual Statement* mutate( CatchStmt *catchStmt ) override final;
     
    171186        virtual Expression* mutate( ConstructorExpr *ctorExpr ) override final;
    172187        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr ) override final;
    173         virtual Expression* mutate( UntypedValofExpr *valofExpr ) override final;
    174188        virtual Expression* mutate( RangeExpr *rangeExpr ) override final;
    175189        virtual Expression* mutate( UntypedTupleExpr *tupleExpr ) override final;
    176190        virtual Expression* mutate( TupleExpr *tupleExpr ) override final;
    177191        virtual Expression* mutate( TupleIndexExpr *tupleExpr ) override final;
    178         virtual Expression* mutate( MemberTupleExpr *tupleExpr ) override final;
    179192        virtual Expression* mutate( TupleAssignExpr *assignExpr ) override final;
    180193        virtual Expression* mutate( StmtExpr * stmtExpr ) override final;
     
    207220
    208221private:
     222        template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
     223        template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
     224
    209225        template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
    210226        template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
     
    218234        void set_env( TypeSubstitution * env ) { set_env_impl( pass, env, 0); }
    219235
    220         void visitStatementList( std::list< Statement* > &statements );
     236        template< typename func_t >
     237        void handleStatementList( std::list< Statement * > & statements, func_t func );
     238        void visitStatementList ( std::list< Statement* > &statements );
    221239        void mutateStatementList( std::list< Statement* > &statements );
    222240
    223         Statement * visitStatement( Statement * stmt );
     241        template< typename func_t >
     242        Statement * handleStatement( Statement * stmt, func_t func );
     243        Statement * visitStatement ( Statement * stmt );
    224244        Statement * mutateStatement( Statement * stmt );
    225245
    226         void visitExpression( Expression * expr );
     246        template< typename func_t >
     247        Expression * handleExpression( Expression * expr, func_t func );
     248        Expression * visitExpression ( Expression * expr );
    227249        Expression * mutateExpression( Expression * expr );
    228250
     
    231253        std::list< Statement* > *       get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
    232254        std::list< Statement* > *       get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
    233         bool visit_children() { bool* skip = skip_children_impl(pass, 0); return ! (skip && *skip); }
     255        std::list< Declaration* > *     get_beforeDecls() { return declsToAddBefore_impl( pass, 0); }
     256        std::list< Declaration* > *     get_afterDecls () { return declsToAddAfter_impl ( pass, 0); }
     257
     258        void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); }
     259
     260        guard_value_impl init_guard() {
     261                guard_value_impl guard;
     262                auto at_cleanup = at_cleanup_impl(pass, 0);
     263                if( at_cleanup ) {
     264                        *at_cleanup = [&guard]( cleanup_func_t && func, void* val ) {
     265                                guard.push( std::move( func ), val );
     266                        };
     267                }
     268                return guard;
     269        }
     270};
     271
     272template<typename pass_type, typename T>
     273void GuardValue( pass_type * pass, T& val ) {
     274        pass->at_cleanup( [ val ]( void * newVal ) {
     275                * static_cast< T * >( newVal ) = val;
     276        }, static_cast< void * >( & val ) );
     277}
     278
     279class WithTypeSubstitution {
     280protected:
     281        WithTypeSubstitution() = default;
     282        ~WithTypeSubstitution() = default;
     283
     284public:
     285        TypeSubstitution * env = nullptr;
     286};
     287
     288class WithStmtsToAdd {
     289protected:
     290        WithStmtsToAdd() = default;
     291        ~WithStmtsToAdd() = default;
     292
     293public:
     294        std::list< Statement* > stmtsToAddBefore;
     295        std::list< Statement* > stmtsToAddAfter;
     296};
     297
     298class WithDeclsToAdd {
     299protected:
     300        WithDeclsToAdd() = default;
     301        ~WithDeclsToAdd() = default;
     302
     303public:
     304        std::list< Declaration* > declsToAddBefore;
     305        std::list< Declaration* > declsToAddAfter;
     306};
     307
     308class WithShortCircuiting {
     309protected:
     310        WithShortCircuiting() = default;
     311        ~WithShortCircuiting() = default;
     312
     313public:
     314        bool_ref visit_children;
     315};
     316
     317class WithGuards {
     318protected:
     319        WithGuards() = default;
     320        ~WithGuards() = default;
     321
     322public:
     323        at_cleanup_t at_cleanup;
     324
     325        template< typename T >
     326        void GuardValue( T& val ) {
     327                at_cleanup( [ val ]( void * newVal ) {
     328                        * static_cast< T * >( newVal ) = val;
     329                }, static_cast< void * >( & val ) );
     330        }
     331
     332        template< typename T >
     333        void GuardScope( T& val ) {
     334                val.beginScope();
     335                at_cleanup( []( void * val ) {
     336                        static_cast< T * >( val )->endScope();
     337                }, static_cast< void * >( & val ) );
     338        }
     339
     340        template< typename Func >
     341        void GuardAction( Func func ) {
     342                at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
     343        }
     344};
     345
     346template<typename pass_type>
     347class WithVisitorRef {
     348protected:
     349        WithVisitorRef() {}
     350        ~WithVisitorRef() {}
     351
     352public:
     353        PassVisitor<pass_type> * const visitor = nullptr;
    234354};
    235355
  • src/Common/PassVisitor.impl.h

    re4d829b r579263a  
    11#pragma once
    22
    3 #define VISIT_START( node )  \
    4         call_previsit( node ); \
    5         if( visit_children() ) { \
    6 
    7 #define VISIT_END( node )            \
    8         }                              \
    9         return call_postvisit( node ); \
    10 
    11 #define MUTATE_START( node )  \
    12         call_premutate( node ); \
    13         if( visit_children() ) { \
     3#define VISIT_START( node )                     \
     4        __attribute__((unused))                   \
     5        const auto & guard = init_guard();        \
     6        bool visit_children = true;               \
     7        set_visit_children( visit_children );   \
     8        call_previsit( node );                    \
     9        if( visit_children ) {                    \
     10
     11#define VISIT_END( node )                       \
     12        }                                         \
     13        call_postvisit( node );                   \
     14
     15#define MUTATE_START( node )                    \
     16        __attribute__((unused))                   \
     17        const auto & guard = init_guard();        \
     18        bool visit_children = true;               \
     19        set_visit_children( visit_children );   \
     20        call_premutate( node );                   \
     21        if( visit_children ) {                    \
    1422
    1523#define MUTATE_END( type, node )                \
     
    1826
    1927
    20 #define VISIT_BODY( node )    \
    21         VISIT_START( node );  \
    22         Visitor::visit( node ); \
    23         VISIT_END( node ); \
     28#define VISIT_BODY( node )        \
     29        VISIT_START( node );        \
     30        Visitor::visit( node );     \
     31        VISIT_END( node );          \
    2432
    2533
     
    3644}
    3745
    38 typedef std::list< Statement * > StmtList_t;
    39 
    40 template< typename pass_type >
    41 void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
     46typedef std::list< Statement   * > StmtList_t;
     47typedef std::list< Declaration * > DeclList_t;
     48
     49template<typename iterator_t>
     50static inline void splice( iterator_t it, DeclList_t * decls ) {
     51        std::transform(
     52                decls->begin(),
     53                decls->end(),
     54                it,
     55                [](Declaration * decl) -> auto {
     56                        return new DeclStmt( noLabels, decl );
     57                }
     58        );
     59        decls->clear();
     60}
     61
     62template< typename pass_type >
     63static inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
     64
     65        DeclList_t* beforeDecls = visitor.get_beforeDecls();
     66        DeclList_t* afterDecls  = visitor.get_afterDecls();
     67
     68        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
     69                // splice in new declarations after previous decl
     70                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
     71
     72                if ( i == decls.end() ) break;
     73
     74                // run mutator on declaration
     75                maybeAccept( *i, visitor );
     76
     77                // splice in new declarations before current decl
     78                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
     79        }
     80}
     81
     82template< typename pass_type >
     83static inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
     84
     85        DeclList_t* beforeDecls = mutator.get_beforeDecls();
     86        DeclList_t* afterDecls  = mutator.get_afterDecls();
     87
     88        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
     89                // splice in new declarations after previous decl
     90                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
     91
     92                if ( i == decls.end() ) break;
     93
     94                // run mutator on declaration
     95                *i = maybeMutate( *i, mutator );
     96
     97                // splice in new declarations before current decl
     98                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
     99        }
     100}
     101
     102template< typename pass_type >
     103template< typename func_t >
     104void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
    42105        SemanticError errors;
     106
     107        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     108        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
     109        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
     110        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
     111        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
    43112
    44113        StmtList_t* beforeStmts = get_beforeStmts();
    45114        StmtList_t* afterStmts  = get_afterStmts();
     115        DeclList_t* beforeDecls = get_beforeDecls();
     116        DeclList_t* afterDecls  = get_afterDecls();
    46117
    47118        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     119
     120                if ( !empty( afterDecls ) ) { splice( std::inserter( statements, i ), afterDecls ); }
    48121                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
     122
    49123                try {
    50                         (*i)->accept( *this );
     124                        func( *i );
     125                        assert(( empty( beforeStmts ) && empty( afterStmts ))
     126                            || ( empty( beforeDecls ) && empty( afterDecls )) );
     127
    51128                } catch ( SemanticError &e ) {
    52129                        errors.append( e );
    53130                }
     131
     132                if ( !empty( beforeDecls ) ) { splice( std::inserter( statements, i ), beforeDecls ); }
    54133                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    55134        }
    56135
     136        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
    57137        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
    58138        if ( !errors.isEmpty() ) { throw errors; }
     
    60140
    61141template< typename pass_type >
     142void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
     143        handleStatementList( statements, [this]( Statement * stmt) {
     144                stmt->accept( *this );
     145        });
     146}
     147
     148template< typename pass_type >
    62149void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    63         SemanticError errors;
     150        handleStatementList( statements, [this]( Statement *& stmt) {
     151                stmt = stmt->acceptMutator( *this );
     152        });
     153}
     154
     155
     156template< typename pass_type >
     157template< typename func_t >
     158Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
     159        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     160        ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
     161        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
     162        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
     163        ValueGuardPtr< StmtList_t >          oldBeforeStmts( get_beforeStmts() );
     164        ValueGuardPtr< StmtList_t >          oldAfterStmts ( get_afterStmts () );
     165
     166        Statement *newStmt = func( stmt );
    64167
    65168        StmtList_t* beforeStmts = get_beforeStmts();
    66169        StmtList_t* afterStmts  = get_afterStmts();
    67 
    68         for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    69                 if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
    70                 try {
    71                         *i = (*i)->acceptMutator( *this );
    72                 } catch ( SemanticError &e ) {
    73                         errors.append( e );
    74                 }
    75                 if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    76         }
    77 
    78         if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
    79         if ( !errors.isEmpty() ) { throw errors; }
    80 }
    81 
    82 template< typename pass_type >
    83 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
    84         // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    85         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
    86         ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    87         ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    88 
    89         maybeAccept( stmt, *this );
    90 
    91         StmtList_t* beforeStmts = get_beforeStmts();
    92         StmtList_t* afterStmts  = get_afterStmts();
    93 
    94         if( empty(beforeStmts) && empty(afterStmts) ) { return stmt; }
     170        DeclList_t* beforeDecls = get_beforeDecls();
     171        DeclList_t* afterDecls  = get_afterDecls();
     172
     173        if( empty(beforeStmts) && empty(afterStmts) && empty(beforeDecls) && empty(afterDecls) ) { return newStmt; }
     174        assert(( empty( beforeStmts ) && empty( afterStmts ))
     175            || ( empty( beforeDecls ) && empty( afterDecls )) );
    95176
    96177        CompoundStmt *compound = new CompoundStmt( noLabels );
     178        if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
    97179        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
    98         compound->get_kids().push_back( stmt );
     180        compound->get_kids().push_back( newStmt );
     181        if( !empty(afterDecls) ) { splice( std::back_inserter( compound->get_kids() ), afterDecls ); }
    99182        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
    100183        return compound;
     
    102185
    103186template< typename pass_type >
     187Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
     188        return handleStatement( stmt, [this]( Statement * stmt ) {
     189                maybeAccept( stmt, *this );
     190                return stmt;
     191        });
     192}
     193
     194template< typename pass_type >
    104195Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    105         // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    106         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
    107         ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    108         ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    109 
    110         Statement *newStmt = maybeMutate( stmt, *this );
    111 
    112         StmtList_t* beforeStmts = get_beforeStmts();
    113         StmtList_t* afterStmts  = get_afterStmts();
    114 
    115         if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; }
    116 
    117         CompoundStmt *compound = new CompoundStmt( noLabels );
    118         if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
    119         compound->get_kids().push_back( newStmt );
    120         if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
    121         return compound;
    122 }
    123 
    124 
    125 
    126 template< typename pass_type >
    127 void PassVisitor< pass_type >::visitExpression( Expression * expr ) {
    128         if( !expr ) return;
     196        return handleStatement( stmt, [this]( Statement * stmt ) {
     197                return maybeMutate( stmt, *this );
     198        });
     199}
     200
     201template< typename pass_type >
     202template< typename func_t >
     203Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
     204        if( !expr ) return nullptr;
    129205
    130206        auto env_ptr = get_env_ptr();
     
    132208                *env_ptr = expr->get_env();
    133209        }
    134         // xxx - should env be cloned (or moved) onto the result of the mutate?
    135         expr->accept( *this );
     210
     211        // should env be cloned (or moved) onto the result of the mutate?
     212        return func( expr );
     213}
     214
     215template< typename pass_type >
     216Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
     217        return handleExpression(expr, [this]( Expression * expr ) {
     218                expr->accept( *this );
     219                return expr;
     220        });
    136221}
    137222
    138223template< typename pass_type >
    139224Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
    140         if( !expr ) return nullptr;
    141 
    142         auto env_ptr = get_env_ptr();
    143         if ( env_ptr && expr->get_env() ) {
    144                 *env_ptr = expr->get_env();
    145         }
    146         // xxx - should env be cloned (or moved) onto the result of the mutate?
    147         return expr->acceptMutator( *this );
    148 }
    149 
     225        return handleExpression(expr, [this]( Expression * expr ) {
     226                return expr->acceptMutator( *this );
     227        });
     228}
    150229
    151230//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    153232template< typename pass_type >
    154233void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
    155         VISIT_BODY( node ); 
     234        VISIT_BODY( node );
    156235}
    157236
    158237template< typename pass_type >
    159238void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
    160         VISIT_BODY( node ); 
     239        VISIT_BODY( node );
    161240}
    162241
    163242template< typename pass_type >
    164243void PassVisitor< pass_type >::visit( StructDecl * node ) {
    165         VISIT_BODY( node ); 
     244        VISIT_BODY( node );
    166245}
    167246
    168247template< typename pass_type >
    169248void PassVisitor< pass_type >::visit( UnionDecl * node ) {
    170         VISIT_BODY( node ); 
     249        VISIT_BODY( node );
    171250}
    172251
    173252template< typename pass_type >
    174253void PassVisitor< pass_type >::visit( EnumDecl * node ) {
    175         VISIT_BODY( node ); 
     254        VISIT_BODY( node );
    176255}
    177256
    178257template< typename pass_type >
    179258void PassVisitor< pass_type >::visit( TraitDecl * node ) {
    180         VISIT_BODY( node ); 
     259        VISIT_BODY( node );
    181260}
    182261
    183262template< typename pass_type >
    184263void PassVisitor< pass_type >::visit( TypeDecl * node ) {
    185         VISIT_BODY( node ); 
     264        VISIT_BODY( node );
    186265}
    187266
    188267template< typename pass_type >
    189268void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
    190         VISIT_BODY( node ); 
     269        VISIT_BODY( node );
    191270}
    192271
    193272template< typename pass_type >
    194273void PassVisitor< pass_type >::visit( AsmDecl * node ) {
    195         VISIT_BODY( node ); 
     274        VISIT_BODY( node );
    196275}
    197276
     
    225304void PassVisitor< pass_type >::visit( ExprStmt * node ) {
    226305        VISIT_START( node );
    227         call_beginScope();
    228306
    229307        visitExpression( node->get_expr() );
    230308
    231         call_endScope();
    232309        VISIT_END( node );
    233310}
     
    242319}
    243320
     321//--------------------------------------------------------------------------
     322// AsmStmt
    244323template< typename pass_type >
    245324void PassVisitor< pass_type >::visit( AsmStmt * node ) {
    246         VISIT_BODY( node );
     325        VISIT_BODY( node );
     326}
     327
     328template< typename pass_type >
     329Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
     330        MUTATE_BODY( Statement, node );
    247331}
    248332
     
    251335template< typename pass_type >
    252336void PassVisitor< pass_type >::visit( IfStmt * node ) {
    253         VISIT_START( node ); 
     337        VISIT_START( node );
    254338
    255339        visitExpression( node->get_condition() );
     
    262346template< typename pass_type >
    263347Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    264         MUTATE_START( node ); 
     348        MUTATE_START( node );
    265349
    266350        node->set_condition( mutateExpression( node->get_condition() ) );
     
    275359template< typename pass_type >
    276360void PassVisitor< pass_type >::visit( WhileStmt * node ) {
    277         VISIT_START( node ); 
     361        VISIT_START( node );
    278362
    279363        visitExpression( node->get_condition() );
     
    285369template< typename pass_type >
    286370Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
    287         MUTATE_START( node ); 
     371        MUTATE_START( node );
    288372
    289373        node->set_condition( mutateExpression( node->get_condition() ) );
     
    294378
    295379//--------------------------------------------------------------------------
    296 // WhileStmt
     380// ForStmt
    297381template< typename pass_type >
    298382void PassVisitor< pass_type >::visit( ForStmt * node ) {
    299         VISIT_START( node ); 
     383        VISIT_START( node );
    300384
    301385        acceptAll( node->get_initialization(), *this );
     
    309393template< typename pass_type >
    310394Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    311         MUTATE_START( node ); 
     395        MUTATE_START( node );
    312396
    313397        mutateAll( node->get_initialization(), *this );
     
    323407template< typename pass_type >
    324408void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
    325         VISIT_START( node ); 
     409        VISIT_START( node );
    326410
    327411        visitExpression( node->get_condition() );
     
    333417template< typename pass_type >
    334418Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
    335         MUTATE_START( node ); 
    336        
     419        MUTATE_START( node );
     420
    337421        node->set_condition( mutateExpression( node->get_condition() ) );
    338422        mutateStatementList( node->get_statements() );
    339        
     423
    340424        MUTATE_END( Statement, node );
    341425}
    342426
    343427//--------------------------------------------------------------------------
    344 // SwitchStmt
     428// CaseStmt
    345429template< typename pass_type >
    346430void PassVisitor< pass_type >::visit( CaseStmt * node ) {
    347         VISIT_START( node ); 
    348        
     431        VISIT_START( node );
     432
    349433        visitExpression( node->get_condition() );
    350434        visitStatementList( node->get_statements() );
    351        
     435
    352436        VISIT_END( node );
    353437}
     
    355439template< typename pass_type >
    356440Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
    357         MUTATE_START( node ); 
    358        
     441        MUTATE_START( node );
     442
    359443        node->set_condition(  mutateExpression( node->get_condition() ) );
    360444        mutateStatementList( node->get_statements() );
    361        
     445
    362446        MUTATE_END( Statement, node );
    363447}
    364448
     449//--------------------------------------------------------------------------
     450// BranchStmt
    365451template< typename pass_type >
    366452void PassVisitor< pass_type >::visit( BranchStmt * node ) {
    367         VISIT_BODY( node );
     453        VISIT_BODY( node );
     454}
     455
     456template< typename pass_type >
     457Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
     458        MUTATE_BODY( Statement, node );
    368459}
    369460
     
    386477
    387478        MUTATE_END( Statement, node );
     479}
     480
     481//--------------------------------------------------------------------------
     482// ThrowStmt
     483
     484template< typename pass_type >
     485void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
     486        VISIT_BODY( node );
     487}
     488
     489template< typename pass_type >
     490Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
     491        MUTATE_BODY( Statement, node );
    388492}
    389493
     
    396500        maybeAccept( node->get_block(), *this );
    397501        acceptAll( node->get_catchers(), *this );
     502        maybeAccept( node->get_finally(), *this );
    398503
    399504        VISIT_END( node );
     
    406511        node->set_block(  maybeMutate( node->get_block(), *this ) );
    407512        mutateAll( node->get_catchers(), *this );
    408        
     513        node->set_finally( maybeMutate( node->get_finally(), *this ) );
     514
    409515        MUTATE_END( Statement, node );
    410516}
     
    416522        VISIT_START( node );
    417523
     524        maybeAccept( node->get_decl(), *this );
     525        node->set_cond( visitExpression( node->get_cond() ) );
    418526        node->set_body( visitStatement( node->get_body() ) );
    419         maybeAccept( node->get_decl(), *this );
    420527
    421528        VISIT_END( node );
     
    425532Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    426533        MUTATE_START( node );
    427        
    428         node->set_body(  mutateStatement( node->get_body() ) );
    429         node->set_decl(  maybeMutate( node->get_decl(), *this ) );
    430        
     534
     535        node->set_decl( maybeMutate( node->get_decl(), *this ) );
     536        node->set_cond( mutateExpression( node->get_cond() ) );
     537        node->set_body( mutateStatement( node->get_body() ) );
     538
    431539        MUTATE_END( Statement, node );
    432540}
     
    434542template< typename pass_type >
    435543void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
    436         VISIT_BODY( node ); 
     544        VISIT_BODY( node );
    437545}
    438546
    439547template< typename pass_type >
    440548void PassVisitor< pass_type >::visit( NullStmt * node ) {
    441         VISIT_BODY( node ); 
     549        VISIT_BODY( node );
    442550}
    443551
    444552template< typename pass_type >
    445553void PassVisitor< pass_type >::visit( DeclStmt * node ) {
    446         VISIT_BODY( node ); 
     554        VISIT_BODY( node );
    447555}
    448556
    449557template< typename pass_type >
    450558void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
    451         VISIT_BODY( node ); 
     559        VISIT_BODY( node );
    452560}
    453561
    454562template< typename pass_type >
    455563void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
    456         VISIT_BODY( node ); 
     564        VISIT_BODY( node );
    457565}
    458566
     
    462570void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
    463571        VISIT_START( node );
     572
     573        // maybeAccept( node->get_env(), *this );
     574        maybeAccept( node->get_result(), *this );
    464575
    465576        for ( auto expr : node->get_args() ) {
     
    474585        MUTATE_START( node );
    475586
     587        node->set_env( maybeMutate( node->get_env(), *this ) );
     588        node->set_result( maybeMutate( node->get_result(), *this ) );
     589
    476590        for ( auto& expr : node->get_args() ) {
    477591                expr = mutateExpression( expr );
     
    483597template< typename pass_type >
    484598void PassVisitor< pass_type >::visit( NameExpr * node ) {
    485         VISIT_BODY( node ); 
     599        VISIT_BODY( node );
    486600}
    487601
    488602template< typename pass_type >
    489603void PassVisitor< pass_type >::visit( CastExpr * node ) {
    490         VISIT_BODY( node ); 
     604        VISIT_BODY( node );
    491605}
    492606
    493607template< typename pass_type >
    494608void PassVisitor< pass_type >::visit( AddressExpr * node ) {
    495         VISIT_BODY( node ); 
     609        VISIT_BODY( node );
    496610}
    497611
    498612template< typename pass_type >
    499613void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
    500         VISIT_BODY( node ); 
     614        VISIT_BODY( node );
    501615}
    502616
    503617template< typename pass_type >
    504618void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
    505         VISIT_BODY( node ); 
     619        VISIT_BODY( node );
    506620}
    507621
    508622template< typename pass_type >
    509623void PassVisitor< pass_type >::visit( MemberExpr * node ) {
    510         VISIT_BODY( node ); 
     624        VISIT_BODY( node );
    511625}
    512626
    513627template< typename pass_type >
    514628void PassVisitor< pass_type >::visit( VariableExpr * node ) {
    515         VISIT_BODY( node ); 
     629        VISIT_BODY( node );
    516630}
    517631
    518632template< typename pass_type >
    519633void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
    520         VISIT_BODY( node ); 
     634        VISIT_BODY( node );
    521635}
    522636
    523637template< typename pass_type >
    524638void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
    525         VISIT_BODY( node ); 
     639        VISIT_BODY( node );
    526640}
    527641
    528642template< typename pass_type >
    529643void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
    530         VISIT_BODY( node ); 
     644        VISIT_BODY( node );
    531645}
    532646
    533647template< typename pass_type >
    534648void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
    535         VISIT_BODY( node ); 
     649        VISIT_BODY( node );
    536650}
    537651
    538652template< typename pass_type >
    539653void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
    540         VISIT_BODY( node ); 
     654        VISIT_BODY( node );
    541655}
    542656
    543657template< typename pass_type >
    544658void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
    545         VISIT_BODY( node ); 
     659        VISIT_BODY( node );
    546660}
    547661
    548662template< typename pass_type >
    549663void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    550         VISIT_BODY( node ); 
     664        VISIT_BODY( node );
    551665}
    552666
    553667template< typename pass_type >
    554668void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
    555         VISIT_BODY( node ); 
     669        VISIT_BODY( node );
    556670}
    557671
    558672template< typename pass_type >
    559673void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
    560         VISIT_BODY( node ); 
     674        VISIT_BODY( node );
    561675}
    562676
    563677template< typename pass_type >
    564678void PassVisitor< pass_type >::visit( CommaExpr * node ) {
    565         VISIT_BODY( node ); 
     679        VISIT_BODY( node );
    566680}
    567681
    568682template< typename pass_type >
    569683void PassVisitor< pass_type >::visit( TypeExpr * node ) {
    570         VISIT_BODY( node ); 
     684        VISIT_BODY( node );
    571685}
    572686
    573687template< typename pass_type >
    574688void PassVisitor< pass_type >::visit( AsmExpr * node ) {
    575         VISIT_BODY( node ); 
     689        VISIT_BODY( node );
    576690}
    577691
    578692template< typename pass_type >
    579693void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
    580         VISIT_BODY( node ); 
     694        VISIT_BODY( node );
    581695}
    582696
    583697template< typename pass_type >
    584698void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
    585         VISIT_BODY( node ); 
     699        VISIT_BODY( node );
    586700}
    587701
    588702template< typename pass_type >
    589703void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
    590         VISIT_BODY( node );
    591 }
    592 
    593 template< typename pass_type >
    594 void PassVisitor< pass_type >::visit( UntypedValofExpr * node ) {
    595         VISIT_BODY( node );
     704        VISIT_BODY( node );
    596705}
    597706
    598707template< typename pass_type >
    599708void PassVisitor< pass_type >::visit( RangeExpr * node ) {
    600         VISIT_BODY( node ); 
     709        VISIT_BODY( node );
    601710}
    602711
    603712template< typename pass_type >
    604713void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
    605         VISIT_BODY( node ); 
     714        VISIT_BODY( node );
    606715}
    607716
    608717template< typename pass_type >
    609718void PassVisitor< pass_type >::visit( TupleExpr * node ) {
    610         VISIT_BODY( node ); 
     719        VISIT_BODY( node );
    611720}
    612721
    613722template< typename pass_type >
    614723void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
    615         VISIT_BODY( node );
    616 }
    617 
    618 template< typename pass_type >
    619 void PassVisitor< pass_type >::visit( MemberTupleExpr * node ) {
    620         VISIT_BODY( node );
     724        VISIT_BODY( node );
    621725}
    622726
    623727template< typename pass_type >
    624728void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
    625         VISIT_BODY( node ); 
     729        VISIT_BODY( node );
    626730}
    627731
     
    645749Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
    646750        MUTATE_START( node );
    647        
     751
    648752        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    649753        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     
    658762template< typename pass_type >
    659763void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
    660         VISIT_BODY( node ); 
     764        VISIT_BODY( node );
    661765}
    662766
    663767template< typename pass_type >
    664768void PassVisitor< pass_type >::visit( VoidType * node ) {
    665         VISIT_BODY( node ); 
     769        VISIT_BODY( node );
    666770}
    667771
    668772template< typename pass_type >
    669773void PassVisitor< pass_type >::visit( BasicType * node ) {
    670         VISIT_BODY( node ); 
     774        VISIT_BODY( node );
    671775}
    672776
    673777template< typename pass_type >
    674778void PassVisitor< pass_type >::visit( PointerType * node ) {
    675         VISIT_BODY( node ); 
     779        VISIT_BODY( node );
    676780}
    677781
    678782template< typename pass_type >
    679783void PassVisitor< pass_type >::visit( ArrayType * node ) {
    680         VISIT_BODY( node ); 
     784        VISIT_BODY( node );
    681785}
    682786
    683787template< typename pass_type >
    684788void PassVisitor< pass_type >::visit( FunctionType * node ) {
    685         VISIT_BODY( node ); 
     789        VISIT_BODY( node );
    686790}
    687791
    688792template< typename pass_type >
    689793void PassVisitor< pass_type >::visit( StructInstType * node ) {
    690         VISIT_BODY( node ); 
     794        VISIT_BODY( node );
    691795}
    692796
    693797template< typename pass_type >
    694798void PassVisitor< pass_type >::visit( UnionInstType * node ) {
    695         VISIT_BODY( node ); 
     799        VISIT_BODY( node );
    696800}
    697801
    698802template< typename pass_type >
    699803void PassVisitor< pass_type >::visit( EnumInstType * node ) {
    700         VISIT_BODY( node ); 
     804        VISIT_BODY( node );
    701805}
    702806
    703807template< typename pass_type >
    704808void PassVisitor< pass_type >::visit( TraitInstType * node ) {
    705         VISIT_BODY( node ); 
     809        VISIT_BODY( node );
    706810}
    707811
    708812template< typename pass_type >
    709813void PassVisitor< pass_type >::visit( TypeInstType * node ) {
    710         VISIT_BODY( node ); 
     814        VISIT_BODY( node );
    711815}
    712816
    713817template< typename pass_type >
    714818void PassVisitor< pass_type >::visit( TupleType * node ) {
    715         VISIT_BODY( node ); 
     819        VISIT_BODY( node );
    716820}
    717821
    718822template< typename pass_type >
    719823void PassVisitor< pass_type >::visit( TypeofType * node ) {
    720         VISIT_BODY( node ); 
     824        VISIT_BODY( node );
    721825}
    722826
    723827template< typename pass_type >
    724828void PassVisitor< pass_type >::visit( AttrType * node ) {
    725         VISIT_BODY( node ); 
     829        VISIT_BODY( node );
    726830}
    727831
    728832template< typename pass_type >
    729833void PassVisitor< pass_type >::visit( VarArgsType * node ) {
    730         VISIT_BODY( node ); 
     834        VISIT_BODY( node );
    731835}
    732836
    733837template< typename pass_type >
    734838void PassVisitor< pass_type >::visit( ZeroType * node ) {
    735         VISIT_BODY( node ); 
     839        VISIT_BODY( node );
    736840}
    737841
    738842template< typename pass_type >
    739843void PassVisitor< pass_type >::visit( OneType * node ) {
    740         VISIT_BODY( node ); 
     844        VISIT_BODY( node );
    741845}
    742846
     
    763867template< typename pass_type >
    764868void PassVisitor< pass_type >::visit( ListInit * node ) {
    765         VISIT_BODY( node ); 
     869        VISIT_BODY( node );
    766870}
    767871
    768872template< typename pass_type >
    769873void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
    770         VISIT_BODY( node ); 
     874        VISIT_BODY( node );
    771875}
    772876
    773877template< typename pass_type >
    774878void PassVisitor< pass_type >::visit( Subrange * node ) {
    775         VISIT_BODY( node ); 
     879        VISIT_BODY( node );
    776880}
    777881
    778882template< typename pass_type >
    779883void PassVisitor< pass_type >::visit( Constant * node ) {
    780         VISIT_BODY( node ); 
     884        VISIT_BODY( node );
    781885}
    782886
     
    829933
    830934template< typename pass_type >
    831 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    832         MUTATE_BODY( Statement, node );
    833 }
    834 
    835 template< typename pass_type >
    836 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
    837         MUTATE_BODY( Statement, node );
    838 }
    839 
    840 template< typename pass_type >
    841935Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    842936        MUTATE_BODY( Statement, node );
     
    9741068
    9751069template< typename pass_type >
    976 Expression * PassVisitor< pass_type >::mutate( UntypedValofExpr * node ) {
    977         MUTATE_BODY( Expression, node );
    978 }
    979 
    980 template< typename pass_type >
    9811070Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
    9821071        MUTATE_BODY( Expression, node );
     
    9951084template< typename pass_type >
    9961085Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
    997         MUTATE_BODY( Expression, node );
    998 }
    999 
    1000 template< typename pass_type >
    1001 Expression * PassVisitor< pass_type >::mutate( MemberTupleExpr * node ) {
    10021086        MUTATE_BODY( Expression, node );
    10031087}
  • src/Common/PassVisitor.proto.h

    re4d829b r579263a  
    11#pragma once
     2
     3template<typename pass_type>
     4class PassVisitor;
     5
     6typedef std::function<void( void * )> cleanup_func_t;
     7
     8class guard_value_impl {
     9public:
     10        guard_value_impl() = default;
     11
     12        ~guard_value_impl() {
     13                while( !cleanups.empty() ) {
     14                        auto& cleanup = cleanups.top();
     15                        cleanup.func( cleanup.val );
     16                        cleanups.pop();
     17                }
     18        }
     19
     20        void push( cleanup_func_t && func, void* val ) {
     21                cleanups.emplace( std::move(func), val );
     22        }
     23
     24private:
     25        struct cleanup_t {
     26                cleanup_func_t func;
     27                void * val;
     28
     29                cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {}
     30        };
     31
     32        std::stack< cleanup_t > cleanups;
     33};
     34
     35typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
     36
     37class bool_ref {
     38public:
     39        bool_ref() = default;
     40        ~bool_ref() = default;
     41
     42        operator bool() { return *m_ref; }
     43        bool operator=( bool val ) { return *m_ref = val; }
     44
     45private:
     46
     47        template<typename pass>
     48        friend class PassVisitor;
     49
     50        void set( bool & val ) { m_ref = &val; };
     51
     52        bool * m_ref;
     53};
    254
    355//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    456// Deep magic (a.k.a template meta programming) to make the templated visitor work
    557// Basically the goal is to make 2 previsit_impl
    6 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
     58// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    759//     'pass.previsit( node )' that compiles will be used for that node for that type
    860//     This requires that this option only compile for passes that actually define an appropriate visit.
     
    1870// Visit
    1971template<typename pass_type, typename node_type>
    20 static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.previsit( node ), void() ) {
     72static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
    2173        pass.previsit( node );
    2274}
     
    2779
    2880template<typename pass_type, typename node_type>
    29 static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postvisit( node ), void() ) {
     81static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
    3082        pass.postvisit( node );
    3183}
     
    3688// Mutate
    3789template<typename pass_type, typename node_type>
    38 static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.premutate( node ), void() ) {
     90static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.premutate( node ), void() ) {
    3991        return pass.premutate( node );
    4092}
     
    4597
    4698template<typename return_type, typename pass_type, typename node_type>
    47 static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postmutate( node ) ) {
     99static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postmutate( node ) ) {
    48100        return pass.postmutate( node );
    49101}
     
    54106// Begin/End scope
    55107template<typename pass_type>
    56 static inline auto begin_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( pass.beginScope(), void() ) {
     108static inline auto begin_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( pass.beginScope(), void() ) {
    57109        pass.beginScope();
    58110}
     
    63115
    64116template<typename pass_type>
    65 static inline auto end_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( pass.endScope(), void() ) {
     117static inline auto end_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( pass.endScope(), void() ) {
    66118        pass.endScope();
    67119}
     
    73125#define FIELD_PTR( type, name )                                                                                                        \
    74126template<typename pass_type>                                                                                                           \
    75 static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( &pass.name ) { return &pass.name; } \
     127static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( &pass.name ) { return &pass.name; } \
    76128                                                                                                                                       \
    77129template<typename pass_type>                                                                                                           \
     
    81133FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
    82134FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
    83 FIELD_PTR( bool, skip_children )
     135FIELD_PTR( std::list< Declaration* >, declsToAddBefore )
     136FIELD_PTR( std::list< Declaration* >, declsToAddAfter  )
     137FIELD_PTR( bool_ref, visit_children )
     138FIELD_PTR( at_cleanup_t, at_cleanup )
     139FIELD_PTR( PassVisitor<pass_type> * const, visitor )
  • src/GenPoly/Box.cc

    re4d829b r579263a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 13 09:26:38 2017
    13 // Update Count     : 341
     12// Last Modified On : Wed Jun 21 15:49:59 2017
     13// Update Count     : 346
    1414//
    1515
     
    108108                        Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
    109109                        /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
    110                         Expression *addDynRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *polyType, std::list< Expression *>::iterator &arg );
     110                        Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg );
    111111                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    112112                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
     
    341341        Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
    342342                // check that the lhs is zeroed out to the level of rhs
    343                 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );
     343                Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    344344                // if not aligned, increment to alignment
    345345                Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
     
    384384
    385385                // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size)
    386                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
    387                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
     386                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) );
     387                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    388388                unsigned long n_members = 0;
    389389                bool firstMember = true;
     
    441441
    442442                // calculate union layout in function body
    443                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    444                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
     443                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
     444                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    445445                for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
    446446                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
     
    504504                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    505505                        if ( functionDecl->get_statements() ) {         // empty routine body ?
     506                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506507                                doBeginScope();
    507508                                scopeTyVars.beginScope();
     
    548549                                retval = oldRetval;
    549550                                doEndScope();
     551                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    550552                        } // if
    551553                        return functionDecl;
     
    726728                }
    727729
    728                 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *dynType, std::list< Expression *>::iterator &arg ) {
     730                Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) {
    729731                        assert( env );
    730732                        Type *concrete = replaceWithConcrete( appExpr, dynType );
     
    11161118
    11171119                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    1118                         // std::cerr << "mutate appExpr: ";
     1120                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11191121                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    11201122                        //      std::cerr << i->first << " ";
     
    11411143                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
    11421144
     1145                        // std::cerr << function << std::endl;
     1146                        // std::cerr << "scopeTyVars: ";
     1147                        // printTyVarMap( std::cerr, scopeTyVars );
     1148                        // std::cerr << "exprTyVars: ";
     1149                        // printTyVarMap( std::cerr, exprTyVars );
     1150                        // std::cerr << "env: " << *env << std::endl;
     1151                        // std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl;
     1152
    11431153                        // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr
    11441154                        // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int))
    11451155                        // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome.
    11461156                        if ( dynRetType ) {
     1157                                // std::cerr << "dynRetType: " << dynRetType << std::endl;
    11471158                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    1148                                 ret = addDynRetParam( appExpr, function, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
     1159                                ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
    11491160                        } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...?
    11501161                                // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed.
     
    15641575                /// Returns an index expression into the offset array for a type
    15651576                Expression *makeOffsetIndex( Type *objectType, long i ) {
    1566                         std::stringstream offset_namer;
    1567                         offset_namer << i;
    1568                         ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1577                        ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) );
    15691578                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    15701579                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) );
     
    17791788                                // all union members are at offset zero
    17801789                                delete offsetofExpr;
    1781                                 return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "0" ) );
     1790                                return new ConstantExpr( Constant::from_ulong( 0 ) );
    17821791                        } else return offsetofExpr;
    17831792                }
  • src/GenPoly/DeclMutator.cc

    re4d829b r579263a  
    99// Author           : Aaron B. Moss
    1010// Created On       : Fri Nov 27 14:44:00 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug  4 11:16:43 2016
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Jun 22 13:49:00 2017
     13// Update Count     : 4
    1414//
    1515
     
    178178        Statement* DeclMutator::mutate(CatchStmt *catchStmt) {
    179179                catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
     180                catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
    180181                catchStmt->set_body( mutateStatement( catchStmt->get_body() ) );
    181182                return catchStmt;
  • src/GenPoly/InstantiateGeneric.cc

    re4d829b r579263a  
    2222#include "InstantiateGeneric.h"
    2323
    24 #include "DeclMutator.h"
    2524#include "GenPoly.h"
    2625#include "ScopedSet.h"
    2726#include "ScrubTyVars.h"
    28 #include "PolyMutator.h"
     27
     28#include "Common/PassVisitor.h"
     29#include "Common/ScopedMap.h"
     30#include "Common/UniqueName.h"
     31#include "Common/utility.h"
    2932
    3033#include "ResolvExpr/typeops.h"
     
    3437#include "SynTree/Type.h"
    3538
    36 #include "Common/ScopedMap.h"
    37 #include "Common/UniqueName.h"
    38 #include "Common/utility.h"
     39
     40#include "InitTweak/InitTweak.h"
     41
    3942
    4043namespace GenPoly {
     
    153156        }
    154157
    155         // collect the environments of each TypeInstType so that type variables can be replaced
    156         // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.
    157         class EnvFinder final : public GenPoly::PolyMutator {
    158         public:
    159                 using GenPoly::PolyMutator::mutate;
    160                 virtual Type * mutate( TypeInstType * inst ) override {
    161                         if ( env ) envMap[inst] = env;
    162                         return inst;
    163                 }
    164 
    165                 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?
    166                 virtual Type * mutate( FunctionType * ftype ) override {
    167                         return ftype;
    168                 }
    169                 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;
    170         };
    171 
    172158        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    173         class GenericInstantiator final : public DeclMutator {
     159        struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
    174160                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    175161                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     
    178164                /// Namer for concrete types
    179165                UniqueName typeNamer;
    180                 /// Reference to mapping of environments
    181                 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
    182         public:
    183                 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
    184 
    185                 using DeclMutator::mutate;
    186                 virtual Type* mutate( StructInstType *inst ) override;
    187                 virtual Type* mutate( UnionInstType *inst ) override;
    188 
    189                 virtual void doBeginScope() override;
    190                 virtual void doEndScope() override;
     166                /// Should not make use of type environment to replace types of function parameter and return values.
     167                bool inFunctionType = false;
     168                GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
     169
     170                Type* postmutate( StructInstType *inst );
     171                Type* postmutate( UnionInstType *inst );
     172
     173                void premutate( FunctionType * ftype ) {
     174                        GuardValue( inFunctionType );
     175                        inFunctionType = true;
     176                }
     177
     178                void beginScope();
     179                void endScope();
    191180        private:
    192181                /// Wrap instantiation lookup for structs
     
    207196
    208197        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
    209                 EnvFinder finder;
    210                 mutateAll( translationUnit, finder );
    211                 GenericInstantiator instantiator( finder.envMap );
    212                 instantiator.mutateDeclarationList( translationUnit );
     198                PassVisitor<GenericInstantiator> instantiator;
     199                mutateAll( translationUnit, instantiator );
    213200        }
    214201
     
    306293        Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) {
    307294                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    308                         if ( envMap.count( typeInst ) ) {
    309                                 TypeSubstitution * env = envMap.at( typeInst );
     295                        if ( env && ! inFunctionType ) {
    310296                                Type *concrete = env->lookup( typeInst->get_name() );
    311297                                if ( concrete ) {
     
    331317
    332318
    333         Type* GenericInstantiator::mutate( StructInstType *inst ) {
    334                 // mutate subtypes
    335                 Type *mutated = Mutator::mutate( inst );
    336                 inst = dynamic_cast< StructInstType* >( mutated );
    337                 if ( ! inst ) return mutated;
    338 
     319        Type* GenericInstantiator::postmutate( StructInstType *inst ) {
    339320                // exit early if no need for further mutation
    340321                if ( inst->get_parameters().empty() ) return inst;
     
    368349                                substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    369350                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    370                                 concDecl->acceptMutator( *this ); // recursively instantiate members
    371                                 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
     351                                concDecl->acceptMutator( *visitor ); // recursively instantiate members
     352                                declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
    372353                        }
    373354                        StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    388369        }
    389370
    390         Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    391                 // mutate subtypes
    392                 Type *mutated = Mutator::mutate( inst );
    393                 inst = dynamic_cast< UnionInstType* >( mutated );
    394                 if ( ! inst ) return mutated;
    395 
     371        Type* GenericInstantiator::postmutate( UnionInstType *inst ) {
    396372                // exit early if no need for further mutation
    397373                if ( inst->get_parameters().empty() ) return inst;
     
    423399                                substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    424400                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    425                                 concDecl->acceptMutator( *this ); // recursively instantiate members
    426                                 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
     401                                concDecl->acceptMutator( *visitor ); // recursively instantiate members
     402                                declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
    427403                        }
    428404                        UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    442418        }
    443419
    444         void GenericInstantiator::doBeginScope() {
    445                 DeclMutator::doBeginScope();
     420        void GenericInstantiator::beginScope() {
    446421                instantiations.beginScope();
    447422                dtypeStatics.beginScope();
    448423        }
    449424
    450         void GenericInstantiator::doEndScope() {
    451                 DeclMutator::doEndScope();
     425        void GenericInstantiator::endScope() {
    452426                instantiations.endScope();
    453427                dtypeStatics.endScope();
  • src/GenPoly/PolyMutator.cc

    re4d829b r579263a  
    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 Aug  4 11:26:22 2016
    13 // Update Count     : 16
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Jun 22 13:47:00 2017
     13// Update Count     : 17
    1414//
    1515
     
    123123
    124124        Statement * PolyMutator::mutate(TryStmt *tryStmt) {
    125                 tryStmt->set_block(  maybeMutate( tryStmt->get_block(), *this ) );
     125                tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
    126126                mutateAll( tryStmt->get_catchers(), *this );
     127                tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) );
    127128                return tryStmt;
    128129        }
    129130
    130131        Statement * PolyMutator::mutate(CatchStmt *cathStmt) {
    131                 cathStmt->set_body(  mutateStatement( cathStmt->get_body() ) );
    132                 cathStmt->set_decl(  maybeMutate( cathStmt->get_decl(), *this ) );
     132                cathStmt->set_body( mutateStatement( cathStmt->get_body() ) );
     133                cathStmt->set_cond( maybeMutate( cathStmt->get_cond(), *this ) );
     134                cathStmt->set_decl( maybeMutate( cathStmt->get_decl(), *this ) );
    133135                return cathStmt;
    134136        }
  • src/GenPoly/Specialize.cc

    re4d829b r579263a  
    9393        }
    9494
    95         bool needsTupleSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     95        bool needsTupleSpecialization( Type *formalType, Type *actualType ) {
    9696                // Needs tuple specialization if the structure of the formal type and actual type do not match.
    9797                // This is the case if the formal type has ttype polymorphism, or if the structure  of tuple types
     
    9999                if ( FunctionType * fftype = getFunctionType( formalType ) ) {
    100100                        if ( fftype->isTtype() ) return true;
     101                        // conversion of 0 (null) to function type does not require tuple specialization
     102                        if ( dynamic_cast< ZeroType * >( actualType ) ) return false;
    101103                        FunctionType * aftype = getFunctionType( actualType );
    102104                        assertf( aftype, "formal type is a function type, but actual type is not." );
     
    112114
    113115        bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
    114                 return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType, env );
     116                return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType );
    115117        }
    116118
  • src/InitTweak/FixInit.cc

    re4d829b r579263a  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:13:47 2017
    13 // Update Count     : 71
     12// Last Modified On : Wed Jun 21 17:35:05 2017
     13// Update Count     : 74
    1414//
    1515
     
    5656                typedef std::unordered_map< int, int > UnqCount;
    5757
    58                 class InsertImplicitCalls {
     58                class InsertImplicitCalls : public WithTypeSubstitution {
    5959                public:
    6060                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
     
    6969                        // collects environments for relevant nodes
    7070                        EnvMap & envMap;
    71                         TypeSubstitution * env; //Magically populated by the PassVisitor
    7271                };
    7372
     
    192191                };
    193192
    194                 class FixInit {
     193                class FixInit : public WithStmtsToAdd {
    195194                  public:
    196195                        /// expand each object declaration to use its constructor after it is declared.
     
    200199
    201200                        std::list< Declaration * > staticDtorDecls;
    202                         std::list< Statement * > stmtsToAddAfter; // found by PassVisitor
    203201                };
    204202
     
    726724                                                // static bool __objName_uninitialized = true
    727725                                                BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    728                                                 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ) );
     726                                                SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) );
    729727                                                ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr );
    730728                                                isUninitializedVar->fixUniqueId();
     
    733731                                                UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
    734732                                                setTrue->get_args().push_back( new VariableExpr( isUninitializedVar ) );
    735                                                 setTrue->get_args().push_back( new ConstantExpr( Constant( boolType->clone(), "0" ) ) );
     733                                                setTrue->get_args().push_back( new ConstantExpr( Constant::from_int( 0 ) ) );
    736734
    737735                                                // generate body of if
     
    902900                }
    903901
    904                 void InsertDtors::visit( ReturnStmt * returnStmt ) {
     902                void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) {
    905903                        // return exits all scopes, so dump destructors for all scopes
    906904                        for ( OrderedDecls & od : reverseDeclOrder ) {
  • src/InitTweak/GenInit.cc

    re4d829b r579263a  
    3939
    4040namespace InitTweak {
    41         class ReturnFixer final : public GenPoly::PolyMutator {
    42           public:
     41        namespace {
     42                const std::list<Label> noLabels;
     43                const std::list<Expression *> noDesignators;
     44        }
     45
     46        struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
    4347                /// consistently allocates a temporary variable for the return value
    4448                /// of a function so that anything which the resolver decides can be constructed
     
    4650                static void makeReturnTemp( std::list< Declaration * > &translationUnit );
    4751
    48                 typedef GenPoly::PolyMutator Parent;
    49                 using Parent::mutate;
    50                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
    51                 virtual Statement * mutate( ReturnStmt * returnStmt ) override;
     52                void premutate( FunctionDecl *functionDecl );
     53                void premutate( ReturnStmt * returnStmt );
    5254
    5355          protected:
     
    5658        };
    5759
    58         class CtorDtor final : public GenPoly::PolyMutator {
    59           public:
    60                 typedef GenPoly::PolyMutator Parent;
    61                 using Parent::mutate;
     60        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6261                /// create constructor and destructor statements for object declarations.
    6362                /// the actual call statements will be added in after the resolver has run
     
    6665                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
    6766
    68                 virtual DeclarationWithType * mutate( ObjectDecl * ) override;
    69                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     67                void previsit( ObjectDecl * );
     68                void previsit( FunctionDecl *functionDecl );
     69
    7070                // should not traverse into any of these declarations to find objects
    7171                // that need to be constructed or destructed
    72                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
    73                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    74                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    75                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    76                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    77                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    78 
    79                 virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
    80 
    81                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
     72                void previsit( StructDecl *aggregateDecl );
     73                void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
     74                void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
     75                void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
     76                void previsit( TypeDecl *typeDecl ) { visit_children = false; }
     77                void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
     78
     79                void previsit( FunctionType *funcType ) { visit_children = false; }
     80
     81                void previsit( CompoundStmt * compoundStmt );
    8282
    8383          private:
     
    131131
    132132        void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
    133                 ReturnFixer fixer;
     133                PassVisitor<ReturnFixer> fixer;
    134134                mutateAll( translationUnit, fixer );
    135135        }
    136136
    137         Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) {
     137        void ReturnFixer::premutate( ReturnStmt *returnStmt ) {
    138138                std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();
    139139                assert( returnVals.size() == 0 || returnVals.size() == 1 );
     
    146146                        construct->get_args().push_back( new AddressExpr( new VariableExpr( returnVals.front() ) ) );
    147147                        construct->get_args().push_back( returnStmt->get_expr() );
    148                         stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
     148                        stmtsToAddBefore.push_back(new ExprStmt(noLabels, construct));
    149149
    150150                        // return the retVal object
    151151                        returnStmt->set_expr( new VariableExpr( returnVals.front() ) );
    152152                } // if
    153                 return returnStmt;
    154         }
    155 
    156         DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    157                 ValueGuard< FunctionType * > oldFtype( ftype );
    158                 ValueGuard< std::string > oldFuncName( funcName );
     153        }
     154
     155        void ReturnFixer::premutate( FunctionDecl *functionDecl ) {
     156                GuardValue( ftype );
     157                GuardValue( funcName );
    159158
    160159                ftype = functionDecl->get_functionType();
    161160                funcName = functionDecl->get_name();
    162                 return Parent::mutate( functionDecl );
    163161        }
    164162
     
    210208
    211209        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    212                 CtorDtor ctordtor;
    213                 mutateAll( translationUnit, ctordtor );
     210                PassVisitor<CtorDtor> ctordtor;
     211                acceptAll( translationUnit, ctordtor );
    214212        }
    215213
     
    288286        }
    289287
    290         DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     288        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    291289                handleDWT( objDecl );
    292290                // hands off if @=, extern, builtin, etc.
     
    300298                        objDecl->set_init( genCtorInit( objDecl ) );
    301299                }
    302                 return Parent::mutate( objDecl );
    303         }
    304 
    305         DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    306                 ValueGuard< bool > oldInFunc = inFunction;
     300        }
     301
     302        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     303                GuardValue( inFunction );
    307304                inFunction = true;
    308305
    309306                handleDWT( functionDecl );
    310307
    311                 managedTypes.beginScope();
     308                GuardScope( managedTypes );
    312309                // go through assertions and recursively add seen ctor/dtors
    313310                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
     
    316313                        }
    317314                }
    318                 // parameters should not be constructed and destructed, so don't mutate FunctionType
    319                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    320 
    321                 managedTypes.endScope();
    322                 return functionDecl;
    323         }
    324 
    325         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
     315
     316                PassVisitor<CtorDtor> newCtorDtor;
     317                newCtorDtor.pass = *this;
     318                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     319                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     320        }
     321
     322        void CtorDtor::previsit( StructDecl *aggregateDecl ) {
     323                visit_children = false; // do not try to construct and destruct aggregate members
     324
    326325                // don't construct members, but need to take note if there is a managed member,
    327326                // because that means that this type is also managed
     
    335334                        }
    336335                }
    337                 return aggregateDecl;
    338         }
    339 
    340         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    341                 managedTypes.beginScope();
    342                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    343                 managedTypes.endScope();
    344                 return stmt;
    345         }
    346 
     336        }
     337
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     339                GuardScope( managedTypes );
     340        }
    347341} // namespace InitTweak
    348342
  • src/InitTweak/InitTweak.cc

    re4d829b r579263a  
    471471        public:
    472472                ConstExprChecker() : isConstExpr( true ) {}
     473
     474                using Visitor::visit;
    473475
    474476                virtual void visit( __attribute((unused)) ApplicationExpr *applicationExpr ) { isConstExpr = false; }
  • src/Parser/ExpressionNode.cc

    re4d829b r579263a  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 17 21:31:01 2017
    13 // Update Count     : 527
     12// Last Modified On : Wed Jun 21 16:44:46 2017
     13// Update Count     : 541
    1414//
    1515
     
    6262        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    6363        int size;                                                                                       // 0 => int, 1 => long, 2 => long long
    64         unsigned long long v;                                                           // converted integral value
     64        unsigned long long int v;                                                               // converted integral value
    6565        size_t last = str.length() - 1;                                         // last character of constant
    6666
     
    118118        } // if
    119119
    120         Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ) );
     120        Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str, v ) );
    121121        delete &str;                                                                            // created by lex
    122122        return ret;
     
    133133        // floating-point constant has minimum of 2 characters: 1. or .1
    134134        size_t last = str.length() - 1;
     135        double v;
     136
     137        sscanf( str.c_str(), "%lg", &v );
    135138
    136139        if ( checkI( str[last] ) ) {                                            // imaginary ?
     
    150153        } // if
    151154
    152         Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) );
     155        Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str, v ) );
    153156        delete &str;                                                                            // created by lex
    154157        return ret;
     
    156159
    157160Expression *build_constantChar( const std::string & str ) {
    158         Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) );
     161        Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
    159162        delete &str;                                                                            // created by lex
    160163        return ret;
     
    164167        // string should probably be a primitive type
    165168        ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
    166                                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
    167                                                                                         toString( str.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
     169                                                                   new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ),  // +1 for '\0' and -2 for '"'
    168170                                                                   false, false );
    169         ConstantExpr * ret = new ConstantExpr( Constant( at, str ) );
     171        // constant 0 is ignored for pure string value
     172        ConstantExpr * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) );
    170173        delete &str;                                                                            // created by lex
    171174        return ret;
     
    173176
    174177Expression *build_constantZeroOne( const std::string & str ) {
    175         Expression * ret = new ConstantExpr( Constant( str == "0" ? (Type *)new ZeroType( emptyQualifiers ) : (Type*)new OneType( emptyQualifiers ), str ) );
     178        Expression * ret = new ConstantExpr( Constant( str == "0" ? (Type *)new ZeroType( emptyQualifiers ) : (Type*)new OneType( emptyQualifiers ), str,
     179                                                                                                   str == "0" ? (unsigned long long int)0 : (unsigned long long int)1 ) );
    176180        delete &str;                                                                            // created by lex
    177181        return ret;
     
    184188        std::stringstream ss( str );
    185189        ss >> a >> dot >> b;
    186         UntypedMemberExpr * ret = new UntypedMemberExpr(
    187                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::SignedInt ), toString( b ) ) ),
    188                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::SignedInt ), toString( a ) ) ) );
     190        UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
    189191        delete &str;
    190192        return ret;
     
    223225} // build_field_name_REALDECIMALconstant
    224226
    225 NameExpr * build_varref( const string *name, bool labelp ) {
     227NameExpr * build_varref( const string *name ) {
    226228        NameExpr *expr = new NameExpr( *name, nullptr );
    227229        delete name;
     
    346348
    347349Expression *build_valexpr( StatementNode *s ) {
    348         return new UntypedValofExpr( maybeMoveBuild< Statement >(s), nullptr );
     350        return new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(s) ) );
    349351}
    350352Expression *build_typevalue( DeclarationNode *decl ) {
  • src/Parser/ParseNode.h

    re4d829b r579263a  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 15:42:18 2017
    13 // Update Count     : 777
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jun 12 13:00:00 2017
     13// Update Count     : 779
    1414//
    1515
     
    166166Expression * build_field_name_REALDECIMALconstant( const std::string & str );
    167167
    168 NameExpr * build_varref( const std::string * name, bool labelp = false );
     168NameExpr * build_varref( const std::string * name );
    169169Expression * build_typevalue( DeclarationNode * decl );
    170170
     
    393393Statement * build_return( ExpressionNode * ctl );
    394394Statement * build_throw( ExpressionNode * ctl );
     395Statement * build_resume( ExpressionNode * ctl );
     396Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
    395397Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
    396 Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false );
     398Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
    397399Statement * build_finally( StatementNode * stmt );
    398400Statement * build_compound( StatementNode * first );
     
    413415                                result->location = cur->location;
    414416                                * out++ = result;
     417                        } else {
     418                                assertf(false, "buildList unknown type");
    415419                        } // if
    416420                } catch( SemanticError &e ) {
  • src/Parser/StatementNode.cc

    re4d829b r579263a  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 14:59:41 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  2 22:16:40 2017
    13 // Update Count     : 327
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jun 12 13:03:00 2017
     13// Update Count     : 329
    1414//
    1515
     
    152152        return new ReturnStmt( noLabels, exps.size() > 0 ? exps.back() : nullptr );
    153153}
     154
    154155Statement *build_throw( ExpressionNode *ctl ) {
    155156        std::list< Expression * > exps;
    156157        buildMoveList( ctl, exps );
    157158        assertf( exps.size() < 2, "This means we are leaking memory");
    158         return new ReturnStmt( noLabels, !exps.empty() ? exps.back() : nullptr, true );
     159        return new ThrowStmt( noLabels, ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
     160}
     161
     162Statement *build_resume( ExpressionNode *ctl ) {
     163        std::list< Expression * > exps;
     164        buildMoveList( ctl, exps );
     165        assertf( exps.size() < 2, "This means we are leaking memory");
     166        return new ThrowStmt( noLabels, ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
     167}
     168
     169Statement *build_resume_at( ExpressionNode *ctl, ExpressionNode *target ) {
     170        (void)ctl;
     171        (void)target;
     172        assertf( false, "resume at (non-local throw) is not yet supported," );
    159173}
    160174
    161175Statement *build_try( StatementNode *try_stmt, StatementNode *catch_stmt, StatementNode *finally_stmt ) {
    162         std::list< Statement * > branches;
    163         buildMoveList< Statement, StatementNode >( catch_stmt, branches );
     176        std::list< CatchStmt * > branches;
     177        buildMoveList< CatchStmt, StatementNode >( catch_stmt, branches );
    164178        CompoundStmt *tryBlock = safe_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_stmt));
    165179        FinallyStmt *finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) );
    166180        return new TryStmt( noLabels, tryBlock, branches, finallyBlock );
    167181}
    168 Statement *build_catch( DeclarationNode *decl, StatementNode *stmt, bool catchAny ) {
    169         std::list< Statement * > branches;
    170         buildMoveList< Statement, StatementNode >( stmt, branches );
    171         assert( branches.size() == 1 );
    172         return new CatchStmt( noLabels, maybeMoveBuild< Declaration >(decl), branches.front(), catchAny );
     182Statement *build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body ) {
     183        std::list< Statement * > branches;
     184        buildMoveList< Statement, StatementNode >( body, branches );
     185        assert( branches.size() == 1 );
     186        return new CatchStmt( noLabels, kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() );
    173187}
    174188Statement *build_finally( StatementNode *stmt ) {
  • src/Parser/parser.yy

    re4d829b r579263a  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 25 15:21:59 2017
    13 // Update Count     : 2398
     12// Last Modified On : Mon Jun 12 12:59:00 2017
     13// Update Count     : 2402
    1414//
    1515
     
    193193%type<sn> case_value_list                               case_label                                      case_label_list
    194194%type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
    195 %type<sn> handler_list                                  handler_clause                          finally_clause
     195%type<sn> /* handler_list */                    handler_clause                          finally_clause
    196196
    197197// declarations
     
    547547                { $$ = new ExpressionNode( build_attrtype( build_varref( $1 ), $3 ) ); }
    548548//      | ANDAND IDENTIFIER                                                                     // GCC, address of label
    549 //              { $$ = new ExpressionNode( new OperatorNode( OperKinds::LabelAddress ), new ExpressionNode( build_varref( $2, true ) ); }
     549//              { $$ = new ExpressionNode( new OperatorNode( OperKinds::LabelAddress ), new ExpressionNode( build_varref( $2 ) ); }
    550550        ;
    551551
     
    931931                { $$ = new StatementNode( build_throw( $2 ) ); }
    932932        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    933                 { $$ = new StatementNode( build_throw( $2 ) ); }
     933                { $$ = new StatementNode( build_resume( $2 ) ); }
    934934        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    935                 { $$ = new StatementNode( build_throw( $2 ) ); }
     935                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
    936936        ;
    937937
    938938exception_statement:
    939         TRY compound_statement handler_list
     939        TRY compound_statement handler_clause
    940940                { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
    941941        | TRY compound_statement finally_clause
    942942                { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
    943         | TRY compound_statement handler_list finally_clause
     943        | TRY compound_statement handler_clause finally_clause
    944944                { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
    945945        ;
    946946
    947 handler_list:
    948         handler_clause
    949                 // ISO/IEC 9899:1999 Section 15.3(6 ) If present, a "..." handler shall be the last handler for its try block.
    950         | CATCH '(' ELLIPSIS ')' compound_statement
    951                 { $$ = new StatementNode( build_catch( 0, $5, true ) ); }
    952         | handler_clause CATCH '(' ELLIPSIS ')' compound_statement
    953                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); }
    954         | CATCHRESUME '(' ELLIPSIS ')' compound_statement
    955                 { $$ = new StatementNode( build_catch( 0, $5, true ) ); }
    956         | handler_clause CATCHRESUME '(' ELLIPSIS ')' compound_statement
    957                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); }
    958         ;
     947//handler_list:
     948//      handler_clause
     949//              // ISO/IEC 9899:1999 Section 15.3(6 ) If present, a "..." handler shall be the last handler for its try block.
     950//      | CATCH '(' ELLIPSIS ')' compound_statement
     951//              { $$ = new StatementNode( build_catch( 0, $5, true ) ); }
     952//      | handler_clause CATCH '(' ELLIPSIS ')' compound_statement
     953//              { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); }
     954//      | CATCHRESUME '(' ELLIPSIS ')' compound_statement
     955//              { $$ = new StatementNode( build_catch( 0, $5, true ) ); }
     956//      | handler_clause CATCHRESUME '(' ELLIPSIS ')' compound_statement
     957//              { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( 0, $6, true ) ) ); }
     958//      ;
    959959
    960960handler_clause:
    961961        CATCH '(' push push exception_declaration pop ')' compound_statement pop
    962                 { $$ = new StatementNode( build_catch( $5, $8 ) ); }
     962                { $$ = new StatementNode( build_catch( CatchStmt::Terminate, $5, nullptr, $8 ) ); }
    963963        | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
    964                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $6, $9 ) ) ); }
     964                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, $6, nullptr, $9 ) ) ); }
    965965        | CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop
    966                 { $$ = new StatementNode( build_catch( $5, $8 ) ); }
     966                { $$ = new StatementNode( build_catch( CatchStmt::Resume, $5, nullptr, $8 ) ); }
    967967        | handler_clause CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop
    968                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $6, $9 ) ) ); }
     968                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Resume, $6, nullptr, $9 ) ) ); }
    969969        ;
    970970
  • src/Parser/parseutility.cc

    re4d829b r579263a  
    1010// Created On       : Sat May 16 15:30:39 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug 14 23:45:03 2016
    13 // Update Count     : 3
     12// Last Modified On : Wed Jun 21 15:33:41 2017
     13// Update Count     : 5
    1414//
    1515
     
    2626        UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
    2727        comparison->get_args().push_back( orig );
    28         comparison->get_args().push_back( new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0" ) ) );
     28        comparison->get_args().push_back( new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0", (unsigned long long int)0 ) ) );
    2929        return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    3030}
  • src/ResolvExpr/AlternativeFinder.cc

    re4d829b r579263a  
    9797                /// Prunes a list of alternatives down to those that have the minimum conversion cost for a given return type; skips ambiguous interpretations
    9898                template< typename InputIterator, typename OutputIterator >
    99                 void pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer ) {
     99                void pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out ) {
    100100                        // select the alternatives that have the minimum conversion cost for a particular set of result types
    101101                        std::map< std::string, PruneStruct > selected;
     
    183183                        )
    184184                        AltList::iterator oldBegin = alternatives.begin();
    185                         pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
     185                        pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ) );
    186186                        if ( alternatives.begin() == oldBegin ) {
    187187                                std::ostringstream stream;
  • src/ResolvExpr/CommonType.cc

    re4d829b r579263a  
    157157        void CommonType::visit( PointerType *pointerType ) {
    158158                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    159                         if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base(), indexer) ) {
     159                        if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
    160160                                getCommonWithVoidPointer( otherPointer, pointerType );
    161                         } else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base(), indexer) ) {
     161                        } else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
    162162                                getCommonWithVoidPointer( pointerType, otherPointer );
    163163                        } else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
  • src/ResolvExpr/PtrsCastable.cc

    re4d829b r579263a  
    135135        }
    136136
    137         void PtrsCastable::visit(TraitInstType *inst) {
    138                 // I definitely don't think we should be doing anything here
    139         }
     137        void PtrsCastable::visit( __attribute__((unused)) TraitInstType *inst ) {}
    140138
    141139        void PtrsCastable::visit(TypeInstType *inst) {
  • src/ResolvExpr/Unify.cc

    re4d829b r579263a  
    114114        }
    115115
    116         bool isFtype( Type *type, const SymTab::Indexer &indexer ) {
     116        bool isFtype( Type *type ) {
    117117                if ( dynamic_cast< FunctionType* >( type ) ) {
    118118                        return true;
     
    123123        }
    124124
    125         bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) {
     125        bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    126126                switch ( data.kind ) {
    127127                  case TypeDecl::Any:
     
    131131                        // type must also be complete
    132132                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    133                         return ! isFtype( type, indexer ) && (! data.isComplete || type->isComplete() );
     133                        return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
    134134                  case TypeDecl::Ftype:
    135                         return isFtype( type, indexer );
     135                        return isFtype( type );
    136136                  case TypeDecl::Ttype:
    137137                        // ttype unifies with any tuple type
     
    144144                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    145145                assert( tyvar != openVars.end() );
    146                 if ( ! tyVarCompatible( tyvar->second, other, indexer ) ) {
     146                if ( ! tyVarCompatible( tyvar->second, other ) ) {
    147147                        return false;
    148148                } // if
     
    388388        }
    389389
    390         void Unify::visit(VoidType *voidType) {
     390        void Unify::visit( __attribute__((unused)) VoidType *voidType) {
    391391                result = dynamic_cast< VoidType* >( type2 );
    392392        }
     
    683683
    684684        template< typename Iterator1, typename Iterator2 >
    685         bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     685        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    686686                auto get_type = [](Type * t) { return t; };
    687687                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     
    733733                        flatten( flat2.get(), back_inserter( types2 ) );
    734734
    735                         result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    736                 } // if
    737         }
    738 
    739         void Unify::visit(VarArgsType *varArgsType) {
     735                        result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, indexer );
     736                } // if
     737        }
     738
     739        void Unify::visit( __attribute__((unused)) VarArgsType *varArgsType ) {
    740740                result = dynamic_cast< VarArgsType* >( type2 );
    741741        }
    742742
    743         void Unify::visit(ZeroType *zeroType) {
     743        void Unify::visit( __attribute__((unused)) ZeroType *zeroType ) {
    744744                result = dynamic_cast< ZeroType* >( type2 );
    745745        }
    746746
    747         void Unify::visit(OneType *oneType) {
     747        void Unify::visit( __attribute__((unused)) OneType *oneType ) {
    748748                result = dynamic_cast< OneType* >( type2 );
    749749        }
  • src/ResolvExpr/typeops.h

    re4d829b r579263a  
    118118
    119119        // in Unify.cc
    120         bool isFtype( Type *type, const SymTab::Indexer &indexer );
     120        bool isFtype( Type *type );
    121121        bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    122122        bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
  • src/SymTab/Autogen.cc

    re4d829b r579263a  
    262262        // E ?=?(E volatile*, int),
    263263        //   ?=?(E _Atomic volatile*, int);
    264         void makeEnumFunctions( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
     264        void makeEnumFunctions( EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
    265265
    266266                // T ?=?(E *, E);
     
    486486
    487487        /// generates the body of a union assignment/copy constructor/field constructor
    488         void makeUnionAssignBody( FunctionDecl * funcDecl, bool isDynamicLayout ) {
     488        void makeUnionAssignBody( FunctionDecl * funcDecl ) {
    489489                FunctionType * ftype = funcDecl->get_functionType();
    490490                assert( ftype->get_parameters().size() == 2 );
     
    506506                // Make function polymorphic in same parameters as generic union, if applicable
    507507                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    508                 bool isDynamicLayout = hasDynamicLayout( aggregateDecl );  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    509 
     508               
    510509                // default ctor/dtor need only first parameter
    511510                // void ?{}(T *); void ^?{}(T *);
     
    533532                FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting );
    534533
    535                 makeUnionAssignBody( assignDecl, isDynamicLayout );
     534                makeUnionAssignBody( assignDecl );
    536535
    537536                // body of assignment and copy ctor is the same
    538                 makeUnionAssignBody( copyCtorDecl, isDynamicLayout );
     537                makeUnionAssignBody( copyCtorDecl );
    539538
    540539                // create a constructor which takes the first member type as a parameter.
     
    551550                                FunctionDecl * ctor = genFunc( "?{}", memCtorType, functionNesting );
    552551
    553                                 makeUnionAssignBody( ctor, isDynamicLayout );
     552                                makeUnionAssignBody( ctor );
    554553                                memCtors.push_back( ctor );
    555554                                // only generate a ctor for the first field
     
    578577                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
    579578                        // enumInst->set_baseEnum( enumDecl );
    580                         makeEnumFunctions( enumDecl, enumInst, functionNesting, declsToAddAfter );
     579                        makeEnumFunctions( enumInst, functionNesting, declsToAddAfter );
    581580                }
    582581        }
  • src/SymTab/Autogen.h

    re4d829b r579263a  
    1010// Created On       : Sun May 17 21:53:34 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:10:41 2017
    13 // Update Count     : 9
     12// Last Modified On : Wed Jun 21 17:25:26 2017
     13// Update Count     : 14
    1414//
    1515
     
    4343        template< typename OutputIterator >
    4444        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    45                 // want to be able to generate assignment, ctor, and dtor generically,
    46                 // so fname is either ?=?, ?{}, or ^?{}
    47                 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
     45        // want to be able to generate assignment, ctor, and dtor generically,
     46        // so fname is either ?=?, ?{}, or ^?{}
     47        UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    4848
    49                 // do something special for unnamed members
    50                 dstParam = new AddressExpr( dstParam );
    51                 if ( addCast ) {
    52                         // cast to T* with qualifiers removed, so that qualified objects can be constructed
    53                         // and destructed with the same functions as non-qualified objects.
    54                         // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
    55                         // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
    56                         // remove lvalue as a qualifier, this can change to
    57                         //   type->get_qualifiers() = Type::Qualifiers();
    58                         assert( type );
    59                         Type * castType = type->clone();
    60 //                      castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
    61                         castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    62                         castType->set_lvalue( true ); // xxx - might not need this
    63                         dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    64                 }
    65                 fExpr->get_args().push_back( dstParam );
     49        // do something special for unnamed members
     50        dstParam = new AddressExpr( dstParam );
     51        if ( addCast ) {
     52                // cast to T* with qualifiers removed, so that qualified objects can be constructed
     53                // and destructed with the same functions as non-qualified objects.
     54                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     55                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     56                // remove lvalue as a qualifier, this can change to
     57                //   type->get_qualifiers() = Type::Qualifiers();
     58                assert( type );
     59                Type * castType = type->clone();
     60                castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     61                castType->set_lvalue( true ); // xxx - might not need this
     62                dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
     63        }
     64        fExpr->get_args().push_back( dstParam );
    6665
    67                 Statement * listInit = srcParam.buildListInit( fExpr );
     66        Statement * listInit = srcParam.buildListInit( fExpr );
    6867
    69                 std::list< Expression * > args = *++srcParam;
    70                 fExpr->get_args().splice( fExpr->get_args().end(), args );
     68        std::list< Expression * > args = *++srcParam;
     69        fExpr->get_args().splice( fExpr->get_args().end(), args );
    7170
    72                 *out++ = new ExprStmt( noLabels, fExpr );
     71        *out++ = new ExprStmt( noLabels, fExpr );
    7372
    74                 srcParam.clearArrayIndices();
     73        srcParam.clearArrayIndices();
    7574
    76                 return listInit;
     75        return listInit;
    7776        }
    7877
     
    8887                Expression * begin, * end, * update, * cmp;
    8988                if ( forward ) {
    90                         // generate: for ( int i = 0; i < 0; ++i )
    91                         begin = new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0" ) );
     89                        // generate: for ( int i = 0; i < N; ++i )
     90                        begin = new ConstantExpr( Constant::from_int( 0 ) );
    9291                        end = array->get_dimension()->clone();
    9392                        cmp = new NameExpr( "?<?" );
     
    9796                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
    9897                        ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    99                         ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant( new OneType( emptyQualifiers ), "1" ) ) );
    100                         end = new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0" ) );
     98                        ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     99                        end = new ConstantExpr( Constant::from_int( 0 ) );
    101100                        cmp = new NameExpr( "?>=?" );
    102101                        update = new NameExpr( "--?" );
  • src/SymTab/ImplementationType.cc

    re4d829b r579263a  
    7676        }
    7777
    78         void ImplementationType::visit(FunctionType *functionType) {
    79 ///   FunctionType *newType = functionType->clone();
    80 ///   for ( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
    81 ///     i->set_type( implementationType( i->get_type(), indexer ) );
    82 ///   }
    83 ///   for ( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
    84 ///     i->set_type( implementationType( i->get_type(), indexer ) );
    85 ///   }
    86         }
    87 
     78        void ImplementationType::visit( __attribute__((unused)) FunctionType *functionType ) {}
    8879        void ImplementationType::visit( __attribute__((unused)) StructInstType * aggregateUseType ) {}
    8980        void ImplementationType::visit( __attribute__((unused)) UnionInstType * aggregateUseType ) {}
  • src/SymTab/Indexer.cc

    re4d829b r579263a  
    495495        }
    496496
    497         void Indexer::visit( UntypedValofExpr *valofExpr ) {
    498                 acceptNewScope( valofExpr->get_result(), *this );
    499                 maybeAccept( valofExpr->get_body(), *this );
    500         }
    501 
    502497        void Indexer::visit( RangeExpr *rangeExpr ) {
    503498                maybeAccept( rangeExpr->get_low(), *this );
     
    518513                acceptNewScope( tupleExpr->get_result(), *this );
    519514                maybeAccept( tupleExpr->get_tuple(), *this );
    520         }
    521 
    522         void Indexer::visit( MemberTupleExpr *tupleExpr ) {
    523                 acceptNewScope( tupleExpr->get_result(), *this );
    524                 maybeAccept( tupleExpr->get_member(), *this );
    525                 maybeAccept( tupleExpr->get_aggregate(), *this );
    526515        }
    527516
  • src/SymTab/Indexer.h

    re4d829b r579263a  
    6969                virtual void visit( ConstructorExpr * ctorExpr );
    7070                virtual void visit( CompoundLiteralExpr *compLitExpr );
    71                 virtual void visit( UntypedValofExpr *valofExpr );
    7271                virtual void visit( RangeExpr *rangeExpr );
    7372                virtual void visit( UntypedTupleExpr *tupleExpr );
    7473                virtual void visit( TupleExpr *tupleExpr );
    7574                virtual void visit( TupleIndexExpr *tupleExpr );
    76                 virtual void visit( MemberTupleExpr *tupleExpr );
    7775                virtual void visit( TupleAssignExpr *tupleExpr );
    7876                virtual void visit( StmtExpr * stmtExpr );
  • src/SymTab/Mangler.cc

    re4d829b r579263a  
    236236        }
    237237
    238         void Mangler::visit( ZeroType *zeroType ) {
     238        void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
    239239                mangleName << "Z";
    240240        }
    241241
    242         void Mangler::visit( OneType *oneType ) {
     242        void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
    243243                mangleName << "O";
    244244        }
  • src/SymTab/Validate.cc

    re4d829b r579263a  
    106106
    107107        /// Fix return types so that every function returns exactly one value
    108         class ReturnTypeFixer {
    109           public:
     108        struct ReturnTypeFixer {
    110109                static void fix( std::list< Declaration * > &translationUnit );
    111110
     
    115114
    116115        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    117         class EnumAndPointerDecayPass final : public Visitor {
    118                 typedef Visitor Parent;
    119                 virtual void visit( EnumDecl *aggregateDecl );
    120                 virtual void visit( FunctionType *func );
     116        struct EnumAndPointerDecay {
     117                void previsit( EnumDecl *aggregateDecl );
     118                void previsit( FunctionType *func );
    121119        };
    122120
     
    126124          public:
    127125                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    128           private:
    129126                using Parent::visit;
    130127                void visit( EnumInstType *enumInst ) final;
     
    136133                void visit( UnionDecl *unionDecl ) final;
    137134                void visit( TypeInstType *typeInst ) final;
    138 
     135          private:
    139136                const Indexer *indexer;
    140137
     
    147144        };
    148145
    149         /// Replaces array and function types in forall lists by appropriate pointer type
    150         class Pass3 final : public Indexer {
     146        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
     147        class ForallPointerDecay final : public Indexer {
    151148                typedef Indexer Parent;
    152149          public:
    153150                using Parent::visit;
    154                 Pass3( const Indexer *indexer );
    155           private:
     151                ForallPointerDecay( const Indexer *indexer );
     152
    156153                virtual void visit( ObjectDecl *object ) override;
    157154                virtual void visit( FunctionDecl *func ) override;
     
    160157        };
    161158
    162         class ReturnChecker {
    163           public:
     159        struct ReturnChecker : public WithGuards {
    164160                /// Checks that return statements return nothing if their return type is void
    165161                /// and return something if the return type is non-void.
    166162                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    167           private:
     163
    168164                void previsit( FunctionDecl * functionDecl );
    169                 void postvisit( FunctionDecl * functionDecl );
    170165                void previsit( ReturnStmt * returnStmt );
    171166
    172167                typedef std::list< DeclarationWithType * > ReturnVals;
    173168                ReturnVals returnVals;
    174                 std::stack< ReturnVals > returnValsStack;
    175169        };
    176170
     
    208202        };
    209203
    210         class VerifyCtorDtorAssign {
    211         public:
     204        struct VerifyCtorDtorAssign {
    212205                /// ensure that constructors, destructors, and assignment have at least one
    213206                /// parameter, the first of which must be a pointer, and that ctor/dtors have no
     
    219212
    220213        /// ensure that generic types have the correct number of type arguments
    221         class ValidateGenericParameters {
    222         public:
     214        struct ValidateGenericParameters {
    223215                void previsit( StructInstType * inst );
    224216                void previsit( UnionInstType * inst );
    225217        };
    226218
    227         class ArrayLength {
    228         public:
     219        struct ArrayLength {
    229220                /// for array types without an explicit length, compute the length and store it so that it
    230221                /// is known to the rest of the phases. For example,
     
    239230        };
    240231
    241         class CompoundLiteral final : public GenPoly::DeclMutator {
     232        struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
    242233                Type::StorageClasses storageClasses;
    243234
    244                 using GenPoly::DeclMutator::mutate;
    245                 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
    246                 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
     235                void premutate( ObjectDecl *objectDecl );
     236                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    247237        };
    248238
    249239        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    250                 EnumAndPointerDecayPass epc;
     240                PassVisitor<EnumAndPointerDecay> epc;
    251241                LinkReferenceToTypes lrt( doDebug, 0 );
    252                 Pass3 pass3( 0 );
    253                 CompoundLiteral compoundliteral;
     242                ForallPointerDecay fpd( 0 );
     243                PassVisitor<CompoundLiteral> compoundliteral;
    254244                PassVisitor<ValidateGenericParameters> genericParams;
    255245
     
    262252                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    263253                Concurrency::applyKeywords( translationUnit );
    264                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     254                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    265255                Concurrency::implementMutexFuncs( translationUnit );
    266256                Concurrency::implementThreadStarter( translationUnit );
    267257                ReturnChecker::checkFunctionReturns( translationUnit );
    268                 compoundliteral.mutateDeclarationList( translationUnit );
    269                 acceptAll( translationUnit, pass3 );
     258                mutateAll( translationUnit, compoundliteral );
     259                acceptAll( translationUnit, fpd );
    270260                ArrayLength::computeLength( translationUnit );
    271261        }
    272262
    273263        void validateType( Type *type, const Indexer *indexer ) {
    274                 EnumAndPointerDecayPass epc;
     264                PassVisitor<EnumAndPointerDecay> epc;
    275265                LinkReferenceToTypes lrt( false, indexer );
    276                 Pass3 pass3( indexer );
     266                ForallPointerDecay fpd( indexer );
    277267                type->accept( epc );
    278268                type->accept( lrt );
    279                 type->accept( pass3 );
     269                type->accept( fpd );
    280270        }
    281271
     
    356346        }
    357347
    358         void EnumAndPointerDecayPass::visit( EnumDecl *enumDecl ) {
     348        void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
    359349                // Set the type of each member of the enumeration to be EnumConstant
    360350                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     
    363353                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
    364354                } // for
    365                 Parent::visit( enumDecl );
    366355        }
    367356
     
    370359                void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    371360                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    372                         // entirely other fix ups are handled by the FixFunction class
     361                        // entirely. other fix ups are handled by the FixFunction class
    373362                        typedef typename DWTList::iterator DWTIterator;
    374363                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
     
    389378                                for ( ; i != end; ++i ) {
    390379                                        FixFunction fixer;
    391                                         *i = (*i )->acceptMutator( fixer );
     380                                        *i = (*i)->acceptMutator( fixer );
    392381                                        if ( fixer.get_isVoid() ) {
    393382                                                throw SemanticError( "invalid type void in function type ", func );
     
    398387        }
    399388
    400         void EnumAndPointerDecayPass::visit( FunctionType *func ) {
     389        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    401390                // Fix up parameters and return types
    402391                fixFunctionList( func->get_parameters(), func );
    403392                fixFunctionList( func->get_returnVals(), func );
    404                 Visitor::visit( func );
    405393        }
    406394
     
    549537        }
    550538
    551         Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
     539        ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
    552540                if ( other_indexer ) {
    553541                        indexer = other_indexer;
     
    587575        }
    588576
    589         void Pass3::visit( ObjectDecl *object ) {
     577        void ForallPointerDecay::visit( ObjectDecl *object ) {
    590578                forallFixer( object->get_type() );
    591579                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     
    596584        }
    597585
    598         void Pass3::visit( FunctionDecl *func ) {
     586        void ForallPointerDecay::visit( FunctionDecl *func ) {
    599587                forallFixer( func->get_type() );
    600588                Parent::visit( func );
     
    608596
    609597        void ReturnChecker::previsit( FunctionDecl * functionDecl ) {
    610                 returnValsStack.push( returnVals );
     598                GuardValue( returnVals );
    611599                returnVals = functionDecl->get_functionType()->get_returnVals();
    612         }
    613         void ReturnChecker::postvisit( FunctionDecl * functionDecl ) {
    614                 returnVals = returnValsStack.top();
    615                 returnValsStack.pop();
    616600        }
    617601
     
    892876        }
    893877
    894         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
     878        void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
    895879                storageClasses = objectDecl->get_storageClasses();
    896                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    897                 return temp;
    898         }
    899 
    900         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
     880        }
     881
     882        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    901883                // transform [storage_class] ... (struct S){ 3, ... };
    902884                // into [storage_class] struct S temp =  { 3, ... };
    903885                static UniqueName indexName( "_compLit" );
    904886
    905                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );
    906                 compLitExpr->set_result( 0 );
    907                 compLitExpr->set_initializer( 0 );
     887                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     888                compLitExpr->set_result( nullptr );
     889                compLitExpr->set_initializer( nullptr );
    908890                delete compLitExpr;
    909                 DeclarationWithType * newtempvar = mutate( tempvar );
    910                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    911                 return new VariableExpr( newtempvar );
     891                declsToAddBefore.push_back( tempvar );                                  // add modified temporary to current block
     892                return new VariableExpr( tempvar );
    912893        }
    913894
  • src/SynTree/BaseSyntaxNode.h

    re4d829b r579263a  
    2424        CodeLocation location;
    2525
    26         virtual void accept( Visitor & v ) = 0; // temporary -- needs to be here so that BaseSyntaxNode is polymorphic and can be dynamic_cast
     26        virtual ~BaseSyntaxNode() {}
     27
     28        virtual void accept( Visitor & v ) = 0;
    2729};
    2830
  • src/SynTree/Constant.cc

    re4d829b r579263a  
    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 30 15:18:38 2015
    13 // Update Count     : 12
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Jun 22 10:11:00 2017
     13// Update Count     : 28
    1414//
    1515
     
    2121#include "Type.h"
    2222
    23 Constant::Constant( Type *type_, std::string value_ ) : type( type_ ), value( value_ ) {}
     23Constant::Constant( Type * type, std::string rep, unsigned long long val ) : type( type ), rep( rep ), val( val ) {}
     24Constant::Constant( Type * type, std::string rep, double val ) : type( type ), rep( rep ), val( val ) {}
    2425
    25 Constant::Constant( const Constant &other ) {
     26Constant::Constant( const Constant &other ) : rep( other.rep ), val( other.val ) {
    2627        type = other.type->clone();
    27         value = other.value;
    2828}
    2929
    3030Constant::~Constant() { delete type; }
    3131
     32Constant Constant::from_bool( bool b ) {
     33        return Constant( new BasicType( Type::Qualifiers(), BasicType::Bool ), b ? "1" : "0" , (unsigned long long int)b );
     34}
     35
    3236Constant Constant::from_int( int i ) {
    33         return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) );
     37        return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ), (unsigned long long int)i );
    3438}
    3539
    3640Constant Constant::from_ulong( unsigned long i ) {
    37         return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) );
     41        return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ), (unsigned long long int)i );
    3842}
    3943
    4044Constant Constant::from_double( double d ) {
    41         return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) );
     45        return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ), d );
    4246}
    4347
    44 Constant *Constant::clone() const { assert( false ); return 0; }
    45 
    4648void Constant::print( std::ostream &os ) const {
    47         os << "(" << value;
     49        os << "(" << rep << " " << val.ival;
    4850        if ( type ) {
    4951                os << ": ";
  • src/SynTree/Constant.h

    re4d829b r579263a  
    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 Jun 30 13:33:17 2016
    13 // Update Count     : 6
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Jun 22 10:13:00 2017
     13// Update Count     : 15
    1414//
    1515
     
    2323class Constant {
    2424  public:
    25         Constant( Type *type, std::string value );
    26         Constant( const Constant &other );
     25        Constant( Type * type, std::string rep, unsigned long long val );
     26        Constant( Type * type, std::string rep, double val );
     27        Constant( const Constant & other );
    2728        virtual ~Constant();
    2829
    29         Type *get_type() { return type; }
    30         void set_type( Type *newValue ) { type = newValue; }
    31         std::string &get_value() { return value; }
    32         void set_value( std::string newValue ) { value = newValue; }
     30        Type * get_type() { return type; }
     31        void set_type( Type * newValue ) { type = newValue; }
     32        std::string & get_value() { return rep; }
     33        void set_value( std::string newValue ) { rep = newValue; }
    3334
     35        /// generates a boolean constant of the given bool
     36        static Constant from_bool( bool b );
    3437        /// generates an integer constant of the given int
    3538        static Constant from_int( int i );
     
    3942        static Constant from_double( double d );
    4043
    41         virtual Constant *clone() const;
    42         virtual void accept( Visitor &v ) { v.visit( this ); }
    43         virtual Constant *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    44         virtual void print( std::ostream &os ) const;
     44        virtual void accept( Visitor & v ) { v.visit( this ); }
     45        virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     46        virtual void print( std::ostream & os ) const;
    4547  private:
    46         Type *type;
    47         std::string value;
     48        Type * type;
     49        std::string rep;
     50        union Val {
     51                unsigned long long ival;
     52                double dval;
     53                Val( unsigned long long ival ) : ival( ival ) {}
     54                Val( double dval ) : dval( dval ) {}
     55        } val;
    4856};
    4957
  • src/SynTree/Expression.cc

    re4d829b r579263a  
    287287}
    288288
    289 // CastExpr *CastExpr::clone() const { return 0; }
    290 
    291289void CastExpr::print( std::ostream &os, int indent ) const {
    292290        os << "Cast of:" << std::endl << std::string( indent+2, ' ' );
     
    354352}
    355353
    356 //// is this right? It's cloning the member, but the member is a declaration so probably shouldn't be cloned...
    357354MemberExpr::MemberExpr( const MemberExpr &other ) :
    358355                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
     
    360357
    361358MemberExpr::~MemberExpr() {
    362         // delete member;
     359        // don't delete the member declaration, since it points somewhere else in the tree
    363360        delete aggregate;
    364361}
     
    590587}
    591588
    592 UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {}
    593 
    594 UntypedValofExpr::~UntypedValofExpr() { delete body; }
    595 
    596 void UntypedValofExpr::print( std::ostream &os, int indent ) const {
    597         os << std::string( indent, ' ' ) << "Valof Expression: " << std::endl;
    598         if ( get_body() != 0 )
    599                 get_body()->print( os, indent + 2 );
    600 }
    601 
    602589RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    603590RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
  • src/SynTree/Expression.h

    re4d829b r579263a  
    226226};
    227227
    228 /// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
     228/// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer.
     229/// Does not take ownership of member.
    229230class MemberExpr : public Expression {
    230231  public:
     
    247248};
    248249
    249 /// VariableExpr represents an expression that simply refers to the value of a named variable
     250/// VariableExpr represents an expression that simply refers to the value of a named variable.
     251/// Does not take ownership of var.
    250252class VariableExpr : public Expression {
    251253  public:
     
    598600};
    599601
    600 /// ValofExpr represents a GCC 'lambda expression'
    601 class UntypedValofExpr : public Expression {
    602   public:
    603         UntypedValofExpr( Statement *_body, Expression *_aname = nullptr ) : Expression( _aname ), body ( _body ) {}
    604         UntypedValofExpr( const UntypedValofExpr & other );
    605         virtual ~UntypedValofExpr();
    606 
    607         Expression * get_value();
    608         Statement * get_body() const { return body; }
    609 
    610         virtual UntypedValofExpr * clone() const { return new UntypedValofExpr( * this ); }
    611         virtual void accept( Visitor & v ) { v.visit( this ); }
    612         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    613         virtual void print( std::ostream & os, int indent = 0 ) const;
    614   private:
    615         Statement * body;
    616 };
    617 
    618602/// RangeExpr represents a range e.g. '3 ... 5' or '1~10'
    619603class RangeExpr : public Expression {
     
    688672        Expression * tuple;
    689673        unsigned int index;
    690 };
    691 
    692 /// MemberTupleExpr represents a tuple member selection operation on a struct type, e.g. s.[a, b, c] after processing by the expression analyzer
    693 class MemberTupleExpr : public Expression {
    694   public:
    695         MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname = nullptr );
    696         MemberTupleExpr( const MemberTupleExpr & other );
    697         virtual ~MemberTupleExpr();
    698 
    699         Expression * get_member() const { return member; }
    700         Expression * get_aggregate() const { return aggregate; }
    701         MemberTupleExpr * set_member( Expression * newValue ) { member = newValue; return this; }
    702         MemberTupleExpr * set_aggregate( Expression * newValue ) { aggregate = newValue; return this; }
    703 
    704         virtual MemberTupleExpr * clone() const { return new MemberTupleExpr( * this ); }
    705         virtual void accept( Visitor & v ) { v.visit( this ); }
    706         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    707         virtual void print( std::ostream & os, int indent = 0 ) const;
    708   private:
    709         Expression * member;
    710         Expression * aggregate;
    711674};
    712675
  • src/SynTree/Initializer.cc

    re4d829b r579263a  
    4242        } // if
    4343}
    44 
    4544
    4645Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
  • src/SynTree/Mutator.cc

    re4d829b r579263a  
    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 Mar 30 16:45:19 2017
    13 // Update Count     : 22
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Jun 22 13:43:00 2017
     13// Update Count     : 24
    1414//
    1515
     
    153153}
    154154
     155Statement *Mutator::mutate( ThrowStmt *throwStmt ) {
     156        throwStmt->set_expr( maybeMutate( throwStmt->get_expr(), *this ) );
     157        throwStmt->set_target( maybeMutate( throwStmt->get_target(), *this ) );
     158        return throwStmt;
     159}
     160
    155161Statement *Mutator::mutate( TryStmt *tryStmt ) {
    156162        tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
    157163        mutateAll( tryStmt->get_catchers(), *this );
     164        tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) );
    158165        return tryStmt;
    159166}
     
    161168Statement *Mutator::mutate( CatchStmt *catchStmt ) {
    162169        catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
     170        catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
    163171        catchStmt->set_body( maybeMutate( catchStmt->get_body(), *this ) );
    164172        return catchStmt;
     
    374382}
    375383
    376 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
    377         valofExpr->set_env( maybeMutate( valofExpr->get_env(), *this ) );
    378         valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ) );
    379         return valofExpr;
    380 }
    381 
    382384Expression *Mutator::mutate( RangeExpr *rangeExpr ) {
    383385        rangeExpr->set_env( maybeMutate( rangeExpr->get_env(), *this ) );
     
    405407        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
    406408        tupleExpr->set_tuple( maybeMutate( tupleExpr->get_tuple(), *this ) );
    407         return tupleExpr;
    408 }
    409 
    410 Expression *Mutator::mutate( MemberTupleExpr *tupleExpr ) {
    411         tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    412         tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
    413         tupleExpr->set_member( maybeMutate( tupleExpr->get_member(), *this ) );
    414         tupleExpr->set_aggregate( maybeMutate( tupleExpr->get_aggregate(), *this ) );
    415409        return tupleExpr;
    416410}
  • src/SynTree/Mutator.h

    re4d829b r579263a  
    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 Feb  9 14:23:23 2017
    13 // Update Count     : 13
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Jun  8 15:45:00 2017
     13// Update Count     : 14
    1414//
    1515#include <cassert>
     
    4646        virtual Statement* mutate( BranchStmt *branchStmt );
    4747        virtual Statement* mutate( ReturnStmt *returnStmt );
    48         virtual Statement* mutate( TryStmt *returnStmt );
     48        virtual Statement* mutate( ThrowStmt *throwStmt );
     49        virtual Statement* mutate( TryStmt *tryStmt );
    4950        virtual Statement* mutate( CatchStmt *catchStmt );
    5051        virtual Statement* mutate( FinallyStmt *catchStmt );
     
    7778        virtual Expression* mutate( ConstructorExpr *ctorExpr );
    7879        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
    79         virtual Expression* mutate( UntypedValofExpr *valofExpr );
    8080        virtual Expression* mutate( RangeExpr *rangeExpr );
    8181        virtual Expression* mutate( UntypedTupleExpr *tupleExpr );
    8282        virtual Expression* mutate( TupleExpr *tupleExpr );
    8383        virtual Expression* mutate( TupleIndexExpr *tupleExpr );
    84         virtual Expression* mutate( MemberTupleExpr *tupleExpr );
    8584        virtual Expression* mutate( TupleAssignExpr *assignExpr );
    8685        virtual Expression* mutate( StmtExpr * stmtExpr );
  • src/SynTree/ObjectDecl.cc

    re4d829b r579263a  
    5656
    5757        if ( init ) {
    58                 os << " with initializer ";
    59                 init->print( os, indent );
    60                 os << std::endl << std::string(indent, ' ');
     58                os << " with initializer " << std::endl;
     59                init->print( os, indent+2 );
     60                os << std::endl << std::string(indent+2, ' ');
    6161                os << "maybeConstructed? " << init->get_maybeConstructed();
    6262        } // if
  • src/SynTree/Statement.cc

    re4d829b r579263a  
    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 Aug 12 13:58:48 2016
    13 // Update Count     : 62
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jun 12 10:37:00 2017
     13// Update Count     : 64
    1414//
    1515
     
    101101}
    102102
    103 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr, bool throwP ) : Statement( labels ), expr( _expr ), isThrow( throwP ) {}
    104 
    105 ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ), isThrow( other.isThrow ) {}
     103ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr ) : Statement( labels ), expr( _expr ) {}
     104
     105ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
    106106
    107107ReturnStmt::~ReturnStmt() {
     
    110110
    111111void ReturnStmt::print( std::ostream &os, int indent ) const {
    112         os << string ( isThrow? "Throw":"Return" ) << " Statement, returning: ";
     112        os <<  "Return Statement, returning: ";
    113113        if ( expr != 0 ) {
    114114                os << endl << string( indent+2, ' ' );
     
    287287}
    288288
    289 TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &_handlers, FinallyStmt *_finallyBlock ) :
     289ThrowStmt::ThrowStmt( std::list<Label> labels, Kind kind, Expression * expr, Expression * target ) :
     290                Statement( labels ), kind(kind), expr(expr), target(target)     {
     291        assertf(Resume == kind || nullptr == target, "Non-local termination throw is not accepted." );
     292}
     293
     294ThrowStmt::ThrowStmt( const ThrowStmt &other ) :
     295        Statement ( other ), kind( other.kind ), expr( maybeClone( other.expr ) ), target( maybeClone( other.target ) ) {
     296}
     297
     298ThrowStmt::~ThrowStmt() {
     299        delete expr;
     300        delete target;
     301}
     302
     303void ThrowStmt::print( std::ostream &os, int indent) const {
     304        if ( target ) {
     305                os << "Non-Local ";
     306        }
     307        os << "Throw Statement, raising: ";
     308        expr->print(os, indent + 4);
     309        if ( target ) {
     310                os << "At: ";
     311                target->print(os, indent + 4);
     312        }
     313}
     314
     315TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<CatchStmt *> &_handlers, FinallyStmt *_finallyBlock ) :
    290316        Statement( labels ), block( tryBlock ),  handlers( _handlers ), finallyBlock( _finallyBlock ) {
    291317}
     
    308334        // handlers
    309335        os << string( indent + 2, ' ' ) << "and handlers: " << endl;
    310         for ( std::list<Statement *>::const_iterator i = handlers.begin(); i != handlers.end(); i++)
     336        for ( std::list<CatchStmt *>::const_iterator i = handlers.begin(); i != handlers.end(); i++)
    311337                (*i )->print( os, indent + 4 );
    312338
     
    318344}
    319345
    320 CatchStmt::CatchStmt( std::list<Label> labels, Declaration *_decl, Statement *_body, bool catchAny ) :
    321         Statement( labels ), decl ( _decl ), body( _body ), catchRest ( catchAny ) {
     346CatchStmt::CatchStmt( std::list<Label> labels, Kind _kind, Declaration *_decl, Expression *_cond, Statement *_body ) :
     347        Statement( labels ), kind ( _kind ), decl ( _decl ), cond ( _cond ), body( _body ) {
    322348}
    323349
    324350CatchStmt::CatchStmt( const CatchStmt & other ) :
    325         Statement( other ), decl ( maybeClone( other.decl ) ), body( maybeClone( other.body ) ), catchRest ( other.catchRest ) {
     351        Statement( other ), kind ( other.kind ), decl ( maybeClone( other.decl ) ), cond ( maybeClone( other.cond ) ), body( maybeClone( other.body ) ) {
    326352}
    327353
     
    332358
    333359void CatchStmt::print( std::ostream &os, int indent ) const {
    334         os << "Catch Statement" << endl;
     360        os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl;
    335361
    336362        os << string( indent, ' ' ) << "... catching" << endl;
     
    338364                decl->printShort( os, indent + 4 );
    339365                os << endl;
    340         } else if ( catchRest )
    341                 os << string( indent + 4 , ' ' ) << "the rest" << endl;
     366        }
    342367        else
    343368                os << string( indent + 4 , ' ' ) << ">>> Error:  this catch clause must have a declaration <<<" << endl;
  • src/SynTree/Statement.h

    re4d829b r579263a  
    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 Aug 12 13:57:46 2016
    13 // Update Count     : 65
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jun 12 13:35:00 2017
     13// Update Count     : 67
    1414//
    1515
     
    5757  private:
    5858        std::list<Statement*> kids;
     59};
     60
     61class NullStmt : public CompoundStmt {
     62  public:
     63        NullStmt();
     64        NullStmt( std::list<Label> labels );
     65
     66        virtual NullStmt *clone() const { return new NullStmt( *this ); }
     67        virtual void accept( Visitor &v ) { v.visit( this ); }
     68        virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     69        virtual void print( std::ostream &os, int indent = 0 ) const;
     70
     71  private:
    5972};
    6073
     
    261274class ReturnStmt : public Statement {
    262275  public:
    263         ReturnStmt( std::list<Label> labels, Expression *expr, bool throwP = false );
     276        ReturnStmt( std::list<Label> labels, Expression *expr );
    264277        ReturnStmt( const ReturnStmt &other );
    265278        virtual ~ReturnStmt();
     
    274287  private:
    275288        Expression *expr;
    276         bool isThrow;
    277 };
    278 
    279 
    280 class NullStmt : public CompoundStmt {
    281   public:
    282         NullStmt();
    283         NullStmt( std::list<Label> labels );
    284 
    285         virtual NullStmt *clone() const { return new NullStmt( *this ); }
    286         virtual void accept( Visitor &v ) { v.visit( this ); }
    287         virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    288         virtual void print( std::ostream &os, int indent = 0 ) const;
    289 
    290   private:
     289};
     290
     291class ThrowStmt : public Statement {
     292  public:
     293        enum Kind { Terminate, Resume };
     294
     295        ThrowStmt( std::list<Label> labels, Kind kind, Expression * expr, Expression * target = nullptr );
     296        ThrowStmt( const ThrowStmt &other );
     297        virtual ~ThrowStmt();
     298
     299        Kind get_kind() { return kind; }
     300        Expression * get_expr() { return expr; }
     301        void set_expr( Expression * newExpr ) { expr = newExpr; }
     302        Expression * get_target() { return target; }
     303        void set_target( Expression * newTarget ) { target = newTarget; }
     304
     305        virtual ThrowStmt *clone() const { return new ThrowStmt( *this ); }
     306        virtual void accept( Visitor &v ) { v.visit( this ); }
     307        virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     308        virtual void print( std::ostream &os, int indent = 0 ) const;
     309  private:
     310        Kind kind;
     311        Expression * expr;
     312        Expression * target;
    291313};
    292314
    293315class TryStmt : public Statement {
    294316  public:
    295         TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &handlers, FinallyStmt *finallyBlock = 0 );
     317        TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
    296318        TryStmt( const TryStmt &other );
    297319        virtual ~TryStmt();
     
    299321        CompoundStmt *get_block() const { return block; }
    300322        void set_block( CompoundStmt *newValue ) { block = newValue; }
    301         std::list<Statement *>& get_catchers() { return handlers; }
     323        std::list<CatchStmt *>& get_catchers() { return handlers; }
    302324
    303325        FinallyStmt *get_finally() const { return finallyBlock; }
     
    311333  private:
    312334        CompoundStmt *block;
    313         std::list<Statement *> handlers;
     335        std::list<CatchStmt *> handlers;
    314336        FinallyStmt *finallyBlock;
    315337};
     
    317339class CatchStmt : public Statement {
    318340  public:
    319         CatchStmt( std::list<Label> labels, Declaration *decl, Statement *body, bool catchAny = false );
     341        enum Kind { Terminate, Resume };
     342
     343        CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl,
     344                   Expression *cond, Statement *body );
    320345        CatchStmt( const CatchStmt &other );
    321346        virtual ~CatchStmt();
    322347
     348        Kind get_kind() { return kind; }
    323349        Declaration *get_decl() { return decl; }
    324350        void set_decl( Declaration *newValue ) { decl = newValue; }
    325 
     351        Expression *get_cond() { return cond; }
     352        void set_cond( Expression *newCond ) { cond = newCond; }
    326353        Statement *get_body() { return body; }
    327354        void set_body( Statement *newValue ) { body = newValue; }
     
    333360
    334361  private:
     362        Kind kind;
    335363        Declaration *decl;
     364        Expression *cond;
    336365        Statement *body;
    337         bool catchRest;
    338366};
    339367
  • src/SynTree/SynTree.h

    re4d829b r579263a  
    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 Feb  9 14:23:49 2017
    13 // Update Count     : 8
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Jun  8 17:00:00 2017
     13// Update Count     : 9
    1414//
    1515
     
    5151class BranchStmt;
    5252class ReturnStmt;
     53class ThrowStmt;
    5354class TryStmt;
    5455class CatchStmt;
     
    8990class TupleExpr;
    9091class TupleIndexExpr;
    91 class MemberTupleExpr;
    9292class TupleAssignExpr;
    9393class StmtExpr;
  • src/SynTree/TupleExpr.cc

    re4d829b r579263a  
    7878}
    7979
    80 MemberTupleExpr::MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname ) : Expression( _aname ) {
    81         set_result( maybeClone( member->get_result() ) ); // xxx - ???
    82 }
    83 
    84 MemberTupleExpr::MemberTupleExpr( const MemberTupleExpr &other ) : Expression( other ), member( other.member->clone() ), aggregate( other.aggregate->clone() ) {
    85 }
    86 
    87 MemberTupleExpr::~MemberTupleExpr() {
    88         delete member;
    89         delete aggregate;
    90 }
    91 
    92 void MemberTupleExpr::print( std::ostream &os, int indent ) const {
    93         os << "Member Tuple Expression, with aggregate:" << std::endl;
    94         os << std::string( indent+2, ' ' );
    95         aggregate->print( os, indent+2 );
    96         os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
    97         os << std::string( indent+2, ' ' );
    98         member->print( os, indent+2 );
    99         Expression::print( os, indent );
    100 }
    101 
    10280TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ) {
    10381        // convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments
  • src/SynTree/Visitor.cc

    re4d829b r579263a  
    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 Mar 30 16:45:25 2017
    13 // Update Count     : 24
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Jun 22 13:41:00 2017
     13// Update Count     : 26
    1414//
    1515
     
    129129}
    130130
     131void Visitor::visit( ThrowStmt * throwStmt ) {
     132        maybeAccept( throwStmt->get_expr(), *this );
     133        maybeAccept( throwStmt->get_target(), *this );
     134}
     135
    131136void Visitor::visit( TryStmt *tryStmt ) {
    132137        maybeAccept( tryStmt->get_block(), *this );
    133138        acceptAll( tryStmt->get_catchers(), *this );
     139        maybeAccept( tryStmt->get_finally(), *this );
    134140}
    135141
    136142void Visitor::visit( CatchStmt *catchStmt ) {
    137143        maybeAccept( catchStmt->get_decl(), *this );
     144        maybeAccept( catchStmt->get_cond(), *this );
    138145        maybeAccept( catchStmt->get_body(), *this );
    139146}
     
    296303}
    297304
    298 void Visitor::visit( UntypedValofExpr *valofExpr ) {
    299         maybeAccept( valofExpr->get_result(), *this );
    300         maybeAccept( valofExpr->get_body(), *this );
    301 }
    302 
    303305void Visitor::visit( RangeExpr *rangeExpr ) {
    304306        maybeAccept( rangeExpr->get_low(), *this );
     
    319321        maybeAccept( tupleExpr->get_result(), *this );
    320322        maybeAccept( tupleExpr->get_tuple(), *this );
    321 }
    322 
    323 void Visitor::visit( MemberTupleExpr *tupleExpr ) {
    324         maybeAccept( tupleExpr->get_result(), *this );
    325         maybeAccept( tupleExpr->get_member(), *this );
    326         maybeAccept( tupleExpr->get_aggregate(), *this );
    327323}
    328324
  • src/SynTree/Visitor.h

    re4d829b r579263a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed May  3 08:58:00 2017
    13 // Update Count     : 10
     12// Last Modified On : Thr Jun 08 15:45:00 2017
     13// Update Count     : 11
    1414//
    1515
     
    4949        virtual void visit( BranchStmt *branchStmt );
    5050        virtual void visit( ReturnStmt *returnStmt );
     51        virtual void visit( ThrowStmt *throwStmt );
    5152        virtual void visit( TryStmt *tryStmt );
    5253        virtual void visit( CatchStmt *catchStmt );
     
    8081        virtual void visit( ConstructorExpr * ctorExpr );
    8182        virtual void visit( CompoundLiteralExpr *compLitExpr );
    82         virtual void visit( UntypedValofExpr *valofExpr );
    8383        virtual void visit( RangeExpr *rangeExpr );
    8484        virtual void visit( UntypedTupleExpr *tupleExpr );
    8585        virtual void visit( TupleExpr *tupleExpr );
    8686        virtual void visit( TupleIndexExpr *tupleExpr );
    87         virtual void visit( MemberTupleExpr *tupleExpr );
    8887        virtual void visit( TupleAssignExpr *assignExpr );
    8988        virtual void visit( StmtExpr * stmtExpr );
  • src/SynTree/ZeroOneType.cc

    re4d829b r579263a  
    2020ZeroType::ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {}
    2121
    22 void ZeroType::print( std::ostream &os, int indent ) const {
     22void ZeroType::print( std::ostream &os, __attribute__((unused)) int indent ) const {
    2323        os << "zero_t";
    2424}
     
    2828OneType::OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {}
    2929
    30 void OneType::print( std::ostream &os, int indent ) const {
     30void OneType::print( std::ostream &os, __attribute__((unused)) int indent ) const {
    3131        os << "one_t";
    3232}
  • src/Tuples/TupleExpansion.cc

    re4d829b r579263a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:05:17 2017
    13 // Update Count     : 15
     12// Last Modified On : Wed Jun 21 17:35:04 2017
     13// Update Count     : 19
    1414//
    1515
     
    191191                                commaExpr->set_arg1( nullptr );
    192192                        }
    193                         BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    194                         ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ), new SingleInit( new ConstantExpr( Constant( boolType->clone(), "0" ) ) ) );
     193                        ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ),
     194                                                                                                        new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    195195                        addDeclaration( finished );
    196196                        // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
    197197                        // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code.
    198                         Expression * assignFinished = UntypedExpr::createAssign( new VariableExpr(finished), new ConstantExpr( Constant( boolType->clone(), "1" ) ) );
     198                        Expression * assignFinished = UntypedExpr::createAssign( new VariableExpr(finished), new ConstantExpr( Constant::from_int( 1 ) ) );
    199199                        ConditionalExpr * condExpr = new ConditionalExpr( new VariableExpr( finished ), var->clone(),
    200200                                new CommaExpr( new CommaExpr( assignUnq, assignFinished ), var->clone() ) );
     
    354354                                maybeImpure = true;
    355355                        }
    356                         virtual void visit( UntypedExpr * untypedExpr ) { maybeImpure = true; }
     356                        virtual void visit( __attribute__((unused)) UntypedExpr * untypedExpr ) { maybeImpure = true; }
    357357                        bool maybeImpure = false;
    358358                };
  • src/libcfa/concurrency/alarm.c

    re4d829b r579263a  
    104104
    105105static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    106         assert( it );
    107         assert( (*it)->next == n );
     106        verify( it );
     107        verify( (*it)->next == n );
    108108
    109109        (*it)->next = n->next;
  • src/libcfa/concurrency/coroutine

    re4d829b r579263a  
    7171// Suspend implementation inlined for performance
    7272static inline void suspend() {
    73       coroutine_desc * src = this_coroutine();          // optimization
     73        coroutine_desc * src = this_coroutine();                // optimization
    7474
    7575        assertf( src->last != 0,
     
    9191        coroutine_desc * dst = get_coroutine(cor);
    9292
    93       if( unlikely(!dst->stack.base) ) {
     93        if( unlikely(!dst->stack.base) ) {
    9494                create_stack(&dst->stack, dst->stack.size);
    9595                CtxStart(cor, CtxInvokeCoroutine);
    9696        }
    9797
    98       // not resuming self ?
     98        // not resuming self ?
    9999        if ( src != dst ) {
    100100                assertf( dst->state != Halted ,
     
    103103                        src->name, src, dst->name, dst );
    104104
    105             // set last resumer
     105                // set last resumer
    106106                dst->last = src;
    107107        } // if
    108108
    109       // always done for performance testing
     109        // always done for performance testing
    110110        CoroutineCtxSwitch( src, dst );
    111111}
     
    114114        coroutine_desc * src = this_coroutine();                // optimization
    115115
    116       // not resuming self ?
     116        // not resuming self ?
    117117        if ( src != dst ) {
    118118                assertf( dst->state != Halted ,
     
    121121                        src->name, src, dst->name, dst );
    122122
    123             // set last resumer
     123                // set last resumer
    124124                dst->last = src;
    125125        } // if
    126126
    127       // always done for performance testing
     127        // always done for performance testing
    128128        CoroutineCtxSwitch( src, dst );
    129129}
  • src/libcfa/concurrency/kernel.c

    re4d829b r579263a  
    311311        // appropriate stack.
    312312        proc_cor_storage.__cor.state = Active;
    313       main( &proc_cor_storage );
    314       proc_cor_storage.__cor.state = Halted;
     313        main( &proc_cor_storage );
     314        proc_cor_storage.__cor.state = Halted;
    315315
    316316        // Main routine of the core returned, the core is now fully terminated
     
    333333        if( !thrd ) return;
    334334
    335         assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
     335        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    336336       
    337337        lock( &systemProcessor->proc.cltr->lock );
     
    577577
    578578void append( __thread_queue_t * this, thread_desc * t ) {
    579         assert(this->tail != NULL);
     579        verify(this->tail != NULL);
    580580        *this->tail = t;
    581581        this->tail = &t->next;
     
    599599
    600600void push( __condition_stack_t * this, __condition_criterion_t * t ) {
    601         assert( !t->next );
     601        verify( !t->next );
    602602        t->next = this->top;
    603603        this->top = t;
  • src/libcfa/concurrency/kernel_private.h

    re4d829b r579263a  
    2222
    2323#include "alarm.h"
     24
     25#include "libhdr.h"
    2426
    2527//-----------------------------------------------------------------------------
     
    6668
    6769static inline void enable_interrupts_noRF() {
    68         unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    69         assert( prev != (unsigned short) 0 );
     70        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     71        verify( prev != (unsigned short) 0 );
    7072}
    7173
    7274static inline void enable_interrupts() {
    73         unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    74         assert( prev != (unsigned short) 0 );
     75        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     76        verify( prev != (unsigned short) 0 );
    7577        if( prev == 1 && this_processor->pending_preemption ) {
    7678                ScheduleInternal( this_processor->current_thread );
  • src/libcfa/concurrency/monitor

    re4d829b r579263a  
    2626static inline void ?{}(monitor_desc * this) {
    2727        this->owner = NULL;
    28       this->stack_owner = NULL;
     28        this->stack_owner = NULL;
    2929        this->recursion = 0;
    3030}
     
    3333        monitor_desc ** m;
    3434        int count;
    35       monitor_desc ** prev_mntrs;
    36       unsigned short  prev_count;
     35        monitor_desc ** prev_mntrs;
     36        unsigned short  prev_count;
    3737};
    3838
  • src/libcfa/concurrency/monitor.c

    re4d829b r579263a  
    5656                else if( this->owner == thrd) {
    5757                        //We already have the monitor, just not how many times we took it
    58                         assert( this->recursion > 0 );
     58                        verify( this->recursion > 0 );
    5959                        this->recursion += 1;
    6060                }
     
    7878                lock( &this->lock );
    7979
    80                 thread_desc * thrd = this_thread();
    81 
    8280                LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    83                 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
     81                verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion );
    8482
    8583                //Leaving a recursion level, decrement the counter
     
    167165        //Check that everything is as expected
    168166        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    169         assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    170         assertf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
     167        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
     168        verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
    171169
    172170        unsigned short count = this->monitor_count;
     
    229227
    230228        //Check that everything is as expected
    231         assert( this->monitors );
    232         assert( this->monitor_count != 0 );
     229        verify( this->monitors );
     230        verify( this->monitor_count != 0 );
    233231
    234232        unsigned short count = this->monitor_count;
     
    278276
    279277        //Check that everything is as expected
    280         assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    281         assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
     278        verifyf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
     279        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    282280
    283281        unsigned short count = this->monitor_count;
     
    327325
    328326uintptr_t front( condition * this ) {
    329         LIB_DEBUG_DO(
    330                 if( is_empty(this) ) {
    331                         abortf( "Attempt to access user data on an empty condition.\n"
    332                     "Possible cause is not checking if the condition is empty before reading stored data." );
    333                 }
     327        verifyf( !is_empty(this),
     328                "Attempt to access user data on an empty condition.\n"
     329                "Possible cause is not checking if the condition is empty before reading stored data."
    334330        );
    335331        return this->blocked.head->user_info;
     
    491487
    492488void append( __condition_blocked_queue_t * this, __condition_node_t * c ) {
    493         assert(this->tail != NULL);
     489        verify(this->tail != NULL);
    494490        *this->tail = c;
    495491        this->tail = &c->next;
  • src/libcfa/containers/maybe

    re4d829b r579263a  
    1010// Created On       : Wed May 24 14:43:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May 25 16:36:00 2017
    13 // Update Count     : 1
     12// Last Modified On : Fri Jun 16 15:42:00 2017
     13// Update Count     : 2
    1414//
    1515
     
    4646bool ?!=?(maybe(T) this, zero_t);
    4747
     48/* Waiting for bug#11 to be fixed.
    4849forall(otype T)
    4950maybe(T) maybe_value(T value);
     
    5152forall(otype T)
    5253maybe(T) maybe_none();
     54*/
    5355
    5456forall(otype T)
  • src/libcfa/containers/result

    re4d829b r579263a  
    1010// Created On       : Wed May 24 14:45:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May 25 16:39:00 2017
    13 // Update Count     : 1
     12// Last Modified On : Fri Jun 16 15:41:00 2017
     13// Update Count     : 2
    1414//
    1515
     
    5555bool ?!=?(result(T, E) this, zero_t);
    5656
     57/* Wating for bug#11 to be fixed.
    5758forall(otype T, otype E)
    5859result(T, E) result_value(T value);
     
    6061forall(otype T, otype E)
    6162result(T, E) result_error(E error);
     63*/
    6264
    6365forall(otype T, otype E)
  • src/libcfa/containers/result.c

    re4d829b r579263a  
    7474forall(otype T, otype E)
    7575bool ?!=?(result(T, E) this, zero_t) {
    76         return !this.has_value;
     76        return this.has_value;
    7777}
    7878
     
    100100forall(otype T, otype E)
    101101E get_error(result(T, E) * this) {
    102         assertf(this->has_value, "attempt to get from result without error");
     102        assertf(!this->has_value, "attempt to get from result without error");
    103103        return this->error;
    104104}
  • src/libcfa/libhdr/libdebug.h

    re4d829b r579263a  
    1818
    1919#ifdef __CFA_DEBUG__
    20       #define LIB_DEBUG_DO(x) x
    21       #define LIB_NO_DEBUG_DO(x) ((void)0)
     20        #define LIB_DEBUG_DO(x) x
     21        #define LIB_NO_DEBUG_DO(x) ((void)0)
    2222#else
    23       #define LIB_DEBUG_DO(x) ((void)0)
    24       #define LIB_NO_DEBUG_DO(x) x     
     23        #define LIB_DEBUG_DO(x) ((void)0)
     24        #define LIB_NO_DEBUG_DO(x) x     
    2525#endif
     26
     27#if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__))
     28        #define verify(x) assert(x)
     29        #define verifyf(x, ...) assertf(x, __VA_ARGS__)
     30#else
     31        #define verify(x)
     32        #define verifyf(x, ...)
     33#endif
     34
    2635
    2736#ifdef __cforall
  • src/tests/.expect/32/KRfunctions.txt

    re4d829b r579263a  
    66extern int printf(const char *__restrict __format, ...);
    77int __f0__Fi_iPCii__1(int __a__i_1, const int *__b__PCi_1, int __c__i_1){
    8     int ___retval_f0__i_1;
     8    __attribute__ ((unused)) int ___retval_f0__i_1;
    99}
    1010int __f1__Fi_PiiPi__1(int *__a__Pi_1, __attribute__ ((unused)) int __b__i_1, int *__c__Pi_1){
    11     int ___retval_f1__i_1;
     11    __attribute__ ((unused)) int ___retval_f1__i_1;
    1212}
    1313int __f2__Fi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    14     int ___retval_f2__i_1;
     14    __attribute__ ((unused)) int ___retval_f2__i_1;
    1515}
    1616struct S {
     
    4040}
    4141int __f3__Fi_2sS2sSPi__1(struct S __a__2sS_1, struct S __b__2sS_1, int *__c__Pi_1){
    42     int ___retval_f3__i_1;
     42    __attribute__ ((unused)) int ___retval_f3__i_1;
    4343    struct S __s__2sS_2;
    4444}
    4545int __f4__Fi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    46     int ___retval_f4__i_1;
     46    __attribute__ ((unused)) int ___retval_f4__i_1;
    4747}
    4848int __f5__Fi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    49     int ___retval_f5__i_1;
     49    __attribute__ ((unused)) int ___retval_f5__i_1;
    5050}
    5151int (*__f6__FPFi_i__iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))(int __anonymous_object0){
    52     int (*___retval_f6__PFi_i__1)(int __anonymous_object1);
     52    __attribute__ ((unused)) int (*___retval_f6__PFi_i__1)(int __anonymous_object1);
    5353}
    5454int (*__f7__FPFi_ii__iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))(int __a__i_1, int __b__i_1){
    55     int (*___retval_f7__PFi_ii__1)(int __a__i_1, int __b__i_1);
     55    __attribute__ ((unused)) int (*___retval_f7__PFi_ii__1)(int __a__i_1, int __b__i_1);
    5656}
    5757int *__f8__FPi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    58     int *___retval_f8__Pi_1;
     58    __attribute__ ((unused)) int *___retval_f8__Pi_1;
    5959}
    6060int *const __f9__FCPi_PiiPi__1(int *__a__Pi_1, int __b__i_1, int *__c__Pi_1){
    61     int *const ___retval_f9__CPi_1;
     61    __attribute__ ((unused)) int *const ___retval_f9__CPi_1;
    6262}
    6363int *(*__f10__FPFPi_ii__iPiPid__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1, double __y__d_1))(int __x__i_1, int __y__i_1){
    64     int *(*___retval_f10__PFPi_ii__1)(int __x__i_1, int __y__i_1);
     64    __attribute__ ((unused)) int *(*___retval_f10__PFPi_ii__1)(int __x__i_1, int __y__i_1);
    6565    int *__x__FPi_ii__2(int __anonymous_object2, int __anonymous_object3);
    6666    ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */);
     
    6868}
    6969int (*__f11__FPA0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[]{
    70     int (*___retval_f11__PA0i_1)[];
     70    __attribute__ ((unused)) int (*___retval_f11__PA0i_1)[];
    7171}
    7272int (*__f12__FPA0A0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[][((unsigned int )10)]{
    73     int (*___retval_f12__PA0A0i_1)[][((unsigned int )10)];
     73    __attribute__ ((unused)) int (*___retval_f12__PA0A0i_1)[][((unsigned int )10)];
    7474}
    7575int (*__f13__FPA0A0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[][((unsigned int )10)]{
    76     int (*___retval_f13__PA0A0i_1)[][((unsigned int )10)];
     76    __attribute__ ((unused)) int (*___retval_f13__PA0A0i_1)[][((unsigned int )10)];
    7777}
    7878int (*__f14__FPA0A0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[][((unsigned int )10)]{
    79     int (*___retval_f14__PA0A0i_1)[][((unsigned int )10)];
     79    __attribute__ ((unused)) int (*___retval_f14__PA0A0i_1)[][((unsigned int )10)];
    8080}
    8181const int __fred__FCi___1(){
    82     const int ___retval_fred__Ci_1;
     82    __attribute__ ((unused)) const int ___retval_fred__Ci_1;
    8383    int *(*__x__PFPi_ii__2)(int __anonymous_object4, int __anonymous_object5);
    8484    int __a__i_2;
     
    8888    ((void)((*((int *(**)(int __x__i_1, int __y__i_1))(&_tmp_cp_ret0)))) /* ^?{} */);
    8989    const int __f1__FCi_iPiPi__2(int __a__i_2, int *__b__Pi_2, int *__c__Pi_2){
    90         const int ___retval_f1__Ci_2;
     90        __attribute__ ((unused)) const int ___retval_f1__Ci_2;
    9191    }
    9292    const int __f2__FCi_iii__2(int __a__i_2, int __b__i_2, int __c__i_2){
    93         const int ___retval_f2__Ci_2;
     93        __attribute__ ((unused)) const int ___retval_f2__Ci_2;
    9494    }
    9595}
  • src/tests/.expect/32/attributes.txt

    re4d829b r579263a  
    66extern int printf(const char *__restrict __format, ...);
    77int __la__Fi___1(){
    8     int ___retval_la__i_1;
     8    __attribute__ ((unused)) int ___retval_la__i_1;
    99    L: __attribute__ ((unused)) ((void)1);
    1010}
     
    226226__attribute__ ((unused,used)) int __f1__Fi___1();
    227227__attribute__ ((unused)) int __f1__Fi___1(){
    228     int ___retval_f1__i_1;
     228    __attribute__ ((unused)) int ___retval_f1__i_1;
    229229}
    230230__attribute__ ((unused,unused,unused,used)) int **const __f2__FCPPi___1();
    231231__attribute__ ((unused,unused,unused)) int **const __f2__FCPPi___1(){
    232     int **const ___retval_f2__CPPi_1;
     232    __attribute__ ((unused)) int **const ___retval_f2__CPPi_1;
    233233}
    234234__attribute__ ((unused,used,unused)) int (*__f3__FPA0i_i__1(int __anonymous_object1))[];
    235235__attribute__ ((unused,unused)) int (*__f3__FPA0i_i__1(int __p__i_1))[]{
    236     int (*___retval_f3__PA0i_1)[];
     236    __attribute__ ((unused)) int (*___retval_f3__PA0i_1)[];
    237237}
    238238__attribute__ ((unused,used,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object2);
    239239__attribute__ ((unused,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object3){
    240     int (*___retval_f4__PFi_i__1)(int __anonymous_object4);
     240    __attribute__ ((unused)) int (*___retval_f4__PFi_i__1)(int __anonymous_object4);
    241241}
    242242int __vtr__Fi___1(){
    243     int ___retval_vtr__i_1;
     243    __attribute__ ((unused)) int ___retval_vtr__i_1;
    244244    __attribute__ ((unused,unused,used)) int __t1__i_2;
    245245    __attribute__ ((unused,unused,unused,unused,unused)) int **__t2__PPi_2;
     
    251251int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1);
    252252int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1){
    253     int ___retval_ipd1__i_1;
     253    __attribute__ ((unused)) int ___retval_ipd1__i_1;
    254254}
    255255int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
    256256int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){
    257     int ___retval_ipd2__i_1;
     257    __attribute__ ((unused)) int ___retval_ipd2__i_1;
    258258}
    259259int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
    260260int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){
    261     int ___retval_ipd3__i_1;
     261    __attribute__ ((unused)) int ___retval_ipd3__i_1;
    262262}
    263263int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)());
    264264int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)()){
    265     int ___retval_ipd4__i_1;
     265    __attribute__ ((unused)) int ___retval_ipd4__i_1;
    266266}
    267267int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) int __Foo__i_1);
     
    273273int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9)));
    274274int __ad__Fi___1(){
    275     int ___retval_ad__i_1;
     275    __attribute__ ((unused)) int ___retval_ad__i_1;
    276276    __attribute__ ((used,unused)) int __ad1__i_2;
    277277    __attribute__ ((unused,unused,unused)) int *__ad2__Pi_2;
  • src/tests/.expect/32/declarationSpecifier.txt

    re4d829b r579263a  
    670670static inline volatile const short __f48__FCVs___1();
    671671int __main__Fi_iPPCc__1(int __argc__i_1, const char **__argv__PPCc_1){
    672     int ___retval_main__i_1;
     672    __attribute__ ((unused)) int ___retval_main__i_1;
    673673    ((void)(___retval_main__i_1=((int )0)) /* ?{} */);
    674674    return ((int )___retval_main__i_1);
     
    685685static inline int invoke_main(int argc, char **argv, char **envp);
    686686int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
    687     int ___retval_main__i_1;
     687    __attribute__ ((unused)) int ___retval_main__i_1;
    688688    int _tmp_cp_ret0;
    689689    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
  • src/tests/.expect/32/extension.txt

    re4d829b r579263a  
    8585__extension__ int j;
    8686__extension__ int __fred__Fi_i__1(int __p__i_1){
    87     int ___retval_fred__i_1;
     87    __attribute__ ((unused)) int ___retval_fred__i_1;
    8888    __extension__ struct S {
    8989        __extension__ int __a__i_2;
     
    105105    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    106106    __extension__ int __mary__Fi_i__2(int __p__i_2){
    107         int ___retval_mary__i_2;
     107        __attribute__ ((unused)) int ___retval_mary__i_2;
    108108    }
    109109    ((void)__extension__ sizeof(3));
  • src/tests/.expect/32/gccExtensions.txt

    re4d829b r579263a  
    77extern int __x__i_1 asm ( "xx" );
    88int __main__Fi_iPPCc__1(int __argc__i_1, const char **__argv__PPCc_1){
    9     int ___retval_main__i_1;
     9    __attribute__ ((unused)) int ___retval_main__i_1;
    1010    asm ( "nop" :  :  :  );
    1111    asm ( "nop" :  :  :  );
     
    2626    const int __i3__Ci_2;
    2727    inline int __f1__Fi___2(){
    28         int ___retval_f1__i_2;
     28        __attribute__ ((unused)) int ___retval_f1__i_2;
    2929    }
    3030    inline int __f2__Fi___2(){
    31         int ___retval_f2__i_2;
     31        __attribute__ ((unused)) int ___retval_f2__i_2;
    3232    }
    3333    int __s1__i_2;
     
    182182static inline int invoke_main(int argc, char **argv, char **envp);
    183183int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
    184     int ___retval_main__i_1;
     184    __attribute__ ((unused)) int ___retval_main__i_1;
    185185    int _tmp_cp_ret0;
    186186    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
  • src/tests/.expect/64/KRfunctions.txt

    re4d829b r579263a  
    66extern int printf(const char *__restrict __format, ...);
    77int __f0__Fi_iPCii__1(int __a__i_1, const int *__b__PCi_1, int __c__i_1){
    8     int ___retval_f0__i_1;
     8    __attribute__ ((unused)) int ___retval_f0__i_1;
    99}
    1010int __f1__Fi_PiiPi__1(int *__a__Pi_1, __attribute__ ((unused)) int __b__i_1, int *__c__Pi_1){
    11     int ___retval_f1__i_1;
     11    __attribute__ ((unused)) int ___retval_f1__i_1;
    1212}
    1313int __f2__Fi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    14     int ___retval_f2__i_1;
     14    __attribute__ ((unused)) int ___retval_f2__i_1;
    1515}
    1616struct S {
     
    4040}
    4141int __f3__Fi_2sS2sSPi__1(struct S __a__2sS_1, struct S __b__2sS_1, int *__c__Pi_1){
    42     int ___retval_f3__i_1;
     42    __attribute__ ((unused)) int ___retval_f3__i_1;
    4343    struct S __s__2sS_2;
    4444}
    4545int __f4__Fi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    46     int ___retval_f4__i_1;
     46    __attribute__ ((unused)) int ___retval_f4__i_1;
    4747}
    4848int __f5__Fi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    49     int ___retval_f5__i_1;
     49    __attribute__ ((unused)) int ___retval_f5__i_1;
    5050}
    5151int (*__f6__FPFi_i__iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))(int __anonymous_object0){
    52     int (*___retval_f6__PFi_i__1)(int __anonymous_object1);
     52    __attribute__ ((unused)) int (*___retval_f6__PFi_i__1)(int __anonymous_object1);
    5353}
    5454int (*__f7__FPFi_ii__iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))(int __a__i_1, int __b__i_1){
    55     int (*___retval_f7__PFi_ii__1)(int __a__i_1, int __b__i_1);
     55    __attribute__ ((unused)) int (*___retval_f7__PFi_ii__1)(int __a__i_1, int __b__i_1);
    5656}
    5757int *__f8__FPi_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1){
    58     int *___retval_f8__Pi_1;
     58    __attribute__ ((unused)) int *___retval_f8__Pi_1;
    5959}
    6060int *const __f9__FCPi_PiiPi__1(int *__a__Pi_1, int __b__i_1, int *__c__Pi_1){
    61     int *const ___retval_f9__CPi_1;
     61    __attribute__ ((unused)) int *const ___retval_f9__CPi_1;
    6262}
    6363int *(*__f10__FPFPi_ii__iPiPid__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1, double __y__d_1))(int __x__i_1, int __y__i_1){
    64     int *(*___retval_f10__PFPi_ii__1)(int __x__i_1, int __y__i_1);
     64    __attribute__ ((unused)) int *(*___retval_f10__PFPi_ii__1)(int __x__i_1, int __y__i_1);
    6565    int *__x__FPi_ii__2(int __anonymous_object2, int __anonymous_object3);
    6666    ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */);
     
    6868}
    6969int (*__f11__FPA0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[]{
    70     int (*___retval_f11__PA0i_1)[];
     70    __attribute__ ((unused)) int (*___retval_f11__PA0i_1)[];
    7171}
    7272int (*__f12__FPA0A0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[][((long unsigned int )10)]{
    73     int (*___retval_f12__PA0A0i_1)[][((long unsigned int )10)];
     73    __attribute__ ((unused)) int (*___retval_f12__PA0A0i_1)[][((long unsigned int )10)];
    7474}
    7575int (*__f13__FPA0A0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[][((long unsigned int )10)]{
    76     int (*___retval_f13__PA0A0i_1)[][((long unsigned int )10)];
     76    __attribute__ ((unused)) int (*___retval_f13__PA0A0i_1)[][((long unsigned int )10)];
    7777}
    7878int (*__f14__FPA0A0i_iPiPi__1(int __a__i_1, int *__b__Pi_1, int *__c__Pi_1))[][((long unsigned int )10)]{
    79     int (*___retval_f14__PA0A0i_1)[][((long unsigned int )10)];
     79    __attribute__ ((unused)) int (*___retval_f14__PA0A0i_1)[][((long unsigned int )10)];
    8080}
    8181const int __fred__FCi___1(){
    82     const int ___retval_fred__Ci_1;
     82    __attribute__ ((unused)) const int ___retval_fred__Ci_1;
    8383    int *(*__x__PFPi_ii__2)(int __anonymous_object4, int __anonymous_object5);
    8484    int __a__i_2;
     
    8888    ((void)((*((int *(**)(int __x__i_1, int __y__i_1))(&_tmp_cp_ret0)))) /* ^?{} */);
    8989    const int __f1__FCi_iPiPi__2(int __a__i_2, int *__b__Pi_2, int *__c__Pi_2){
    90         const int ___retval_f1__Ci_2;
     90        __attribute__ ((unused)) const int ___retval_f1__Ci_2;
    9191    }
    9292    const int __f2__FCi_iii__2(int __a__i_2, int __b__i_2, int __c__i_2){
    93         const int ___retval_f2__Ci_2;
     93        __attribute__ ((unused)) const int ___retval_f2__Ci_2;
    9494    }
    9595}
  • src/tests/.expect/64/attributes.txt

    re4d829b r579263a  
    66extern int printf(const char *__restrict __format, ...);
    77int __la__Fi___1(){
    8     int ___retval_la__i_1;
     8    __attribute__ ((unused)) int ___retval_la__i_1;
    99    L: __attribute__ ((unused)) ((void)1);
    1010}
     
    226226__attribute__ ((unused,used)) int __f1__Fi___1();
    227227__attribute__ ((unused)) int __f1__Fi___1(){
    228     int ___retval_f1__i_1;
     228    __attribute__ ((unused)) int ___retval_f1__i_1;
    229229}
    230230__attribute__ ((unused,unused,unused,used)) int **const __f2__FCPPi___1();
    231231__attribute__ ((unused,unused,unused)) int **const __f2__FCPPi___1(){
    232     int **const ___retval_f2__CPPi_1;
     232    __attribute__ ((unused)) int **const ___retval_f2__CPPi_1;
    233233}
    234234__attribute__ ((unused,used,unused)) int (*__f3__FPA0i_i__1(int __anonymous_object1))[];
    235235__attribute__ ((unused,unused)) int (*__f3__FPA0i_i__1(int __p__i_1))[]{
    236     int (*___retval_f3__PA0i_1)[];
     236    __attribute__ ((unused)) int (*___retval_f3__PA0i_1)[];
    237237}
    238238__attribute__ ((unused,used,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object2);
    239239__attribute__ ((unused,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object3){
    240     int (*___retval_f4__PFi_i__1)(int __anonymous_object4);
     240    __attribute__ ((unused)) int (*___retval_f4__PFi_i__1)(int __anonymous_object4);
    241241}
    242242int __vtr__Fi___1(){
    243     int ___retval_vtr__i_1;
     243    __attribute__ ((unused)) int ___retval_vtr__i_1;
    244244    __attribute__ ((unused,unused,used)) int __t1__i_2;
    245245    __attribute__ ((unused,unused,unused,unused,unused)) int **__t2__PPi_2;
     
    251251int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1);
    252252int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1){
    253     int ___retval_ipd1__i_1;
     253    __attribute__ ((unused)) int ___retval_ipd1__i_1;
    254254}
    255255int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
    256256int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){
    257     int ___retval_ipd2__i_1;
     257    __attribute__ ((unused)) int ___retval_ipd2__i_1;
    258258}
    259259int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
    260260int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){
    261     int ___retval_ipd3__i_1;
     261    __attribute__ ((unused)) int ___retval_ipd3__i_1;
    262262}
    263263int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)());
    264264int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)()){
    265     int ___retval_ipd4__i_1;
     265    __attribute__ ((unused)) int ___retval_ipd4__i_1;
    266266}
    267267int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) int __Foo__i_1);
     
    273273int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9)));
    274274int __ad__Fi___1(){
    275     int ___retval_ad__i_1;
     275    __attribute__ ((unused)) int ___retval_ad__i_1;
    276276    __attribute__ ((used,unused)) int __ad1__i_2;
    277277    __attribute__ ((unused,unused,unused)) int *__ad2__Pi_2;
  • src/tests/.expect/64/declarationSpecifier.txt

    re4d829b r579263a  
    670670static inline volatile const short __f48__FCVs___1();
    671671int __main__Fi_iPPCc__1(int __argc__i_1, const char **__argv__PPCc_1){
    672     int ___retval_main__i_1;
     672    __attribute__ ((unused)) int ___retval_main__i_1;
    673673    ((void)(___retval_main__i_1=((int )0)) /* ?{} */);
    674674    return ((int )___retval_main__i_1);
     
    685685static inline int invoke_main(int argc, char **argv, char **envp);
    686686int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
    687     int ___retval_main__i_1;
     687    __attribute__ ((unused)) int ___retval_main__i_1;
    688688    int _tmp_cp_ret0;
    689689    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
  • src/tests/.expect/64/extension.txt

    re4d829b r579263a  
    8585__extension__ int j;
    8686__extension__ int __fred__Fi_i__1(int __p__i_1){
    87     int ___retval_fred__i_1;
     87    __attribute__ ((unused)) int ___retval_fred__i_1;
    8888    __extension__ struct S {
    8989        __extension__ int __a__i_2;
     
    105105    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    106106    __extension__ int __mary__Fi_i__2(int __p__i_2){
    107         int ___retval_mary__i_2;
     107        __attribute__ ((unused)) int ___retval_mary__i_2;
    108108    }
    109109    ((void)__extension__ sizeof(3));
  • src/tests/.expect/64/gccExtensions.txt

    re4d829b r579263a  
    77extern int __x__i_1 asm ( "xx" );
    88int __main__Fi_iPPCc__1(int __argc__i_1, const char **__argv__PPCc_1){
    9     int ___retval_main__i_1;
     9    __attribute__ ((unused)) int ___retval_main__i_1;
    1010    asm ( "nop" :  :  :  );
    1111    asm ( "nop" :  :  :  );
     
    2626    const int __i3__Ci_2;
    2727    inline int __f1__Fi___2(){
    28         int ___retval_f1__i_2;
     28        __attribute__ ((unused)) int ___retval_f1__i_2;
    2929    }
    3030    inline int __f2__Fi___2(){
    31         int ___retval_f2__i_2;
     31        __attribute__ ((unused)) int ___retval_f2__i_2;
    3232    }
    3333    int __s1__i_2;
     
    182182static inline int invoke_main(int argc, char **argv, char **envp);
    183183int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
    184     int ___retval_main__i_1;
     184    __attribute__ ((unused)) int ___retval_main__i_1;
    185185    int _tmp_cp_ret0;
    186186    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
  • src/tests/.expect/io.txt

    re4d829b r579263a  
    44123
    55
     6x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
     71, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
     8x`1`x'2'x"3"x:4:x 5 x   6       x
     97
     10x
     118
     12x
     139
     14x
     1510
     16x
     17x ( 1 ) x 2 , x 3 :x: 4
    618A
    7191 2 3 4 5 6 7 8
     
    1830abc, $xyz
    1931
    20 v(27 v[27 v{27 $27 =27 £27 ¥27 ¡27 ¿27 «27
    21 25, 25. 25: 25; 25! 25? 25% 25¢ 25» 25) 25] 25}
    22 25'27 25`27 25"27 25 27 25
    23 27 25
    24 27 25
    25 27 25   27 25
    26 27
     321, 2, 3, 4
     331, $2, $3 ", $"
     341 2 3 " "
     35 1 2 3
     3612 3
     37123
     381 23
     391 2 3
     401 2 3 4 " "
     411, 2, 3, 4 ", "
     421, 2, 3, 4
    27433, 4, a, 7.2
    28443, 4, a, 7.2
    29453 4 a 7.2
    30  3 4 a 7.234a7.2 3 4 a 7.2
     46 3 4 a 7.234a7.23 4 a 7.2
    31473-4-a-7.2^3^4-3-4-a-7.2
  • src/tests/.expect/scopeErrors.txt

    re4d829b r579263a  
    33  with parameters
    44    double
    5   returning
    6     _retval_butThisIsAnError: double
    7   with body
     5  returning
     6    _retval_butThisIsAnError:       Attribute with name: unused
     7double
     8  with body
    89    CompoundStmt
  • src/tests/Makefile.am

    re4d829b r579263a  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Thu May 25 14:39:15 2017
    14 ## Update Count     : 43
     13## Last Modified On : Thu Jun  8 07:41:43 2017
     14## Update Count     : 44
    1515###############################################################################
    1616
     
    2020
    2121if BUILD_CONCURRENCY
    22 concurrent=yes
    23 quick_test+= coroutine thread monitor
    24 concurrent_test=coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
     22concurrent = yes
     23quick_test += coroutine thread monitor
     24concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
    2525else
    2626concurrent=no
     
    5757        @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}
    5858
    59 .dummy : .dummy.c
     59.dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@
    6060        ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@}                              #don't use CFLAGS, this rule is not a real test
    6161
    62 dtor-early-exit-ERR1: dtor-early-exit.c
     62
     63% : %.c @CFA_BINDIR@/@CFA_NAME@
     64        ${CC} ${CFLAGS} ${<} -o ${@}
     65
     66dtor-early-exit-ERR1: dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
    6367        ${CC} ${CFLAGS} -DERR1 ${<} -o ${@}
    6468
    65 dtor-early-exit-ERR2: dtor-early-exit.c
     69dtor-early-exit-ERR2: dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
    6670        ${CC} ${CFLAGS} -DERR2 ${<} -o ${@}
    6771
    68 declarationSpecifier: declarationSpecifier.c
     72declarationSpecifier: declarationSpecifier.c @CFA_BINDIR@/@CFA_NAME@
    6973        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    7074
    71 gccExtensions : gccExtensions.c
     75gccExtensions : gccExtensions.c @CFA_BINDIR@/@CFA_NAME@
    7276        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    7377
    74 extension : extension.c
     78extension : extension.c @CFA_BINDIR@/@CFA_NAME@
    7579        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    7680
    77 attributes : attributes.c
     81attributes : attributes.c @CFA_BINDIR@/@CFA_NAME@
    7882        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    7983
    80 KRfunctions : KRfunctions.c
     84KRfunctions : KRfunctions.c @CFA_BINDIR@/@CFA_NAME@
    8185        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    8286
    83 gmp : gmp.c
     87gmp : gmp.c @CFA_BINDIR@/@CFA_NAME@
    8488        ${CC} ${CFLAGS} -lgmp ${<} -o ${@}
    8589
    86 memberCtors-ERR1: memberCtors.c
     90memberCtors-ERR1: memberCtors.c @CFA_BINDIR@/@CFA_NAME@
    8791        ${CC} ${CFLAGS} -DERR1 ${<} -o ${@}
    8892
    89 completeTypeError : completeTypeError.c
     93completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@
    9094        ${CC} ${CFLAGS} -DERR1 ${<} -o ${@}
  • src/tests/Makefile.in

    re4d829b r579263a  
    661661        @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}
    662662
    663 .dummy : .dummy.c
     663.dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@
    664664        ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@}                              #don't use CFLAGS, this rule is not a real test
    665665
    666 dtor-early-exit-ERR1: dtor-early-exit.c
     666% : %.c @CFA_BINDIR@/@CFA_NAME@
     667        ${CC} ${CFLAGS} ${<} -o ${@}
     668
     669dtor-early-exit-ERR1: dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
    667670        ${CC} ${CFLAGS} -DERR1 ${<} -o ${@}
    668671
    669 dtor-early-exit-ERR2: dtor-early-exit.c
     672dtor-early-exit-ERR2: dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
    670673        ${CC} ${CFLAGS} -DERR2 ${<} -o ${@}
    671674
    672 declarationSpecifier: declarationSpecifier.c
     675declarationSpecifier: declarationSpecifier.c @CFA_BINDIR@/@CFA_NAME@
    673676        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    674677
    675 gccExtensions : gccExtensions.c
     678gccExtensions : gccExtensions.c @CFA_BINDIR@/@CFA_NAME@
    676679        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    677680
    678 extension : extension.c
     681extension : extension.c @CFA_BINDIR@/@CFA_NAME@
    679682        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    680683
    681 attributes : attributes.c
     684attributes : attributes.c @CFA_BINDIR@/@CFA_NAME@
    682685        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    683686
    684 KRfunctions : KRfunctions.c
     687KRfunctions : KRfunctions.c @CFA_BINDIR@/@CFA_NAME@
    685688        ${CC} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    686689
    687 gmp : gmp.c
     690gmp : gmp.c @CFA_BINDIR@/@CFA_NAME@
    688691        ${CC} ${CFLAGS} -lgmp ${<} -o ${@}
    689692
    690 memberCtors-ERR1: memberCtors.c
     693memberCtors-ERR1: memberCtors.c @CFA_BINDIR@/@CFA_NAME@
    691694        ${CC} ${CFLAGS} -DERR1 ${<} -o ${@}
    692695
    693 completeTypeError : completeTypeError.c
     696completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@
    694697        ${CC} ${CFLAGS} -DERR1 ${<} -o ${@}
    695698
  • src/tests/coroutine.c

    re4d829b r579263a  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// fibonacci.c --
     8//
     9// Author           : Thierry Delisle
     10// Created On       : Thu Jun  8 07:29:37 2017
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jun  8 07:37:12 2017
     13// Update Count     : 5
     14//
     15
    116#include <fstream>
    217#include <coroutine>
    318
    419coroutine Fibonacci {
    5       int fn; // used for communication
     20        int fn;                                         // used for communication
    621};
    722
    8 void ?{}(Fibonacci* this) {
    9       this->fn = 0;
     23void ?{}( Fibonacci * this ) {
     24        this->fn = 0;
    1025}
    1126
    12 void main(Fibonacci* this) {
    13       int fn1, fn2;             // retained between resumes
    14       this->fn = 0;
    15       fn1 = this->fn;
    16       suspend();                // return to last resume
     27void main( Fibonacci * this ) {
     28        int fn1, fn2;                                   // retained between resumes
     29        this->fn = 0;                                   // case 0
     30        fn1 = this->fn;
     31        suspend();                                              // return to last resume
    1732
    18       this->fn = 1;
    19       fn2 = fn1;
    20       fn1 = this->fn;
    21       suspend();                // return to last resume
     33        this->fn = 1;                                   // case 1
     34        fn2 = fn1;
     35        fn1 = this->fn;
     36        suspend();                                              // return to last resume
    2237
    23       for ( ;; ) {
    24             this->fn = fn1 + fn2;
    25             fn2 = fn1;
    26             fn1 = this->fn;
    27             suspend(); // return to last resume
    28       }
     38        for ( ;; ) {                                    // general case
     39                this->fn = fn1 + fn2;
     40                fn2 = fn1;
     41                fn1 = this->fn;
     42                suspend();                                      // return to last resume
     43        } // for
    2944}
    3045
    31 int next(Fibonacci* this) {
    32       resume(this); // transfer to last suspend
    33       return this->fn;
     46int next( Fibonacci * this ) {
     47        resume( this );                                 // transfer to last suspend
     48        return this->fn;
    3449}
    3550
    3651int main() {
    37       Fibonacci f1, f2;
    38       for ( int i = 1; i <= 10; i += 1 ) {
    39             sout | next(&f1) | ' ' | next(&f2) | endl;
    40       }
     52        Fibonacci f1, f2;
     53        for ( int i = 1; i <= 10; i += 1 ) {
     54                sout | next( &f1 ) | ' ' | next( &f2 ) | endl;
     55        } // for
     56}
    4157
    42       return 0;
    43 }
     58// Local Variables: //
     59// tab-width: 4 //
     60// compile-command: "cfa fibonacci.c" //
     61// End: //
  • src/tests/identity.c

    re4d829b r579263a  
    77// identity.c --
    88//
    9 // Author           : Richard C. Bilson
     9// Author           : Peter A. Buhr
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar  8 22:15:08 2016
    13 // Update Count     : 13
     12// Last Modified On : Thu Jun  8 08:21:32 2017
     13// Update Count     : 18
    1414//
    1515
     
    3232        sout | "double\t\t\t"                           | identity( 4.1 ) | endl;
    3333        sout | "long double\t\t"                        | identity( 4.1l ) | endl;
     34        sout | "float _Complex\t\t"                     | identity( -4.1F-2.0iF ) | endl;
     35        sout | "double _Complex\t\t"            | identity( -4.1D-2.0iD ) | endl;
     36        sout | "long double _Complex\t"         | identity( -4.1L-2.0iL ) | endl;
    3437}
    3538
  • src/tests/io.c

    re4d829b r579263a  
    1010// Created On       : Wed Mar  2 16:56:02 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 21 22:36:06 2017
    13 // Update Count     : 48
     12// Last Modified On : Thu Jun  8 09:52:10 2017
     13// Update Count     : 51
    1414//
    1515
     
    1717
    1818int main() {
    19         char c;                                                                                                         // basic types
     19        char c;                                                                                         // basic types
    2020        short int si;
    2121        unsigned short int usi;
     
    3232        double _Complex dc;
    3333        long double _Complex ldc;
    34         char s1[10], s2[10];
     34        enum { size = 10 };
     35        char s1[size], s2[size];
    3536
    3637        int x = 3, y = 5, z = 7;
     
    4142        sout | endl;
    4243
    43         ifstream in;                                                                                            // create / open file
     44        sout
     45                // opening delimiters
     46                | "x (" | 1
     47                | "x [" | 2
     48                | "x {" | 3
     49                | "x =" | 4
     50                | "x $" | 5
     51                | "x £" | 6
     52                | "x ¥" | 7
     53                | "x ¡" | 8
     54                | "x ¿" | 9
     55                | "x «" | 10
     56                | endl;
     57        sout
     58                // closing delimiters
     59                | 1 | ", x"
     60                | 2 | ". x"
     61                | 3 | "; x"
     62                | 4 | "! x"
     63                | 5 | "? x"
     64                | 6 | "% x"
     65                | 7 | "¢ x"
     66                | 8 | "» x"
     67                | 9 | ") x"
     68                | 10 | "] x"
     69                | 11 | "} x"
     70                | endl;
     71        sout
     72                // opening-closing delimiters
     73                | "x`" | 1 | "`x'" | 2
     74                | "'x\"" | 3 | "\"x:" | 4
     75                | ":x " | 5 | " x\t" | 6
     76                | "\tx\f" | 7 | "\fx\v" | 8
     77                | "\vx\n" | 9 | "\nx\r" | 10
     78                | "\rx" |
     79                endl;
     80        sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
     81
     82        ifstream in;                                                                            // create / open file
    4483        open( &in, "io.data", "r" );
    4584
    46         &in | &c                                                                                                        // character
    47                 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli             // integral
    48                 | &f | &d | &ld                                                                                 // floating point
    49                 | &fc | &dc | &ldc                                                                              // floating-point complex
    50                 | cstr( s1 ) | cstr( s2, 10 );                                                  // C string, length unchecked and checked
     85        &in | &c                                                                                        // character
     86                | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli     // integral
     87                | &f | &d | &ld                                                                 // floating point
     88                | &fc | &dc | &ldc                                                              // floating-point complex
     89                | cstr( s1 ) | cstr( s2, size );                                // C string, length unchecked and checked
    5190
    52         sout | c | ' ' | endl                                                                           // character
    53                  | si | usi | i | ui | li | uli | lli | ulli | endl             // integral
    54                  | f | d | ld | endl                                                                    // floating point
    55                  | fc | dc | ldc | endl;                                                                // complex
     91        sout | c | ' ' | endl                                                           // character
     92                | si | usi | i | ui | li | uli | lli | ulli | endl // integral
     93                | f | d | ld | endl                                                             // floating point
     94                | fc | dc | ldc | endl;                                                 // complex
    5695        sout | endl;
    57         sout | f | "" | d | "" | ld | endl                                                      // floating point without separator
    58                  | sepDisable | fc | dc | ldc | sepEnable | endl                // complex without separator
    59                  | sepOn | s1 | sepOff | s2 | endl                                              // local separator removal
    60                  | s1 | "" | s2 | endl;                                                                 // C string without separator
     96        sout | f | "" | d | "" | ld | endl                                      // floating point without separator
     97                | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator
     98                | sepOn | s1 | sepOff | s2 | endl                               // local separator removal
     99                | s1 | "" | s2 | endl;                                                  // C string without separator
    61100        sout | endl;
    62101
    63         sepSet( sout, ", $" );                                                                          // change separator, maximum of 15 characters
     102        sepSet( sout, ", $" );                                                          // change separator, maximum of 15 characters
    64103        sout | f | d | ld | endl
    65                  | fc | dc | ldc | endl
    66                  | s1 | s2 | endl;
     104                | fc | dc | ldc | endl
     105                | s1 | s2 | endl;
    67106        sout | endl;
     107
     108        [int, int] t1 = [1, 2], t2 = [3, 4];
     109        sout | t1 | t2 | endl;                                                          // print tuple
     110
    68111        sepSet( sout, " " );
     112        sepSet( sout, ", $" );                                                          // set separator from " " to ", $"
     113        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
     114        sepSet( sout, " " );                                                            // reset separator to " "
     115        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
    69116
    70         sout
    71                 // opening delimiters
    72                 | "v(" | 27
    73                 | "v[" | 27
    74                 | "v{" | 27
    75                 | "$" | 27
    76                 | "=" | 27
    77                 | "£" | 27
    78                 | "¥" | 27
    79                 | "¡" | 27
    80                 | "¿" | 27
    81                 | "«" | 27
    82                 | endl
    83                 // closing delimiters
    84                 | 25 | ","
    85                 | 25 | "."
    86                 | 25 | ":"
    87                 | 25 | ";"
    88                 | 25 | "!"
    89                 | 25 | "?"
    90                 | 25 | "%"
    91                 | 25 | "¢"
    92                 | 25 | "»"
    93                 | 25 | ")"
    94                 | 25 | "]"
    95                 | 25 | "}"
    96                 | endl
    97                 // opening-closing delimiters
    98                 | 25 | "'" | 27
    99                 | 25 | "`" | 27
    100                 | 25 | "\"" | 27
    101                 | 25 | " " | 27
    102                 | 25 | "\f" | 27
    103                 | 25 | "\n" | 27
    104                 | 25 | "\r" | 27
    105                 | 25 | "\t" | 27
    106                 | 25 | "\v" | 27
    107                 | endl;
     117        sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // separator at start of line
     118        sout | 1 | sepOff | 2 | 3 | endl;                                       // locally turn off implicit separator
    108119
    109         [int, int, const char *, double] t = { 3, 4, "a", 7.2 };
     120        sout | sepDisable | 1 | 2 | 3 | endl;                           // globally turn off implicit separation
     121        sout | 1 | sepOn | 2 | 3 | endl;                                        // locally turn on implicit separator
     122        sout | sepEnable | 1 | 2 | 3 | endl;                            // globally turn on implicit separation
     123
     124        sepSetTuple( sout, " " );                                                       // set tuple separator from ", " to " "
     125        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
     126        sepSetTuple( sout, ", " );                                                      // reset tuple separator to ", "
     127        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
     128
     129        sout | t1 | t2 | endl;                                                          // print tuple
     130
     131        [int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
    110132        sout | [ 3, 4, "a", 7.2 ] | endl;
    111         sout | t | endl;
     133        sout | t3 | endl;
    112134        sepSetTuple( sout, " " );
    113         sout | t | endl;
    114         sout | sepOn | t | sepDisable | t | sepEnable | t | endl;
     135        sout | t3 | endl;
     136        sout | sepOn | t3 | sepDisable | t3 | sepEnable | t3 | endl;
    115137        sepSet( sout, "^" );
    116138        sepSetTuple( sout, "-" );
    117         sout | t | 3 | 4 | t | endl;
     139        sout | t3 | 3 | 4 | t3 | endl;
    118140}
    119141
Note: See TracChangeset for help on using the changeset viewer.