Changeset 4c03e63


Ignore:
Timestamp:
Jun 23, 2017, 4:20:33 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
74e58ea3, 7bbba76
Parents:
e1c1829 (diff), 88177cf (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
2 added
52 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    re1c1829 r4c03e63  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon May 15 18:03:29 2017
    14 %% Update Count     : 302
     13%% Last Modified On : Sun Jun 18 20:32:32 2017
     14%% Update Count     : 319
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3636% Names used in the document.
    3737
    38 \newcommand{\CFA}{\textrm{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
     38\newcommand{\CFAIcon}{\textrm{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
     39\newcommand{\CFA}{\protect\CFAIcon} % safe for section/caption
    3940\newcommand{\CFL}{\textrm{Cforall}\xspace} % Cforall symbolic name
    4041\newcommand{\Celeven}{\textrm{C11}\xspace} % C11 symbolic name
     
    241242belowskip=3pt,
    242243% replace/adjust listing characters that look bad in sanserif
    243 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1
     244literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1
    244245        {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
    245         {__}{\_\,\_}2 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2
    246         {___}{\_\,\_\,\_}3,
     246        {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2,
    247247moredelim=**[is][\color{red}]{®}{®},                                    % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
    248248moredelim=**[is][\color{blue}]{ß}{ß},                                   % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
  • doc/proposals/tagged-struct.txt

    re1c1829 r4c03e63  
    1414say which of the possible values is currently stored in the union. The idea
    1515here is similar, however the possibilities are more open ended.
     16
     17Alternate names include virtual structure and abstract structure.
    1618
    1719
     
    3638their parent's fields to their field list so they can be upcast.
    3739
     40The type field may be public, if it is then it can be accessed through a
     41simple field access "instance.type". The type field would then be able to be
     42used to access the type object, which contains the information for the type.
     43It may just be a pointer to the type object "*instance.type", although a
     44lookup function could also be used.
     45
     46
     47Usage:
     48
     49The central feature for tagged structs is a checked cast between pointer types
     50to the structures. A cast is successful if the true type of the pointed object
     51is of the type being cast to or any of its children, otherwise the cast
     52returns null.
     53
     54The type field should also allow for equality comparison of types.
     55
     56Currently, with only these operations (and similar features) the type field
     57could be hidden and the operations given through helper functions. However
     58if the type object has more complex (or even open ended) information in it
     59than providing direct access becomes very valuable.
     60
    3861
    3962Implemenation:
    4063
    41 Adding to the field list is a simple matter, should be doable during
    42 translation. The type field is just a pointer to a type object. With proper
    43 linking we can create a single unique instance of the type object for each
    44 declared tagged struct. The instance's address is used as an id for the type.
    45 It also holds data about the type, such as its parent's id/a pointer to the
    46 parent type object.
     64Adding to the field list would have to be handled during translation. The
     65simple act of adding declarations should not be difficult, althought it might
     66take a bit of work to find the parent's declarations.
    4767
    48 The type field could be hidden (as best as C can hide it) or it could be
    49 visible to the user with easy access to allow the user to examine the type
    50 object directly.
    51 
    52 Direct access is more useful if the data on the type-objects can change, other
    53 wise the build in function could handle all cases. Perhaps each root object
    54 can specify a type object to use or the type objects are themselves tagged,
    55 although there may not be a base case with the latter.
    56 
    57 In the simplest case the type object is a pointer to the parent type object.
    58 Additional data could be added, such as a name, or a function pointer to the
    59 destructor.
     68Type objects are also simple in to generate, they should just be global
     69(program lifetime) structures. Getting there to be exactly one instance of
     70each allows the pointer to the structure to be used as the type id, and that
     71should be possible to do during linking.
    6072
    6173
     
    94106If unions are declared tagged instead of creating a new tagged type, all
    95107possible values of the union must be of that tagged type or a child type.
     108
     109
     110Custom Type Objects (Extention):
     111
     112Some method to define type objects used within a tree of types. One option is
     113to allow the tree's type object to be specified by the tree root. It would
     114then have to be filled in for each type in the tree, including the root.
     115
     116The only required field is the parent field, a pointer to the type object's
     117type. (This is also the only required field on the tagged structure itself.)
     118
     119A further extention could allow expanding type objects, so child types could
     120append fields to their parent's feild list. They might need their own type
     121objects at that point, or maybe static checks will be enough to see the
     122minimum field list.
  • doc/rob_thesis/intro.tex

    re1c1829 r4c03e63  
    33%======================================================================
    44
    5 \section{\CFA Background}
     5\section{\protect\CFA Background}
    66\label{s:background}
    77\CFA \footnote{Pronounced ``C-for-all'', and written \CFA or Cforall.} is a modern non-object-oriented extension to the C programming language.
     
    370370    \end{tabular}
    371371  \end{center}
    372   \caption{\label{table:types} The different kinds of type parameters in \CFA}
     372  \caption{\label{table:types} The different kinds of type parameters in \protect\CFA}
    373373\end{table}
    374374
  • doc/rob_thesis/thesis.tex

    re1c1829 r4c03e63  
    6666% ,monochrome % toggle black and white mode
    6767}{xcolor}
     68\PassOptionsToPackage{pdftex}{graphicx}
    6869\documentclass[letterpaper,12pt,titlepage,oneside,final]{book}
    6970
  • doc/working/exception/translate.c

    re1c1829 r4c03e63  
    11/* Translation rules for exception handling code, from Cforall to C.
    22 *
    3  * Note that these are not final. Names, syntax and the exact translation
    4  * will be updated. The first section is the shared definitions, not generated
    5  * by the local translations but used by the translated code.
     3 * Reminder: This is not final. Besides names and things it is also going very
     4 * much for correctness and simplisity over efficiency.
     5 *
     6 * The first section is the shared definitions, not generated by the local
     7 * translations but used by the translated code.
    68 *
    79 * Most of these exist only after translation (in C code). The first (the
     
    1618typedef int exception;
    1719
     20// Will have to be availibe to user. Consider new name. Requires tagged types.
     21forall(dtype parent | tagged(parent), dtype child | tagged(child))
     22parent *dynamic_cast(child *);
     23
    1824void __throw_terminate(exception except) __attribute__((noreturn));
    1925void __rethrow_terminate() __attribute__((noreturn));
     
    116122                }
    117123                int match1(exception except) {
    118                         OtherException inner_except;
    119                         if (dynamic_cast__SomeException(except)) {
    120                                 return 1;
    121                         }
    122                         else if ( (inner_except = dynamic_cast__OtherException(except)) &&
    123                                         inner_except.priority > 3) {
    124                                 return 2;
    125                         }
    126                         else return 0;
     124                        {
     125                                if (dynamic_cast__SomeException(except)) {
     126                                        return 1;
     127                                }
     128                        }
     129                        {
     130                                OtherException err;
     131                                if ( (err = dynamic_cast__OtherException(except)) &&
     132                                                err.priority > 3) {
     133                                        return 2;
     134                                }
     135                        }
     136                        return 0;
    127137                }
    128138                __try_terminate(try1, catch1, match1);
     
    151161        {
    152162                bool handle1(exception except) {
    153                         OtherException inner_except;
    154                         if (dynamic_cast__SomeException(except)) {
    155                                 fiddleThing();
    156                                 return true;
    157                         } else if (dynamic_cast__OtherException(except) &&
    158                                         inner_except.priority > 3) {
    159                                 twiddleWidget();
    160                                 return true;
    161                         } else {
    162                                 return false;
    163                         }
     163                        {
     164                                if (dynamic_cast__SomeException(except)) {
     165                                        fiddleThing();
     166                                        return true;
     167                                }
     168                        }
     169                        {
     170                                OtherException err;
     171                                if ( ( err = dynamic_cast__OtherException(except) ) &&
     172                                                err.priority > 3) {
     173                                        twiddleWidget();
     174                                        return true;
     175                                }
     176                        }
     177                        return false;
    164178                }
    165179                struct __try_resume_node data =
     
    230244                }
    231245                bool handle1(exception except) {
    232                         if (dynamic_cast__SomeException(except)) {
    233                                 fiddleThing();
    234                                 return true;
    235                         } else {
    236                                 return false;
    237                         }
     246                        {
     247                                if (dynamic_cast__SomeException(except)) {
     248                                        fiddleThing();
     249                                        return true;
     250                                }
     251                        }
     252                        return false;
    238253                }
    239254                struct __cleanup_hook generated_name
     
    273288        {
    274289                bool handle1() {
    275                         if (dynamic_cast__OtherException(except)) {
    276                                 twiddleWidget();
    277                                 return true;
     290                        {
     291                                if (dynamic_cast__OtherException(except)) {
     292                                        twiddleWidget();
     293                                        return true;
     294                                }
    278295                        }
    279296                        return false;
     
    297314                }
    298315                int match1(exception except) {
    299                         if (dynamic_cast__SomeException(except)) {
    300                                 return 1;
     316                        {
     317                                if (dynamic_cast__SomeException(except)) {
     318                                        return 1;
     319                                }
    301320                        }
    302321                        return 0;
  • src/CodeGen/FixNames.cc

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    1818// Templated visitor type
    1919// To use declare a PassVisitor< YOUR VISITOR TYPE >
    20 // The visitor type should specify the previsit/postvisit for types that are desired.
     20// The visitor type should specify the previsit/postvisit/premutate/postmutate for types that are desired.
     21// Note: previsit/postvisit/premutate/postmutate must be **public** members
     22//
     23// Several additional features are available through inheritance
     24// | WithTypeSubstitution - provides polymorphic TypeSubstitution * env for the current expression
     25// | WithStmtsToAdd       - provides the ability to insert statements before or after the current statement by adding new statements into
     26//                          stmtsToAddBefore or stmtsToAddAfter respectively.
     27// | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children
     28// | WithScopes           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
     29//                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
    2130//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    2231template< typename pass_type >
     
    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;
     
    86101        virtual void visit( ConstructorExpr * ctorExpr ) override final;
    87102        virtual void visit( CompoundLiteralExpr *compLitExpr ) override final;
    88         virtual void visit( UntypedValofExpr *valofExpr ) override final;
    89103        virtual void visit( RangeExpr *rangeExpr ) override final;
    90104        virtual void visit( UntypedTupleExpr *tupleExpr ) override final;
     
    172186        virtual Expression* mutate( ConstructorExpr *ctorExpr ) override final;
    173187        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr ) override final;
    174         virtual Expression* mutate( UntypedValofExpr *valofExpr ) override final;
    175188        virtual Expression* mutate( RangeExpr *rangeExpr ) override final;
    176189        virtual Expression* mutate( UntypedTupleExpr *tupleExpr ) 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); }
    234         void reset_visit() { bool* skip = skip_children_impl(pass, 0); if(skip) *skip = false; }
     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 ); }
    235259
    236260        guard_value_impl init_guard() {
     
    271295        std::list< Statement* > stmtsToAddAfter;
    272296};
    273 
    274297class WithShortCircuiting {
    275298protected:
     
    278301
    279302public:
    280         bool skip_children;
     303        bool_ref visit_children;
    281304};
    282305
     
    297320};
    298321
     322template<typename pass_type>
     323class WithVisitorRef {
     324protected:
     325        WithVisitorRef() = default;
     326        ~WithVisitorRef() = default;
     327
     328public:
     329        PassVisitor<pass_type> * const visitor;
     330};
    299331
    300332#include "PassVisitor.impl.h"
  • src/Common/PassVisitor.impl.h

    re1c1829 r4c03e63  
    44        __attribute__((unused))                   \
    55        const auto & guard = init_guard();        \
     6        bool visit_children = true;               \
     7        set_visit_children( visit_children );   \
    68        call_previsit( node );                    \
    7         if( visit_children() ) {                  \
    8                 reset_visit();                      \
     9        if( visit_children ) {                    \
    910
    1011#define VISIT_END( node )                       \
     
    1516        __attribute__((unused))                   \
    1617        const auto & guard = init_guard();        \
     18        bool visit_children = true;               \
     19        set_visit_children( visit_children );   \
    1720        call_premutate( node );                   \
    18         if( visit_children() ) {                  \
    19                 reset_visit();                      \
     21        if( visit_children ) {                    \
    2022
    2123#define MUTATE_END( type, node )                \
     
    4244}
    4345
    44 typedef std::list< Statement * > StmtList_t;
    45 
    46 template< typename pass_type >
    47 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 ) {
    48105        SemanticError errors;
    49106
    50107        StmtList_t* beforeStmts = get_beforeStmts();
    51108        StmtList_t* afterStmts  = get_afterStmts();
     109        DeclList_t* beforeDecls = get_beforeDecls();
     110        DeclList_t* afterDecls  = get_afterDecls();
    52111
    53112        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     113
     114                if ( !empty( afterDecls ) ) { splice( std::inserter( statements, i ), afterDecls ); }
    54115                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
     116
    55117                try {
    56                         (*i)->accept( *this );
     118                        func( *i );
     119                        assert(( empty( beforeStmts ) && empty( afterStmts ))
     120                            || ( empty( beforeDecls ) && empty( afterDecls )) );
     121
    57122                } catch ( SemanticError &e ) {
    58123                        errors.append( e );
    59124                }
     125
     126                if ( !empty( beforeDecls ) ) { splice( std::inserter( statements, i ), beforeDecls ); }
    60127                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    61128        }
    62129
     130        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
    63131        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
    64132        if ( !errors.isEmpty() ) { throw errors; }
     
    66134
    67135template< typename pass_type >
     136void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
     137        handleStatementList( statements, [this]( Statement * stmt) {
     138                stmt->accept( *this );
     139        });
     140}
     141
     142template< typename pass_type >
    68143void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    69         SemanticError errors;
     144        handleStatementList( statements, [this]( Statement *& stmt) {
     145                stmt = stmt->acceptMutator( *this );
     146        });
     147}
     148
     149
     150template< typename pass_type >
     151template< typename func_t >
     152Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
     153        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     154        ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
     155        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
     156        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
     157        ValueGuardPtr< StmtList_t >          oldBeforeStmts( get_beforeStmts() );
     158        ValueGuardPtr< StmtList_t >          oldAfterStmts ( get_afterStmts () );
     159
     160        Statement *newStmt = func( stmt );
    70161
    71162        StmtList_t* beforeStmts = get_beforeStmts();
    72163        StmtList_t* afterStmts  = get_afterStmts();
    73 
    74         for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    75                 if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
    76                 try {
    77                         *i = (*i)->acceptMutator( *this );
    78                 } catch ( SemanticError &e ) {
    79                         errors.append( e );
    80                 }
    81                 if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    82         }
    83 
    84         if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
    85         if ( !errors.isEmpty() ) { throw errors; }
    86 }
    87 
    88 template< typename pass_type >
    89 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
    90         // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    91         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
    92         ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    93         ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    94 
    95         maybeAccept( stmt, *this );
    96 
    97         StmtList_t* beforeStmts = get_beforeStmts();
    98         StmtList_t* afterStmts  = get_afterStmts();
    99 
    100         if( empty(beforeStmts) && empty(afterStmts) ) { return stmt; }
     164        DeclList_t* beforeDecls = get_beforeDecls();
     165        DeclList_t* afterDecls  = get_afterDecls();
     166
     167        if( empty(beforeStmts) && empty(afterStmts) && empty(beforeDecls) && empty(afterDecls) ) { return newStmt; }
     168        assert(( empty( beforeStmts ) && empty( afterStmts ))
     169            || ( empty( beforeDecls ) && empty( afterDecls )) );
    101170
    102171        CompoundStmt *compound = new CompoundStmt( noLabels );
     172        if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
    103173        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
    104         compound->get_kids().push_back( stmt );
     174        compound->get_kids().push_back( newStmt );
     175        if( !empty(afterDecls) ) { splice( std::back_inserter( compound->get_kids() ), afterDecls ); }
    105176        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
    106177        return compound;
     
    108179
    109180template< typename pass_type >
     181Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
     182        return handleStatement( stmt, [this]( Statement * stmt ) {
     183                maybeAccept( stmt, *this );
     184                return stmt;
     185        });
     186}
     187
     188template< typename pass_type >
    110189Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    111         // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    112         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
    113         ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    114         ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    115 
    116         Statement *newStmt = maybeMutate( stmt, *this );
    117 
    118         StmtList_t* beforeStmts = get_beforeStmts();
    119         StmtList_t* afterStmts  = get_afterStmts();
    120 
    121         if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; }
    122 
    123         CompoundStmt *compound = new CompoundStmt( noLabels );
    124         if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
    125         compound->get_kids().push_back( newStmt );
    126         if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
    127         return compound;
    128 }
    129 
    130 
    131 
    132 template< typename pass_type >
    133 void PassVisitor< pass_type >::visitExpression( Expression * expr ) {
    134         if( !expr ) return;
     190        return handleStatement( stmt, [this]( Statement * stmt ) {
     191                return maybeMutate( stmt, *this );
     192        });
     193}
     194
     195template< typename pass_type >
     196template< typename func_t >
     197Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
     198        if( !expr ) return nullptr;
    135199
    136200        auto env_ptr = get_env_ptr();
     
    138202                *env_ptr = expr->get_env();
    139203        }
    140         // xxx - should env be cloned (or moved) onto the result of the mutate?
    141         expr->accept( *this );
     204
     205        // should env be cloned (or moved) onto the result of the mutate?
     206        return func( expr );
     207}
     208
     209template< typename pass_type >
     210Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
     211        return handleExpression(expr, [this]( Expression * expr ) {
     212                expr->accept( *this );
     213                return expr;
     214        });             
    142215}
    143216
    144217template< typename pass_type >
    145218Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
    146         if( !expr ) return nullptr;
    147 
    148         auto env_ptr = get_env_ptr();
    149         if ( env_ptr && expr->get_env() ) {
    150                 *env_ptr = expr->get_env();
    151         }
    152         // xxx - should env be cloned (or moved) onto the result of the mutate?
    153         return expr->acceptMutator( *this );
    154 }
    155 
     219        return handleExpression(expr, [this]( Expression * expr ) {
     220                return expr->acceptMutator( *this );
     221        });
     222}
    156223
    157224//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    159226template< typename pass_type >
    160227void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
    161         VISIT_BODY( node ); 
     228        VISIT_BODY( node );
    162229}
    163230
    164231template< typename pass_type >
    165232void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
    166         VISIT_BODY( node ); 
     233        VISIT_BODY( node );
    167234}
    168235
    169236template< typename pass_type >
    170237void PassVisitor< pass_type >::visit( StructDecl * node ) {
    171         VISIT_BODY( node ); 
     238        VISIT_BODY( node );
    172239}
    173240
    174241template< typename pass_type >
    175242void PassVisitor< pass_type >::visit( UnionDecl * node ) {
    176         VISIT_BODY( node ); 
     243        VISIT_BODY( node );
    177244}
    178245
    179246template< typename pass_type >
    180247void PassVisitor< pass_type >::visit( EnumDecl * node ) {
    181         VISIT_BODY( node ); 
     248        VISIT_BODY( node );
    182249}
    183250
    184251template< typename pass_type >
    185252void PassVisitor< pass_type >::visit( TraitDecl * node ) {
    186         VISIT_BODY( node ); 
     253        VISIT_BODY( node );
    187254}
    188255
    189256template< typename pass_type >
    190257void PassVisitor< pass_type >::visit( TypeDecl * node ) {
    191         VISIT_BODY( node ); 
     258        VISIT_BODY( node );
    192259}
    193260
    194261template< typename pass_type >
    195262void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
    196         VISIT_BODY( node ); 
     263        VISIT_BODY( node );
    197264}
    198265
    199266template< typename pass_type >
    200267void PassVisitor< pass_type >::visit( AsmDecl * node ) {
    201         VISIT_BODY( node ); 
     268        VISIT_BODY( node );
    202269}
    203270
     
    231298void PassVisitor< pass_type >::visit( ExprStmt * node ) {
    232299        VISIT_START( node );
    233         call_beginScope();
    234300
    235301        visitExpression( node->get_expr() );
    236302
    237         call_endScope();
    238303        VISIT_END( node );
    239304}
     
    248313}
    249314
     315//--------------------------------------------------------------------------
     316// AsmStmt
    250317template< typename pass_type >
    251318void PassVisitor< pass_type >::visit( AsmStmt * node ) {
    252         VISIT_BODY( node );
     319        VISIT_BODY( node );
     320}
     321
     322template< typename pass_type >
     323Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
     324        MUTATE_BODY( Statement, node );
    253325}
    254326
     
    257329template< typename pass_type >
    258330void PassVisitor< pass_type >::visit( IfStmt * node ) {
    259         VISIT_START( node ); 
     331        VISIT_START( node );
    260332
    261333        visitExpression( node->get_condition() );
     
    268340template< typename pass_type >
    269341Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    270         MUTATE_START( node ); 
     342        MUTATE_START( node );
    271343
    272344        node->set_condition( mutateExpression( node->get_condition() ) );
     
    281353template< typename pass_type >
    282354void PassVisitor< pass_type >::visit( WhileStmt * node ) {
    283         VISIT_START( node ); 
     355        VISIT_START( node );
    284356
    285357        visitExpression( node->get_condition() );
     
    291363template< typename pass_type >
    292364Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
    293         MUTATE_START( node ); 
     365        MUTATE_START( node );
    294366
    295367        node->set_condition( mutateExpression( node->get_condition() ) );
     
    300372
    301373//--------------------------------------------------------------------------
    302 // WhileStmt
     374// ForStmt
    303375template< typename pass_type >
    304376void PassVisitor< pass_type >::visit( ForStmt * node ) {
    305         VISIT_START( node ); 
     377        VISIT_START( node );
    306378
    307379        acceptAll( node->get_initialization(), *this );
     
    315387template< typename pass_type >
    316388Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    317         MUTATE_START( node ); 
     389        MUTATE_START( node );
    318390
    319391        mutateAll( node->get_initialization(), *this );
     
    329401template< typename pass_type >
    330402void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
    331         VISIT_START( node ); 
     403        VISIT_START( node );
    332404
    333405        visitExpression( node->get_condition() );
     
    339411template< typename pass_type >
    340412Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
    341         MUTATE_START( node ); 
    342        
     413        MUTATE_START( node );
     414
    343415        node->set_condition( mutateExpression( node->get_condition() ) );
    344416        mutateStatementList( node->get_statements() );
    345        
     417
    346418        MUTATE_END( Statement, node );
    347419}
    348420
    349421//--------------------------------------------------------------------------
    350 // SwitchStmt
     422// CaseStmt
    351423template< typename pass_type >
    352424void PassVisitor< pass_type >::visit( CaseStmt * node ) {
    353         VISIT_START( node ); 
    354        
     425        VISIT_START( node );
     426
    355427        visitExpression( node->get_condition() );
    356428        visitStatementList( node->get_statements() );
    357        
     429
    358430        VISIT_END( node );
    359431}
     
    361433template< typename pass_type >
    362434Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
    363         MUTATE_START( node ); 
    364        
     435        MUTATE_START( node );
     436
    365437        node->set_condition(  mutateExpression( node->get_condition() ) );
    366438        mutateStatementList( node->get_statements() );
    367        
     439
    368440        MUTATE_END( Statement, node );
    369441}
    370442
     443//--------------------------------------------------------------------------
     444// BranchStmt
    371445template< typename pass_type >
    372446void PassVisitor< pass_type >::visit( BranchStmt * node ) {
    373         VISIT_BODY( node );
     447        VISIT_BODY( node );
     448}
     449
     450template< typename pass_type >
     451Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
     452        MUTATE_BODY( Statement, node );
    374453}
    375454
     
    415494        maybeAccept( node->get_block(), *this );
    416495        acceptAll( node->get_catchers(), *this );
     496        maybeAccept( node->get_finally(), *this );
    417497
    418498        VISIT_END( node );
     
    425505        node->set_block(  maybeMutate( node->get_block(), *this ) );
    426506        mutateAll( node->get_catchers(), *this );
    427        
     507        node->set_finally( maybeMutate( node->get_finally(), *this ) );
     508
    428509        MUTATE_END( Statement, node );
    429510}
     
    435516        VISIT_START( node );
    436517
     518        maybeAccept( node->get_decl(), *this );
     519        node->set_cond( visitExpression( node->get_cond() ) );
    437520        node->set_body( visitStatement( node->get_body() ) );
    438         maybeAccept( node->get_decl(), *this );
    439521
    440522        VISIT_END( node );
     
    444526Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    445527        MUTATE_START( node );
    446        
    447         node->set_body(  mutateStatement( node->get_body() ) );
    448         node->set_decl(  maybeMutate( node->get_decl(), *this ) );
    449        
     528
     529        node->set_decl( maybeMutate( node->get_decl(), *this ) );
     530        node->set_cond( mutateExpression( node->get_cond() ) );
     531        node->set_body( mutateStatement( node->get_body() ) );
     532
    450533        MUTATE_END( Statement, node );
    451534}
     
    453536template< typename pass_type >
    454537void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
    455         VISIT_BODY( node ); 
     538        VISIT_BODY( node );
    456539}
    457540
    458541template< typename pass_type >
    459542void PassVisitor< pass_type >::visit( NullStmt * node ) {
    460         VISIT_BODY( node ); 
     543        VISIT_BODY( node );
    461544}
    462545
    463546template< typename pass_type >
    464547void PassVisitor< pass_type >::visit( DeclStmt * node ) {
    465         VISIT_BODY( node ); 
     548        VISIT_BODY( node );
    466549}
    467550
    468551template< typename pass_type >
    469552void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
    470         VISIT_BODY( node ); 
     553        VISIT_BODY( node );
    471554}
    472555
    473556template< typename pass_type >
    474557void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
    475         VISIT_BODY( node ); 
     558        VISIT_BODY( node );
    476559}
    477560
     
    502585template< typename pass_type >
    503586void PassVisitor< pass_type >::visit( NameExpr * node ) {
    504         VISIT_BODY( node ); 
     587        VISIT_BODY( node );
    505588}
    506589
    507590template< typename pass_type >
    508591void PassVisitor< pass_type >::visit( CastExpr * node ) {
    509         VISIT_BODY( node ); 
     592        VISIT_BODY( node );
    510593}
    511594
    512595template< typename pass_type >
    513596void PassVisitor< pass_type >::visit( AddressExpr * node ) {
    514         VISIT_BODY( node ); 
     597        VISIT_BODY( node );
    515598}
    516599
    517600template< typename pass_type >
    518601void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
    519         VISIT_BODY( node ); 
     602        VISIT_BODY( node );
    520603}
    521604
    522605template< typename pass_type >
    523606void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
    524         VISIT_BODY( node ); 
     607        VISIT_BODY( node );
    525608}
    526609
    527610template< typename pass_type >
    528611void PassVisitor< pass_type >::visit( MemberExpr * node ) {
    529         VISIT_BODY( node ); 
     612        VISIT_BODY( node );
    530613}
    531614
    532615template< typename pass_type >
    533616void PassVisitor< pass_type >::visit( VariableExpr * node ) {
    534         VISIT_BODY( node ); 
     617        VISIT_BODY( node );
    535618}
    536619
    537620template< typename pass_type >
    538621void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
    539         VISIT_BODY( node ); 
     622        VISIT_BODY( node );
    540623}
    541624
    542625template< typename pass_type >
    543626void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
    544         VISIT_BODY( node ); 
     627        VISIT_BODY( node );
    545628}
    546629
    547630template< typename pass_type >
    548631void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
    549         VISIT_BODY( node ); 
     632        VISIT_BODY( node );
    550633}
    551634
    552635template< typename pass_type >
    553636void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
    554         VISIT_BODY( node ); 
     637        VISIT_BODY( node );
    555638}
    556639
    557640template< typename pass_type >
    558641void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
    559         VISIT_BODY( node ); 
     642        VISIT_BODY( node );
    560643}
    561644
    562645template< typename pass_type >
    563646void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
    564         VISIT_BODY( node ); 
     647        VISIT_BODY( node );
    565648}
    566649
    567650template< typename pass_type >
    568651void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    569         VISIT_BODY( node ); 
     652        VISIT_BODY( node );
    570653}
    571654
    572655template< typename pass_type >
    573656void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
    574         VISIT_BODY( node ); 
     657        VISIT_BODY( node );
    575658}
    576659
    577660template< typename pass_type >
    578661void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
    579         VISIT_BODY( node ); 
     662        VISIT_BODY( node );
    580663}
    581664
    582665template< typename pass_type >
    583666void PassVisitor< pass_type >::visit( CommaExpr * node ) {
    584         VISIT_BODY( node ); 
     667        VISIT_BODY( node );
    585668}
    586669
    587670template< typename pass_type >
    588671void PassVisitor< pass_type >::visit( TypeExpr * node ) {
    589         VISIT_BODY( node ); 
     672        VISIT_BODY( node );
    590673}
    591674
    592675template< typename pass_type >
    593676void PassVisitor< pass_type >::visit( AsmExpr * node ) {
    594         VISIT_BODY( node ); 
     677        VISIT_BODY( node );
    595678}
    596679
    597680template< typename pass_type >
    598681void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
    599         VISIT_BODY( node ); 
     682        VISIT_BODY( node );
    600683}
    601684
    602685template< typename pass_type >
    603686void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
    604         VISIT_BODY( node ); 
     687        VISIT_BODY( node );
    605688}
    606689
    607690template< typename pass_type >
    608691void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
    609         VISIT_BODY( node );
    610 }
    611 
    612 template< typename pass_type >
    613 void PassVisitor< pass_type >::visit( UntypedValofExpr * node ) {
    614         VISIT_BODY( node );
     692        VISIT_BODY( node );
    615693}
    616694
    617695template< typename pass_type >
    618696void PassVisitor< pass_type >::visit( RangeExpr * node ) {
    619         VISIT_BODY( node ); 
     697        VISIT_BODY( node );
    620698}
    621699
    622700template< typename pass_type >
    623701void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
    624         VISIT_BODY( node ); 
     702        VISIT_BODY( node );
    625703}
    626704
    627705template< typename pass_type >
    628706void PassVisitor< pass_type >::visit( TupleExpr * node ) {
    629         VISIT_BODY( node ); 
     707        VISIT_BODY( node );
    630708}
    631709
    632710template< typename pass_type >
    633711void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
    634         VISIT_BODY( node ); 
     712        VISIT_BODY( node );
    635713}
    636714
    637715template< typename pass_type >
    638716void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
    639         VISIT_BODY( node ); 
     717        VISIT_BODY( node );
    640718}
    641719
     
    659737Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
    660738        MUTATE_START( node );
    661        
     739
    662740        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    663741        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     
    672750template< typename pass_type >
    673751void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
    674         VISIT_BODY( node ); 
     752        VISIT_BODY( node );
    675753}
    676754
    677755template< typename pass_type >
    678756void PassVisitor< pass_type >::visit( VoidType * node ) {
    679         VISIT_BODY( node ); 
     757        VISIT_BODY( node );
    680758}
    681759
    682760template< typename pass_type >
    683761void PassVisitor< pass_type >::visit( BasicType * node ) {
    684         VISIT_BODY( node ); 
     762        VISIT_BODY( node );
    685763}
    686764
    687765template< typename pass_type >
    688766void PassVisitor< pass_type >::visit( PointerType * node ) {
    689         VISIT_BODY( node ); 
     767        VISIT_BODY( node );
    690768}
    691769
    692770template< typename pass_type >
    693771void PassVisitor< pass_type >::visit( ArrayType * node ) {
    694         VISIT_BODY( node ); 
     772        VISIT_BODY( node );
    695773}
    696774
    697775template< typename pass_type >
    698776void PassVisitor< pass_type >::visit( FunctionType * node ) {
    699         VISIT_BODY( node ); 
     777        VISIT_BODY( node );
    700778}
    701779
    702780template< typename pass_type >
    703781void PassVisitor< pass_type >::visit( StructInstType * node ) {
    704         VISIT_BODY( node ); 
     782        VISIT_BODY( node );
    705783}
    706784
    707785template< typename pass_type >
    708786void PassVisitor< pass_type >::visit( UnionInstType * node ) {
    709         VISIT_BODY( node ); 
     787        VISIT_BODY( node );
    710788}
    711789
    712790template< typename pass_type >
    713791void PassVisitor< pass_type >::visit( EnumInstType * node ) {
    714         VISIT_BODY( node ); 
     792        VISIT_BODY( node );
    715793}
    716794
    717795template< typename pass_type >
    718796void PassVisitor< pass_type >::visit( TraitInstType * node ) {
    719         VISIT_BODY( node ); 
     797        VISIT_BODY( node );
    720798}
    721799
    722800template< typename pass_type >
    723801void PassVisitor< pass_type >::visit( TypeInstType * node ) {
    724         VISIT_BODY( node ); 
     802        VISIT_BODY( node );
    725803}
    726804
    727805template< typename pass_type >
    728806void PassVisitor< pass_type >::visit( TupleType * node ) {
    729         VISIT_BODY( node ); 
     807        VISIT_BODY( node );
    730808}
    731809
    732810template< typename pass_type >
    733811void PassVisitor< pass_type >::visit( TypeofType * node ) {
    734         VISIT_BODY( node ); 
     812        VISIT_BODY( node );
    735813}
    736814
    737815template< typename pass_type >
    738816void PassVisitor< pass_type >::visit( AttrType * node ) {
    739         VISIT_BODY( node ); 
     817        VISIT_BODY( node );
    740818}
    741819
    742820template< typename pass_type >
    743821void PassVisitor< pass_type >::visit( VarArgsType * node ) {
    744         VISIT_BODY( node ); 
     822        VISIT_BODY( node );
    745823}
    746824
    747825template< typename pass_type >
    748826void PassVisitor< pass_type >::visit( ZeroType * node ) {
    749         VISIT_BODY( node ); 
     827        VISIT_BODY( node );
    750828}
    751829
    752830template< typename pass_type >
    753831void PassVisitor< pass_type >::visit( OneType * node ) {
    754         VISIT_BODY( node ); 
     832        VISIT_BODY( node );
    755833}
    756834
     
    777855template< typename pass_type >
    778856void PassVisitor< pass_type >::visit( ListInit * node ) {
    779         VISIT_BODY( node ); 
     857        VISIT_BODY( node );
    780858}
    781859
    782860template< typename pass_type >
    783861void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
    784         VISIT_BODY( node ); 
     862        VISIT_BODY( node );
    785863}
    786864
    787865template< typename pass_type >
    788866void PassVisitor< pass_type >::visit( Subrange * node ) {
    789         VISIT_BODY( node ); 
     867        VISIT_BODY( node );
    790868}
    791869
    792870template< typename pass_type >
    793871void PassVisitor< pass_type >::visit( Constant * node ) {
    794         VISIT_BODY( node ); 
     872        VISIT_BODY( node );
    795873}
    796874
     
    843921
    844922template< typename pass_type >
    845 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    846         MUTATE_BODY( Statement, node );
    847 }
    848 
    849 template< typename pass_type >
    850 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
    851         MUTATE_BODY( Statement, node );
    852 }
    853 
    854 template< typename pass_type >
    855923Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    856924        MUTATE_BODY( Statement, node );
     
    9881056
    9891057template< typename pass_type >
    990 Expression * PassVisitor< pass_type >::mutate( UntypedValofExpr * node ) {
    991         MUTATE_BODY( Expression, node );
    992 }
    993 
    994 template< typename pass_type >
    9951058Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
    9961059        MUTATE_BODY( Expression, node );
  • src/Common/PassVisitor.proto.h

    re1c1829 r4c03e63  
    11#pragma once
     2
     3template<typename pass_type>
     4class PassVisitor;
    25
    36typedef std::function<void( void * )> cleanup_func_t;
     
    3134
    3235typedef 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};
    3354
    3455//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    112133FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
    113134FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
    114 FIELD_PTR( bool, skip_children )
     135FIELD_PTR( std::list< Declaration* >, declsToAddBefore )
     136FIELD_PTR( std::list< Declaration* >, declsToAddAfter  )
     137FIELD_PTR( bool_ref, visit_children )
    115138FIELD_PTR( at_cleanup_t, at_cleanup )
     139FIELD_PTR( PassVisitor<pass_type> * const, visitor )
  • src/GenPoly/Box.cc

    re1c1829 r4c03e63  
    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
     
    6262namespace GenPoly {
    6363        namespace {
    64                 const std::list<Label> noLabels;
    65 
    6664                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6765
     
    343341        Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
    344342                // check that the lhs is zeroed out to the level of rhs
    345                 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 ) ) ) );
    346344                // if not aligned, increment to alignment
    347345                Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
     
    386384
    387385                // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size)
    388                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
    389                 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 ) ) ) );
    390388                unsigned long n_members = 0;
    391389                bool firstMember = true;
     
    443441
    444442                // calculate union layout in function body
    445                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    446                 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 ) ) ) );
    447445                for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
    448446                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
     
    15661564                /// Returns an index expression into the offset array for a type
    15671565                Expression *makeOffsetIndex( Type *objectType, long i ) {
    1568                         std::stringstream offset_namer;
    1569                         offset_namer << i;
    1570                         ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1566                        ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) );
    15711567                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    15721568                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) );
     
    17811777                                // all union members are at offset zero
    17821778                                delete offsetofExpr;
    1783                                 return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "0" ) );
     1779                                return new ConstantExpr( Constant::from_ulong( 0 ) );
    17841780                        } else return offsetofExpr;
    17851781                }
  • src/GenPoly/CopyParams.cc

    re1c1829 r4c03e63  
    4545
    4646        CopyParams::CopyParams() : namer( "_cp" ) {}
    47 
    48         static const std::list< Label > noLabels;
    4947
    5048        void CopyParams::visit( FunctionDecl *funcDecl ) {
  • src/GenPoly/DeclMutator.cc

    re1c1829 r4c03e63  
    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
     
    2020
    2121namespace GenPoly {
    22         namespace {
    23                 const std::list<Label> noLabels;
    24         }
    25 
    2622        DeclMutator::DeclMutator() : Mutator(), declsToAdd(1), declsToAddAfter(1) {}
    2723
    2824        DeclMutator::~DeclMutator() {}
    29        
     25
    3026        void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) {
    3127                for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) {
     
    3430
    3531                        if ( decl == decls.end() ) break;
    36                        
     32
    3733                        // run mutator on declaration
    3834                        *decl = maybeMutate( *decl, *this );
     
    5551                newBack->splice( newBack->end(), *back );
    5652                declsToAdd.pop_back();
    57                
     53
    5854                back = declsToAddAfter.rbegin();
    5955                newBack = back + 1;
     
    6662                CompoundStmt *compoundStmt = dynamic_cast< CompoundStmt* >(stmt);
    6763                if ( compoundStmt ) return mutate( compoundStmt );
    68                
     64
    6965                doBeginScope();
    70                
     66
    7167                // run mutator on statement
    7268                stmt = maybeMutate( stmt, *this );
     
    10298                doBeginScope();
    10399
    104                
     100
    105101                for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) {
    106102                        // add any new declarations after the previous statement
     
    112108
    113109                        if ( stmt == stmts.end() ) break;
    114                        
     110
    115111                        // run mutator on statement
    116112                        *stmt = maybeMutate( *stmt, *this );
     
    123119                        declsToAdd.back().clear();
    124120                }
    125                
     121
    126122                doEndScope();
    127123        }
     
    139135                return compoundStmt;
    140136        }
    141        
     137
    142138        Statement* DeclMutator::mutate(IfStmt *ifStmt) {
    143139                ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) );
     
    146142                return ifStmt;
    147143        }
    148        
     144
    149145        Statement* DeclMutator::mutate(WhileStmt *whileStmt) {
    150146                whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) );
     
    152148                return whileStmt;
    153149        }
    154        
     150
    155151        Statement* DeclMutator::mutate(ForStmt *forStmt) {
    156152                mutateAll( forStmt->get_initialization(), *this );
     
    160156                return forStmt;
    161157        }
    162        
     158
    163159        Statement* DeclMutator::mutate(SwitchStmt *switchStmt) {
    164160                switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
     
    166162                return switchStmt;
    167163        }
    168        
     164
    169165        Statement* DeclMutator::mutate(CaseStmt *caseStmt) {
    170166                caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
     
    172168                return caseStmt;
    173169        }
    174        
     170
    175171        Statement* DeclMutator::mutate(TryStmt *tryStmt) {
    176172                tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
     
    179175                return tryStmt;
    180176        }
    181        
     177
    182178        Statement* DeclMutator::mutate(CatchStmt *catchStmt) {
    183179                catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
     180                catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
    184181                catchStmt->set_body( mutateStatement( catchStmt->get_body() ) );
    185182                return catchStmt;
  • src/GenPoly/Lvalue.cc

    re1c1829 r4c03e63  
    3535namespace GenPoly {
    3636        namespace {
    37                 const std::list<Label> noLabels;
    38 
    3937                /// Replace uses of lvalue returns with appropriate pointers
    4038                class Pass1 : public Mutator {
  • src/GenPoly/PolyMutator.cc

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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." );
  • src/InitTweak/FixGlobalInit.cc

    re1c1829 r4c03e63  
    2626
    2727namespace InitTweak {
    28         namespace {
    29                 const std::list<Label> noLabels;
    30         }
    31 
    3228        class GlobalFixer : public Visitor {
    3329          public:
  • src/InitTweak/FixInit.cc

    re1c1829 r4c03e63  
    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" ) ), noDesignators );
     726                                                SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ), noDesignators );
    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
  • src/InitTweak/GenInit.cc

    re1c1829 r4c03e63  
    2121
    2222#include "Common/PassVisitor.h"
     23
     24#include "GenPoly/DeclMutator.h"
     25#include "GenPoly/PolyMutator.h"
     26#include "GenPoly/ScopedSet.h"
     27
     28#include "ResolvExpr/typeops.h"
    2329
    2430#include "SynTree/Declaration.h"
     
    3137#include "SymTab/Autogen.h"
    3238#include "SymTab/Mangler.h"
    33 
    34 #include "GenPoly/DeclMutator.h"
    35 #include "GenPoly/PolyMutator.h"
    36 #include "GenPoly/ScopedSet.h"
    37 
    38 #include "ResolvExpr/typeops.h"
    3939
    4040namespace InitTweak {
  • src/InitTweak/InitTweak.cc

    re1c1829 r4c03e63  
    474474        public:
    475475                ConstExprChecker() : isConstExpr( true ) {}
     476
     477                using Visitor::visit;
    476478
    477479                virtual void visit( __attribute((unused)) ApplicationExpr *applicationExpr ) { isConstExpr = false; }
  • src/Parser/ExpressionNode.cc

    re1c1829 r4c03e63  
    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;
     
    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

    re1c1829 r4c03e63  
    415415                                result->location = cur->location;
    416416                                * out++ = result;
     417                        } else {
     418                                assertf(false, "buildList unknown type");
    417419                        } // if
    418420                } catch( SemanticError &e ) {
  • src/Parser/StatementNode.cc

    re1c1829 r4c03e63  
    168168
    169169Statement *build_resume_at( ExpressionNode *ctl, ExpressionNode *target ) {
    170         std::list< Expression * > exps;
    171         buildMoveList( ctl, exps );
    172         assertf( exps.size() < 2, "This means we are leaking memory");
    173         return new ThrowStmt( noLabels, ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
     170        (void)ctl;
     171        (void)target;
     172        assertf( false, "resume at (non-local throw) is not yet supported," );
    174173}
    175174
    176175Statement *build_try( StatementNode *try_stmt, StatementNode *catch_stmt, StatementNode *finally_stmt ) {
    177         std::list< Statement * > branches;
    178         buildMoveList< Statement, StatementNode >( catch_stmt, branches );
     176        std::list< CatchStmt * > branches;
     177        buildMoveList< CatchStmt, StatementNode >( catch_stmt, branches );
    179178        CompoundStmt *tryBlock = safe_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_stmt));
    180179        FinallyStmt *finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) );
  • src/Parser/parseutility.cc

    re1c1829 r4c03e63  
    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/SymTab/Autogen.h

    re1c1829 r4c03e63  
    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
     
    2525
    2626namespace SymTab {
    27         /// Generates assignment operators, constructors, and destructor for aggregate types as required
    28         void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     27    /// Generates assignment operators, constructors, and destructor for aggregate types as required
     28    void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    2929
    30         /// returns true if obj's name is the empty string and it has a bitfield width
    31         bool isUnnamedBitfield( ObjectDecl * obj );
     30    /// returns true if obj's name is the empty string and it has a bitfield width
     31    bool isUnnamedBitfield( ObjectDecl * obj );
    3232
    33         /// size_t type - set when size_t typedef is seen. Useful in a few places,
    34         /// such as in determining array dimension type
    35         extern Type * SizeType;
     33    /// size_t type - set when size_t typedef is seen. Useful in a few places,
     34    /// such as in determining array dimension type
     35    extern Type * SizeType;
    3636
    37         /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    38         template< typename OutputIterator >
     37    /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
     38    template< typename OutputIterator >
    3939        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
    4040
    41         /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    42         /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    43         template< typename OutputIterator >
     41    /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
     42    /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
     43    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();
     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();
    6060//                      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 );
     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 );
    6666
    67                 Statement * listInit = srcParam.buildListInit( fExpr );
     67        Statement * listInit = srcParam.buildListInit( fExpr );
    6868
    69                 std::list< Expression * > args = *++srcParam;
    70                 fExpr->get_args().splice( fExpr->get_args().end(), args );
     69        std::list< Expression * > args = *++srcParam;
     70        fExpr->get_args().splice( fExpr->get_args().end(), args );
    7171
    72                 *out++ = new ExprStmt( noLabels, fExpr );
     72        *out++ = new ExprStmt( noLabels, fExpr );
    7373
    74                 srcParam.clearArrayIndices();
     74        srcParam.clearArrayIndices();
    7575
    76                 return listInit;
     76        return listInit;
     77    }
     78
     79    /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
     80    /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
     81    template< typename OutputIterator >
     82        void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
     83        static UniqueName indexName( "_index" );
     84
     85        // for a flexible array member nothing is done -- user must define own assignment
     86        if ( ! array->get_dimension() ) return ;
     87
     88        Expression * begin, * end, * update, * cmp;
     89        if ( forward ) {
     90            // generate: for ( int i = 0; i < N; ++i )
     91            begin = new ConstantExpr( Constant::from_int( 0 ) );
     92            end = array->get_dimension()->clone();
     93            cmp = new NameExpr( "?<?" );
     94            update = new NameExpr( "++?" );
     95        } else {
     96            // generate: for ( int i = N-1; i >= 0; --i )
     97            begin = new UntypedExpr( new NameExpr( "?-?" ) );
     98            ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     99            ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     100            end = new ConstantExpr( Constant::from_int( 0 ) );
     101            cmp = new NameExpr( "?>=?" );
     102            update = new NameExpr( "--?" );
    77103        }
    78104
    79         /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    80         /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    81         template< typename OutputIterator >
    82         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
    83                 static UniqueName indexName( "_index" );
     105        ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
    84106
    85                 // for a flexible array member nothing is done -- user must define own assignment
    86                 if ( ! array->get_dimension() ) return ;
     107        UntypedExpr *cond = new UntypedExpr( cmp );
     108        cond->get_args().push_back( new VariableExpr( index ) );
     109        cond->get_args().push_back( end );
    87110
    88                 Expression * begin, * end, * update, * cmp;
    89                 if ( forward ) {
    90                         // generate: for ( int i = 0; i < 0; ++i )
    91                         begin = new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0" ) );
    92                         end = array->get_dimension()->clone();
    93                         cmp = new NameExpr( "?<?" );
    94                         update = new NameExpr( "++?" );
    95                 } else {
    96                         // generate: for ( int i = N-1; i >= 0; --i )
    97                         begin = new UntypedExpr( new NameExpr( "?-?" ) );
    98                         ((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" ) );
    101                         cmp = new NameExpr( "?>=?" );
    102                         update = new NameExpr( "--?" );
    103                 }
     111        UntypedExpr *inc = new UntypedExpr( update );
     112        inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    104113
    105                 ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
     114        UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     115        dstIndex->get_args().push_back( dstParam );
     116        dstIndex->get_args().push_back( new VariableExpr( index ) );
     117        dstParam = dstIndex;
    106118
    107                 UntypedExpr *cond = new UntypedExpr( cmp );
    108                 cond->get_args().push_back( new VariableExpr( index ) );
    109                 cond->get_args().push_back( end );
     119        // srcParam must keep track of the array indices to build the
     120        // source parameter and/or array list initializer
     121        srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    110122
    111                 UntypedExpr *inc = new UntypedExpr( update );
    112                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     123        // for stmt's body, eventually containing call
     124        CompoundStmt * body = new CompoundStmt( noLabels );
     125        Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
    113126
    114                 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    115                 dstIndex->get_args().push_back( dstParam );
    116                 dstIndex->get_args().push_back( new VariableExpr( index ) );
    117                 dstParam = dstIndex;
     127        // block containing for stmt and index variable
     128        std::list<Statement *> initList;
     129        CompoundStmt * block = new CompoundStmt( noLabels );
     130        block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     131        if ( listInit ) block->get_kids().push_back( listInit );
     132        block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
    118133
    119                 // srcParam must keep track of the array indices to build the
    120                 // source parameter and/or array list initializer
    121                 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
     134        *out++ = block;
     135    }
    122136
    123                 // for stmt's body, eventually containing call
    124                 CompoundStmt * body = new CompoundStmt( noLabels );
    125                 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     137    template< typename OutputIterator >
     138        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
     139        if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     140            genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     141            return 0;
     142        } else {
     143            return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     144        }
     145    }
    126146
    127                 // block containing for stmt and index variable
    128                 std::list<Statement *> initList;
    129                 CompoundStmt * block = new CompoundStmt( noLabels );
    130                 block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    131                 if ( listInit ) block->get_kids().push_back( listInit );
    132                 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     147    /// inserts into out a generated call expression to function fname with arguments dstParam
     148    /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     149    /// object being constructed. The function wraps constructor and destructor calls in an
     150    /// ImplicitCtorDtorStmt node.
     151    template< typename OutputIterator >
     152        void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     153        ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
     154        assert( obj );
     155        // unnamed bit fields are not copied as they cannot be accessed
     156        if ( isUnnamedBitfield( obj ) ) return;
    133157
    134                 *out++ = block;
     158        bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
     159        std::list< Statement * > stmts;
     160        genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
     161
     162        // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
     163        assert( stmts.size() <= 1 );
     164        if ( stmts.size() == 1 ) {
     165            Statement * callStmt = stmts.front();
     166            if ( addCast ) {
     167                // implicitly generated ctor/dtor calls should be wrapped
     168                // so that later passes are aware they were generated.
     169                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     170                // because this causes the address to be taken at codegen, which is illegal in C.
     171                callStmt = new ImplicitCtorDtorStmt( callStmt );
     172            }
     173            *out++ = callStmt;
    135174        }
    136 
    137         template< typename OutputIterator >
    138         Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    139                 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    140                         genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
    141                         return 0;
    142                 } else {
    143                         return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
    144                 }
    145         }
    146 
    147         /// inserts into out a generated call expression to function fname with arguments dstParam
    148         /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
    149         /// object being constructed. The function wraps constructor and destructor calls in an
    150         /// ImplicitCtorDtorStmt node.
    151         template< typename OutputIterator >
    152         void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    153                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    154                 assert( obj );
    155                 // unnamed bit fields are not copied as they cannot be accessed
    156                 if ( isUnnamedBitfield( obj ) ) return;
    157 
    158                 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
    159                 std::list< Statement * > stmts;
    160                 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
    161 
    162                 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
    163                 assert( stmts.size() <= 1 );
    164                 if ( stmts.size() == 1 ) {
    165                         Statement * callStmt = stmts.front();
    166                         if ( addCast ) {
    167                                 // implicitly generated ctor/dtor calls should be wrapped
    168                                 // so that later passes are aware they were generated.
    169                                 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    170                                 // because this causes the address to be taken at codegen, which is illegal in C.
    171                                 callStmt = new ImplicitCtorDtorStmt( callStmt );
    172                         }
    173                         *out++ = callStmt;
    174                 }
    175         }
     175    }
    176176} // namespace SymTab
    177177#endif // AUTOGEN_H
  • src/SymTab/Indexer.cc

    re1c1829 r4c03e63  
    493493                acceptNewScope( compLitExpr->get_result(), *this );
    494494                maybeAccept( compLitExpr->get_initializer(), *this );
    495         }
    496 
    497         void Indexer::visit( UntypedValofExpr *valofExpr ) {
    498                 acceptNewScope( valofExpr->get_result(), *this );
    499                 maybeAccept( valofExpr->get_body(), *this );
    500495        }
    501496
  • src/SymTab/Indexer.h

    re1c1829 r4c03e63  
    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 );
  • src/SymTab/Validate.cc

    re1c1829 r4c03e63  
    6666#include "ResolvExpr/typeops.h"
    6767
     68#include "SynTree/Attribute.h"
    6869#include "SynTree/Expression.h"
    6970#include "SynTree/Mutator.h"
     
    114115
    115116        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    116         class EnumAndPointerDecayPass final : public Visitor {
    117                 typedef Visitor Parent;
    118                 virtual void visit( EnumDecl *aggregateDecl );
    119                 virtual void visit( FunctionType *func );
     117        class EnumAndPointerDecay {
     118        public:
     119                void previsit( EnumDecl *aggregateDecl );
     120                void previsit( FunctionType *func );
    120121        };
    121122
     
    125126          public:
    126127                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    127           private:
    128128                using Parent::visit;
    129129                void visit( EnumInstType *enumInst ) final;
     
    135135                void visit( UnionDecl *unionDecl ) final;
    136136                void visit( TypeInstType *typeInst ) final;
    137 
     137          private:
    138138                const Indexer *indexer;
    139139
     
    146146        };
    147147
    148         /// Replaces array and function types in forall lists by appropriate pointer type
    149         class Pass3 final : public Indexer {
     148        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
     149        class ForallPointerDecay final : public Indexer {
    150150                typedef Indexer Parent;
    151151          public:
    152152                using Parent::visit;
    153                 Pass3( const Indexer *indexer );
    154           private:
     153                ForallPointerDecay( const Indexer *indexer );
     154
    155155                virtual void visit( ObjectDecl *object ) override;
    156156                virtual void visit( FunctionDecl *func ) override;
     
    159159        };
    160160
    161         class ReturnChecker {
     161        class ReturnChecker : public WithScopes {
    162162          public:
    163163                /// Checks that return statements return nothing if their return type is void
     
    166166          private:
    167167                void previsit( FunctionDecl * functionDecl );
    168                 void postvisit( FunctionDecl * functionDecl );
    169168                void previsit( ReturnStmt * returnStmt );
    170169
    171170                typedef std::list< DeclarationWithType * > ReturnVals;
    172171                ReturnVals returnVals;
    173                 std::stack< ReturnVals > returnValsStack;
    174172        };
    175173
     
    247245
    248246        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    249                 EnumAndPointerDecayPass epc;
     247                PassVisitor<EnumAndPointerDecay> epc;
    250248                LinkReferenceToTypes lrt( doDebug, 0 );
    251                 Pass3 pass3( 0 );
     249                ForallPointerDecay fpd( 0 );
    252250                CompoundLiteral compoundliteral;
    253251                PassVisitor<ValidateGenericParameters> genericParams;
     
    261259                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    262260                Concurrency::applyKeywords( translationUnit );
    263                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     261                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    264262                Concurrency::implementMutexFuncs( translationUnit );
    265263                Concurrency::implementThreadStarter( translationUnit );
    266264                ReturnChecker::checkFunctionReturns( translationUnit );
    267265                compoundliteral.mutateDeclarationList( translationUnit );
    268                 acceptAll( translationUnit, pass3 );
     266                acceptAll( translationUnit, fpd );
    269267                ArrayLength::computeLength( translationUnit );
    270268        }
    271269
    272270        void validateType( Type *type, const Indexer *indexer ) {
    273                 EnumAndPointerDecayPass epc;
     271                PassVisitor<EnumAndPointerDecay> epc;
    274272                LinkReferenceToTypes lrt( false, indexer );
    275                 Pass3 pass3( indexer );
     273                ForallPointerDecay fpd( indexer );
    276274                type->accept( epc );
    277275                type->accept( lrt );
    278                 type->accept( pass3 );
     276                type->accept( fpd );
    279277        }
    280278
     
    355353        }
    356354
    357         void EnumAndPointerDecayPass::visit( EnumDecl *enumDecl ) {
     355        void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
    358356                // Set the type of each member of the enumeration to be EnumConstant
    359357                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     
    362360                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
    363361                } // for
    364                 Parent::visit( enumDecl );
    365362        }
    366363
     
    369366                void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    370367                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    371                         // entirely other fix ups are handled by the FixFunction class
     368                        // entirely. other fix ups are handled by the FixFunction class
    372369                        typedef typename DWTList::iterator DWTIterator;
    373370                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
     
    388385                                for ( ; i != end; ++i ) {
    389386                                        FixFunction fixer;
    390                                         *i = (*i )->acceptMutator( fixer );
     387                                        *i = (*i)->acceptMutator( fixer );
    391388                                        if ( fixer.get_isVoid() ) {
    392389                                                throw SemanticError( "invalid type void in function type ", func );
     
    397394        }
    398395
    399         void EnumAndPointerDecayPass::visit( FunctionType *func ) {
     396        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    400397                // Fix up parameters and return types
    401398                fixFunctionList( func->get_parameters(), func );
    402399                fixFunctionList( func->get_returnVals(), func );
    403                 Visitor::visit( func );
    404400        }
    405401
     
    548544        }
    549545
    550         Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
     546        ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
    551547                if ( other_indexer ) {
    552548                        indexer = other_indexer;
     
    586582        }
    587583
    588         void Pass3::visit( ObjectDecl *object ) {
     584        void ForallPointerDecay::visit( ObjectDecl *object ) {
    589585                forallFixer( object->get_type() );
    590586                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     
    595591        }
    596592
    597         void Pass3::visit( FunctionDecl *func ) {
     593        void ForallPointerDecay::visit( FunctionDecl *func ) {
    598594                forallFixer( func->get_type() );
    599595                Parent::visit( func );
     
    607603
    608604        void ReturnChecker::previsit( FunctionDecl * functionDecl ) {
    609                 returnValsStack.push( returnVals );
     605                GuardValue( returnVals );
    610606                returnVals = functionDecl->get_functionType()->get_returnVals();
    611         }
    612         void ReturnChecker::postvisit( __attribute__((unused)) FunctionDecl * functionDecl ) {
    613                 returnVals = returnValsStack.top();
    614                 returnValsStack.pop();
    615607        }
    616608
     
    927919                                ret->set_name( toString( "_retval_", CodeGen::genName( functionDecl ) ) );
    928920                        }
     921                        ret->get_attributes().push_back( new Attribute( "unused" ) );
    929922                }
    930923        }
  • src/SynTree/Attribute.h

    re1c1829 r4c03e63  
    4040};
    4141
     42const std::list< Attribute * > noAttributes;
     43
    4244#endif
    4345
  • src/SynTree/BaseSyntaxNode.h

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    288288}
    289289
    290 // CastExpr *CastExpr::clone() const { return 0; }
    291 
    292290void CastExpr::print( std::ostream &os, int indent ) const {
    293291        os << "Cast of:" << std::endl << std::string( indent+2, ' ' );
     
    355353}
    356354
    357 //// is this right? It's cloning the member, but the member is a declaration so probably shouldn't be cloned...
    358355MemberExpr::MemberExpr( const MemberExpr &other ) :
    359356                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
     
    361358
    362359MemberExpr::~MemberExpr() {
    363         // delete member;
     360        // don't delete the member declaration, since it points somewhere else in the tree
    364361        delete aggregate;
    365362}
     
    591588}
    592589
    593 UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {}
    594 
    595 UntypedValofExpr::~UntypedValofExpr() { delete body; }
    596 
    597 void UntypedValofExpr::print( std::ostream &os, int indent ) const {
    598         os << std::string( indent, ' ' ) << "Valof Expression: " << std::endl;
    599         if ( get_body() != 0 )
    600                 get_body()->print( os, indent + 2 );
    601 }
    602 
    603590RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    604591RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
  • src/SynTree/Expression.h

    re1c1829 r4c03e63  
    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 {
  • src/SynTree/Mutator.cc

    re1c1829 r4c03e63  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Mar  8 16:36:00 2017
    13 // Update Count     : 23
     12// Last Modified On : Thu Jun 22 13:43:00 2017
     13// Update Count     : 24
    1414//
    1515
     
    162162        tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
    163163        mutateAll( tryStmt->get_catchers(), *this );
     164        tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) );
    164165        return tryStmt;
    165166}
     
    167168Statement *Mutator::mutate( CatchStmt *catchStmt ) {
    168169        catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
     170        catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
    169171        catchStmt->set_body( maybeMutate( catchStmt->get_body(), *this ) );
    170172        return catchStmt;
     
    380382}
    381383
    382 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
    383         valofExpr->set_env( maybeMutate( valofExpr->get_env(), *this ) );
    384         valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ) );
    385         return valofExpr;
    386 }
    387 
    388384Expression *Mutator::mutate( RangeExpr *rangeExpr ) {
    389385        rangeExpr->set_env( maybeMutate( rangeExpr->get_env(), *this ) );
  • src/SynTree/Mutator.h

    re1c1829 r4c03e63  
    7878        virtual Expression* mutate( ConstructorExpr *ctorExpr );
    7979        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
    80         virtual Expression* mutate( UntypedValofExpr *valofExpr );
    8180        virtual Expression* mutate( RangeExpr *rangeExpr );
    8281        virtual Expression* mutate( UntypedTupleExpr *tupleExpr );
  • src/SynTree/ObjectDecl.cc

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    313313}
    314314
    315 TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &_handlers, FinallyStmt *_finallyBlock ) :
     315TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<CatchStmt *> &_handlers, FinallyStmt *_finallyBlock ) :
    316316        Statement( labels ), block( tryBlock ),  handlers( _handlers ), finallyBlock( _finallyBlock ) {
    317317}
     
    334334        // handlers
    335335        os << string( indent + 2, ' ' ) << "and handlers: " << endl;
    336         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++)
    337337                (*i )->print( os, indent + 4 );
    338338
  • src/SynTree/Statement.h

    re1c1829 r4c03e63  
    315315class TryStmt : public Statement {
    316316  public:
    317         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 );
    318318        TryStmt( const TryStmt &other );
    319319        virtual ~TryStmt();
     
    321321        CompoundStmt *get_block() const { return block; }
    322322        void set_block( CompoundStmt *newValue ) { block = newValue; }
    323         std::list<Statement *>& get_catchers() { return handlers; }
     323        std::list<CatchStmt *>& get_catchers() { return handlers; }
    324324
    325325        FinallyStmt *get_finally() const { return finallyBlock; }
     
    333333  private:
    334334        CompoundStmt *block;
    335         std::list<Statement *> handlers;
     335        std::list<CatchStmt *> handlers;
    336336        FinallyStmt *finallyBlock;
    337337};
  • src/SynTree/Visitor.cc

    re1c1829 r4c03e63  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Jun  8 16:31:00 2017
    13 // Update Count     : 25
     12// Last Modified On : Thu Jun 22 13:41:00 2017
     13// Update Count     : 26
    1414//
    1515
     
    137137        maybeAccept( tryStmt->get_block(), *this );
    138138        acceptAll( tryStmt->get_catchers(), *this );
     139        maybeAccept( tryStmt->get_finally(), *this );
    139140}
    140141
    141142void Visitor::visit( CatchStmt *catchStmt ) {
    142143        maybeAccept( catchStmt->get_decl(), *this );
     144        maybeAccept( catchStmt->get_cond(), *this );
    143145        maybeAccept( catchStmt->get_body(), *this );
    144146}
     
    299301        maybeAccept( compLitExpr->get_result(), *this );
    300302        maybeAccept( compLitExpr->get_initializer(), *this );
    301 }
    302 
    303 void Visitor::visit( UntypedValofExpr *valofExpr ) {
    304         maybeAccept( valofExpr->get_result(), *this );
    305         maybeAccept( valofExpr->get_body(), *this );
    306303}
    307304
  • src/SynTree/Visitor.h

    re1c1829 r4c03e63  
    8181        virtual void visit( ConstructorExpr * ctorExpr );
    8282        virtual void visit( CompoundLiteralExpr *compLitExpr );
    83         virtual void visit( UntypedValofExpr *valofExpr );
    8483        virtual void visit( RangeExpr *rangeExpr );
    8584        virtual void visit( UntypedTupleExpr *tupleExpr );
     
    163162                        } // if
    164163                } catch( SemanticError &e ) {
    165                         e.set_location( (*i)->location );                       
     164                        e.set_location( (*i)->location );
    166165                        errors.append( e );
    167166                } // try
  • src/Tuples/TupleExpansion.cc

    re1c1829 r4c03e63  
    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" ) ), noDesignators ) );
     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 ) ), noDesignators ) );
    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() ) );
  • src/tests/.expect/32/KRfunctions.txt

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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

    re1c1829 r4c03e63  
    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/scopeErrors.txt

    re1c1829 r4c03e63  
    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
Note: See TracChangeset for help on using the changeset viewer.