Changeset 67fa9f9 for src


Ignore:
Timestamp:
Jul 5, 2017, 10:50:22 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
0614d14
Parents:
11dbfe1 (diff), 307a732 (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

Location:
src
Files:
6 added
1 deleted
57 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r11dbfe1 r67fa9f9  
    288288        }
    289289
    290         void CodeGenerator::printDesignators( std::list< Expression * > & designators ) {
    291                 typedef std::list< Expression * > DesignatorList;
     290        void CodeGenerator::visit( Designation * designation ) {
     291                std::list< Expression * > designators = designation->get_designators();
    292292                if ( designators.size() == 0 ) return;
    293                 for ( DesignatorList::iterator iter = designators.begin(); iter != designators.end(); ++iter ) {
    294                         if ( dynamic_cast< NameExpr * >( *iter ) ) {
    295                                 // if expression is a name, then initializing aggregate member
     293                for ( Expression * des : designators ) {
     294                        if ( dynamic_cast< NameExpr * >( des ) || dynamic_cast< VariableExpr * >( des ) ) {
     295                                // if expression is a NameExpr or VariableExpr, then initializing aggregate member
    296296                                output << ".";
    297                                 (*iter)->accept( *this );
     297                                des->accept( *this );
    298298                        } else {
    299                                 // if not a simple name, it has to be a constant expression, i.e. an array designator
     299                                // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt
    300300                                output << "[";
    301                                 (*iter)->accept( *this );
     301                                des->accept( *this );
    302302                                output << "]";
    303303                        } // if
     
    307307
    308308        void CodeGenerator::visit( SingleInit * init ) {
    309                 printDesignators( init->get_designators() );
    310309                init->get_value()->accept( *this );
    311310        }
    312311
    313312        void CodeGenerator::visit( ListInit * init ) {
    314                 printDesignators( init->get_designators() );
     313                auto initBegin = init->begin();
     314                auto initEnd = init->end();
     315                auto desigBegin = init->get_designations().begin();
     316                auto desigEnd = init->get_designations().end();
     317
    315318                output << "{ ";
    316                 genCommaList( init->begin(), init->end() );
     319                for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
     320                        (*desigBegin)->accept( *this );
     321                        (*initBegin)->accept( *this );
     322                        ++initBegin, ++desigBegin;
     323                        if ( initBegin != initEnd ) {
     324                                output << ", ";
     325                        }
     326                }
    317327                output << " }";
     328                assertf( initBegin == initEnd && desigBegin == desigEnd, "Initializers and designators not the same length. %s", toString( init ).c_str() );
    318329        }
    319330
     
    716727
    717728        void CodeGenerator::visit( TypeExpr * typeExpr ) {
    718                 assertf( ! genC, "TypeExpr should not reach code generation." );
    719                 output<< genType( typeExpr->get_type(), "", pretty, genC );
     729                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
     730                // assertf( ! genC, "TypeExpr should not reach code generation." );
     731                if ( ! genC ) {
     732                        output<< genType( typeExpr->get_type(), "", pretty, genC );
     733                }
    720734        }
    721735
  • src/CodeGen/CodeGenerator.h

    r11dbfe1 r67fa9f9  
    4747
    4848                //*** Initializer
     49                virtual void visit( Designation * );
    4950                virtual void visit( SingleInit * );
    5051                virtual void visit( ListInit * );
     
    137138                bool lineMarks = false;
    138139
    139                 void printDesignators( std::list< Expression * > & );
    140140                void handleStorageClass( DeclarationWithType *decl );
    141141                void handleAggregate( AggregateDecl *aggDecl, const std::string & kind );
  • src/Common/PassVisitor.h

    r11dbfe1 r67fa9f9  
    1212#include "SynTree/Expression.h"
    1313#include "SynTree/Constant.h"
     14#include "SynTree/TypeSubstitution.h"
    1415
    1516#include "PassVisitor.proto.h"
     
    2627//                          stmtsToAddBefore or stmtsToAddAfter respectively.
    2728// | 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// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
    2930//                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
    3031//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    3233class PassVisitor final : public Visitor, public Mutator {
    3334public:
    34         PassVisitor() = default;
    3535
    3636        template< typename... Args >
     
    257257
    258258        void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); }
    259 
    260         guard_value_impl init_guard() {
    261                 guard_value_impl guard;
    262                 auto at_cleanup = at_cleanup_impl(pass, 0);
    263                 if( at_cleanup ) {
    264                         *at_cleanup = [&guard]( cleanup_func_t && func, void* val ) {
    265                                 guard.push( std::move( func ), val );
    266                         };
    267                 }
    268                 return guard;
    269         }
    270259};
    271260
     
    283272
    284273public:
    285         TypeSubstitution * env;
     274        TypeSubstitution * env = nullptr;
    286275};
    287276
     
    295284        std::list< Statement* > stmtsToAddAfter;
    296285};
     286
     287class WithDeclsToAdd {
     288protected:
     289        WithDeclsToAdd() = default;
     290        ~WithDeclsToAdd() = default;
     291
     292public:
     293        std::list< Declaration* > declsToAddBefore;
     294        std::list< Declaration* > declsToAddAfter;
     295};
     296
    297297class WithShortCircuiting {
    298298protected:
     
    304304};
    305305
    306 class WithScopes {
    307 protected:
    308         WithScopes() = default;
    309         ~WithScopes() = default;
     306class WithGuards {
     307protected:
     308        WithGuards() = default;
     309        ~WithGuards() = default;
    310310
    311311public:
     
    318318                }, static_cast< void * >( & val ) );
    319319        }
     320
     321        template< typename T >
     322        void GuardScope( T& val ) {
     323                val.beginScope();
     324                at_cleanup( []( void * val ) {
     325                        static_cast< T * >( val )->endScope();
     326                }, static_cast< void * >( & val ) );
     327        }
     328
     329        template< typename Func >
     330        void GuardAction( Func func ) {
     331                at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
     332        }
    320333};
    321334
     
    323336class WithVisitorRef {
    324337protected:
    325         WithVisitorRef() = default;
    326         ~WithVisitorRef() = default;
    327 
    328 public:
    329         PassVisitor<pass_type> * const visitor;
     338        WithVisitorRef() {}
     339        ~WithVisitorRef() {}
     340
     341public:
     342        PassVisitor<pass_type> * const visitor = nullptr;
    330343};
    331344
  • src/Common/PassVisitor.impl.h

    r11dbfe1 r67fa9f9  
    33#define VISIT_START( node )                     \
    44        __attribute__((unused))                   \
    5         const auto & guard = init_guard();        \
     5        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
    66        bool visit_children = true;               \
    77        set_visit_children( visit_children );   \
     
    1515#define MUTATE_START( node )                    \
    1616        __attribute__((unused))                   \
    17         const auto & guard = init_guard();        \
     17        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
    1818        bool visit_children = true;               \
    1919        set_visit_children( visit_children );   \
     
    6868        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    6969                // splice in new declarations after previous decl
    70                 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 
     70                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
    7171
    7272                if ( i == decls.end() ) break;
     
    8888        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    8989                // splice in new declarations after previous decl
    90                 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 
     90                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
    9191
    9292                if ( i == decls.end() ) break;
     
    104104void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
    105105        SemanticError errors;
     106
     107        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     108        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
     109        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
     110        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
     111        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
    106112
    107113        StmtList_t* beforeStmts = get_beforeStmts();
     
    181187Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
    182188        return handleStatement( stmt, [this]( Statement * stmt ) {
    183                 maybeAccept( stmt, *this ); 
     189                maybeAccept( stmt, *this );
    184190                return stmt;
    185191        });
     
    212218                expr->accept( *this );
    213219                return expr;
    214         });             
     220        });
    215221}
    216222
     
    565571        VISIT_START( node );
    566572
     573        // maybeAccept( node->get_env(), *this );
     574        maybeAccept( node->get_result(), *this );
     575
    567576        for ( auto expr : node->get_args() ) {
    568577                visitExpression( expr );
     
    575584Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    576585        MUTATE_START( node );
     586
     587        node->set_env( maybeMutate( node->get_env(), *this ) );
     588        node->set_result( maybeMutate( node->get_result(), *this ) );
    577589
    578590        for ( auto& expr : node->get_args() ) {
  • src/Common/PassVisitor.proto.h

    r11dbfe1 r67fa9f9  
    55
    66typedef std::function<void( void * )> cleanup_func_t;
     7typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
    78
    89class guard_value_impl {
    910public:
    10         guard_value_impl() = default;
     11        guard_value_impl( at_cleanup_t * at_cleanup ) {
     12                if( at_cleanup ) {
     13                        *at_cleanup = [this]( cleanup_func_t && func, void* val ) {
     14                                push( std::move( func ), val );
     15                        };
     16                }
     17        }
    1118
    1219        ~guard_value_impl() {
     
    3340};
    3441
    35 typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
    3642
    3743class bool_ref {
     
    5662// Deep magic (a.k.a template meta programming) to make the templated visitor work
    5763// Basically the goal is to make 2 previsit_impl
    58 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
     64// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    5965//     'pass.previsit( node )' that compiles will be used for that node for that type
    6066//     This requires that this option only compile for passes that actually define an appropriate visit.
  • src/Common/utility.h

    r11dbfe1 r67fa9f9  
    305305// for ( val : group_iterate( container1, container2, ... ) ) {}
    306306// syntax to have a for each that iterates multiple containers of the same length
    307 // TODO: update to use variadic arguments
     307// TODO: update to use variadic arguments, perfect forwarding
    308308
    309309template< typename T1, typename T2 >
  • src/ControlStruct/ExceptTranslate.cc

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jun 22 15:57:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Fri Jun 30 13:30:00 2017
     13// Update Count     : 1
    1414//
    1515
    1616#include "ExceptTranslate.h"
    1717#include "Common/PassVisitor.h"
    18 
    19 namespace ControlFlow {
     18#include "SynTree/Statement.h"
     19#include "SynTree/Declaration.h"
     20#include "SynTree/Expression.h"
     21#include "SynTree/Type.h"
     22#include "SynTree/Attribute.h"
     23
     24namespace ControlStruct {
    2025
    2126        // This (large) section could probably be moved out of the class
     
    2429        // Type(Qualifiers &, false, std::list<Attribute *> &)
    2530
    26         // void (*function)()
    27         static FunctionType void_func_t(Type::Qualifiers(), false);
     31        // void (*function)();
     32        static FunctionType try_func_t(Type::Qualifiers(), false);
    2833        // void (*function)(int, exception);
    2934        static FunctionType catch_func_t(Type::Qualifiers(), false);
     
    3237        // bool (*function)(exception);
    3338        static FunctionType handle_func_t(Type::Qualifiers(), false);
     39        // void (*function)(__attribute__((unused)) void *);
     40        static FunctionType finally_func_t(Type::Qualifiers(), false);
    3441
    3542        static void init_func_types() {
    36                 static init_complete = false;
     43                static bool init_complete = false;
    3744                if (init_complete) {
    3845                        return;
    3946                }
    4047                ObjectDecl index_obj(
    41                         "index_t",
     48                        "__handler_index",
    4249                        Type::StorageClasses(),
    4350                        LinkageSpec::Cforall,
    4451                        /*bitfieldWidth*/ NULL,
    45                         new BasicType(emptyQualifiers, BasicType::UnsignedInt),
     52                        new BasicType( emptyQualifiers, BasicType::SignedInt ),
    4653                        /*init*/ NULL
    47                 );
     54                        );
    4855                ObjectDecl exception_obj(
    49                         "exception_t",
     56                        "__exception_inst",
    5057                        Type::StorageClasses(),
    5158                        LinkageSpec::Cforall,
    5259                        /*bitfieldWidth*/ NULL,
    53                         new BasicType(emptyQualifiers, BasicType::UnsignedInt),
     60                        new PointerType(
     61                                emptyQualifiers,
     62                                new BasicType( emptyQualifiers, BasicType::SignedInt )
     63                                ),
    5464                        /*init*/ NULL
    55                 );
     65                        );
    5666                ObjectDecl bool_obj(
    57                         "bool_t",
     67                        "__ret_bool",
    5868                        Type::StorageClasses(),
    5969                        LinkageSpec::Cforall,
     
    6171                        new BasicType(emptyQualifiers, BasicType::Bool),
    6272                        /*init*/ NULL
    63                 );
    64 
    65                 catch_func_t.get_parameters().push_back(index_obj.clone());
    66                 catch_func_t.get_parameters().push_back(exception_obj.clone());
    67                 match_func_t.get_returnVals().push_back(index_obj.clone());
    68                 match_func_t.get_parameters().push_back(exception_obj.clone());
    69                 handle_func_t.get_returnVals().push_back(bool_obj.clone());
    70                 handle_func_t.get_parameters().push_back(exception_obj.clone());
     73                        );
     74                ObjectDecl voidptr_obj(
     75                        "__hook",
     76                        Type::StorageClasses(),
     77                        LinkageSpec::Cforall,
     78                        NULL,
     79                        new PointerType(
     80                                emptyQualifiers,
     81                                new VoidType(
     82                                        emptyQualifiers
     83                                        ),
     84                                std::list<Attribute *>{new Attribute("unused")}
     85                                ),
     86                        NULL
     87                        );
     88
     89                catch_func_t.get_parameters().push_back( index_obj.clone() );
     90                catch_func_t.get_parameters().push_back( exception_obj.clone() );
     91                match_func_t.get_returnVals().push_back( index_obj.clone() );
     92                match_func_t.get_parameters().push_back( exception_obj.clone() );
     93                handle_func_t.get_returnVals().push_back( bool_obj.clone() );
     94                handle_func_t.get_parameters().push_back( exception_obj.clone() );
     95                finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
    7196
    7297                init_complete = true;
     
    78103
    79104        void split( CatchList& allHandlers, CatchList& terHandlers,
    80                     CatchList& resHandlers ) {
     105                                CatchList& resHandlers ) {
    81106                while ( !allHandlers.empty() ) {
    82                         Statement * stmt = allHandlers.front();
     107                        CatchStmt * stmt = allHandlers.front();
    83108                        allHandlers.pop_front();
    84                         if (CaseStmt::Terminate == stmt->get_kind()) {
     109                        if (CatchStmt::Terminate == stmt->get_kind()) {
    85110                                terHandlers.push_back(stmt);
    86111                        } else {
     
    92117        template<typename T>
    93118        void free_all( std::list<T *> &list ) {
    94                 std::list<T *>::iterator it;
     119                typename std::list<T *>::iterator it;
    95120                for ( it = list.begin() ; it != list.end() ; ++it ) {
    96121                        delete *it;
     
    100125
    101126        void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
    102                 block->push_back(new DeclStmt(no_labels, item));
    103         }
    104 
    105         Expression * nameOf( FunctionDecl * function ) {
    106                 return new VariableExpr( function );
     127                block->push_back(new DeclStmt(noLabels, item));
     128        }
     129
     130        Expression * nameOf( DeclarationWithType * decl ) {
     131                return new VariableExpr( decl );
    107132        }
    108133
    109134        // ThrowStmt Mutation Helpers
    110135
    111         Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
    112                 // __throw_terminate( EXPR );
    113                 ApplicationExpr * call = new ApplicationExpr( /* ... */ );
    114                 call->get_args.push_back( throwStmt->get_expr() );
    115                 Statement * result = new ExprStmt( throwStmt->get_labels(), call );
     136        Statement * create_given_throw(
     137                        const char * throwFunc, ThrowStmt * throwStmt ) {
     138                // { int NAME = EXPR; throwFunc( &NAME ); }
     139                CompoundStmt * result = new CompoundStmt( noLabels );
     140                ObjectDecl * local = new ObjectDecl(
     141                        "__local_exception_copy",
     142                        Type::StorageClasses(),
     143                        LinkageSpec::Cforall,
     144                        NULL,
     145                        new BasicType( emptyQualifiers, BasicType::SignedInt ),
     146                        new SingleInit( throwStmt->get_expr() )
     147                        );
     148                appendDeclStmt( result, local );
     149                UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
     150                call->get_args().push_back( new AddressExpr( nameOf( local ) ) );
     151                result->push_back( new ExprStmt( throwStmt->get_labels(), call ) );
    116152                throwStmt->set_expr( nullptr );
    117153                delete throwStmt;
    118154                return result;
    119155        }
     156
     157        Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
     158                // { int NAME = EXPR; __throw_terminate( &NAME ); }
     159                return create_given_throw( "__cfaehm__throw_termination", throwStmt );
     160        }
    120161        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
    121162                // __rethrow_terminate();
     163                assert( nullptr == throwStmt->get_expr() );
    122164                Statement * result = new ExprStmt(
    123165                        throwStmt->get_labels(),
    124                         new ApplicationExpr( /* ... */ );
     166                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) )
    125167                        );
    126168                delete throwStmt;
     
    129171        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    130172                // __throw_resume( EXPR );
    131                 ApplicationExpr * call = new ApplicationExpr( /* ... */ );
    132                 call->get_args.push_back( throwStmt->get_expr() );
    133                 Statement * result = new ExprStmt( throwStmt->get_labels(), call );
    134                 throwStmt->set_expr( nullptr );
    135                 delete throwStmt;
    136                 return result;
     173                return create_given_throw( "__cfaehm__throw_resumption", throwStmt );
    137174        }
    138175        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
     
    140177                Statement * result = new ReturnStmt(
    141178                        throwStmt->get_labels(),
    142                         new ConstantExpr(
    143                                 Constant(
    144                                         new BasicType(
    145                                                 Type::Qualifiers(),
    146                                                 BasicType::Bool
    147                                                 ),
    148                                         "0")
    149                                 )
     179                        new ConstantExpr( Constant::from_bool( false ) )
    150180                        );
    151181                delete throwStmt;
     
    160190                return block;
    161191        }
    162         FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) {
    163                 CompoundStmt * body = base_try->get_block();
    164                 base_try->set_block(nullptr);
    165 
    166                 return new FunctionDecl("try", Type::StorageClasses(),
    167                         LinkageSpec::Cforall, void_func_t, body);
     192        FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
     193
     194                return new FunctionDecl( "try", Type::StorageClasses(),
     195                        LinkageSpec::Cforall, try_func_t.clone(), body );
    168196        }
    169197
    170198        FunctionDecl * create_terminate_catch( CatchList &handlers ) {
    171199                std::list<CaseStmt *> handler_wrappers;
     200
     201                FunctionType *func_type = catch_func_t.clone();
     202                DeclarationWithType * index_obj = func_type->get_parameters().front();
     203        //      DeclarationWithType * except_obj = func_type->get_parameters().back();
    172204
    173205                // Index 1..{number of handlers}
     
    178210                        CatchStmt * handler = *it;
    179211
    180                         std::list<Statement *> core;
    181                         if ( /*the exception is named*/ ) {
    182                                 ObjectDecl * local_except = /* Dynamic case, same */;
    183                                 core->push_back( new DeclStmt( noLabel, local_except ) );
    184                         }
    185                         // Append the provided statement to the handler.
    186                         core->push_back( cur_handler->get_body() );
    187                         // Append return onto the inner block? case stmt list?
    188                         CaseStmt * wrapper = new CaseStmt(
     212                        // INTEGERconstant Version
     213                        // case `index`:
     214                        // {
     215                        //     `handler.body`
     216                        // }
     217                        // return;
     218                        std::list<Statement *> caseBody;
     219                        caseBody.push_back( handler->get_body() );
     220                        handler->set_body( nullptr );
     221                        caseBody.push_back( new ReturnStmt( noLabels, nullptr ) );
     222
     223                        handler_wrappers.push_back( new CaseStmt(
    189224                                noLabels,
    190225                                new ConstantExpr( Constant::from_int( index ) ),
    191                                 core
    192                                 );
    193                         handler_wrappers.push_back(wrapper);
     226                                caseBody
     227                                ) );
    194228                }
    195229                // TODO: Some sort of meaningful error on default perhaps?
     230
     231                std::list<Statement*> stmt_handlers;
     232                while ( !handler_wrappers.empty() ) {
     233                        stmt_handlers.push_back( handler_wrappers.front() );
     234                        handler_wrappers.pop_front();
     235                }
    196236
    197237                SwitchStmt * handler_lookup = new SwitchStmt(
    198238                        noLabels,
    199                         /*parameter 0: index*/,
    200                         handler_wrappers,
    201                         false
     239                        nameOf( index_obj ),
     240                        stmt_handlers
    202241                        );
    203242                CompoundStmt * body = new CompoundStmt( noLabels );
     
    205244
    206245                return new FunctionDecl("catch", Type::StorageClasses(),
    207                         LinkageSpec::Cforall, catch_func_t, body);
     246                        LinkageSpec::Cforall, func_type, body);
    208247        }
    209248
    210249        // Create a single check from a moddified handler.
    211         CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) {
    212                 CompoundStmt * block = new CompoundStmt( noLables );
    213 
    214                 appendDeclStmt( block, modded_handler->get_decl() );
    215 
    216                 // TODO: This is not the actual check.
    217                 LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) );
     250        // except_obj is referenced, modded_handler will be freed.
     251        CompoundStmt *create_single_matcher(
     252                        DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
     253                CompoundStmt * block = new CompoundStmt( noLabels );
     254
     255                // INTEGERconstant Version
     256                assert( nullptr == modded_handler->get_decl() );
     257                ConstantExpr * number =
     258                        dynamic_cast<ConstantExpr*>( modded_handler->get_cond() );
     259                assert( number );
     260                modded_handler->set_cond( nullptr );
     261
     262                Expression * cond;
     263                {
     264                        std::list<Expression *> args;
     265                        args.push_back( number );
     266
     267                        std::list<Expression *> rhs_args;
     268                        rhs_args.push_back( nameOf( except_obj ) );
     269                        Expression * rhs = new UntypedExpr(
     270                                new NameExpr( "*?" ), rhs_args );
     271                        args.push_back( rhs );
     272
     273                        cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args );
     274                }
    218275
    219276                if ( modded_handler->get_cond() ) {
    220                         cond = new LogicalExpr( cond, modded_handler->get_cond() )q
     277                        cond = new LogicalExpr( cond, modded_handler->get_cond() );
    221278                }
    222279                block->push_back( new IfStmt( noLabels,
    223                         cond, modded_handler->get_body() );
     280                        cond, modded_handler->get_body(), nullptr ) );
    224281
    225282                modded_handler->set_decl( nullptr );
     
    232289        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    233290                CompoundStmt * body = new CompoundStmt( noLabels );
     291
     292                FunctionType * func_type = match_func_t.clone();
     293                DeclarationWithType * except_obj = func_type->get_parameters().back();
    234294
    235295                // Index 1..{number of handlers}
     
    240300                        CatchStmt * handler = *it;
    241301
    242                         // body should have been taken by create_terminate_catch.
    243                         // assert( nullptr == handler->get_body() );
     302                        // Body should have been taken by create_terminate_catch.
     303                        assert( nullptr == handler->get_body() );
     304
     305                        // Create new body.
    244306                        handler->set_body( new ReturnStmt( noLabels,
    245307                                new ConstantExpr( Constant::from_int( index ) ) ) );
    246308
    247                         body->push_back( create_single_matcher( handler ) );
    248                 }
     309                        // Create the handler.
     310                        body->push_back( create_single_matcher( except_obj, handler ) );
     311                        *it = nullptr;
     312                }
     313
     314                body->push_back( new ReturnStmt( noLabels, new ConstantExpr(
     315                        Constant::from_int( 0 ) ) ) );
    249316
    250317                return new FunctionDecl("match", Type::StorageClasses(),
    251                         LinkageSpec::Cforall, match_func_t, body);
    252         }
    253 
    254         Statement * create_terminate_caller(
     318                        LinkageSpec::Cforall, func_type, body);
     319        }
     320
     321        CompoundStmt * create_terminate_caller(
    255322                        FunctionDecl * try_wrapper,
    256323                        FunctionDecl * terminate_catch,
    257324                        FunctionDecl * terminate_match) {
    258325
    259                 ApplicationExpr * caller = new ApplicationExpr( /* ... */ );
    260                 std::list<Expression *>& args = caller.get_args();
     326                UntypedExpr * caller = new UntypedExpr( new NameExpr(
     327                        "__cfaehm__try_terminate" ) );
     328                std::list<Expression *>& args = caller->get_args();
    261329                args.push_back( nameOf( try_wrapper ) );
    262330                args.push_back( nameOf( terminate_catch ) );
    263331                args.push_back( nameOf( terminate_match ) );
    264332
    265                 return new ExprStmt( noLabels, caller );
     333                CompoundStmt * callStmt = new CompoundStmt( noLabels );
     334                callStmt->push_back( new ExprStmt( noLabels, caller ) );
     335                return callStmt;
    266336        }
    267337
    268338        FunctionDecl * create_resume_handler( CatchList &handlers ) {
    269                 CompoundStmt * body = new CompountStmt( noLabels );
     339                CompoundStmt * body = new CompoundStmt( noLabels );
     340
     341                FunctionType * func_type = match_func_t.clone();
     342                DeclarationWithType * except_obj = func_type->get_parameters().back();
    270343
    271344                CatchList::iterator it;
     
    280353                                handling_code->push_back( handler->get_body() );
    281354                        }
    282                         handling_code->push_back( new ReturnStmt( noLabel,
     355                        handling_code->push_back( new ReturnStmt( noLabels,
    283356                                new ConstantExpr( Constant::from_bool( false ) ) ) );
    284357                        handler->set_body( handling_code );
    285358
    286359                        // Create the handler.
    287                         body->push_back( create_single_matcher( handler ) );
     360                        body->push_back( create_single_matcher( except_obj, handler ) );
     361                        *it = nullptr;
    288362                }
    289363
    290364                return new FunctionDecl("handle", Type::StorageClasses(),
    291                         LinkageSpec::Cforall, handle_func_t, body);
    292         }
    293 
    294         Statement * create_resume_wrapper(
     365                        LinkageSpec::Cforall, func_type, body);
     366        }
     367
     368        CompoundStmt * create_resume_wrapper(
     369                        StructDecl * node_decl,
    295370                        Statement * wraps,
    296371                        FunctionDecl * resume_handler ) {
    297372                CompoundStmt * body = new CompoundStmt( noLabels );
    298373
    299                 // struct node = {current top resume handler, call to resume_handler};
    300                 // __attribute__((cleanup( ... )));
    301                 // set top resume handler to node.
    302                 // The wrapped statement.
    303 
    304                 ListInit * node_init;
    305                 {
    306                         std::list<Initializer*> field_inits;
    307                         field_inits.push_back( new SingleInit( /* ... */ ) );
    308                         field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) );
    309                         node_init = new ListInit( field_inits );
    310                 }
     374                // struct __try_resume_node __resume_node
     375                //      __attribute__((cleanup( __cfaehm__try_resume_cleanup )));
     376                // ** unwinding of the stack here could cause problems **
     377                // ** however I don't think that can happen currently **
     378                // __cfaehm__try_resume_setup( &__resume_node, resume_handler );
    311379
    312380                std::list< Attribute * > attributes;
    313381                {
    314382                        std::list< Expression * > attr_params;
    315                         attr_params.push_back( nameOf( /* ... deconstructor ... */ ) );
    316                         attrributes.push_back( new Attribute( "cleanup", attr_params ) );
    317                 }
    318 
    319                 appendDeclStmt( body,
    320                 /**/ ObjectDecl(
    321                         "resume_node",
     383                        attr_params.push_back( new NameExpr(
     384                                "__cfaehm__try_resume_cleanup" ) );
     385                        attributes.push_back( new Attribute( "cleanup", attr_params ) );
     386                }
     387
     388                ObjectDecl * obj = new ObjectDecl(
     389                        "__resume_node",
    322390                        Type::StorageClasses(),
    323391                        LinkageSpec::Cforall,
    324392                        nullptr,
    325                         /* Type* = resume_node */,
    326                         node_init,
     393                        new StructInstType(
     394                                Type::Qualifiers(),
     395                                node_decl
     396                                ),
     397                        nullptr,
    327398                        attributes
    328                         )
    329                 );
     399                        );
     400                appendDeclStmt( body, obj );
     401
     402                UntypedExpr *setup = new UntypedExpr( new NameExpr(
     403                        "__cfaehm__try_resume_setup" ) );
     404                setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) );
     405                setup->get_args().push_back( nameOf( resume_handler ) );
     406
     407                body->push_back( new ExprStmt( noLabels, setup ) );
     408
    330409                body->push_back( wraps );
    331410                return body;
     
    333412
    334413        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    335                 CompoundStmt * body = tryStmt->get_finally();
     414                FinallyStmt * finally = tryStmt->get_finally();
     415                CompoundStmt * body = finally->get_block();
     416                finally->set_block( nullptr );
     417                delete finally;
    336418                tryStmt->set_finally( nullptr );
    337419
    338420                return new FunctionDecl("finally", Type::StorageClasses(),
    339                         LinkageSpec::Cforall, void_func_t, body);
    340         }
    341 
    342         ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) {
    343                 // struct _cleanup_hook NAME __attribute__((cleanup( ... )));
     421                        LinkageSpec::Cforall, finally_func_t.clone(), body);
     422        }
     423
     424        ObjectDecl * create_finally_hook(
     425                        StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
     426                // struct __cfaehm__cleanup_hook __finally_hook
     427                //      __attribute__((cleanup( finally_wrapper )));
    344428
    345429                // Make Cleanup Attribute.
     
    348432                        std::list< Expression * > attr_params;
    349433                        attr_params.push_back( nameOf( finally_wrapper ) );
    350                         attrributes.push_back( new Attribute( "cleanup", attr_params ) );
    351                 }
    352 
    353                 return ObjectDecl( /* ... */
    354                         const std::string &name "finally_hook",
     434                        attributes.push_back( new Attribute( "cleanup", attr_params ) );
     435                }
     436
     437                return new ObjectDecl(
     438                        "__finally_hook",
    355439                        Type::StorageClasses(),
    356440                        LinkageSpec::Cforall,
    357441                        nullptr,
    358                         /* ... Type * ... */,
     442                        new StructInstType(
     443                                emptyQualifiers,
     444                                hook_decl
     445                                ),
    359446                        nullptr,
    360447                        attributes
     
    363450
    364451
    365         class ExceptionMutatorCore : public WithScoping {
     452        class ExceptionMutatorCore : public WithGuards {
    366453                enum Context { NoHandler, TerHandler, ResHandler };
    367454
     
    370457                // loop, switch or the goto stays within the function.
    371458
    372                 Context curContext;
     459                Context cur_context;
    373460
    374461                // We might not need this, but a unique base for each try block's
     
    377464                //unsigned int try_count = 0;
    378465
     466                StructDecl *node_decl;
     467                StructDecl *hook_decl;
    379468
    380469        public:
    381470                ExceptionMutatorCore() :
    382                         curContext(NoHandler)
     471                        cur_context(NoHandler),
     472                        node_decl(nullptr), hook_decl(nullptr)
    383473                {}
    384474
    385                 void premutate( CatchStmt *tryStmt );
     475                void premutate( CatchStmt *catchStmt );
     476                void premutate( StructDecl *structDecl );
    386477                Statement * postmutate( ThrowStmt *throwStmt );
    387478                Statement * postmutate( TryStmt *tryStmt );
     
    393484                        if ( throwStmt->get_expr() ) {
    394485                                return create_terminate_throw( throwStmt );
    395                         } else if ( TerHandler == curContext ) {
     486                        } else if ( TerHandler == cur_context ) {
    396487                                return create_terminate_rethrow( throwStmt );
    397488                        } else {
    398489                                assertf(false, "Invalid throw in %s at %i\n",
    399                                         throwStmt->location.filename,
     490                                        throwStmt->location.filename.c_str(),
    400491                                        throwStmt->location.linenumber);
    401492                                return nullptr;
     
    404495                        if ( throwStmt->get_expr() ) {
    405496                                return create_resume_throw( throwStmt );
    406                         } else if ( ResHandler == curContext ) {
     497                        } else if ( ResHandler == cur_context ) {
    407498                                return create_resume_rethrow( throwStmt );
    408499                        } else {
    409500                                assertf(false, "Invalid throwResume in %s at %i\n",
    410                                         throwStmt->location.filename,
     501                                        throwStmt->location.filename.c_str(),
    411502                                        throwStmt->location.linenumber);
    412503                                return nullptr;
     
    416507
    417508        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
     509                assert( node_decl );
     510                assert( hook_decl );
     511
    418512                // Generate a prefix for the function names?
    419513
    420                 CompoundStmt * block = new CompoundStmt();
    421                 Statement * inner = take_try_block( tryStmt );
     514                CompoundStmt * block = new CompoundStmt( noLabels );
     515                CompoundStmt * inner = take_try_block( tryStmt );
    422516
    423517                if ( tryStmt->get_finally() ) {
     
    427521                        appendDeclStmt( block, finally_block );
    428522                        // Create and add the finally cleanup hook.
    429                         appendDeclStmt( block, create_finally_hook( finally_block ) );
    430                 }
    431 
    432                 StatementList termination_handlers;
    433                 StatementList resumption_handlers;
    434                 split( tryStmt->get_handlers(),
    435                        termination_handlers, resumption_handlers );
    436 
    437                 if ( resumeption_handlers.size() ) {
     523                        appendDeclStmt( block,
     524                                create_finally_hook( hook_decl, finally_block ) );
     525                }
     526
     527                CatchList termination_handlers;
     528                CatchList resumption_handlers;
     529                split( tryStmt->get_catchers(),
     530                           termination_handlers, resumption_handlers );
     531
     532                if ( resumption_handlers.size() ) {
    438533                        // Define the helper function.
    439534                        FunctionDecl * resume_handler =
     
    441536                        appendDeclStmt( block, resume_handler );
    442537                        // Prepare hooks
    443                         inner = create_resume_wrapper( inner, resume_handler );
     538                        inner = create_resume_wrapper( node_decl, inner, resume_handler );
    444539                }
    445540
     
    462557                block->push_back( inner );
    463558
    464                 free_all( termination_handlers );
    465                 free_all( resumption_handlers );
     559                //free_all( termination_handlers );
     560                //free_all( resumption_handlers );
    466561
    467562                return block;
     
    469564
    470565        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    471                 GuardValue( curContext );
    472                 if ( CatchStmt::Termination == catchStmt->get_kind() ) {
    473                         curContext = TerHandler;
     566                GuardValue( cur_context );
     567                if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
     568                        cur_context = TerHandler;
    474569                } else {
    475                         curContext = ResHandler;
    476                 }
    477         }
    478 
    479     void translateEHM( std::list< Declaration *> & translationUnit ) {
     570                        cur_context = ResHandler;
     571                }
     572        }
     573
     574        void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
     575                if ( !structDecl->has_body() ) {
     576                        // Skip children?
     577                        return;
     578                } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
     579                        assert( nullptr == node_decl );
     580                        node_decl = structDecl;
     581                } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
     582                        assert( nullptr == hook_decl );
     583                        hook_decl = structDecl;
     584                }
     585                // Later we might get the exception type as well.
     586        }
     587
     588        void translateEHM( std::list< Declaration *> & translationUnit ) {
     589                init_func_types();
     590
    480591                PassVisitor<ExceptionMutatorCore> translator;
    481592                for ( Declaration * decl : translationUnit ) {
    482                         decl->mutate( translator );
     593                        decl->acceptMutator( translator );
    483594                }
    484595        }
  • src/ControlStruct/ExceptTranslate.h

    r11dbfe1 r67fa9f9  
    1010// Created On       : Tus Jun 06 10:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jun 22 15:57:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Fri Jun 30 10:20:00 2017
     13// Update Count     : 2
    1414//
    1515
     
    1717#define EXCEPT_TRANSLATE_H
    1818
    19 namespace ControlFlow {
     19#include <list>
     20#include "SynTree/SynTree.h"
     21
     22namespace ControlStruct {
    2023        void translateEHM( std::list< Declaration *> & translationUnit );
    2124        /* Converts exception handling structures into their underlying C code.
  • src/ControlStruct/module.mk

    r11dbfe1 r67fa9f9  
    1010## Author           : Richard C. Bilson
    1111## Created On       : Mon Jun  1 17:49:17 2015
    12 ## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Thu Aug  4 11:38:06 2016
    14 ## Update Count     : 3
     12## Last Modified By : Andrew Beach
     13## Last Modified On : Wed Jun 28 16:15:00 2017
     14## Update Count     : 4
    1515###############################################################################
    1616
    1717SRC +=  ControlStruct/LabelGenerator.cc \
    1818        ControlStruct/LabelFixer.cc \
    19         ControlStruct/MLEMutator.cc \
     19        ControlStruct/MLEMutator.cc \
    2020        ControlStruct/Mutate.cc \
    21         ControlStruct/ForExprMutator.cc
    22 
     21        ControlStruct/ForExprMutator.cc \
     22        ControlStruct/ExceptTranslate.cc
  • src/GenPoly/Box.cc

    r11dbfe1 r67fa9f9  
    504504                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    505505                        if ( functionDecl->get_statements() ) {         // empty routine body ?
     506                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506507                                doBeginScope();
    507508                                scopeTyVars.beginScope();
     
    548549                                retval = oldRetval;
    549550                                doEndScope();
     551                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    550552                        } // if
    551553                        return functionDecl;
     
    11161118
    11171119                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    1118                         // std::cerr << "mutate appExpr: ";
     1120                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11191121                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    11201122                        //      std::cerr << i->first << " ";
     
    11411143                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
    11421144
     1145                        // std::cerr << function << std::endl;
     1146                        // std::cerr << "scopeTyVars: ";
     1147                        // printTyVarMap( std::cerr, scopeTyVars );
     1148                        // std::cerr << "exprTyVars: ";
     1149                        // printTyVarMap( std::cerr, exprTyVars );
     1150                        // std::cerr << "env: " << *env << std::endl;
     1151                        // std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl;
     1152
    11431153                        // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr
    11441154                        // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int))
    11451155                        // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome.
    11461156                        if ( dynRetType ) {
     1157                                // std::cerr << "dynRetType: " << dynRetType << std::endl;
    11471158                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    11481159                                ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
  • src/GenPoly/InstantiateGeneric.cc

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

    r11dbfe1 r67fa9f9  
    104104                        typedef AddStmtVisitor Parent;
    105105                        using Parent::visit;
    106                         typedef std::set< ObjectDecl * > ObjectSet;
     106                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
     107                        typedef std::list< ObjectDecl * > ObjectSet;
    107108                        virtual void visit( CompoundStmt *compoundStmt ) override;
    108109                        virtual void visit( DeclStmt *stmt ) override;
     
    116117
    117118                // debug
    118                 struct printSet {
    119                         typedef ObjDeclCollector::ObjectSet ObjectSet;
    120                         printSet( const ObjectSet & objs ) : objs( objs ) {}
     119                template<typename ObjectSet>
     120                struct PrintSet {
     121                        PrintSet( const ObjectSet & objs ) : objs( objs ) {}
    121122                        const ObjectSet & objs;
    122123                };
    123                 std::ostream & operator<<( std::ostream & out, const printSet & set) {
     124                template<typename ObjectSet>
     125                PrintSet<ObjectSet> printSet( const ObjectSet & objs ) { return PrintSet<ObjectSet>( objs ); }
     126                template<typename ObjectSet>
     127                std::ostream & operator<<( std::ostream & out, const PrintSet<ObjectSet> & set) {
    124128                        out << "{ ";
    125129                        for ( ObjectDecl * obj : set.objs ) {
     
    724728                                                // static bool __objName_uninitialized = true
    725729                                                BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    726                                                 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ), noDesignators );
     730                                                SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) );
    727731                                                ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr );
    728732                                                isUninitializedVar->fixUniqueId();
     
    745749
    746750                                                Statement * dtor = ctorInit->get_dtor();
    747                                                 objDecl->set_init( NULL );
    748                                                 ctorInit->set_ctor( NULL );
     751                                                objDecl->set_init( nullptr );
     752                                                ctorInit->set_ctor( nullptr );
    749753                                                ctorInit->set_dtor( nullptr );
    750754                                                if ( dtor ) {
     
    799803                                                } else {
    800804                                                        stmtsToAddAfter.push_back( ctor );
    801                                                         objDecl->set_init( NULL );
    802                                                         ctorInit->set_ctor( NULL );
     805                                                        objDecl->set_init( nullptr );
     806                                                        ctorInit->set_ctor( nullptr );
    803807                                                }
    804808                                        } // if
    805809                                } else if ( Initializer * init = ctorInit->get_init() ) {
    806810                                        objDecl->set_init( init );
    807                                         ctorInit->set_init( NULL );
     811                                        ctorInit->set_init( nullptr );
    808812                                } else {
    809813                                        // no constructor and no initializer, which is okay
    810                                         objDecl->set_init( NULL );
     814                                        objDecl->set_init( nullptr );
    811815                                } // if
    812816                                delete ctorInit;
     
    816820
    817821                void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {
    818                         std::set< ObjectDecl * > prevVars = curVars;
     822                        ObjectSet prevVars = curVars;
    819823                        Parent::visit( compoundStmt );
    820824                        curVars = prevVars;
     
    824828                        // keep track of all variables currently in scope
    825829                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    826                                 curVars.insert( objDecl );
     830                                curVars.push_back( objDecl );
    827831                        } // if
    828832                        Parent::visit( stmt );
     
    939943                        )
    940944                        if ( ! diff.empty() ) {
     945                                // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.
     946                                std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );
     947
    941948                                // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor
    942949                                OrderedDecls ordered;
    943950                                for ( OrderedDecls & rdo : reverseDeclOrder ) {
    944951                                        // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
    945                                         copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return diff.count( objDecl ); } );
     952                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    946953                                } // for
    947954                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
  • src/InitTweak/GenInit.cc

    r11dbfe1 r67fa9f9  
    4444        }
    4545
    46         class ReturnFixer : public WithStmtsToAdd, public WithScopes {
    47           public:
     46        struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
    4847                /// consistently allocates a temporary variable for the return value
    4948                /// of a function so that anything which the resolver decides can be constructed
     
    5958        };
    6059
    61         class CtorDtor final : public GenPoly::PolyMutator {
    62           public:
    63                 typedef GenPoly::PolyMutator Parent;
    64                 using Parent::mutate;
     60        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6561                /// create constructor and destructor statements for object declarations.
    6662                /// the actual call statements will be added in after the resolver has run
     
    6965                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
    7066
    71                 virtual DeclarationWithType * mutate( ObjectDecl * ) override;
    72                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     67                void previsit( ObjectDecl * );
     68                void previsit( FunctionDecl *functionDecl );
     69
    7370                // should not traverse into any of these declarations to find objects
    7471                // that need to be constructed or destructed
    75                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
    76                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    77                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    78                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    79                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    80                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    81 
    82                 virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
    83 
    84                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
     72                void previsit( StructDecl *aggregateDecl );
     73                void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
     74                void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
     75                void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
     76                void previsit( TypeDecl *typeDecl ) { visit_children = false; }
     77                void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
     78
     79                void previsit( FunctionType *funcType ) { visit_children = false; }
     80
     81                void previsit( CompoundStmt * compoundStmt );
    8582
    8683          private:
     
    211208
    212209        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    213                 CtorDtor ctordtor;
    214                 mutateAll( translationUnit, ctordtor );
     210                PassVisitor<CtorDtor> ctordtor;
     211                acceptAll( translationUnit, ctordtor );
    215212        }
    216213
     
    289286        }
    290287
    291         DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     288        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    292289                handleDWT( objDecl );
    293290                // hands off if @=, extern, builtin, etc.
     
    301298                        objDecl->set_init( genCtorInit( objDecl ) );
    302299                }
    303                 return Parent::mutate( objDecl );
    304         }
    305 
    306         DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    307                 ValueGuard< bool > oldInFunc = inFunction;
     300        }
     301
     302        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     303                GuardValue( inFunction );
    308304                inFunction = true;
    309305
    310306                handleDWT( functionDecl );
    311307
    312                 managedTypes.beginScope();
     308                GuardScope( managedTypes );
    313309                // go through assertions and recursively add seen ctor/dtors
    314310                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
     
    317313                        }
    318314                }
    319                 // parameters should not be constructed and destructed, so don't mutate FunctionType
    320                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    321 
    322                 managedTypes.endScope();
    323                 return functionDecl;
    324         }
    325 
    326         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
     315
     316                PassVisitor<CtorDtor> newCtorDtor;
     317                newCtorDtor.pass = *this;
     318                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     319                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     320        }
     321
     322        void CtorDtor::previsit( StructDecl *aggregateDecl ) {
     323                visit_children = false; // do not try to construct and destruct aggregate members
     324
    327325                // don't construct members, but need to take note if there is a managed member,
    328326                // because that means that this type is also managed
     
    336334                        }
    337335                }
    338                 return aggregateDecl;
    339         }
    340 
    341         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    342                 managedTypes.beginScope();
    343                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    344                 managedTypes.endScope();
    345                 return stmt;
    346         }
    347 
     336        }
     337
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     339                GuardScope( managedTypes );
     340        }
    348341} // namespace InitTweak
    349342
  • src/InitTweak/InitTweak.cc

    r11dbfe1 r67fa9f9  
    1414                public:
    1515                        bool hasDesignations = false;
    16                         template<typename Init>
    17                         void handleInit( Init * init ) {
    18                                 if ( ! init->get_designators().empty() ) hasDesignations = true;
    19                                 else Visitor::visit( init );
    20                         }
    21                         virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
    22                         virtual void visit( ListInit * listInit ) { handleInit( listInit); }
     16                        virtual void visit( Designation * des ) {
     17                                if ( ! des->get_designators().empty() ) hasDesignations = true;
     18                                else Visitor::visit( des );
     19                        }
    2320                };
    2421
  • src/MakeLibCfa.cc

    r11dbfe1 r67fa9f9  
    9292                assert( ! objDecl->get_init() );
    9393                std::list< Expression* > noDesignators;
    94                 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
     94                objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed
    9595                newDecls.push_back( objDecl );
    9696        }
  • src/Makefile.in

    r11dbfe1 r67fa9f9  
    119119        ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
    120120        ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
     121        ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) \
    121122        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    122123        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
     
    161162        ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
    162163        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
     164        ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
    163165        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    164166        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    394396        ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
    395397        ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
    396         ControlStruct/ForExprMutator.cc GenPoly/Box.cc \
     398        ControlStruct/ForExprMutator.cc \
     399        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    397400        GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
    398401        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
     
    414417        ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \
    415418        ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \
    416         ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \
    417         SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    418         SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    419         SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
    420         SynTree/BasicType.cc SynTree/PointerType.cc \
    421         SynTree/ArrayType.cc SynTree/FunctionType.cc \
    422         SynTree/ReferenceToType.cc SynTree/TupleType.cc \
    423         SynTree/TypeofType.cc SynTree/AttrType.cc \
     419        ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \
     420        SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
     421        SymTab/FixFunction.cc SymTab/ImplementationType.cc \
     422        SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
     423        SynTree/VoidType.cc SynTree/BasicType.cc \
     424        SynTree/PointerType.cc SynTree/ArrayType.cc \
     425        SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
     426        SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
    424427        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    425428        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    592595        ControlStruct/$(DEPDIR)/$(am__dirstamp)
    593596ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT):  \
     597        ControlStruct/$(am__dirstamp) \
     598        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     599ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT):  \
    594600        ControlStruct/$(am__dirstamp) \
    595601        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     
    721727        ResolvExpr/$(am__dirstamp) \
    722728        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     729ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT):  \
     730        ResolvExpr/$(am__dirstamp) \
     731        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    723732SymTab/$(am__dirstamp):
    724733        @$(MKDIR_P) SymTab
     
    853862        -rm -f Common/driver_cfa_cpp-UniqueName.$(OBJEXT)
    854863        -rm -f Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT)
     864        -rm -f ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT)
    855865        -rm -f ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT)
    856866        -rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT)
     
    890900        -rm -f ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT)
    891901        -rm -f ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT)
     902        -rm -f ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT)
    892903        -rm -f ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT)
    893904        -rm -f ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT)
     
    965976@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@
    966977@AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po@am__quote@
     978@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po@am__quote@
    967979@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@
    968980@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
     
    10021014@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@
    10031015@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
     1016@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
    10041017@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    10051018@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
     
    13551368@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
    13561369
     1370ControlStruct/driver_cfa_cpp-ExceptTranslate.o: ControlStruct/ExceptTranslate.cc
     1371@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
     1372@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
     1373@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.o' libtool=no @AMDEPBACKSLASH@
     1374@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1375@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
     1376
     1377ControlStruct/driver_cfa_cpp-ExceptTranslate.obj: ControlStruct/ExceptTranslate.cc
     1378@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
     1379@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
     1380@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.obj' libtool=no @AMDEPBACKSLASH@
     1381@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1382@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
     1383
    13571384GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc
    13581385@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
     
    19421969@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    19431970@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
     1971
     1972ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc
     1973@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
     1974@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
     1975@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.o' libtool=no @AMDEPBACKSLASH@
     1976@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1977@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
     1978
     1979ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc
     1980@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
     1981@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
     1982@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.obj' libtool=no @AMDEPBACKSLASH@
     1983@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1984@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
    19441985
    19451986SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
  • src/Parser/InitializerNode.cc

    r11dbfe1 r67fa9f9  
    7474
    7575        InitializerNode *moreInit;
    76         if  ( get_next() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) != 0) )
     76        if ( (moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) ) {
    7777                moreInit->printOneLine( os );
     78        }
    7879}
    7980
    8081Initializer *InitializerNode::build() const {
    8182        if ( aggregate ) {
     83                // steal designators from children
     84                std::list< Designation * > designlist;
     85                InitializerNode * child = next_init();
     86                for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
     87                        std::list< Expression * > desList;
     88                        buildList< Expression, ExpressionNode >( child->designator, desList );
     89                        designlist.push_back( new Designation( desList ) );
     90                } // for
    8291                std::list< Initializer * > initlist;
    8392                buildList< Initializer, InitializerNode >( next_init(), initlist );
    84 
    85                 std::list< Expression * > designlist;
    86 
    87                 if ( designator != 0 ) {
    88                         buildList< Expression, ExpressionNode >( designator, designlist );
    89                 } // if
    90 
    9193                return new ListInit( initlist, designlist, maybeConstructed );
    9294        } else {
    93                 std::list< Expression * > designators;
    94 
    95                 if ( designator != 0 )
    96                         buildList< Expression, ExpressionNode >( designator, designators );
    97 
    98                 if ( get_expression() != 0)
    99                         return new SingleInit( maybeBuild< Expression >( get_expression() ), designators, maybeConstructed );
     95                if ( get_expression() != 0) {
     96                        return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed );
     97                }
    10098        } // if
    101 
    10299        return 0;
    103100}
  • src/Parser/TypeData.cc

    r11dbfe1 r67fa9f9  
    760760                if ( cur->has_enumeratorValue() ) {
    761761                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
    762                         member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), list< Expression * >() ) );
     762                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
    763763                } // if
    764764        } // for
     
    777777TupleType * buildTuple( const TypeData * td ) {
    778778        assert( td->kind == TypeData::Tuple );
    779         TupleType * ret = new TupleType( buildQualifiers( td ) );
    780         buildTypeList( td->tuple, ret->get_types() );
     779        std::list< Type * > types;
     780        buildTypeList( td->tuple, types );
     781        TupleType * ret = new TupleType( buildQualifiers( td ), types );
    781782        buildForall( td->forall, ret->get_forall() );
    782783        return ret;
  • src/Parser/parser.yy

    r11dbfe1 r67fa9f9  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 28 22:11:22 2017
    13 // Update Count     : 2414
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jun 30 15:38:00 2017
     13// Update Count     : 2415
    1414//
    1515
     
    104104        std::string * str;
    105105        bool flag;
     106        CatchStmt::Kind catch_kind;
    106107}
    107108
     
    192193%type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
    193194%type<sn> /* handler_list */                    handler_clause                          finally_clause
     195%type<catch_kind> handler_key
    194196
    195197// declarations
     
    958960handler_clause:
    959961        // TEMPORARY, TEST EXCEPTIONS
    960         CATCH '(' push push INTEGERconstant pop ')' compound_statement pop
    961                 { $$ = new StatementNode( build_catch( CatchStmt::Terminate, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); }
    962         | handler_clause CATCH '(' push push INTEGERconstant pop ')' compound_statement pop
    963                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); }
    964 
    965         | CATCH '(' push push exception_declaration pop ')' compound_statement pop
    966                 { $$ = new StatementNode( build_catch( CatchStmt::Terminate, $5, nullptr, $8 ) ); }
    967         | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
    968                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, $6, nullptr, $9 ) ) ); }
    969         | CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop
    970                 { $$ = new StatementNode( build_catch( CatchStmt::Resume, $5, nullptr, $8 ) ); }
    971         | handler_clause CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop
    972                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Resume, $6, nullptr, $9 ) ) ); }
     962        handler_key '(' push push INTEGERconstant pop ')' compound_statement pop
     963                { $$ = new StatementNode( build_catch( $1, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); }
     964        | handler_clause handler_key '(' push push INTEGERconstant pop ')' compound_statement pop
     965                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); }
     966
     967        | handler_key '(' push push exception_declaration pop ')' compound_statement pop
     968                { $$ = new StatementNode( build_catch( $1, $5, nullptr, $8 ) ); }
     969        | handler_clause handler_key '(' push push exception_declaration pop ')' compound_statement pop
     970                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, nullptr, $9 ) ) ); }
     971        ;
     972
     973handler_key:
     974        CATCH
     975                { $$ = CatchStmt::Terminate; }
     976        | CATCHRESUME
     977                { $$ = CatchStmt::Resume; }
    973978        ;
    974979
  • src/ResolvExpr/AlternativeFinder.cc

    r11dbfe1 r67fa9f9  
    604604//          )
    605605                SymTab::Indexer decls( indexer );
    606                 PRINT(
    607                         std::cerr << "============= original indexer" << std::endl;
    608                         indexer.print( std::cerr );
    609                         std::cerr << "============= new indexer" << std::endl;
    610                         decls.print( std::cerr );
    611                 )
     606                // PRINT(
     607                //      std::cerr << "============= original indexer" << std::endl;
     608                //      indexer.print( std::cerr );
     609                //      std::cerr << "============= new indexer" << std::endl;
     610                //      decls.print( std::cerr );
     611                // )
    612612                addToIndexer( have, decls );
    613613                AssertionSet newNeed;
     
    809809        }
    810810
     811        Expression * restructureCast( Expression * argExpr, Type * toType ) {
     812                if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
     813                        // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
     814                        // to its corresponding target type, producing the tuple of those cast expressions. If there are
     815                        // more components of the tuple than components in the target type, then excess components do not
     816                        // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
     817                        if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
     818                                // expressions which may contain side effects require a single unique instance of the expression.
     819                                argExpr = new UniqueExpr( argExpr );
     820                        }
     821                        std::list< Expression * > componentExprs;
     822                        for ( unsigned int i = 0; i < toType->size(); i++ ) {
     823                                // cast each component
     824                                TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
     825                                componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) );
     826                        }
     827                        delete argExpr;
     828                        assert( componentExprs.size() > 0 );
     829                        // produce the tuple of casts
     830                        return new TupleExpr( componentExprs );
     831                } else {
     832                        // handle normally
     833                        return new CastExpr( argExpr, toType->clone() );
     834                }
     835        }
     836
    811837        void AlternativeFinder::visit( CastExpr *castExpr ) {
    812838                Type *& toType = castExpr->get_result();
     
    840866                                thisCost += Cost( 0, 0, discardedValues );
    841867
    842                                 Expression * argExpr = i->expr->clone();
    843                                 if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) {
    844                                         // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
    845                                         // to its corresponding target type, producing the tuple of those cast expressions. If there are
    846                                         // more components of the tuple than components in the target type, then excess components do not
    847                                         // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
    848                                         if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
    849                                                 // expressions which may contain side effects require a single unique instance of the expression.
    850                                                 argExpr = new UniqueExpr( argExpr );
    851                                         }
    852                                         std::list< Expression * > componentExprs;
    853                                         for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) {
    854                                                 // cast each component
    855                                                 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
    856                                                 componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) );
    857                                         }
    858                                         delete argExpr;
    859                                         assert( componentExprs.size() > 0 );
    860                                         // produce the tuple of casts
    861                                         candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) );
    862                                 } else {
    863                                         // handle normally
    864                                         candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) );
    865                                 }
     868                                candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
    866869                        } // if
    867870                } // for
     
    11821185        }
    11831186
     1187        void AlternativeFinder::visit( UntypedInitExpr *initExpr ) {
     1188                // handle each option like a cast
     1189                AltList candidates;
     1190                PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; )
     1191                // O(N^2) checks of d-types with e-types
     1192                for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
     1193                        Type * toType = resolveTypeof( initAlt.type, indexer );
     1194                        SymTab::validateType( toType, &indexer );
     1195                        adjustExprType( toType, env, indexer );
     1196                        // Ideally the call to findWithAdjustment could be moved out of the loop, but unfortunately it currently has to occur inside or else
     1197                        // polymorphic return types are not properly bound to the initialization type, since return type variables are only open for the duration of resolving
     1198                        // the UntypedExpr. This is only actually an issue in initialization contexts that allow more than one possible initialization type, but it is still suboptimal.
     1199                        AlternativeFinder finder( indexer, env );
     1200                        finder.targetType = toType;
     1201                        finder.findWithAdjustment( initExpr->get_expr() );
     1202                        for ( Alternative & alt : finder.get_alternatives() ) {
     1203                                TypeEnvironment newEnv( alt.env );
     1204                                AssertionSet needAssertions, haveAssertions;
     1205                                OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
     1206                                PRINT( std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl; )
     1207                                // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
     1208                                // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
     1209                                // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
     1210                                // to.
     1211                                int discardedValues = alt.expr->get_result()->size() - toType->size();
     1212                                if ( discardedValues < 0 ) continue;
     1213                                // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
     1214                                // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
     1215                                // unification run for side-effects
     1216                                unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
     1217
     1218                                Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv );
     1219                                if ( thisCost != Cost::infinity ) {
     1220                                        // count one safe conversion for each value that is thrown away
     1221                                        thisCost += Cost( 0, 0, discardedValues );
     1222                                        candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
     1223                                }
     1224                        }
     1225                }
     1226
     1227                // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
     1228                // cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
     1229                // selects first based on argument cost, then on conversion cost.
     1230                AltList minArgCost;
     1231                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
     1232                findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
     1233        }
    11841234} // namespace ResolvExpr
    11851235
  • src/ResolvExpr/AlternativeFinder.h

    r11dbfe1 r67fa9f9  
    7373                virtual void visit( UniqueExpr *unqExpr );
    7474                virtual void visit( StmtExpr *stmtExpr );
     75                virtual void visit( UntypedInitExpr *initExpr );
    7576                /// Runs a new alternative finder on each element in [begin, end)
    7677                /// and writes each alternative finder to out.
  • src/ResolvExpr/Resolver.cc

    r11dbfe1 r67fa9f9  
    1414//
    1515
     16#include <iostream>
     17
     18#include "Alternative.h"
     19#include "AlternativeFinder.h"
     20#include "CurrentObject.h"
     21#include "RenameVars.h"
    1622#include "Resolver.h"
    17 #include "AlternativeFinder.h"
    18 #include "Alternative.h"
    19 #include "RenameVars.h"
    2023#include "ResolveTypeof.h"
    2124#include "typeops.h"
     25
     26#include "SynTree/Expression.h"
     27#include "SynTree/Initializer.h"
    2228#include "SynTree/Statement.h"
    2329#include "SynTree/Type.h"
    24 #include "SynTree/Expression.h"
    25 #include "SynTree/Initializer.h"
     30
     31#include "SymTab/Autogen.h"
    2632#include "SymTab/Indexer.h"
    27 #include "SymTab/Autogen.h"
     33
    2834#include "Common/utility.h"
     35
    2936#include "InitTweak/InitTweak.h"
    3037
    31 #include <iostream>
    3238using namespace std;
    3339
     
    3945                        if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
    4046                                functionReturn = res->functionReturn;
    41                                 initContext = res->initContext;
     47                                currentObject = res->currentObject;
    4248                                inEnumDecl = res->inEnumDecl;
    4349                        }
     
    6470                virtual void visit( BranchStmt *branchStmt ) override;
    6571                virtual void visit( ReturnStmt *returnStmt ) override;
     72                virtual void visit( ThrowStmt *throwStmt ) override;
    6673
    6774                virtual void visit( SingleInit *singleInit ) override;
     
    7986
    8087                Type * functionReturn = nullptr;
    81                 Type *initContext = nullptr;
     88                CurrentObject currentObject = nullptr;
    8289                bool inEnumDecl = false;
    8390        };
     
    186193                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    187194                // the RHS.
    188                 Type *temp = initContext;
    189                 initContext = new_type;
    190                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     195                ValueGuard<CurrentObject> temp( currentObject );
     196                currentObject = CurrentObject( objectDecl->get_type() );
     197                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    191198                        // enumerator initializers should not use the enum type to initialize, since
    192199                        // the enum type is still incomplete at this point. Use signed int instead.
    193                         initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     200                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    194201                }
    195202                Parent::visit( objectDecl );
    196                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     203                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    197204                        // delete newly created signed int type
    198                         delete initContext;
    199                 }
    200                 initContext = temp;
     205                        // delete currentObject.getType();
     206                }
    201207        }
    202208
     
    315321
    316322        void Resolver::visit( SwitchStmt *switchStmt ) {
    317                 ValueGuard< Type * > oldInitContext( initContext );
     323                ValueGuard< CurrentObject > oldCurrentObject( currentObject );
    318324                Expression *newExpr;
    319325                newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
     
    321327                switchStmt->set_condition( newExpr );
    322328
    323                 initContext = newExpr->get_result();
     329                currentObject = CurrentObject( newExpr->get_result() );
    324330                Parent::visit( switchStmt );
    325331        }
     
    327333        void Resolver::visit( CaseStmt *caseStmt ) {
    328334                if ( caseStmt->get_condition() ) {
    329                         assert( initContext );
    330                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() );
     335                        std::list< InitAlternative > initAlts = currentObject.getOptions();
     336                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     337                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    331338                        Expression * newExpr = findSingleExpression( castExpr, *this );
    332339                        castExpr = safe_dynamic_cast< CastExpr * >( newExpr );
     
    360367        }
    361368
     369        void Resolver::visit( ThrowStmt *throwStmt ) {
     370                if ( throwStmt->get_expr() ) {
     371                        Expression * wrapped = new CastExpr( throwStmt->get_expr(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     372                        Expression * newExpr = findSingleExpression( wrapped, *this );
     373                        throwStmt->set_expr( newExpr );
     374                }
     375        }
     376
    362377        template< typename T >
    363378        bool isCharType( T t ) {
     
    370385
    371386        void Resolver::visit( SingleInit *singleInit ) {
    372                 if ( singleInit->get_value() ) {
    373                         // // find all the d's
    374                         // std::list<Expression *> &designators = singleInit->get_designators();
    375                         // std::list<Type *> types1{ initContext }, types2;
    376                         // for ( Expression * expr: designators ) {
    377                         //      cerr << expr << endl;
    378                         //      if ( NameExpr * nexpr = dynamic_cast<NameExpr *>( expr ) ) {
    379                         //              for ( Type * type: types1 ) {
    380                         //                      cerr << type << endl;
    381                         //                      ReferenceToType * fred = dynamic_cast<ReferenceToType *>(type);
    382                         //                      std::list<Declaration *> members;
    383                         //                      if ( fred ) {
    384                         //                              fred->lookup( nexpr->get_name(), members ); // concatenate identical field name
    385                         //                              for ( Declaration * mem: members ) {
    386                         //                                      if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>(mem) ) {
    387                         //                                              types2.push_back( dwt->get_type() );
    388                         //                                      } // if
    389                         //                              } // for
    390                         //                      } // if
    391                         //              } // for
    392                         //              types1 = types2;
    393                         //              types2.clear();
    394                         //      } // if
    395                         // } // for
    396                         // // for ( Type * type: types1 ) {
    397                         // //   cerr << type << endl;
    398                         // // } // for
    399 
    400                         // // O(N^2) checks of d-types with f-types
    401                         // // find the minimum cost
    402                         CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
    403                         Expression *newExpr = findSingleExpression( castExpr, *this );
    404                         delete castExpr;
    405                         singleInit->set_value( newExpr );
    406 
    407                         // check if initializing type is char[]
    408                         if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
    409                                 if ( isCharType( at->get_base() ) ) {
    410                                         // check if the resolved type is char *
    411                                         if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    412                                                 if ( isCharType( pt->get_base() ) ) {
    413                                                         // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    414                                                         CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
    415                                                         singleInit->set_value( ce->get_arg() );
    416                                                         ce->set_arg( NULL );
    417                                                         delete ce;
    418                                                 }
     387                // resolve initialization using the possibilities as determined by the currentObject cursor
     388                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
     389                Expression * newExpr = findSingleExpression( untyped, *this );
     390                InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
     391
     392                // move cursor to the object that is actually initialized
     393                currentObject.setNext( initExpr->get_designation() );
     394
     395                // discard InitExpr wrapper and retain relevant pieces
     396                newExpr = initExpr->get_expr();
     397                newExpr->set_env( initExpr->get_env() );
     398                initExpr->set_expr( nullptr );
     399                initExpr->set_env( nullptr );
     400                delete initExpr;
     401
     402                // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
     403                Type * initContext = currentObject.getCurrentType();
     404
     405                // check if actual object's type is char[]
     406                if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     407                        if ( isCharType( at->get_base() ) ) {
     408                                // check if the resolved type is char *
     409                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
     410                                        if ( isCharType( pt->get_base() ) ) {
     411                                                // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     412                                                CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr );
     413                                                newExpr = ce->get_arg();
     414                                                ce->set_arg( nullptr );
     415                                                delete ce;
    419416                                        }
    420417                                }
    421418                        }
    422                 } // if
    423         }
    424 
    425         template< typename AggrInst >
    426         TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) {
    427                 assert( inst );
    428                 assert( inst->get_baseParameters() );
    429                 std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
    430                 std::list< Expression * > typeSubs = inst->get_parameters();
    431                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    432                 return subs;
    433         }
    434 
    435         ReferenceToType * isStructOrUnion( Type * type ) {
    436                 if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
    437                         return sit;
    438                 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
    439                         return uit;
    440                 }
    441                 return nullptr;
    442         }
    443 
    444         void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
    445                 DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl );
    446                 assert( dt );
    447                 // need to substitute for generic types, so that casts are to concrete types
    448                 initContext = dt->get_type()->clone();
    449                 sub.apply( initContext );
    450 
    451                 try {
    452                         if ( init == initEnd ) return; // stop when there are no more initializers
    453                         (*init)->accept( *this );
    454                         ++init; // made it past an initializer
    455                 } catch( SemanticError & ) {
    456                         // need to delve deeper, if you can
    457                         if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
    458                                 resolveAggrInit( type, init, initEnd );
    459                         } else {
    460                                 // member is not an aggregate type, so can't go any deeper
    461 
    462                                 // might need to rethink what is being thrown
    463                                 throw;
    464                         } // if
    465                 }
    466         }
    467 
    468         void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
    469                 if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
    470                         TypeSubstitution sub = makeGenericSubstitutuion( sit );
    471                         StructDecl * st = sit->get_baseStruct();
    472                         if(st->get_members().empty()) return;
    473                         // want to resolve each initializer to the members of the struct,
    474                         // but if there are more initializers than members we should stop
    475                         list< Declaration * >::iterator it = st->get_members().begin();
    476                         for ( ; it != st->get_members().end(); ++it) {
    477                                 resolveSingleAggrInit( *it, init, initEnd, sub );
    478                         }
    479                 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
    480                         TypeSubstitution sub = makeGenericSubstitutuion( uit );
    481                         UnionDecl * un = uit->get_baseUnion();
    482                         if(un->get_members().empty()) return;
    483                         // only resolve to the first member of a union
    484                         resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
    485                 } // if
     419                }
     420
     421                // set initializer expr to resolved express
     422                singleInit->set_value( newExpr );
     423
     424                // move cursor to next object in preparation for next initializer
     425                currentObject.increment();
    486426        }
    487427
    488428        void Resolver::visit( ListInit * listInit ) {
    489                 InitIterator iter = listInit->begin();
    490                 InitIterator end = listInit->end();
    491 
    492                 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
    493                         // resolve each member to the base type of the array
    494                         for ( ; iter != end; ++iter ) {
    495                                 initContext = at->get_base();
    496                                 (*iter)->accept( *this );
    497                         } // for
    498                 } else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) {
    499                         for ( Type * t : *tt ) {
    500                                 if ( iter == end ) break;
    501                                 initContext = t;
    502                                 (*iter++)->accept( *this );
    503                         }
    504                 } else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
    505                         resolveAggrInit( type, iter, end );
    506                 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
    507                         Type * base = tt->get_baseType()->get_base();
    508                         if ( base ) {
    509                                 // know the implementation type, so try using that as the initContext
    510                                 initContext = base;
    511                                 visit( listInit );
    512                         } else {
    513                                 // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
    514                                 Parent::visit( listInit );
    515                         }
    516                 } else {
    517                         assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext )
    518                                 || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) );
    519                         // basic types are handled here
    520                         Parent::visit( listInit );
    521                 }
    522 
    523 #if 0
    524                 if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
    525                         std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
    526                         for ( ; iter != listInit->end_initializers(); ++iter ) {
    527                                 initContext = at->get_base();
    528                                 (*iter)->accept( *this );
    529                         } // for
    530                 } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
    531                         StructDecl *baseStruct = st->get_baseStruct();
    532                         std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
    533                         std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
    534                         for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
    535                                 if ( (*iter2)->get_designators().empty() ) {
    536                                         DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
    537                                         initContext = dt->get_type();
    538                                         (*iter2)->accept( *this );
    539                                         ++iter1;
    540                                 } else {
    541                                         StructDecl *st = baseStruct;
    542                                         iter1 = st->get_members().begin();
    543                                         std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
    544                                         for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
    545                                                 NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
    546                                                 assert( key );
    547                                                 for ( ; iter1 != st->get_members().end(); ++iter1 ) {
    548                                                         if ( key->get_name() == (*iter1)->get_name() ) {
    549                                                                 (*iter1)->print( cout );
    550                                                                 cout << key->get_name() << endl;
    551                                                                 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
    552                                                                 assert( fred );
    553                                                                 StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
    554                                                                 assert( mary );
    555                                                                 st = mary->get_baseStruct();
    556                                                                 iter1 = st->get_members().begin();
    557                                                                 break;
    558                                                         } // if
    559                                                 }  // for
    560                                         } // for
    561                                         ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
    562                                         assert( fred );
    563                                         initContext = fred->get_type();
    564                                         (*listInit->begin_initializers())->accept( *this );
    565                                 } // if
    566                         } // for
    567                 } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
    568                         DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
    569                         initContext = dt->get_type();
    570                         (*listInit->begin_initializers())->accept( *this );
    571                 } // if
    572 #endif
     429                // move cursor into brace-enclosed initializer-list
     430                currentObject.enterListInit();
     431                // xxx - fix this so that the list isn't copied, iterator should be used to change current element
     432                std::list<Designation *> newDesignations;
     433                for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
     434                        // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving
     435                        // the initializer against that object.
     436                        Designation * des = std::get<0>(p);
     437                        Initializer * init = std::get<1>(p);
     438                        newDesignations.push_back( currentObject.findNext( des ) );
     439                        init->accept( *this );
     440                }
     441                // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
     442                listInit->get_designations() = newDesignations; // xxx - memory management
     443                currentObject.exitListInit();
     444
     445                // xxx - this part has not be folded into CurrentObject yet
     446                // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
     447                //      Type * base = tt->get_baseType()->get_base();
     448                //      if ( base ) {
     449                //              // know the implementation type, so try using that as the initContext
     450                //              ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr );
     451                //              currentObject = &tmpObj;
     452                //              visit( listInit );
     453                //      } else {
     454                //              // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
     455                //              Parent::visit( listInit );
     456                //      }
     457                // } else {
    573458        }
    574459
  • src/ResolvExpr/Unify.cc

    r11dbfe1 r67fa9f9  
    606606                        } else if ( tupleParam ) {
    607607                                // bundle other parameters into tuple to match
    608                                 TupleType* binder = new TupleType{ paramTy->get_qualifiers() };
     608                                std::list< Type * > binderTypes;
    609609
    610610                                do {
    611                                         binder->get_types().push_back( otherParam->get_type()->clone() );
     611                                        binderTypes.push_back( otherParam->get_type()->clone() );
    612612                                        ++jt;
    613613
     
    618618                                } while (true);
    619619
    620                                 otherParamTy = binder;
     620                                otherParamTy = new TupleType{ paramTy->get_qualifiers(), binderTypes };
    621621                                ++it;  // skip ttype parameter for break
    622622                        } else if ( otherTupleParam ) {
    623623                                // bundle parameters into tuple to match other
    624                                 TupleType* binder = new TupleType{ otherParamTy->get_qualifiers() };
     624                                std::list< Type * > binderTypes;
    625625
    626626                                do {
    627                                         binder->get_types().push_back( param->get_type()->clone() );
     627                                        binderTypes.push_back( param->get_type()->clone() );
    628628                                        ++it;
    629629
     
    634634                                } while (true);
    635635
    636                                 paramTy = binder;
     636                                paramTy = new TupleType{ otherParamTy->get_qualifiers(), binderTypes };
    637637                                ++jt;  // skip ttype parameter for break
    638638                        }
     
    756756                        return function->get_returnVals().front()->get_type()->clone();
    757757                } else {
    758                         TupleType * tupleType = new TupleType( Type::Qualifiers() );
     758                        std::list< Type * > types;
    759759                        for ( DeclarationWithType * decl : function->get_returnVals() ) {
    760                                 tupleType->get_types().push_back( decl->get_type()->clone() );
     760                                types.push_back( decl->get_type()->clone() );
    761761                        } // for
    762                         return tupleType;
     762                        return new TupleType( Type::Qualifiers(), types );
    763763                }
    764764        }
  • src/ResolvExpr/module.mk

    r11dbfe1 r67fa9f9  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    3131       ResolvExpr/PolyCost.cc \
    3232       ResolvExpr/Occurs.cc \
    33        ResolvExpr/TypeEnvironment.cc
     33       ResolvExpr/TypeEnvironment.cc \
     34       ResolvExpr/CurrentObject.cc
  • src/SymTab/Autogen.h

    r11dbfe1 r67fa9f9  
    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 ) {
    4545        // want to be able to generate assignment, ctor, and dtor generically,
     
    5050        dstParam = new AddressExpr( dstParam );
    5151        if ( addCast ) {
    52             // cast to T* with qualifiers removed, so that qualified objects can be constructed
    53             // and destructed with the same functions as non-qualified objects.
    54             // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
    55             // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
    56             // remove lvalue as a qualifier, this can change to
    57             //   type->get_qualifiers() = Type::Qualifiers();
    58             assert( type );
    59             Type * castType = type->clone();
    60 //                      castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
    61             castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    62             castType->set_lvalue( true ); // xxx - might not need this
    63             dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
     52                // cast to T* with qualifiers removed, so that qualified objects can be constructed
     53                // and destructed with the same functions as non-qualified objects.
     54                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     55                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     56                // remove lvalue as a qualifier, this can change to
     57                //   type->get_qualifiers() = Type::Qualifiers();
     58                assert( type );
     59                Type * castType = type->clone();
     60                castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     61                castType->set_lvalue( true ); // xxx - might not need this
     62                dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    6463        }
    6564        fExpr->get_args().push_back( dstParam );
     
    7574
    7675        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( "--?" );
    10376        }
    10477
    105         ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
     78        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
     79        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
     80        template< typename OutputIterator >
     81        void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
     82                static UniqueName indexName( "_index" );
    10683
    107         UntypedExpr *cond = new UntypedExpr( cmp );
    108         cond->get_args().push_back( new VariableExpr( index ) );
    109         cond->get_args().push_back( end );
     84                // for a flexible array member nothing is done -- user must define own assignment
     85                if ( ! array->get_dimension() ) return ;
    11086
    111         UntypedExpr *inc = new UntypedExpr( update );
    112         inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     87                Expression * begin, * end, * update, * cmp;
     88                if ( forward ) {
     89                        // generate: for ( int i = 0; i < N; ++i )
     90                        begin = new ConstantExpr( Constant::from_int( 0 ) );
     91                        end = array->get_dimension()->clone();
     92                        cmp = new NameExpr( "?<?" );
     93                        update = new NameExpr( "++?" );
     94                } else {
     95                        // generate: for ( int i = N-1; i >= 0; --i )
     96                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
     97                        ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     98                        ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     99                        end = new ConstantExpr( Constant::from_int( 0 ) );
     100                        cmp = new NameExpr( "?>=?" );
     101                        update = new NameExpr( "--?" );
     102                }
    113103
    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;
     104                ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin ) );
    118105
    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() );
     106                UntypedExpr *cond = new UntypedExpr( cmp );
     107                cond->get_args().push_back( new VariableExpr( index ) );
     108                cond->get_args().push_back( end );
    122109
    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 );
     110                UntypedExpr *inc = new UntypedExpr( update );
     111                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    126112
    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 ) );
     113                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     114                dstIndex->get_args().push_back( dstParam );
     115                dstIndex->get_args().push_back( new VariableExpr( index ) );
     116                dstParam = dstIndex;
    133117
    134         *out++ = block;
    135     }
     118                // srcParam must keep track of the array indices to build the
     119                // source parameter and/or array list initializer
     120                srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    136121
    137     template< typename OutputIterator >
     122                // for stmt's body, eventually containing call
     123                CompoundStmt * body = new CompoundStmt( noLabels );
     124                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     125
     126                // block containing for stmt and index variable
     127                std::list<Statement *> initList;
     128                CompoundStmt * block = new CompoundStmt( noLabels );
     129                block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     130                if ( listInit ) block->get_kids().push_back( listInit );
     131                block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     132
     133                *out++ = block;
     134        }
     135
     136        template< typename OutputIterator >
    138137        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 );
     138                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     139                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     140                        return 0;
     141                } else {
     142                        return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     143                }
    144144        }
    145     }
    146145
    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 >
     146        /// inserts into out a generated call expression to function fname with arguments dstParam
     147        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     148        /// object being constructed. The function wraps constructor and destructor calls in an
     149        /// ImplicitCtorDtorStmt node.
     150        template< typename OutputIterator >
    152151        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;
     152                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
     153                assert( obj );
     154                // unnamed bit fields are not copied as they cannot be accessed
     155                if ( isUnnamedBitfield( obj ) ) return;
    157156
    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 );
     157                bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
     158                std::list< Statement * > stmts;
     159                genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
    161160
    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;
     161                // 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
     162                assert( stmts.size() <= 1 );
     163                if ( stmts.size() == 1 ) {
     164                        Statement * callStmt = stmts.front();
     165                        if ( addCast ) {
     166                                // implicitly generated ctor/dtor calls should be wrapped
     167                                // so that later passes are aware they were generated.
     168                                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     169                                // because this causes the address to be taken at codegen, which is illegal in C.
     170                                callStmt = new ImplicitCtorDtorStmt( callStmt );
     171                        }
     172                        *out++ = callStmt;
     173                }
    174174        }
    175     }
    176175} // namespace SymTab
    177176#endif // AUTOGEN_H
  • src/SymTab/ImplementationType.cc

    r11dbfe1 r67fa9f9  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ImplementationType.cc -- 
     7// ImplementationType.cc --
    88//
    99// Author           : Richard C. Bilson
     
    9292
    9393        void ImplementationType::visit(TupleType *tupleType) {
    94                 TupleType *newType = new TupleType( Type::Qualifiers() );
     94                std::list< Type * > types;
    9595                for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
    9696                        Type *implType = implementationType( *i, indexer );
    9797                        implType->get_qualifiers() |= tupleType->get_qualifiers();
    98                         newType->get_types().push_back( implType );
     98                        types.push_back( implType );
    9999                } // for
    100                 result = newType;
     100                result = new TupleType( Type::Qualifiers(), types );
    101101        }
    102102
  • src/SymTab/Indexer.cc

    r11dbfe1 r67fa9f9  
    652652                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    653653                                // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    654                                 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true;
     654                                if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true;
    655655                        }
    656656                }
     
    669669                                // check for C decls with the same name, skipping
    670670                                // those with an incompatible type (by mangleName)
    671                                 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first == mangleName ) return true;
     671                                if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true;
    672672                        }
    673673                }
     
    724724                        // new definition shadows the autogenerated one, even at the same scope
    725725                        return false;
    726                 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
     726                } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
    727727                        // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
    728728                        // we should ignore outermost pointer qualifiers, except _Atomic?
     
    765765
    766766                // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
    767                 if ( decl->get_linkage() == LinkageSpec::C ) {
     767                if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) {
    768768                        // NOTE this is broken in Richard's original code in such a way that it never triggers (it
    769769                        // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
  • src/SymTab/Validate.cc

    r11dbfe1 r67fa9f9  
    106106
    107107        /// Fix return types so that every function returns exactly one value
    108         class ReturnTypeFixer {
    109           public:
     108        struct ReturnTypeFixer {
    110109                static void fix( std::list< Declaration * > &translationUnit );
    111110
     
    115114
    116115        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    117         class EnumAndPointerDecay {
    118         public:
     116        struct EnumAndPointerDecay {
    119117                void previsit( EnumDecl *aggregateDecl );
    120118                void previsit( FunctionType *func );
     
    159157        };
    160158
    161         class ReturnChecker : public WithScopes {
    162           public:
     159        struct ReturnChecker : public WithGuards {
    163160                /// Checks that return statements return nothing if their return type is void
    164161                /// and return something if the return type is non-void.
    165162                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    166           private:
     163
    167164                void previsit( FunctionDecl * functionDecl );
    168165                void previsit( ReturnStmt * returnStmt );
     
    205202        };
    206203
    207         class VerifyCtorDtorAssign {
    208         public:
     204        struct VerifyCtorDtorAssign {
    209205                /// ensure that constructors, destructors, and assignment have at least one
    210206                /// parameter, the first of which must be a pointer, and that ctor/dtors have no
     
    216212
    217213        /// ensure that generic types have the correct number of type arguments
    218         class ValidateGenericParameters {
    219         public:
     214        struct ValidateGenericParameters {
    220215                void previsit( StructInstType * inst );
    221216                void previsit( UnionInstType * inst );
    222217        };
    223218
    224         class ArrayLength {
    225         public:
     219        struct ArrayLength {
    226220                /// for array types without an explicit length, compute the length and store it so that it
    227221                /// is known to the rest of the phases. For example,
     
    236230        };
    237231
    238         class CompoundLiteral final : public GenPoly::DeclMutator {
     232        struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
    239233                Type::StorageClasses storageClasses;
    240234
    241                 using GenPoly::DeclMutator::mutate;
    242                 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
    243                 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
     235                void premutate( ObjectDecl *objectDecl );
     236                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    244237        };
    245238
     
    248241                LinkReferenceToTypes lrt( doDebug, 0 );
    249242                ForallPointerDecay fpd( 0 );
    250                 CompoundLiteral compoundliteral;
     243                PassVisitor<CompoundLiteral> compoundliteral;
    251244                PassVisitor<ValidateGenericParameters> genericParams;
    252245
     
    263256                Concurrency::implementThreadStarter( translationUnit );
    264257                ReturnChecker::checkFunctionReturns( translationUnit );
    265                 compoundliteral.mutateDeclarationList( translationUnit );
     258                mutateAll( translationUnit, compoundliteral );
    266259                acceptAll( translationUnit, fpd );
    267260                ArrayLength::computeLength( translationUnit );
     
    883876        }
    884877
    885         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
     878        void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
    886879                storageClasses = objectDecl->get_storageClasses();
    887                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    888                 return temp;
    889         }
    890 
    891         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
     880        }
     881
     882        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    892883                // transform [storage_class] ... (struct S){ 3, ... };
    893884                // into [storage_class] struct S temp =  { 3, ... };
    894885                static UniqueName indexName( "_compLit" );
    895886
    896                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );
    897                 compLitExpr->set_result( 0 );
    898                 compLitExpr->set_initializer( 0 );
     887                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     888                compLitExpr->set_result( nullptr );
     889                compLitExpr->set_initializer( nullptr );
    899890                delete compLitExpr;
    900                 DeclarationWithType * newtempvar = mutate( tempvar );
    901                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    902                 return new VariableExpr( newtempvar );
     891                declsToAddBefore.push_back( tempvar );                                  // add modified temporary to current block
     892                return new VariableExpr( tempvar );
    903893        }
    904894
  • src/SynTree/Constant.cc

    r11dbfe1 r67fa9f9  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Constant.cc -- 
     7// Constant.cc --
    88//
    99// Author           : Richard C. Bilson
     
    4646}
    4747
     48unsigned long long Constant::get_ival() const {
     49        assertf( safe_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve ival from non-integer constant." );
     50        return val.ival;
     51}
     52
     53double Constant::get_dval() const {
     54        assertf( ! safe_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve dval from integer constant." );
     55        return val.dval;
     56}
     57
    4858void Constant::print( std::ostream &os ) const {
    4959        os << "(" << rep << " " << val.ival;
  • src/SynTree/Constant.h

    r11dbfe1 r67fa9f9  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Constant.h -- 
     7// Constant.h --
    88//
    99// Author           : Richard C. Bilson
     
    3232        std::string & get_value() { return rep; }
    3333        void set_value( std::string newValue ) { rep = newValue; }
     34        unsigned long long get_ival() const;
     35        double get_dval() const;
    3436
    3537        /// generates a boolean constant of the given bool
  • src/SynTree/Expression.cc

    r11dbfe1 r67fa9f9  
    2121#include <iterator>
    2222
     23#include "Declaration.h"
     24#include "Expression.h"
     25#include "Initializer.h"
     26#include "Statement.h"
    2327#include "Type.h"
    24 #include "Initializer.h"
    25 #include "Expression.h"
    26 #include "Declaration.h"
    27 #include "Statement.h"
    2828#include "TypeSubstitution.h"
     29#include "VarExprReplacer.h"
     30
    2931#include "Common/utility.h"
     32#include "Common/PassVisitor.h"
     33
    3034#include "InitTweak/InitTweak.h"
    3135
     
    9296
    9397        Declaration *decl = get_var();
    94         // if ( decl != 0) decl->print(os, indent + 2);
    9598        if ( decl != 0) decl->printShort(os, indent + 2);
    9699        os << std::endl;
     
    657660}
    658661
     662InitAlternative::InitAlternative( Type * type, Designation * designation ) : type( type ), designation( designation ) {}
     663InitAlternative::InitAlternative( const InitAlternative & other ) : type( maybeClone( other.type ) ), designation( maybeClone( other.designation ) ) {}
     664InitAlternative::~InitAlternative() {
     665        delete type;
     666        delete designation;
     667}
     668
     669UntypedInitExpr::UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ) : expr( expr ), initAlts( initAlts ) {}
     670UntypedInitExpr::UntypedInitExpr( const UntypedInitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), initAlts( other.initAlts ) {}
     671UntypedInitExpr::~UntypedInitExpr() {
     672        delete expr;
     673}
     674
     675void UntypedInitExpr::print( std::ostream & os, int indent ) const {
     676        os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' );
     677        expr->print( os, indent+2 );
     678        if ( ! initAlts.empty() ) {
     679                for ( const InitAlternative & alt : initAlts ) {
     680                        os << std::string( indent+2, ' ' ) <<  "InitAlternative: ";
     681                        alt.type->print( os, indent+2 );
     682                        alt.designation->print( os, indent+2 );
     683                }
     684        }
     685}
     686
     687InitExpr::InitExpr( Expression * expr, Designation * designation ) : expr( expr ), designation( designation ) {
     688        set_result( expr->get_result()->clone() );
     689}
     690InitExpr::InitExpr( const InitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), designation( maybeClone( other.designation) ) {}
     691InitExpr::~InitExpr() {
     692        delete expr;
     693        delete designation;
     694}
     695
     696void InitExpr::print( std::ostream & os, int indent ) const {
     697        os << "Init Expression" << std::endl << std::string( indent+2, ' ' );
     698        expr->print( os, indent+2 );
     699        os << std::string( indent+2, ' ' ) << "with designation: ";
     700        designation->print( os, indent+2 );
     701}
     702
     703
    659704std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
    660705        if ( expr ) {
  • src/SynTree/Expression.h

    r11dbfe1 r67fa9f9  
    744744};
    745745
     746struct InitAlternative {
     747public:
     748        Type * type = nullptr;
     749        Designation * designation = nullptr;
     750        InitAlternative( Type * type, Designation * designation );
     751        InitAlternative( const InitAlternative & other );
     752        InitAlternative & operator=( const Initializer & other ) = delete; // at the moment this isn't used, and I don't want to implement it
     753        ~InitAlternative();
     754};
     755
     756class UntypedInitExpr : public Expression {
     757public:
     758        UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts );
     759        UntypedInitExpr( const UntypedInitExpr & other );
     760        ~UntypedInitExpr();
     761
     762        Expression * get_expr() const { return expr; }
     763        UntypedInitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
     764
     765        std::list<InitAlternative> & get_initAlts() { return initAlts; }
     766
     767        virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); }
     768        virtual void accept( Visitor & v ) { v.visit( this ); }
     769        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     770        virtual void print( std::ostream & os, int indent = 0 ) const;
     771private:
     772        Expression * expr;
     773        std::list<InitAlternative> initAlts;
     774};
     775
     776class InitExpr : public Expression {
     777public:
     778        InitExpr( Expression * expr, Designation * designation );
     779        InitExpr( const InitExpr & other );
     780        ~InitExpr();
     781
     782        Expression * get_expr() const { return expr; }
     783        InitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
     784
     785        Designation * get_designation() const { return designation; }
     786        InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; }
     787
     788        virtual InitExpr * clone() const { return new InitExpr( * this ); }
     789        virtual void accept( Visitor & v ) { v.visit( this ); }
     790        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     791        virtual void print( std::ostream & os, int indent = 0 ) const;
     792private:
     793        Expression * expr;
     794        Designation * designation;
     795};
     796
     797
    746798std::ostream & operator<<( std::ostream & out, const Expression * expr );
    747799
  • src/SynTree/Initializer.cc

    r11dbfe1 r67fa9f9  
    1919#include "Common/utility.h"
    2020
     21Designation::Designation( const std::list< Expression * > & designators ) : designators( designators ) {}
     22Designation::Designation( const Designation & other ) : BaseSyntaxNode( other ) {
     23        // std::cerr << "cloning designation" << std::endl;
     24        cloneAll( other.designators, designators );
     25        // std::cerr << "finished cloning designation" << std::endl;
     26}
     27
     28Designation::~Designation() {
     29        // std::cerr << "destroying designation" << std::endl;
     30        deleteAll( designators );
     31        // std::cerr << "finished destroying designation" << std::endl;
     32}
     33
     34void Designation::print( std::ostream &os, int indent ) const {
     35        if ( ! designators.empty() ) {
     36                os << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;
     37                for ( std::list < Expression * >::const_iterator i = designators.begin(); i != designators.end(); i++ ) {
     38                        os << std::string(indent + 4, ' ' );
     39                        ( *i )->print(os, indent + 4 );
     40                }
     41                os << std::endl;
     42        } // if
     43}
     44
    2145Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
    2246Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) {
    2347}
    24 
    25 
    2648Initializer::~Initializer() {}
    2749
    28 std::string Initializer::designator_name( Expression *des ) {
    29         if ( NameExpr *n = dynamic_cast<NameExpr *>(des) )
    30                 return n->get_name();
    31         else
    32                 throw 0;
    33 }
    34 
    35 // void Initializer::print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent ) {}
    36 
    37 SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
     50SingleInit::SingleInit( Expression *v, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ) {
    3851}
    3952
    4053SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
    41         cloneAll(other.designators, designators );
    4254}
    4355
    4456SingleInit::~SingleInit() {
    4557        delete value;
    46         deleteAll(designators);
    4758}
    4859
    49 void SingleInit::print( std::ostream &os, int indent ) {
    50         os << std::endl << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;
     60void SingleInit::print( std::ostream &os, int indent ) const {
     61        os << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;
    5162        os << std::string(indent+4, ' ' );
    5263        value->print( os, indent+4 );
    53 
    54         if ( ! designators.empty() ) {
    55                 os << std::endl << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;
    56                 for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ ) {
    57                         os << std::string(indent + 4, ' ' );
    58                         ( *i )->print(os, indent + 4 );
    59                 }
    60         } // if
    6164}
    6265
    63 ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
    64         : Initializer( maybeConstructed ), initializers( _initializers ), designators( _designators ) {
     66
     67ListInit::ListInit( const std::list<Initializer*> &inits, const std::list<Designation *> &des, bool maybeConstructed )
     68        : Initializer( maybeConstructed ), initializers( inits ), designations( des ) {
     69                // handle the common case where a ListInit is created without designations by making a list of empty designations with the same length as the initializer
     70                if ( designations.empty() ) {
     71                        for ( auto & i : initializers ) {
     72                                (void)i;
     73                                designations.push_back( new Designation( {} ) );
     74                        }
     75                }
     76                assertf( initializers.size() == designations.size(), "Created ListInit with mismatching initializers (%d) and designations (%d)", initializers.size(), designations.size() );
    6577}
    6678
    6779ListInit::ListInit( const ListInit & other ) : Initializer( other ) {
    6880        cloneAll( other.initializers, initializers );
    69         cloneAll( other.designators, designators );
     81        cloneAll( other.designations, designations );
    7082}
    71 
    7283
    7384ListInit::~ListInit() {
    7485        deleteAll( initializers );
    75         deleteAll( designators );
     86        deleteAll( designations );
    7687}
    7788
    78 void ListInit::print( std::ostream &os, int indent ) {
    79         os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
    80         if ( ! designators.empty() ) {
    81                 os << std::string(indent + 2, ' ' ) << "designated by: [";
    82                 for ( std::list < Expression * >::iterator i = designators.begin();
    83                           i != designators.end(); i++ ) {
    84                         ( *i )->print(os, indent + 4 );
    85                 } // for
     89void ListInit::print( std::ostream &os, int indent ) const {
     90        os << std::string(indent, ' ') << "Compound initializer:  " << std::endl;
     91        for ( Designation * d : designations ) {
     92                d->print( os, indent + 2 );
     93        }
    8694
    87                 os << std::string(indent + 2, ' ' ) << "]";
    88         } // if
    89 
    90         for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ )
    91                 (*i)->print( os, indent + 2 );
     95        for ( const Initializer * init : initializers ) {
     96                init->print( os, indent + 2 );
     97                os << std::endl;
     98        }
    9299}
    93100
     
    103110}
    104111
    105 void ConstructorInit::print( std::ostream &os, int indent ) {
     112void ConstructorInit::print( std::ostream &os, int indent ) const {
    106113        os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl;
    107114        if ( ctor ) {
     
    124131}
    125132
    126 std::ostream & operator<<( std::ostream & out, Initializer * init ) {
    127         init->print( out );
     133std::ostream & operator<<( std::ostream & out, const Initializer * init ) {
     134        if ( init ) {
     135                init->print( out );
     136        } else {
     137                out << "nullptr";
     138        }
     139        return out;
     140}
     141
     142std::ostream & operator<<( std::ostream & out, const Designation * des ) {
     143        if ( des ) {
     144                des->print( out );
     145        } else {
     146                out << "nullptr";
     147        }
    128148        return out;
    129149}
  • src/SynTree/Initializer.h

    r11dbfe1 r67fa9f9  
    2525#include "Visitor.h"
    2626
    27 const std::list<Expression*> noDesignators;
     27// Designation: list of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an object being initialized.
     28class Designation : public BaseSyntaxNode {
     29public:
     30        Designation( const std::list< Expression * > & designators );
     31        Designation( const Designation & other );
     32        virtual ~Designation();
     33
     34        std::list< Expression * > & get_designators() { return designators; }
     35
     36        virtual Designation * clone() const { return new Designation( *this ); };
     37        virtual void accept( Visitor &v ) { v.visit( this ); }
     38        virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
     39        virtual void print( std::ostream &os, int indent = 0 ) const;
     40private:
     41        std::list< Expression * > designators;
     42};
     43
     44const std::list<Designation *> noDesignators;
    2845
    2946// Initializer: base class for object initializers (provide default values)
    3047class Initializer : public BaseSyntaxNode {
    3148  public:
    32         //      Initializer( std::string _name = std::string(""), int _pos = 0 );
    3349        Initializer( bool maybeConstructed );
    3450        Initializer( const Initializer & other );
    3551        virtual ~Initializer();
    36 
    37         static std::string designator_name( Expression *designator );
    38 
    39         //      void set_name( std::string newValue ) { name = newValue; }
    40         //      std::string get_name() const { return name; }
    41 
    42         //      void set_pos( int newValue ) { pos = newValue; }
    43         //      int get_pos() const { return pos; }
    44         virtual void set_designators( std::list<Expression *> & ) { assert(false); }
    45         virtual std::list<Expression *> &get_designators() {
    46                 assert(false);
    47                 std::list<Expression *> *ret = 0; return *ret;  // never reached
    48         }
    4952
    5053        bool get_maybeConstructed() { return maybeConstructed; }
     
    5356        virtual void accept( Visitor &v ) = 0;
    5457        virtual Initializer *acceptMutator( Mutator &m ) = 0;
    55         virtual void print( std::ostream &os, int indent = 0 ) = 0;
     58        virtual void print( std::ostream &os, int indent = 0 ) const = 0;
    5659  private:
    57         //      std::string name;
    58         //      int pos;
    5960        bool maybeConstructed;
    6061};
     
    6364class SingleInit : public Initializer {
    6465  public:
    65         SingleInit( Expression *value, const std::list< Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
     66        SingleInit( Expression *value, bool maybeConstructed = false );
    6667        SingleInit( const SingleInit &other );
    6768        virtual ~SingleInit();
     
    7071        void set_value( Expression *newValue ) { value = newValue; }
    7172
    72         std::list<Expression *> &get_designators() { return designators; }
    73         void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
    74 
    7573        virtual SingleInit *clone() const { return new SingleInit( *this); }
    7674        virtual void accept( Visitor &v ) { v.visit( this ); }
    7775        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    78         virtual void print( std::ostream &os, int indent = 0 );
     76        virtual void print( std::ostream &os, int indent = 0 ) const;
    7977  private:
    8078        //Constant *value;
    8179        Expression *value;      // has to be a compile-time constant
    82         std::list< Expression * > designators;
    8380};
    8481
     
    8885  public:
    8986        ListInit( const std::list<Initializer*> &initializers,
    90                           const std::list<Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
     87                          const std::list<Designation *> &designators = {}, bool maybeConstructed = false );
    9188        ListInit( const ListInit & other );
    9289        virtual ~ListInit();
    9390
    94         void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
    95         std::list<Expression *> &get_designators() { return designators; }
    96         void set_initializers( std::list<Initializer*> &newValue ) { initializers = newValue; }
    97         std::list<Initializer*> &get_initializers() { return initializers; }
     91        std::list<Designation *> & get_designations() { return designations; }
     92        std::list<Initializer *> & get_initializers() { return initializers; }
    9893
    9994        typedef std::list<Initializer*>::iterator iterator;
     95        typedef std::list<Initializer*>::const_iterator const_iterator;
    10096        iterator begin() { return initializers.begin(); }
    10197        iterator end() { return initializers.end(); }
     98        const_iterator begin() const { return initializers.begin(); }
     99        const_iterator end() const { return initializers.end(); }
    102100
    103101        virtual ListInit *clone() const { return new ListInit( *this ); }
    104102        virtual void accept( Visitor &v ) { v.visit( this ); }
    105103        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    106         virtual void print( std::ostream &os, int indent = 0 );
     104        virtual void print( std::ostream &os, int indent = 0 ) const;
    107105  private:
    108         std::list<Initializer*> initializers;  // order *is* important
    109         std::list<Expression *> designators;
     106        std::list<Initializer *> initializers;  // order *is* important
     107        std::list<Designation *> designations;  // order/length is consistent with initializers
    110108};
    111109
     
    130128        virtual void accept( Visitor &v ) { v.visit( this ); }
    131129        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    132         virtual void print( std::ostream &os, int indent = 0 );
     130        virtual void print( std::ostream &os, int indent = 0 ) const;
    133131
    134132  private:
     
    140138};
    141139
    142 std::ostream & operator<<( std::ostream & out, Initializer * init );
     140std::ostream & operator<<( std::ostream & out, const Initializer * init );
     141std::ostream & operator<<( std::ostream & out, const Designation * des );
    143142
    144143#endif // INITIALIZER_H
  • src/SynTree/Mutator.cc

    r11dbfe1 r67fa9f9  
    433433}
    434434
     435Expression *Mutator::mutate( UntypedInitExpr * initExpr ) {
     436        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
     437        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     438        initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) );
     439        // not currently mutating initAlts, but this doesn't matter since this node is only used in the resolver.
     440        return initExpr;
     441}
     442
     443Expression *Mutator::mutate( InitExpr * initExpr ) {
     444        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
     445        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     446        initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) );
     447        initExpr->set_designation( maybeMutate( initExpr->get_designation(), *this ) );
     448        return initExpr;
     449}
     450
    435451
    436452Type *Mutator::mutate( VoidType *voidType ) {
     
    499515        mutateAll( tupleType->get_forall(), *this );
    500516        mutateAll( tupleType->get_types(), *this );
     517        mutateAll( tupleType->get_members(), *this );
    501518        return tupleType;
    502519}
     
    535552
    536553
     554Designation *Mutator::mutate( Designation * designation ) {
     555        mutateAll( designation->get_designators(), *this );
     556        return designation;
     557}
     558
    537559Initializer *Mutator::mutate( SingleInit *singleInit ) {
    538560        singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
     
    541563
    542564Initializer *Mutator::mutate( ListInit *listInit ) {
    543         mutateAll( listInit->get_designators(), *this );
     565        mutateAll( listInit->get_designations(), *this );
    544566        mutateAll( listInit->get_initializers(), *this );
    545567        return listInit;
  • src/SynTree/Mutator.h

    r11dbfe1 r67fa9f9  
    8585        virtual Expression* mutate( StmtExpr * stmtExpr );
    8686        virtual Expression* mutate( UniqueExpr * uniqueExpr );
     87        virtual Expression* mutate( UntypedInitExpr * initExpr );
     88        virtual Expression* mutate( InitExpr * initExpr );
    8789
    8890        virtual Type* mutate( VoidType *basicType );
     
    103105        virtual Type* mutate( OneType *oneType );
    104106
     107        virtual Designation* mutate( Designation *designation );
    105108        virtual Initializer* mutate( SingleInit *singleInit );
    106109        virtual Initializer* mutate( ListInit *listInit );
  • src/SynTree/SynTree.h

    r11dbfe1 r67fa9f9  
    9393class StmtExpr;
    9494class UniqueExpr;
     95class UntypedInitExpr;
     96class InitExpr;
    9597
    9698class Type;
     
    113115class OneType;
    114116
     117class Designation;
    115118class Initializer;
    116119class SingleInit;
  • src/SynTree/TupleType.cc

    r11dbfe1 r67fa9f9  
    1414//
    1515
     16#include "Declaration.h"
     17#include "Initializer.h"
    1618#include "Type.h"
    1719#include "Common/utility.h"
     20#include "Parser/LinkageSpec.h"
    1821
    1922TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), types( types ) {
     23        for ( Type * t : *this ) {
     24                // xxx - this is very awkward. TupleTypes should contain objects so that members can be named, but if they don't have an initializer node then
     25                // they end up getting constructors, which end up being inserted causing problems. This happens because the object decls have to be visited so that
     26                // their types are kept in sync with the types list here. Ultimately, the types list here should be eliminated and perhaps replaced with a list-view
     27                // of the object types list, but I digress. The temporary solution here is to make a ListInit with maybeConstructed = false, that way even when the
     28                // object is visited, it is never constructed. Ultimately, a better solution might be either:
     29                // a) to separate TupleType from its declarations, into TupleDecl and Tuple{Inst?}Type, ala StructDecl and StructInstType
     30                // b) separate initializer nodes better, e.g. add a MaybeConstructed node that is replaced by genInit, rather than what currently exists in a bool
     31                members.push_back( new ObjectDecl( "" , Type::StorageClasses(), LinkageSpec::Cforall, nullptr, t->clone(), new ListInit( {}, {}, false ) ) );
     32        }
    2033}
    2134
    2235TupleType::TupleType( const TupleType& other ) : Type( other ) {
    2336        cloneAll( other.types, types );
     37        cloneAll( other.members, members );
    2438}
    2539
    2640TupleType::~TupleType() {
    2741        deleteAll( types );
     42        deleteAll( members );
    2843}
    2944
  • src/SynTree/Type.h

    r11dbfe1 r67fa9f9  
    481481class TupleType : public Type {
    482482  public:
    483         TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types = std::list< Type * >(), const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
     483        TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    484484        TupleType( const TupleType& );
    485485        virtual ~TupleType();
     
    488488        typedef value_type::iterator iterator;
    489489
    490         std::list<Type*>& get_types() { return types; }
     490        std::list<Type *> & get_types() { return types; }
    491491        virtual unsigned size() const { return types.size(); };
     492
     493        // For now, this is entirely synthetic -- tuple types always have unnamed members.
     494        // Eventually, we may allow named tuples, in which case members should subsume types
     495        std::list<Declaration *> & get_members() { return members; }
    492496
    493497        iterator begin() { return types.begin(); }
     
    506510        virtual void print( std::ostream & os, int indent = 0 ) const;
    507511  private:
    508         std::list<Type*> types;
     512        std::list<Type *> types;
     513        std::list<Declaration *> members;
    509514};
    510515
  • src/SynTree/VarExprReplacer.cc

    r11dbfe1 r67fa9f9  
    1414//
    1515
     16#include "Declaration.h"
    1617#include "Expression.h"
    1718#include "VarExprReplacer.h"
    1819
    19 VarExprReplacer::VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}
     20VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {}
    2021
    2122// replace variable with new node from decl map
    2223void VarExprReplacer::visit( VariableExpr * varExpr ) {
    23   // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
    24   if ( declMap.count( varExpr->get_var() ) ) {
    25     varExpr->set_var( declMap.at( varExpr->get_var() ) );
    26   }
     24        // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
     25        if ( declMap.count( varExpr->get_var() ) ) {
     26                if ( debug ) {
     27                        std::cerr << "replacing variable reference: " << (void*)varExpr->get_var() << " " << varExpr->get_var() << " with " << (void*)declMap.at( varExpr->get_var() ) << " " << declMap.at( varExpr->get_var() ) << std::endl;
     28                }
     29                varExpr->set_var( declMap.at( varExpr->get_var() ) );
     30        }
    2731}
  • src/SynTree/VarExprReplacer.h

    r11dbfe1 r67fa9f9  
    2727private:
    2828        const DeclMap & declMap;
     29  bool debug;
    2930public:
    30         VarExprReplacer( const DeclMap & declMap );
     31        VarExprReplacer( const DeclMap & declMap, bool debug = false );
    3132
    3233        // replace variable with new node from decl map
  • src/SynTree/Visitor.cc

    r11dbfe1 r67fa9f9  
    340340}
    341341
     342void Visitor::visit( UntypedInitExpr * initExpr ) {
     343        maybeAccept( initExpr->get_result(), *this );
     344        maybeAccept( initExpr->get_expr(), *this );
     345        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
     346}
     347
     348void Visitor::visit( InitExpr * initExpr ) {
     349        maybeAccept( initExpr->get_result(), *this );
     350        maybeAccept( initExpr->get_expr(), *this );
     351        maybeAccept( initExpr->get_designation(), *this );
     352}
     353
    342354
    343355void Visitor::visit( VoidType *voidType ) {
     
    395407        acceptAll( tupleType->get_forall(), *this );
    396408        acceptAll( tupleType->get_types(), *this );
     409        acceptAll( tupleType->get_members(), *this );
    397410}
    398411
     
    424437}
    425438
     439void Visitor::visit( Designation * designation ) {
     440        acceptAll( designation->get_designators(), *this );
     441}
    426442
    427443void Visitor::visit( SingleInit *singleInit ) {
     
    430446
    431447void Visitor::visit( ListInit *listInit ) {
    432         acceptAll( listInit->get_designators(), *this );
     448        acceptAll( listInit->get_designations(), *this );
    433449        acceptAll( listInit->get_initializers(), *this );
    434450}
  • src/SynTree/Visitor.h

    r11dbfe1 r67fa9f9  
    8888        virtual void visit( StmtExpr * stmtExpr );
    8989        virtual void visit( UniqueExpr * uniqueExpr );
     90        virtual void visit( UntypedInitExpr * initExpr );
     91        virtual void visit( InitExpr * initExpr );
    9092
    9193        virtual void visit( VoidType *basicType );
     
    106108        virtual void visit( OneType *oneType );
    107109
     110        virtual void visit( Designation *designation );
    108111        virtual void visit( SingleInit *singleInit );
    109112        virtual void visit( ListInit *listInit );
  • src/Tuples/TupleExpansion.cc

    r11dbfe1 r67fa9f9  
    192192                        }
    193193                        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 ) );
     194                                                                                                        new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    195195                        addDeclaration( finished );
    196196                        // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
     
    310310        Type * makeTupleType( const std::list< Expression * > & exprs ) {
    311311                // produce the TupleType which aggregates the types of the exprs
    312                 TupleType *tupleType = new TupleType( Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex ) );
    313                 Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
     312                std::list< Type * > types;
     313                Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex );
    314314                for ( Expression * expr : exprs ) {
    315315                        assert( expr->get_result() );
    316316                        if ( expr->get_result()->isVoid() ) {
    317317                                // if the type of any expr is void, the type of the entire tuple is void
    318                                 delete tupleType;
    319318                                return new VoidType( Type::Qualifiers() );
    320319                        }
    321320                        Type * type = expr->get_result()->clone();
    322                         tupleType->get_types().push_back( type );
     321                        types.push_back( type );
    323322                        // the qualifiers on the tuple type are the qualifiers that exist on all component types
    324323                        qualifiers &= type->get_qualifiers();
    325324                } // for
    326325                if ( exprs.empty() ) qualifiers = Type::Qualifiers();
    327                 return tupleType;
     326                return new TupleType( qualifiers, types );
    328327        }
    329328
  • src/libcfa/Makefile.am

    r11dbfe1 r67fa9f9  
    5050
    5151libobjs = ${headers:=.o}
    52 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c}
     52libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} exception.c
    5353
    5454# not all platforms support concurrency, add option do disable it
  • src/libcfa/Makefile.in

    r11dbfe1 r67fa9f9  
    102102        containers/pair.c containers/result.c containers/vector.c \
    103103        concurrency/coroutine.c concurrency/thread.c \
    104         concurrency/kernel.c concurrency/monitor.c \
     104        concurrency/kernel.c concurrency/monitor.c exception.c \
    105105        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
    106106        concurrency/invoke.c concurrency/preemption.c
     
    126126        libcfa_d_a-interpose.$(OBJEXT) \
    127127        libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \
    128         $(am__objects_3)
     128        libcfa_d_a-exception.$(OBJEXT) $(am__objects_3)
    129129am_libcfa_d_a_OBJECTS = $(am__objects_4)
    130130libcfa_d_a_OBJECTS = $(am_libcfa_d_a_OBJECTS)
     
    136136        containers/pair.c containers/result.c containers/vector.c \
    137137        concurrency/coroutine.c concurrency/thread.c \
    138         concurrency/kernel.c concurrency/monitor.c \
     138        concurrency/kernel.c concurrency/monitor.c exception.c \
    139139        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
    140140        concurrency/invoke.c concurrency/preemption.c
     
    158158        libcfa_a-interpose.$(OBJEXT) \
    159159        libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \
    160         $(am__objects_7)
     160        libcfa_a-exception.$(OBJEXT) $(am__objects_7)
    161161am_libcfa_a_OBJECTS = $(am__objects_8)
    162162libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
     
    328328libobjs = ${headers:=.o}
    329329libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
    330         $(am__append_4)
     330        exception.c $(am__append_4)
    331331libcfa_a_SOURCES = ${libsrc}
    332332libcfa_a_CFLAGS = -nodebug -O2
     
    514514
    515515@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-assert.Po@am__quote@
     516@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-exception.Po@am__quote@
    516517@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-fstream.Po@am__quote@
    517518@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-interpose.Po@am__quote@
     
    524525@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@
    525526@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@
     527@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-exception.Po@am__quote@
    526528@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-fstream.Po@am__quote@
    527529@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-interpose.Po@am__quote@
     
    850852@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
    851853
     854libcfa_d_a-exception.obj: exception.c
     855@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-exception.Tpo -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
     856@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-exception.Tpo $(DEPDIR)/libcfa_d_a-exception.Po
     857@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='exception.c' object='libcfa_d_a-exception.obj' libtool=no @AMDEPBACKSLASH@
     858@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     859@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
     860
    852861concurrency/libcfa_d_a-alarm.o: concurrency/alarm.c
    853862@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-alarm.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-alarm.Tpo -c -o concurrency/libcfa_d_a-alarm.o `test -f 'concurrency/alarm.c' || echo '$(srcdir)/'`concurrency/alarm.c
     
    11431152@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    11441153@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
     1154
     1155libcfa_a-exception.obj: exception.c
     1156@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_a-exception.Tpo -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
     1157@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-exception.Tpo $(DEPDIR)/libcfa_a-exception.Po
     1158@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='exception.c' object='libcfa_a-exception.obj' libtool=no @AMDEPBACKSLASH@
     1159@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1160@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
    11451161
    11461162concurrency/libcfa_a-alarm.o: concurrency/alarm.c
  • src/libcfa/exception.c

    r11dbfe1 r67fa9f9  
    4444// RESUMPTION ================================================================
    4545
    46 void __cfaehm__throw_resume(exception except) {
    47 
    48         // DEBUG
    49         printf("Throwing resumption exception %d\n", except);
    50 
    51         struct __try_resume_node * original_head = shared_stack.current_resume;
    52         struct __try_resume_node * current =
     46void __cfaehm__throw_resumption(exception * except) {
     47
     48        // DEBUG
     49        printf("Throwing resumption exception %d\n", *except);
     50
     51        struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume;
     52        struct __cfaehm__try_resume_node * current =
    5353                (original_head) ? original_head->next : shared_stack.top_resume;
    5454
    5555        for ( ; current ; current = current->next) {
    5656                shared_stack.current_resume = current;
    57                 if (current->try_to_handle(except)) {
     57                if (current->handler(except)) {
    5858                        shared_stack.current_resume = original_head;
    5959                        return;
     
    6161        }
    6262
    63         printf("Unhandled exception %d\n", except);
     63        printf("Unhandled exception %d\n", *except);
    6464        shared_stack.current_resume = original_head;
    6565
    6666        // Fall back to termination:
    67         __cfaehm__throw_terminate(except);
     67        __cfaehm__throw_termination(except);
    6868        // TODO: Default handler for resumption.
    6969}
     
    7373 * after the node is built but before it is made the top node.
    7474 */
    75 void __try_resume_setup(struct __try_resume_node * node,
    76                         bool (*handler)(exception except)) {
     75void __cfaehm__try_resume_setup(struct __cfaehm__try_resume_node * node,
     76                        int (*handler)(exception * except)) {
    7777        node->next = shared_stack.top_resume;
    78         node->try_to_handle = handler;
     78        node->handler = handler;
    7979        shared_stack.top_resume = node;
    8080}
    8181
    82 void __try_resume_cleanup(struct __try_resume_node * node) {
     82void __cfaehm__try_resume_cleanup(struct __cfaehm__try_resume_node * node) {
    8383        shared_stack.top_resume = node->next;
    8484}
     
    111111}
    112112
    113 void __cfaehm__throw_terminate( int val ) {
     113void __cfaehm__throw_termination( exception * val ) {
    114114        // Store the current exception
    115         shared_stack.current_exception = val;
    116 
    117         // DEBUG
    118         printf("Throwing termination exception %d\n", val);
     115        shared_stack.current_exception = *val;
     116
     117        // DEBUG
     118        printf("Throwing termination exception %d\n", *val);
    119119
    120120        // Call stdlibc to raise the exception
     
    147147
    148148// Nesting this the other way would probably be faster.
    149 void __cfaehm__rethrow_terminate(void) {
     149void __cfaehm__rethrow_termination(void) {
    150150        // DEBUG
    151151        printf("Rethrowing termination exception\n");
    152152
    153         __cfaehm__throw_terminate(shared_stack.current_exception);
     153        __cfaehm__throw_termination(&shared_stack.current_exception);
    154154}
    155155
     
    322322// for details
    323323__attribute__((noinline))
    324 void __try_terminate(void (*try_block)(),
    325                 void (*catch_block)(int index, exception except),
    326                 __attribute__((unused)) int (*match_block)(exception except)) {
     324void __cfaehm__try_terminate(void (*try_block)(),
     325                void (*catch_block)(int index, exception * except),
     326                __attribute__((unused)) int (*match_block)(exception * except)) {
    327327        //! volatile int xy = 0;
    328328        //! printf("%p %p %p %p\n", &try_block, &catch_block, &match_block, &xy);
     
    364364        // Exception handler
    365365        catch_block(shared_stack.current_handler_index,
    366                     shared_stack.current_exception);
     366                    &shared_stack.current_exception);
    367367}
    368368
     
    384384        // Body uses language specific data and therefore could be modified arbitrarily
    385385        ".LLSDACSBCFA2:\n"                                              // BODY start
    386         "       .uleb128 .TRYSTART-__try_terminate\n"           // Handled area start  (relative to start of function)
     386        "       .uleb128 .TRYSTART-__cfaehm__try_terminate\n"           // Handled area start  (relative to start of function)
    387387        "       .uleb128 .TRYEND-.TRYSTART\n"                           // Handled area length
    388         "       .uleb128 .CATCH-__try_terminate\n"                              // Hanlder landing pad adress  (relative to start of function)
     388        "       .uleb128 .CATCH-__cfaehm__try_terminate\n"                              // Hanlder landing pad adress  (relative to start of function)
    389389        "       .uleb128 1\n"                                           // Action code, gcc seems to use always 0
    390390        ".LLSDACSECFA2:\n"                                              // BODY end
    391391        "       .text\n"                                                        // TABLE footer
    392         "       .size   __try_terminate, .-__try_terminate\n"
     392        "       .size   __cfaehm__try_terminate, .-__cfaehm__try_terminate\n"
    393393        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
    394394//      "       .section        .note.GNU-stack,\"x\",@progbits\n"
  • src/libcfa/exception.h

    r11dbfe1 r67fa9f9  
    3838// Data structure creates a list of resume handlers.
    3939struct __cfaehm__try_resume_node {
    40     __cfaehm__try_resume_node * next;
     40    struct __cfaehm__try_resume_node * next;
    4141    int (*handler)(exception * except);
    4242};
    4343
    4444void __cfaehm__try_resume_setup(
    45     __cfaehm__try_resume_node * node,
     45    struct __cfaehm__try_resume_node * node,
    4646    int (*handler)(exception * except));
    4747void __cfaehm__try_resume_cleanup(
    48     __cfaehm__try_resume_node * node);
     48    struct __cfaehm__try_resume_node * node);
    4949
    5050// Check for a standard way to call fake deconstructors.
  • src/libcfa/fstream

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 18:11:09 2017
    13 // Update Count     : 104
     12// Last Modified On : Sat Jul  1 16:37:53 2017
     13// Update Count     : 112
    1414//
    1515
     
    2424        _Bool sepDefault;
    2525        _Bool sepOnOff;
     26        _Bool lastSepOn;
    2627        const char * sepCur;
    2728        char separator[separateSize];
     
    3536const char * sepGetCur( ofstream * );
    3637void sepSetCur( ofstream *, const char * );
     38_Bool lastSepOn( ofstream * );
    3739
    3840// public
  • src/libcfa/fstream.c

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 18:11:11 2017
    13 // Update Count     : 234
     12// Last Modified On : Sat Jul  1 16:37:54 2017
     13// Update Count     : 242
    1414//
    1515
     
    3333        this->sepDefault = sepDefault;
    3434        this->sepOnOff = sepOnOff;
     35        this->lastSepOn = false;
    3536        sepSet( this, separator );
    3637        sepSetCur( this, sepGet( this ) );
     
    3940
    4041// private
    41 _Bool sepPrt( ofstream * os ) { return os->sepOnOff; }
     42_Bool lastSepOn( ofstream * os ) { return os->lastSepOn; }
     43_Bool sepPrt( ofstream * os ) { os->lastSepOn = false; return os->sepOnOff; }
    4244void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
    4345void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
     
    4648
    4749// public
    48 void sepOn( ofstream * os ) { os->sepOnOff = 1; }
    49 void sepOff( ofstream * os ) { os->sepOnOff = 0; }
     50void sepOn( ofstream * os ) { os->lastSepOn = true; os->sepOnOff = true; }
     51void sepOff( ofstream * os ) { os->lastSepOn = false; os->sepOnOff = 0; }
    5052
    5153_Bool sepDisable( ofstream *os ) {
    5254        _Bool temp = os->sepDefault;
    5355        os->sepDefault = false;
     56        os->lastSepOn = false;
    5457        sepReset( os );
    5558        return temp;
     
    9295                exit( EXIT_FAILURE );
    9396        } // if
    94         ?{}( os, file, 1, 0, " ", ", " );
     97        ?{}( os, file, true, false, " ", ", " );
    9598} // open
    9699
     
    132135} // fmt
    133136
    134 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, " ", ", " };
     137static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), true, false, " ", ", " };
    135138ofstream *sout = &soutFile;
    136 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, " ", ", " };
     139static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), true, false, " ", ", " };
    137140ofstream *serr = &serrFile;
    138141
  • src/libcfa/iostream

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 18:08:44 2017
    13 // Update Count     : 105
     12// Last Modified On : Sun Jul  2 08:42:56 2017
     13// Update Count     : 110
    1414//
    1515
     
    2626        const char * sepGetCur( ostype * );                                     // get current separator string
    2727        void sepSetCur( ostype *, const char * );                       // set current separator string
     28        _Bool lastSepOn( ostype * );                                            // last manipulator is setOn (context sensitive)
    2829        // public
    2930        void sepOn( ostype * );                                                         // turn separator state on
     
    4344        ostype * write( ostype *, const char *, unsigned long int );
    4445        int fmt( ostype *, const char fmt[], ... );
    45 };
     46}; // ostream
    4647
    4748trait writeable( otype T ) {
    4849        forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T );
    49 };
     50}; // writeable
    5051
    5152// implement writable for intrinsic types
     
    103104        istype * ungetc( istype *, char );
    104105        int fmt( istype *, const char fmt[], ... );
    105 };
     106}; // istream
    106107
    107108trait readable( otype T ) {
    108109        forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T );
    109 };
     110}; // readable
    110111
    111112forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, char * );
  • src/libcfa/iostream.c

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May  8 18:24:23 2017
    13 // Update Count     : 369
     12// Last Modified On : Sun Jul  2 08:54:02 2017
     13// Update Count     : 375
    1414//
    1515
     
    201201forall( dtype ostype, otype T, ttype Params | ostream( ostype ) | writeable( T ) | { ostype * ?|?( ostype *, Params ); } )
    202202ostype * ?|?( ostype * os, T arg, Params rest ) {
     203        os | arg;                                                                                       // print first argument
    203204        sepSetCur( os, sepGetTuple( os ) );                                     // switch to tuple separator
    204         os | arg;                                                                                       // print first argument
    205205        os | rest;                                                                                      // print remaining arguments
    206206        sepSetCur( os, sepGet( os ) );                                          // switch to regular separator
     
    217217forall( dtype ostype | ostream( ostype ) )
    218218ostype * endl( ostype * os ) {
     219        if ( lastSepOn( os ) ) fmt( os, "%s", sepGetCur( os ) );
    219220        os | '\n';
    220221        flush( os );
  • src/main.cc

    r11dbfe1 r67fa9f9  
    1111// Created On       : Fri May 15 23:12:02 2015
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Jun 28 21:56:47 2017
    14 // Update Count     : 440
     13// Last Modified On : Thu Jun 29 12:46:50 2017
     14// Update Count     : 441
    1515//
    1616
     
    3939#include "CodeTools/TrackLoc.h"
    4040#include "ControlStruct/Mutate.h"
     41#include "ControlStruct/ExceptTranslate.h"
    4142#include "SymTab/Validate.h"
    4243#include "ResolvExpr/AlternativePrinter.h"
     
    290291                Tuples::expandUniqueExpr( translationUnit );
    291292
     293                OPTPRINT( "translateEHM" );
     294                ControlStruct::translateEHM( translationUnit );
     295
    292296                OPTPRINT( "convertSpecializations" ) // needs to happen before tuple types are expanded
    293297                GenPoly::convertSpecializations( translationUnit );
     
    481485                        break;
    482486                  case '?':
    483                         assertf( false, "Unknown option: '%c'\n", (char)optopt );
     487                        if ( optopt ) {                                                         // short option ?
     488                                assertf( false, "Unknown option: -%c\n", (char)optopt );
     489                        } else {
     490                                assertf( false, "Unknown option: %s\n", argv[optind - 1] );
     491                        } // if
    484492                  default:
    485493                        abort();
  • src/prelude/Makefile.am

    r11dbfe1 r67fa9f9  
    2323noinst_DATA = ../libcfa/libcfa-prelude.c
    2424
     25CC = ${abs_top_srcdir}/src/driver/cfa
     26
    2527$(DEPDIR) :
    2628        mkdir $(DEPDIR)
     
    4547
    4648# create forward declarations for cfa builtins
    47 builtins.cf : builtins.c
    48         ${AM_V_GEN}@BACKEND_CC@ -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
     49builtins.cf : builtins.c ${CC}
     50        ${AM_V_GEN}${CC} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
    4951        ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
    5052
  • src/prelude/Makefile.in

    r11dbfe1 r67fa9f9  
    9595AWK = @AWK@
    9696BACKEND_CC = @BACKEND_CC@
    97 CC = @CC@
     97CC = ${abs_top_srcdir}/src/driver/cfa
    9898CCAS = @CCAS@
    9999CCASDEPMODE = @CCASDEPMODE@
     
    444444
    445445# create forward declarations for cfa builtins
    446 builtins.cf : builtins.c
    447         ${AM_V_GEN}@BACKEND_CC@ -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
     446builtins.cf : builtins.c ${CC}
     447        ${AM_V_GEN}${CC} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
    448448        ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
    449449
  • src/tests/.expect/io.txt

    r11dbfe1 r67fa9f9  
    44123
    55
     6opening delimiters
    67x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
    7 1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
     8
     9closing delimiters
     101, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
     11
     12opening/closing delimiters
    813x`1`x'2'x"3"x:4:x 5 x   6       x
    9147
     
    1419x
    152010
    16 x
     21x
     22
     23override opening/closing delimiters
    1724x ( 1 ) x 2 , x 3 :x: 4
     25
     26input bacis types
     27
     28output basic types
    1829A
    19301 2 3 4 5 6 7 8
     
    21321.1+2.3i 1.1-2.3i 1.1-2.3i
    2233
     34tuples
     351, 2, 3 3, 4, 5
     36
     37toggle separator
    23381.11.21.3
    24391.1+2.3i1.1-2.3i1.1-2.3i
    25  abcxyz
    26 abcxyz
     40 abcxyz 
     41abcxyz 
    2742
     43change separator
     44from "  "to " , $"
    28451.1, $1.2, $1.3
    29461.1+2.3i, $1.1-2.3i, $1.1-2.3i
    30 abc, $xyz
     47abc, $xyz, $
     481, 2, 3, $3, 4, 5
    3149
    32 1, 2, 3, 4
    33 1, $2, $3 ", $"
    34 1 2 3 " "
     50from ", $"to " "
     511.1 1.2 1.3
     521.1+2.3i 1.1-2.3i 1.1-2.3i
     53abc xyz
     541, 2, 3 3, 4, 5
     55
     56 1 2 3
     5712 3
    3558 1 2 3
    36 12 3
     591 2 3
     60 1 2 3
     61
    3762123
    38631 23
    39641 2 3
    40 1 2 3 4 " "
    41 1, 2, 3, 4 ", "
    42 1, 2, 3, 4
     65123
     661 2 3
     67123
     681 2 3
     69
     701 2 3 3 4 5 " "
     711, 2, 3 3, 4, 5 ", "
     721, 2, 3 3, 4, 5
     73
    43743, 4, a, 7.2
    44753, 4, a, 7.2
    45763 4 a 7.2
    4677 3 4 a 7.234a7.23 4 a 7.2
    47 3-4-a-7.2^3^4-3-4-a-7.2
     783-4-a-7.2^3^4^3-4-a-7.2
  • src/tests/io.c

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed Mar  2 16:56:02 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  8 09:52:10 2017
    13 // Update Count     : 51
     12// Last Modified On : Sun Jul  2 09:40:58 2017
     13// Update Count     : 68
    1414//
    1515
     
    4242        sout | endl;
    4343
     44        sout | "opening delimiters" | endl;
    4445        sout
    45                 // opening delimiters
    4646                | "x (" | 1
    4747                | "x [" | 2
     
    5454                | "x ¿" | 9
    5555                | "x «" | 10
    56                 | endl;
     56                | endl | endl;
     57
     58        sout | "closing delimiters" | endl;
    5759        sout
    58                 // closing delimiters
    5960                | 1 | ", x"
    6061                | 2 | ". x"
     
    6869                | 10 | "] x"
    6970                | 11 | "} x"
    70                 | endl;
     71                | endl | endl;
     72
     73        sout | "opening/closing delimiters" | endl;
    7174        sout
    72                 // opening-closing delimiters
    7375                | "x`" | 1 | "`x'" | 2
    7476                | "'x\"" | 3 | "\"x:" | 4
     
    7678                | "\tx\f" | 7 | "\fx\v" | 8
    7779                | "\vx\n" | 9 | "\nx\r" | 10
    78                 | "\rx" |
    79                 endl;
     80                | "\rx"
     81                | endl | endl;
     82
     83        sout | "override opening/closing delimiters" | endl;
    8084        sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
     85        sout | endl;
    8186
    8287        ifstream in;                                                                            // create / open file
    8388        open( &in, "io.data", "r" );
    8489
     90        sout | "input bacis types" | endl;
    8591        &in | &c                                                                                        // character
    8692                | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli     // integral
     
    8894                | &fc | &dc | &ldc                                                              // floating-point complex
    8995                | cstr( s1 ) | cstr( s2, size );                                // C string, length unchecked and checked
     96        sout | endl;
    9097
     98        sout | "output basic types" | endl;
    9199        sout | c | ' ' | endl                                                           // character
    92100                | si | usi | i | ui | li | uli | lli | ulli | endl // integral
     
    94102                | fc | dc | ldc | endl;                                                 // complex
    95103        sout | endl;
     104
     105        sout | "tuples" | endl;
     106        [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
     107        sout | t1 | t2 | endl;                                                          // print tuple
     108        sout | endl;
     109
     110        sout | "toggle separator" | endl;
    96111        sout | f | "" | d | "" | ld | endl                                      // floating point without separator
    97112                | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator
     
    100115        sout | endl;
    101116
     117        sout | "change separator" | endl;
     118        sout | "from \" " | sepGet( sout ) | "\"";
    102119        sepSet( sout, ", $" );                                                          // change separator, maximum of 15 characters
     120        sout | "to \" " | sepGet( sout ) | "\"" | endl;
    103121        sout | f | d | ld | endl
    104122                | fc | dc | ldc | endl
    105                 | s1 | s2 | endl;
     123                | s1 | s2 | endl
     124                | t1 | t2 | endl;                                                               // print tuple
     125        sout | endl;
     126        sout | "from \"" | sepGet( sout ) | "\"";
     127        sepSet( sout, " " );                                                            // restore separator
     128        sout | "to \"" | sepGet( sout ) | "\"" | endl;
     129        sout | f | d | ld | endl
     130                | fc | dc | ldc | endl
     131                | s1 | s2 | endl
     132                | t1 | t2 | endl;                                                               // print tuple
    106133        sout | endl;
    107134
    108         [int, int] t1 = [1, 2], t2 = [3, 4];
    109         sout | t1 | t2 | endl;                                                          // print tuple
    110 
    111         sepSet( sout, " " );
    112         sepSet( sout, ", $" );                                                          // set separator from " " to ", $"
    113         sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
    114         sepSet( sout, " " );                                                            // reset separator to " "
    115         sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
    116 
    117         sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // separator at start of line
     135        sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // separator at start/end of line
    118136        sout | 1 | sepOff | 2 | 3 | endl;                                       // locally turn off implicit separator
     137        sout | sepOn | 1 | 2 | 3 | sepOn | sepOff | endl;       // separator at start of line
     138        sout | 1 | 2 | 3 | endl | sepOn;                                        // separator at start of next line
     139        sout | 1 | 2 | 3 | endl;
     140        sout | endl;
    119141
    120142        sout | sepDisable | 1 | 2 | 3 | endl;                           // globally turn off implicit separation
    121143        sout | 1 | sepOn | 2 | 3 | endl;                                        // locally turn on implicit separator
    122         sout | sepEnable | 1 | 2 | 3 | endl;                            // globally turn on implicit separation
     144        sout | sepEnable | 1 | 2 | 3 | endl | sepDisable;       // globally turn on/off implicit separation
     145        sout | 1 | 2 | 3 | endl | sepEnable;                            // globally turn on implicit separation
     146        sout | 1 | 2 | 3 | sepOn | sepDisable | endl;           // ignore seperate at end of line
     147        sout | 1 | 2 | 3 | sepOn | sepEnable | endl;            // separator at end of line
     148        sout | 1 | 2 | 3 | endl;
     149        sout | endl;
    123150
    124151        sepSetTuple( sout, " " );                                                       // set tuple separator from ", " to " "
     
    126153        sepSetTuple( sout, ", " );                                                      // reset tuple separator to ", "
    127154        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
    128 
    129155        sout | t1 | t2 | endl;                                                          // print tuple
     156        sout | endl;
    130157
    131158        [int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
Note: See TracChangeset for help on using the changeset viewer.