Changeset 800d275


Ignore:
Timestamp:
Aug 29, 2017, 2:54:49 PM (6 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:
235b41f
Parents:
28e58fd (diff), 6454949 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
5 added
1 deleted
46 edited
1 moved

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    r28e58fd r800d275  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon Jul 24 21:02:14 2017
    14 %% Update Count     : 352
     13%% Last Modified On : Mon Aug 28 20:18:42 2017
     14%% Update Count     : 355
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    148148% Latin abbreviation
    149149\newcommand{\abbrevFont}{\textit}       % set empty for no italics
     150\newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.}
    150151\newcommand*{\eg}{%
    151         \@ifnextchar{,}{\abbrevFont{e}.\abbrevFont{g}.}%
    152                 {\@ifnextchar{:}{\abbrevFont{e}.\abbrevFont{g}.}%
    153                         {\abbrevFont{e}.\abbrevFont{g}.,\xspace}}%
    154 }%
     152        \@ifnextchar{,}{\EG}%
     153                {\@ifnextchar{:}{\EG}%
     154                        {\EG,\xspace}}%
     155}%
     156\newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.}
    155157\newcommand*{\ie}{%
    156         \@ifnextchar{,}{\abbrevFont{i}.\abbrevFont{e}.}%
    157                 {\@ifnextchar{:}{\abbrevFont{i}.\abbrevFont{e}.}%
    158                         {\abbrevFont{i}.\abbrevFont{e}.,\xspace}}%
    159 }%
     158        \@ifnextchar{,}{\IE}%
     159                {\@ifnextchar{:}{\IE}%
     160                        {\IE,\xspace}}%
     161}%
     162\newcommand{\ETC}{\abbrevFont{etc}}
    160163\newcommand*{\etc}{%
    161         \@ifnextchar{.}{\abbrevFont{etc}}%
    162         {\abbrevFont{etc}.\xspace}%
    163 }%
     164        \@ifnextchar{.}{\ETC}%
     165        {\ETC\xspace}%
     166}%
     167\newcommand{\ETAL}{\abbrevFont{et\:al}}
    164168\newcommand{\etal}{%
    165         \@ifnextchar{.}{\abbrevFont{et~al}}%
    166                 {\abbrevFont{et al}.\xspace}%
     169        \@ifnextchar{.}{\ETAL}%
     170                {\abbrevFont{\ETAL}.\xspace}%
     171}%
     172\newcommand{\VIZ}{\abbrevFont{viz}}
     173\newcommand{\viz}{%
     174        \@ifnextchar{.}{\VIZ}%
     175                {\abbrevFont{\VIZ}.\xspace}%
    167176}%
    168177\makeatother
  • src/Common/CodeLocation.h

    r28e58fd r800d275  
    99// Author           : Andrew Beach
    1010// Created On       : Thr Aug 17 11:23:00 2017
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 17 14:07:00 2017
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Aug 28 12:46:01 2017
     13// Update Count     : 2
    1414//
    1515
     
    6666
    6767inline std::string to_string( const CodeLocation& location ) {
    68     return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
     68    // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
     69    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + ":1 " : "";
    6970}
    7071
  • src/Common/PassVisitor.h

    r28e58fd r800d275  
    7575        virtual void visit( CatchStmt *catchStmt ) override final;
    7676        virtual void visit( FinallyStmt *finallyStmt ) override final;
     77        virtual void visit( WaitForStmt *waitforStmt ) override final;
    7778        virtual void visit( NullStmt *nullStmt ) override final;
    7879        virtual void visit( DeclStmt *declStmt ) override final;
     
    159160        virtual Statement* mutate( ReturnStmt *returnStmt ) override final;
    160161        virtual Statement* mutate( ThrowStmt *throwStmt ) override final;
    161         virtual Statement* mutate( TryStmt *returnStmt ) override final;
     162        virtual Statement* mutate( TryStmt *tryStmt ) override final;
    162163        virtual Statement* mutate( CatchStmt *catchStmt ) override final;
    163         virtual Statement* mutate( FinallyStmt *catchStmt ) override final;
     164        virtual Statement* mutate( FinallyStmt *finallyStmt ) override final;
     165        virtual Statement* mutate( WaitForStmt *waitforStmt ) override final;
    164166        virtual NullStmt* mutate( NullStmt *nullStmt ) override final;
    165167        virtual Statement* mutate( DeclStmt *declStmt ) override final;
  • src/Common/PassVisitor.impl.h

    r28e58fd r800d275  
    541541}
    542542
     543//--------------------------------------------------------------------------
     544// FinallyStmt
    543545template< typename pass_type >
    544546void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
     
    547549
    548550template< typename pass_type >
     551Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
     552        MUTATE_BODY( Statement, node );
     553}
     554
     555//--------------------------------------------------------------------------
     556// WaitForStmt
     557template< typename pass_type >
     558void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
     559        VISIT_BODY( node );
     560}
     561
     562template< typename pass_type >
     563Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
     564        MUTATE_BODY( Statement, node );
     565}
     566
     567//--------------------------------------------------------------------------
     568// NullStmt
     569template< typename pass_type >
    549570void PassVisitor< pass_type >::visit( NullStmt * node ) {
    550571        VISIT_BODY( node );
     
    552573
    553574template< typename pass_type >
     575NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
     576        MUTATE_BODY( NullStmt, node );
     577}
     578
     579//--------------------------------------------------------------------------
     580// DeclStmt
     581template< typename pass_type >
    554582void PassVisitor< pass_type >::visit( DeclStmt * node ) {
    555583        VISIT_BODY( node );
     
    557585
    558586template< typename pass_type >
     587Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
     588        MUTATE_BODY( Statement, node );
     589}
     590
     591//--------------------------------------------------------------------------
     592// ImplicitCtorDtorStmt
     593template< typename pass_type >
    559594void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
    560595        VISIT_BODY( node );
     
    562597
    563598template< typename pass_type >
     599Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
     600        MUTATE_BODY( Statement, node );
     601}
     602
     603//--------------------------------------------------------------------------
     604// ApplicationExpr
     605template< typename pass_type >
    564606void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
    565607        VISIT_BODY( node );
     608}
     609
     610template< typename pass_type >
     611Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
     612        MUTATE_BODY( Expression, node );
    566613}
    567614
     
    944991
    945992template< typename pass_type >
    946 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    947         MUTATE_BODY( Statement, node );
    948 }
    949 
    950 template< typename pass_type >
    951 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
    952         MUTATE_BODY( NullStmt, node );
    953 }
    954 
    955 template< typename pass_type >
    956 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
    957         MUTATE_BODY( Statement, node );
    958 }
    959 
    960 template< typename pass_type >
    961 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
    962         MUTATE_BODY( Statement, node );
    963 }
    964 
    965 template< typename pass_type >
    966 Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
    967         MUTATE_BODY( Expression, node );
    968 }
    969 
    970 template< typename pass_type >
    971993Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
    972994        MUTATE_BODY( Expression, node );
  • src/Concurrency/Keywords.cc

    r28e58fd r800d275  
    1919#include <string>                  // for string, operator==
    2020
     21#include "Common/PassVisitor.h"    // for PassVisitor
    2122#include "Common/SemanticError.h"  // for SemanticError
    2223#include "Common/utility.h"        // for deleteAll, map_range
     
    4647
    4748        //=============================================================================================
    48         // Visitors declaration
     49        // Pass declarations
    4950        //=============================================================================================
    5051
     
    5859        //                                           static inline NewField_t * getter_name( MyType * this ) { return &this->newField; }
    5960        //
    60         class ConcurrentSueKeyword : public Visitor {
    61           protected:
    62             template< typename Visitor >
    63             friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     61        class ConcurrentSueKeyword : public WithDeclsToAdd {
    6462          public:
    6563
     
    6967                virtual ~ConcurrentSueKeyword() {}
    7068
    71                 using Visitor::visit;
    72                 virtual void visit( StructDecl * decl ) override final;
     69                void postvisit( StructDecl * decl );
    7370
    7471                void handle( StructDecl * );
     
    8683                bool needs_main;
    8784
    88                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    8985                StructDecl* type_decl = nullptr;
    9086        };
     
    117113
    118114                static void implement( std::list< Declaration * > & translationUnit ) {
    119                         ThreadKeyword impl;
    120                         SymTab::acceptAndAdd( translationUnit, impl );
     115                        PassVisitor< ThreadKeyword > impl;
     116                        acceptAll( translationUnit, impl );
    121117                }
    122118        };
     
    148144
    149145                static void implement( std::list< Declaration * > & translationUnit ) {
    150                         CoroutineKeyword impl;
    151                         SymTab::acceptAndAdd( translationUnit, impl );
     146                        PassVisitor< CoroutineKeyword > impl;
     147                        acceptAll( translationUnit, impl );
    152148                }
    153149        };
     
    179175
    180176                static void implement( std::list< Declaration * > & translationUnit ) {
    181                         MonitorKeyword impl;
    182                         SymTab::acceptAndAdd( translationUnit, impl );
     177                        PassVisitor< MonitorKeyword > impl;
     178                        acceptAll( translationUnit, impl );
    183179                }
    184180        };
     
    192188        // }                                                               }
    193189        //
    194         class MutexKeyword final : public Visitor {
     190        class MutexKeyword final {
    195191          public:
    196192
    197                 using Visitor::visit;
    198                 virtual void visit( FunctionDecl * decl ) override final;
    199                 virtual void visit(   StructDecl * decl ) override final;
     193                void postvisit( FunctionDecl * decl );
     194                void postvisit(   StructDecl * decl );
    200195
    201196                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
    202197                void validate( DeclarationWithType * );
    203                 void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);
     198                void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    204199
    205200                static void implement( std::list< Declaration * > & translationUnit ) {
    206                         MutexKeyword impl;
     201                        PassVisitor< MutexKeyword > impl;
    207202                        acceptAll( translationUnit, impl );
    208203                }
     
    211206                StructDecl* monitor_decl = nullptr;
    212207                StructDecl* guard_decl = nullptr;
     208
     209                static std::unique_ptr< Type > generic_func;
    213210        };
     211
     212        std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >(
     213                new FunctionType(
     214                        noQualifiers,
     215                        true
     216                )
     217        );
    214218
    215219        //-----------------------------------------------------------------------------
     
    221225        // }                                                               }
    222226        //
    223         class ThreadStarter final : public Visitor {
     227        class ThreadStarter final {
    224228          public:
    225229
    226                 using Visitor::visit;
    227                 virtual void visit( FunctionDecl * decl ) override final;
     230                void postvisit( FunctionDecl * decl );
    228231
    229232                void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
    230233
    231234                static void implement( std::list< Declaration * > & translationUnit ) {
    232                         ThreadStarter impl;
     235                        PassVisitor< ThreadStarter > impl;
    233236                        acceptAll( translationUnit, impl );
    234237                }
     
    255258        // Generic keyword implementation
    256259        //=============================================================================================
    257         void ConcurrentSueKeyword::visit(StructDecl * decl) {
    258                 Visitor::visit(decl);
     260        void ConcurrentSueKeyword::postvisit(StructDecl * decl) {
    259261                if( decl->get_name() == type_name && decl->has_body() ) {
    260262                        assert( !type_decl );
     
    344346                }
    345347
    346                 declsToAdd.push_back( forward );
    347                 if( needs_main ) declsToAdd.push_back( main_decl );
    348                 declsToAdd.push_back( get_decl );
     348                declsToAddBefore.push_back( forward );
     349                if( needs_main ) declsToAddBefore.push_back( main_decl );
     350                declsToAddBefore.push_back( get_decl );
    349351
    350352                return get_decl;
     
    395397        // Mutex keyword implementation
    396398        //=============================================================================================
    397         void MutexKeyword::visit(FunctionDecl* decl) {
    398                 Visitor::visit(decl);
     399
     400        void MutexKeyword::postvisit(FunctionDecl* decl) {
    399401
    400402                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
     
    411413                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    412414
    413                 addStatments( body, mutexArgs );
    414         }
    415 
    416         void MutexKeyword::visit(StructDecl* decl) {
    417                 Visitor::visit(decl);
     415                addStatments( decl, body, mutexArgs );
     416        }
     417
     418        void MutexKeyword::postvisit(StructDecl* decl) {
    418419
    419420                if( decl->get_name() == "monitor_desc" ) {
     
    458459        }
    459460
    460         void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     461        void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    461462                ObjectDecl * monitors = new ObjectDecl(
    462463                        "__monitors",
     
    489490                );
    490491
     492                assert(generic_func);
     493
    491494                //in reverse order :
    492                 // monitor_guard_t __guard = { __monitors, # };
     495                // monitor_guard_t __guard = { __monitors, #, func };
    493496                body->push_front(
    494497                        new DeclStmt( noLabels, new ObjectDecl(
     
    504507                                        {
    505508                                                new SingleInit( new VariableExpr( monitors ) ),
    506                                                 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
     509                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ),
     510                                                new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
    507511                                        },
    508512                                        noDesignators,
     
    519523        // General entry routine
    520524        //=============================================================================================
    521         void ThreadStarter::visit(FunctionDecl * decl) {
    522                 Visitor::visit(decl);
    523 
     525        void ThreadStarter::postvisit(FunctionDecl * decl) {
    524526                if( ! CodeGen::isConstructor(decl->get_name()) ) return;
    525527
  • src/GenPoly/Box.cc

    r28e58fd r800d275  
    756756                                Type * newType = arg->get_result()->clone();
    757757                                if ( env ) env->apply( newType );
    758                                 std::auto_ptr<Type> manager( newType );
     758                                std::unique_ptr<Type> manager( newType );
    759759                                if ( isPolyType( newType ) ) {
    760760                                        // if the argument's type is polymorphic, we don't need to box again!
     
    774774                                        newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    775775                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    776                                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     776                                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    777777                                        assign->get_args().push_back( new VariableExpr( newObj ) );
    778778                                        assign->get_args().push_back( arg );
  • src/InitTweak/InitTweak.cc

    r28e58fd r800d275  
    325325                        std::string name = getFunctionName( expr );
    326326                        assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
    327                         assertf( ! expr->get_args().empty(), "Can't get called function from dereference with no arguments" );
     327                        assertf( ! expr->get_args().empty(), "Cannot get called function from dereference with no arguments" );
    328328                        return getCalledFunction( expr->get_args().front() );
    329329                }
     
    418418                        assertf( ! tuple->get_exprs().empty(), "TupleAssignExpr somehow has empty tuple expr." );
    419419                        return getCallArg( tuple->get_exprs().front(), pos );
     420                } else if ( ImplicitCopyCtorExpr * copyCtor = dynamic_cast< ImplicitCopyCtorExpr * >( callExpr ) ) {
     421                        return getCallArg( copyCtor->callExpr, pos );
    420422                } else {
    421423                        assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( callExpr ).c_str() );
     
    431433                        std::string name = getFunctionName( expr );
    432434                        assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
    433                         assertf( ! expr->get_args().empty(), "Can't get function name from dereference with no arguments" );
     435                        assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
    434436                        return funcName( expr->get_args().front() );
    435437                }
     
    450452                        } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( func ) ) {
    451453                                return handleDerefName( appExpr );
     454                        } else if ( ConstructorExpr * ctorExpr = dynamic_cast< ConstructorExpr * >( func ) ) {
     455                                return funcName( getCallArg( ctorExpr->get_callExpr(), 0 ) );
    452456                        } else {
    453                                 assertf( false, "Unexpected expression type being called as a function in call expression" );
     457                                assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );
    454458                        }
    455459                }
  • src/Parser/ParseNode.h

    r28e58fd r800d275  
    414414Statement * build_compound( StatementNode * first );
    415415Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
     416WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
     417WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
     418WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
     419WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
    416420
    417421//##############################################################################
  • src/Parser/StatementNode.cc

    r28e58fd r800d275  
    9393                elseb = branches.front();
    9494        } // if
    95        
     95
    9696        std::list< Statement * > init;
    9797        if ( ctl->init != 0 ) {
     
    207207}
    208208
     209WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) {
     210        auto node = new WaitForStmt();
     211
     212        WaitForStmt::Target target;
     213        target.function = maybeBuild<Expression>( targetExpr );
     214
     215        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
     216        targetExpr->set_next( nullptr );
     217        buildMoveList< Expression >( next, target.arguments );
     218
     219        delete targetExpr;
     220
     221        node->clauses.push_back( WaitForStmt::Clause{
     222                target,
     223                maybeMoveBuild<Statement >( stmt ),
     224                maybeMoveBuild<Expression>( when )
     225        });
     226
     227        return node;
     228}
     229
     230WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) {
     231        WaitForStmt::Target target;
     232        target.function = maybeBuild<Expression>( targetExpr );
     233
     234        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
     235        targetExpr->set_next( nullptr );
     236        buildMoveList< Expression >( next, target.arguments );
     237
     238        delete targetExpr;
     239
     240        node->clauses.push_back( WaitForStmt::Clause{
     241                std::move( target ),
     242                maybeMoveBuild<Statement >( stmt ),
     243                maybeMoveBuild<Expression>( when )
     244        });
     245
     246        return node;
     247}
     248
     249WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) {
     250        auto node = new WaitForStmt();
     251
     252        if( timeout ) {
     253                node->timeout.time      = maybeMoveBuild<Expression>( timeout );
     254                node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
     255                node->timeout.condition = maybeMoveBuild<Expression>( when    );
     256        }
     257        else {
     258                node->orelse.statement  = maybeMoveBuild<Statement >( stmt    );
     259                node->orelse.condition  = maybeMoveBuild<Expression>( when    );
     260        }
     261
     262        return node;
     263}
     264
     265WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when,  StatementNode * else_stmt, ExpressionNode * else_when ) {
     266        auto node = new WaitForStmt();
     267
     268        node->timeout.time      = maybeMoveBuild<Expression>( timeout );
     269        node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
     270        node->timeout.condition = maybeMoveBuild<Expression>( when    );
     271
     272        node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
     273        node->orelse.condition = maybeMoveBuild<Expression>( else_when );
     274
     275        return node;
     276}
     277
     278// WaitForStmt::Target build_waitfor( const std::string * name, ExpressionNode * arguments ) {
     279//       return WaitForStmt::Clause{
     280
     281//       };
     282// }
     283
    209284Statement *build_compound( StatementNode *first ) {
    210285        CompoundStmt *cs = new CompoundStmt( noLabels );
  • src/Parser/parser.yy

    r28e58fd r800d275  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 23 21:08:08 2017
    13 // Update Count     : 2704
     12// Last Modified On : Mon Aug 28 13:24:10 2017
     13// Update Count     : 2720
    1414//
    1515
     
    9797        DeclarationNode::TypeClass tclass;
    9898        StatementNode * sn;
     99        WaitForStmt * wfs;
    99100        ConstantExpr * constant;
    100101        IfCtl * ifctl;
     
    119120%token RESTRICT                                                                                 // C99
    120121%token ATOMIC                                                                                   // C11
    121 %token FORALL MUTEX VIRTUAL                                             // CFA
     122%token FORALL MUTEX VIRTUAL                                                             // CFA
    122123%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    123124%token BOOL COMPLEX IMAGINARY                                                   // C99
     
    189190
    190191// statements
    191 %type<sn> labeled_statement                             compound_statement                      expression_statement            selection_statement
    192 %type<sn> iteration_statement                   jump_statement
    193 %type<sn> with_statement                                exception_statement                     asm_statement
    194 %type<sn> when_clause_opt                               waitfor_statement                       waitfor_clause                          waitfor                         timeout
    195 %type<sn> fall_through_opt                              fall_through
    196 %type<sn> statement                                             statement_list
    197 %type<sn> block_item_list                               block_item
    198 %type<sn> with_clause_opt
     192%type<sn> statement                                             labeled_statement                       compound_statement
     193%type<sn> statement_decl                                statement_decl_list                     statement_list_nodecl
     194%type<sn> selection_statement
     195%type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
    199196%type<en> case_value
    200197%type<sn> case_clause                                   case_value_list                         case_label                                      case_label_list
    201 %type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
    202 %type<sn> handler_clause                                finally_clause
     198%type<sn> fall_through                                  fall_through_opt
     199%type<sn> iteration_statement                   jump_statement
     200%type<sn> expression_statement                  asm_statement
     201%type<sn> with_statement                                with_clause_opt
     202%type<sn> exception_statement                   handler_clause                          finally_clause
    203203%type<catch_kind> handler_key
     204%type<en> when_clause                                   when_clause_opt                         waitfor                                         timeout
     205%type<sn> waitfor_statement
     206%type<wfs> waitfor_clause
    204207
    205208// declarations
     
    773776          push push
    774777          local_label_declaration_opt                                           // GCC, local labels
    775           block_item_list                                                                       // C99, intermix declarations and statements
     778          statement_decl_list                                                           // C99, intermix declarations and statements
    776779          pop '}'
    777780                { $$ = new StatementNode( build_compound( $5 ) ); }
    778781        ;
    779782
    780 block_item_list:                                                                                // C99
    781         block_item
    782         | block_item_list push block_item
     783statement_decl_list:                                                                    // C99
     784        statement_decl
     785        | statement_decl_list push statement_decl
    783786                { if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } }
    784787        ;
    785788
    786 block_item:
     789statement_decl:
    787790        declaration                                                                                     // CFA, new & old style declarations
    788791                { $$ = new StatementNode( $1 ); }
     
    802805        ;
    803806
    804 statement_list:
     807statement_list_nodecl:
    805808        statement
    806         | statement_list statement
     809        | statement_list_nodecl statement
    807810                { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
    808811        ;
     
    814817
    815818selection_statement:
    816         IF '(' push if_control_expression ')' statement                         %prec THEN
     819        IF '(' push if_control_expression ')' statement         %prec THEN
    817820                // explicitly deal with the shift/reduce conflict on if/else
    818821                { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); }
     
    889892
    890893switch_clause_list:                                                                             // CFA
    891         case_label_list statement_list
     894        case_label_list statement_list_nodecl
    892895                { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
    893         | switch_clause_list case_label_list statement_list
     896        | switch_clause_list case_label_list statement_list_nodecl
    894897                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
    895898        ;
     
    904907        case_label_list fall_through
    905908                { $$ = $1->append_last_case( $2 ); }
    906         | case_label_list statement_list fall_through_opt
     909        | case_label_list statement_list_nodecl fall_through_opt
    907910                { $$ = $1->append_last_case( new StatementNode( build_compound( (StatementNode *)$2->set_last( $3 ) ) ) ); }
    908911        | choose_clause_list case_label_list fall_through
    909912                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( $3 ))); }
    910         | choose_clause_list case_label_list statement_list fall_through_opt
     913        | choose_clause_list case_label_list statement_list_nodecl fall_through_opt
    911914                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( (StatementNode *)$3->set_last( $4 ) ) ) ) ) ); }
    912915        ;
     
    977980        ;
    978981
     982when_clause:
     983        WHEN '(' comma_expression ')'
     984                { $$ = $3; }
     985        ;
     986
    979987when_clause_opt:
    980988        // empty
    981                 { $$ = nullptr; }                                                               // FIX ME
    982         | WHEN '(' comma_expression ')'
    983                 { $$ = nullptr; }                                                               // FIX ME
     989                { $$ = nullptr; }
     990        | when_clause
    984991        ;
    985992
    986993waitfor:
    987994        WAITFOR '(' identifier ')'
    988                 { $$ = nullptr; }                                                               // FIX ME
     995                {
     996                        $$ = new ExpressionNode( new NameExpr( *$3 ) );
     997                        delete $3;
     998                }
    989999        | WAITFOR '(' identifier ',' argument_expression_list ')'
    990                 { $$ = nullptr; }                                                               // FIX ME
     1000                {
     1001                        $$ = new ExpressionNode( new NameExpr( *$3 ) );
     1002                        $$->set_last( $5 );
     1003                        delete $3;
     1004                }
    9911005        ;
    9921006
    9931007timeout:
    9941008        TIMEOUT '(' comma_expression ')'
    995                 { $$ = nullptr; }                                                               // FIX ME
     1009                { $$ = $3; }
    9961010        ;
    9971011
    9981012waitfor_clause:
    999         when_clause_opt waitfor statement %prec THEN
    1000                 { $$ = nullptr; }                                                               // FIX ME
     1013        when_clause_opt waitfor statement                                       %prec THEN
     1014                { $$ = build_waitfor( $2, $3, $1 ); }
    10011015        | when_clause_opt waitfor statement WOR waitfor_clause
    1002                 { $$ = nullptr; }                                                               // FIX ME
    1003         | when_clause_opt timeout statement %prec THEN
    1004                 { $$ = nullptr; }                                                               // FIX ME
     1016                { $$ = build_waitfor( $2, $3, $1, $5 ); }
     1017        | when_clause_opt timeout statement                                     %prec THEN
     1018                { $$ = build_waitfor_timeout( $2, $3, $1 ); }
    10051019        | when_clause_opt ELSE statement
    1006                 { $$ = nullptr; }                                                               // FIX ME
    1007         | when_clause_opt timeout statement WOR when_clause_opt ELSE statement
    1008                 { $$ = nullptr; }                                                               // FIX ME
     1020                { $$ = build_waitfor_timeout( nullptr, $3, $1 ); }
     1021                // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
     1022        | when_clause_opt timeout statement WOR when_clause ELSE statement
     1023                { $$ = build_waitfor_timeout( $2, $3, $1, $7, $5 ); }
    10091024        ;
    10101025
    10111026waitfor_statement:
    1012         when_clause_opt waitfor statement %prec THEN
    1013                 { $$ = nullptr; }                                                               // FIX ME
     1027        when_clause_opt waitfor statement                                       %prec THEN
     1028                { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); }
    10141029        | when_clause_opt waitfor statement WOR waitfor_clause
    1015                 { $$ = nullptr; }                                                               // FIX ME
     1030                { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); }
    10161031        ;
    10171032
     
    31213136
    31223137void yyerror( const char * ) {
    3123         cout << "Error ";
    31243138        if ( yyfilename ) {
    3125                 cout << "in file " << yyfilename << " ";
     3139                cout << yyfilename << ":";
    31263140        } // if
    3127         cout << "at line " << yylineno << " reading token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << "\"" << endl;
     3141        cout << yylineno << ":1 syntax error at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << "\"" << endl;
    31283142}
    31293143
  • src/ResolvExpr/AlternativeFinder.cc

    r28e58fd r800d275  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 26 11:33:00 2017
    13 // Update Count     : 31
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Aug 28 13:47:24 2017
     13// Update Count     : 32
    1414//
    1515
     
    195195                                AltList winners;
    196196                                findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    197                                 stream << "Can't choose between " << winners.size() << " alternatives for expression ";
     197                                stream << "Cannot choose between " << winners.size() << " alternatives for expression ";
    198198                                expr->print( stream );
    199199                                stream << "Alternatives are:";
     
    286286        }
    287287
    288         Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     288        Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     289                PRINT(
     290                        std::cerr << std::endl << "converting ";
     291                        actualType->print( std::cerr, 8 );
     292                        std::cerr << std::endl << " to ";
     293                        formalType->print( std::cerr, 8 );
     294                        std::cerr << std::endl << "environment is: ";
     295                        env.print( std::cerr, 8 );
     296                        std::cerr << std::endl;
     297                )
     298                Cost convCost = conversionCost( actualType, formalType, indexer, env );
     299                PRINT(
     300                        std::cerr << std::endl << "cost is" << convCost << std::endl;
     301                )
     302                if ( convCost == Cost::infinity ) {
     303                        return convCost;
     304                }
     305                convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
     306                return convCost;
     307        }
     308
     309        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     310                Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
     311                // if ( convCost != Cost::zero ) {
     312
     313                // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
     314                // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
     315                // previous line.
     316                Cost tmpCost = convCost;
     317                tmpCost.incPoly( -tmpCost.get_polyCost() );
     318                if ( tmpCost != Cost::zero ) {
     319                        Type *newType = formalType->clone();
     320                        env.apply( newType );
     321                        actualExpr = new CastExpr( actualExpr, newType );
     322                        // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly
     323                        // inconsistent, once this is fixed it should be possible to resolve the cast.
     324                        // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing.
     325
     326                        // AlternativeFinder finder( indexer, env );
     327                        // finder.findWithAdjustment( actualExpr );
     328                        // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." );
     329                        // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." );
     330                        // Alternative & alt = finder.get_alternatives().front();
     331                        // delete actualExpr;
     332                        // actualExpr = alt.expr->clone();
     333                }
     334                return convCost;
     335        }
     336
     337        Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    289338                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    290339                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
     
    304353                                actualType->print( std::cerr, 8 );
    305354                        )
    306                         Cost actualCost = Cost::zero;
    307355                        if ( formal == formals.end() ) {
    308356                                if ( function->get_isVarArgs() ) {
     
    325373                                std::cerr << std::endl;
    326374                        )
    327                         Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
    328                         PRINT(
    329                                 std::cerr << std::endl << "cost is" << newCost << std::endl;
    330                         )
    331 
    332                         if ( newCost == Cost::infinity ) {
    333                                 return newCost;
    334                         }
    335                         convCost += newCost;
    336                         actualCost += newCost;
    337                         if ( actualCost != Cost::zero ) {
    338                                 Type *newType = formalType->clone();
    339                                 alt.env.apply( newType );
    340                                 *actualExpr = new CastExpr( *actualExpr, newType );
    341                         }
    342                         convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) );
     375                        convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
    343376                        ++formal; // can't be in for-loop update because of the continue
    344377                }
     
    348381
    349382                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    350                         PRINT(
    351                                 std::cerr << std::endl << "converting ";
    352                                 assert->second.actualType->print( std::cerr, 8 );
    353                                 std::cerr << std::endl << " to ";
    354                                 assert->second.formalType->print( std::cerr, 8 );
    355                         )
    356                         Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    357                         PRINT(
    358                                 std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
    359                         )
    360                         if ( newCost == Cost::infinity ) {
    361                                 return newCost;
    362                         }
    363                         convCost += newCost;
    364                         convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) );
     383                        convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    365384                }
    366385
     
    679698
    680699        void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
    681                 bool doneInit = false;
    682                 AlternativeFinder funcOpFinder( indexer, env );
    683 
    684                 AlternativeFinder funcFinder( indexer, env );
    685 
    686700                {
    687701                        std::string fname = InitTweak::getFunctionName( untypedExpr );
     
    696710                }
    697711
     712                AlternativeFinder funcFinder( indexer, env );
    698713                funcFinder.findWithAdjustment( untypedExpr->get_function() );
     714                // if there are no function alternatives, then proceeding is a waste of time.
     715                if ( funcFinder.alternatives.empty() ) return;
     716
    699717                std::list< AlternativeFinder > argAlternatives;
    700718                findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
     
    706724                // if not tuple assignment, assignment is taken care of as a normal function call
    707725                Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
     726
     727                // find function operators
     728                AlternativeFinder funcOpFinder( indexer, env );
     729                NameExpr *opExpr = new NameExpr( "?()" );
     730                try {
     731                        funcOpFinder.findWithAdjustment( opExpr );
     732                } catch( SemanticError &e ) {
     733                        // it's ok if there aren't any defined function ops
     734                }
     735                PRINT(
     736                        std::cerr << "known function ops:" << std::endl;
     737                        printAlts( funcOpFinder.alternatives, std::cerr, 8 );
     738                )
    708739
    709740                AltList candidates;
     
    735766                                                } // if
    736767                                        } // if
    737                                 } else {
    738                                         // seek a function operator that's compatible
    739                                         if ( ! doneInit ) {
    740                                                 doneInit = true;
    741                                                 NameExpr *opExpr = new NameExpr( "?()" );
    742                                                 try {
    743                                                         funcOpFinder.findWithAdjustment( opExpr );
    744                                                 } catch( SemanticError &e ) {
    745                                                         // it's ok if there aren't any defined function ops
    746                                                 }
    747                                                 PRINT(
    748                                                         std::cerr << "known function ops:" << std::endl;
    749                                                         printAlts( funcOpFinder.alternatives, std::cerr, 8 );
    750                                                 )
    751                                         }
    752 
    753                                         for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    754                                                 // check if the type is pointer to function
    755                                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
    756                                                         if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    757                                                                 referenceToRvalueConversion( funcOp->expr );
    758                                                                 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    759                                                                         AltList currentAlt;
    760                                                                         currentAlt.push_back( *func );
    761                                                                         currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    762                                                                         makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
    763                                                                 } // for
    764                                                         } // if
     768                                }
     769
     770                                // try each function operator ?() with the current function alternative and each of the argument combinations
     771                                for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     772                                        // check if the type is pointer to function
     773                                        if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
     774                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     775                                                        referenceToRvalueConversion( funcOp->expr );
     776                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     777                                                                AltList currentAlt;
     778                                                                currentAlt.push_back( *func );
     779                                                                currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
     780                                                                makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
     781                                                        } // for
    765782                                                } // if
    766                                         } // for
    767                                 } // if
     783                                        } // if
     784                                } // for
    768785                        } catch ( SemanticError &e ) {
    769786                                errors.append( e );
     
    776793                // compute conversionsion costs
    777794                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    778                         Cost cvtCost = computeConversionCost( *withFunc, indexer );
     795                        Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );
    779796
    780797                        PRINT(
     
    895912                                // count one safe conversion for each value that is thrown away
    896913                                thisCost.incSafe( discardedValues );
    897 
    898                                 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
     914                                Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
     915                                // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
     916                                // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
     917
     918                                // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
     919                                candidates.emplace_back( std::move( newAlt ) );
    899920                        } // if
    900921                } // for
     
    11391160                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    11401161                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
     1162                                                // convert both options to the conditional result type
     1163                                                newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
     1164                                                newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    11411165                                                newAlt.expr = newExpr;
    11421166                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
  • src/ResolvExpr/CastCost.cc

    r28e58fd r800d275  
    5858                        return Cost::safe;
    5959                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    60                         return convertToReferenceCost( src, refType, indexer, env );
     60                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer & indexer) {
     61                                return ptrsCastable( t1, t2, env, indexer );
     62                        });
    6163                } else {
    6264                        CastCost converter( dest, indexer, env );
  • src/ResolvExpr/ConversionCost.cc

    r28e58fd r800d275  
    4040#define PRINT(x)
    4141#endif
    42 
    4342        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    4443                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     
    7877                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    7978                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    80                         return convertToReferenceCost( src, refType, indexer, env );
     79                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer &){
     80                                return ptrsAssignable( t1, t2, env );
     81                        });
    8182                } else {
    8283                        ConversionCost converter( dest, indexer, env );
     
    9091        }
    9192
    92         Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     93        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    9394                PRINT( std::cerr << "convert to reference cost..." << std::endl; )
    9495                if ( diff > 0 ) {
    9596                        // TODO: document this
    96                         Cost cost = convertToReferenceCost( safe_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env );
     97                        Cost cost = convertToReferenceCost( safe_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env, func );
    9798                        cost.incReference();
    9899                        return cost;
    99100                } else if ( diff < -1 ) {
    100101                        // TODO: document this
    101                         Cost cost = convertToReferenceCost( src, safe_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env );
     102                        Cost cost = convertToReferenceCost( src, safe_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env, func );
    102103                        cost.incReference();
    103104                        return cost;
     
    110111                                        return Cost::safe;
    111112                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    112                                         int assignResult = ptrsAssignable( srcAsRef->get_base(), destAsRef->get_base(), env );
     113                                        int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
    113114                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    114115                                        if ( assignResult < 0 ) {
     
    157158        }
    158159
    159         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     160        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    160161                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    161                 return convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env );
     162                return convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
    162163        }
    163164
  • src/ResolvExpr/ConversionCost.h

    r28e58fd r800d275  
    1616#pragma once
    1717
     18#include <functional>         // for function
     19
    1820#include "Cost.h"             // for Cost
    1921#include "SynTree/Visitor.h"  // for Visitor
     
    2123
    2224namespace SymTab {
    23 class Indexer;
     25        class Indexer;
    2426}  // namespace SymTab
    2527
    2628namespace ResolvExpr {
    27 class TypeEnvironment;
     29        class TypeEnvironment;
    2830
    2931        class ConversionCost : public Visitor {
     
    5557        };
    5658
    57         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     59        typedef std::function<int(Type *, Type *, const TypeEnvironment &, const SymTab::Indexer &)> PtrsFunction;
     60        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
    5861} // namespace ResolvExpr
    5962
  • src/ResolvExpr/Cost.h

    r28e58fd r800d275  
    2828                Cost & incSafe( int inc = 1 );
    2929                Cost & incReference( int inc = 1 );
     30
     31                int get_unsafeCost() const { return unsafeCost; }
     32                int get_polyCost() const { return polyCost; }
     33                int get_safeCost() const { return safeCost; }
     34                int get_referenceCost() const { return referenceCost; }
    3035
    3136                Cost operator+( const Cost &other ) const;
  • src/SymTab/Indexer.cc

    r28e58fd r800d275  
    345345                leaveScope();
    346346
    347                 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
     347                debugPrint( "Adding trait " << aggregateDecl->get_name() << std::endl );
    348348                addTrait( aggregateDecl );
    349349        }
  • src/SymTab/Validate.cc

    r28e58fd r800d275  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Aug  8 13:27:00 2017
    13 // Update Count     : 358
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Aug 28 13:47:23 2017
     13// Update Count     : 359
    1414//
    1515
     
    467467                        return;
    468468                }
     469
     470                // handle other traits
    469471                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
    470472                if ( ! traitDecl ) {
     
    662664                } else {
    663665                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
    664                         assertf( base != typedeclNames.end(), "Can't find typedecl name %s", typeInst->get_name().c_str() );
     666                        assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->get_name().c_str() );
    665667                        typeInst->set_baseType( base->second );
    666668                } // if
  • src/SynTree/Expression.cc

    r28e58fd r800d275  
    645645                }
    646646        }
     647        // ensure that StmtExpr has a result type
     648        if ( ! result ) {
     649                set_result( new VoidType( Type::Qualifiers() ) );
     650        }
    647651}
    648652StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
  • src/SynTree/Mutator.cc

    r28e58fd r800d275  
    3232Mutator::~Mutator() {}
    3333
    34 DeclarationWithType *Mutator::mutate( ObjectDecl *objectDecl ) {
     34DeclarationWithType * Mutator::mutate( ObjectDecl *objectDecl ) {
    3535        objectDecl->set_type( maybeMutate( objectDecl->get_type(), *this ) );
    3636        objectDecl->set_init( maybeMutate( objectDecl->get_init(), *this ) );
     
    3939}
    4040
    41 DeclarationWithType *Mutator::mutate( FunctionDecl *functionDecl ) {
     41DeclarationWithType * Mutator::mutate( FunctionDecl *functionDecl ) {
    4242        functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    4343        functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     
    4545}
    4646
    47 Declaration *Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {
     47Declaration * Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {
    4848        mutateAll( aggregateDecl->get_parameters(), *this );
    4949        mutateAll( aggregateDecl->get_members(), *this );
     
    5151}
    5252
    53 Declaration *Mutator::mutate( StructDecl *aggregateDecl ) {
     53Declaration * Mutator::mutate( StructDecl *aggregateDecl ) {
    5454        handleAggregateDecl( aggregateDecl );
    5555        return aggregateDecl;
    5656}
    5757
    58 Declaration *Mutator::mutate( UnionDecl *aggregateDecl ) {
     58Declaration * Mutator::mutate( UnionDecl *aggregateDecl ) {
    5959        handleAggregateDecl( aggregateDecl );
    6060        return aggregateDecl;
    6161}
    6262
    63 Declaration *Mutator::mutate( EnumDecl *aggregateDecl ) {
     63Declaration * Mutator::mutate( EnumDecl *aggregateDecl ) {
    6464        handleAggregateDecl( aggregateDecl );
    6565        return aggregateDecl;
    6666}
    6767
    68 Declaration *Mutator::mutate( TraitDecl *aggregateDecl ) {
     68Declaration * Mutator::mutate( TraitDecl *aggregateDecl ) {
    6969        handleAggregateDecl( aggregateDecl );
    7070        return aggregateDecl;
    7171}
    7272
    73 Declaration *Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {
     73Declaration * Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {
    7474        mutateAll( typeDecl->get_parameters(), *this );
    7575        mutateAll( typeDecl->get_assertions(), *this );
     
    7878}
    7979
    80 TypeDecl *Mutator::mutate( TypeDecl *typeDecl ) {
     80TypeDecl * Mutator::mutate( TypeDecl *typeDecl ) {
    8181        handleNamedTypeDecl( typeDecl );
    8282        typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) );
     
    8484}
    8585
    86 Declaration *Mutator::mutate( TypedefDecl *typeDecl ) {
     86Declaration * Mutator::mutate( TypedefDecl *typeDecl ) {
    8787        handleNamedTypeDecl( typeDecl );
    8888        return typeDecl;
    8989}
    9090
    91 AsmDecl *Mutator::mutate( AsmDecl *asmDecl ) {
     91AsmDecl * Mutator::mutate( AsmDecl *asmDecl ) {
    9292        asmDecl->set_stmt( maybeMutate( asmDecl->get_stmt(), *this ) );
    9393        return asmDecl;
     
    9595
    9696
    97 CompoundStmt *Mutator::mutate( CompoundStmt *compoundStmt ) {
     97CompoundStmt * Mutator::mutate( CompoundStmt *compoundStmt ) {
    9898        mutateAll( compoundStmt->get_kids(), *this );
    9999        return compoundStmt;
    100100}
    101101
    102 Statement *Mutator::mutate( ExprStmt *exprStmt ) {
     102Statement * Mutator::mutate( ExprStmt *exprStmt ) {
    103103        exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
    104104        return exprStmt;
    105105}
    106106
    107 Statement *Mutator::mutate( AsmStmt *asmStmt ) {
     107Statement * Mutator::mutate( AsmStmt *asmStmt ) {
    108108        asmStmt->set_instruction( maybeMutate( asmStmt->get_instruction(), *this ) );
    109109        mutateAll( asmStmt->get_output(), *this );
     
    113113}
    114114
    115 Statement *Mutator::mutate( IfStmt *ifStmt ) {
     115Statement * Mutator::mutate( IfStmt *ifStmt ) {
    116116        mutateAll( ifStmt->get_initialization(), *this );
    117117        ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) );
     
    121121}
    122122
    123 Statement *Mutator::mutate( WhileStmt *whileStmt ) {
     123Statement * Mutator::mutate( WhileStmt *whileStmt ) {
    124124        whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) );
    125125        whileStmt->set_body( maybeMutate( whileStmt->get_body(), *this ) );
     
    127127}
    128128
    129 Statement *Mutator::mutate( ForStmt *forStmt ) {
     129Statement * Mutator::mutate( ForStmt *forStmt ) {
    130130        mutateAll( forStmt->get_initialization(), *this );
    131131        forStmt->set_condition( maybeMutate( forStmt->get_condition(), *this ) );
     
    135135}
    136136
    137 Statement *Mutator::mutate( SwitchStmt *switchStmt ) {
     137Statement * Mutator::mutate( SwitchStmt *switchStmt ) {
    138138        switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
    139139        mutateAll( switchStmt->get_statements(), *this );
     
    141141}
    142142
    143 Statement *Mutator::mutate( CaseStmt *caseStmt ) {
     143Statement * Mutator::mutate( CaseStmt *caseStmt ) {
    144144        caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
    145145        mutateAll (caseStmt->get_statements(), *this );
     
    148148}
    149149
    150 Statement *Mutator::mutate( BranchStmt *branchStmt ) {
     150Statement * Mutator::mutate( BranchStmt *branchStmt ) {
    151151        return branchStmt;
    152152}
    153153
    154 Statement *Mutator::mutate( ReturnStmt *returnStmt ) {
     154Statement * Mutator::mutate( ReturnStmt *returnStmt ) {
    155155        returnStmt->set_expr( maybeMutate( returnStmt->get_expr(), *this ) );
    156156        return returnStmt;
    157157}
    158158
    159 Statement *Mutator::mutate( ThrowStmt *throwStmt ) {
     159Statement * Mutator::mutate( ThrowStmt *throwStmt ) {
    160160        throwStmt->set_expr( maybeMutate( throwStmt->get_expr(), *this ) );
    161161        throwStmt->set_target( maybeMutate( throwStmt->get_target(), *this ) );
     
    163163}
    164164
    165 Statement *Mutator::mutate( TryStmt *tryStmt ) {
     165Statement * Mutator::mutate( TryStmt *tryStmt ) {
    166166        tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
    167167        mutateAll( tryStmt->get_catchers(), *this );
     
    170170}
    171171
    172 Statement *Mutator::mutate( CatchStmt *catchStmt ) {
     172Statement * Mutator::mutate( CatchStmt *catchStmt ) {
    173173        catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
    174174        catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
     
    177177}
    178178
    179 Statement *Mutator::mutate( FinallyStmt *finalStmt ) {
     179Statement * Mutator::mutate( FinallyStmt *finalStmt ) {
    180180        finalStmt->set_block( maybeMutate( finalStmt->get_block(), *this ) );
    181181        return finalStmt;
    182182}
    183183
    184 NullStmt *Mutator::mutate( NullStmt *nullStmt ) {
     184Statement * Mutator::mutate( WaitForStmt *waitforStmt ) {
     185        for( auto & clause : waitforStmt->clauses ) {
     186                clause.target.function = maybeMutate( clause.target.function, *this );
     187                mutateAll( clause.target.arguments, *this );
     188
     189                clause.statement = maybeMutate( clause.statement, *this );
     190                clause.condition = maybeMutate( clause.condition, *this );
     191        }
     192
     193        waitforStmt->timeout.time      = maybeMutate( waitforStmt->timeout.time, *this );
     194        waitforStmt->timeout.statement = maybeMutate( waitforStmt->timeout.statement, *this );
     195        waitforStmt->timeout.condition = maybeMutate( waitforStmt->timeout.condition, *this );
     196        waitforStmt->orelse.statement  = maybeMutate( waitforStmt->orelse.statement, *this );
     197        waitforStmt->orelse.condition  = maybeMutate( waitforStmt->orelse.condition, *this );
     198
     199        return waitforStmt;
     200}
     201
     202NullStmt * Mutator::mutate( NullStmt *nullStmt ) {
    185203        return nullStmt;
    186204}
    187205
    188 Statement *Mutator::mutate( DeclStmt *declStmt ) {
     206Statement * Mutator::mutate( DeclStmt *declStmt ) {
    189207        declStmt->set_decl( maybeMutate( declStmt->get_decl(), *this ) );
    190208        return declStmt;
    191209}
    192210
    193 Statement *Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
     211Statement * Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
    194212        impCtorDtorStmt->set_callStmt( maybeMutate( impCtorDtorStmt->get_callStmt(), *this ) );
    195213        return impCtorDtorStmt;
     
    197215
    198216
    199 Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
     217Expression * Mutator::mutate( ApplicationExpr *applicationExpr ) {
    200218        applicationExpr->set_env( maybeMutate( applicationExpr->get_env(), *this ) );
    201219        applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) );
     
    205223}
    206224
    207 Expression *Mutator::mutate( UntypedExpr *untypedExpr ) {
     225Expression * Mutator::mutate( UntypedExpr *untypedExpr ) {
    208226        untypedExpr->set_env( maybeMutate( untypedExpr->get_env(), *this ) );
    209227        untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) );
     
    212230}
    213231
    214 Expression *Mutator::mutate( NameExpr *nameExpr ) {
     232Expression * Mutator::mutate( NameExpr *nameExpr ) {
    215233        nameExpr->set_env( maybeMutate( nameExpr->get_env(), *this ) );
    216234        nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) );
     
    218236}
    219237
    220 Expression *Mutator::mutate( AddressExpr *addressExpr ) {
     238Expression * Mutator::mutate( AddressExpr *addressExpr ) {
    221239        addressExpr->set_env( maybeMutate( addressExpr->get_env(), *this ) );
    222240        addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) );
     
    225243}
    226244
    227 Expression *Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
     245Expression * Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
    228246        labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
    229247        labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
     
    232250}
    233251
    234 Expression *Mutator::mutate( CastExpr *castExpr ) {
     252Expression * Mutator::mutate( CastExpr *castExpr ) {
    235253        castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
    236254        castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
     
    239257}
    240258
    241 Expression *Mutator::mutate( VirtualCastExpr *castExpr ) {
     259Expression * Mutator::mutate( VirtualCastExpr *castExpr ) {
    242260        castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
    243261        castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
     
    246264}
    247265
    248 Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) {
     266Expression * Mutator::mutate( UntypedMemberExpr *memberExpr ) {
    249267        memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
    250268        memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
     
    254272}
    255273
    256 Expression *Mutator::mutate( MemberExpr *memberExpr ) {
     274Expression * Mutator::mutate( MemberExpr *memberExpr ) {
    257275        memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
    258276        memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
     
    261279}
    262280
    263 Expression *Mutator::mutate( VariableExpr *variableExpr ) {
     281Expression * Mutator::mutate( VariableExpr *variableExpr ) {
    264282        variableExpr->set_env( maybeMutate( variableExpr->get_env(), *this ) );
    265283        variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) );
     
    267285}
    268286
    269 Expression *Mutator::mutate( ConstantExpr *constantExpr ) {
     287Expression * Mutator::mutate( ConstantExpr *constantExpr ) {
    270288        constantExpr->set_env( maybeMutate( constantExpr->get_env(), *this ) );
    271289        constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) );
     
    274292}
    275293
    276 Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) {
     294Expression * Mutator::mutate( SizeofExpr *sizeofExpr ) {
    277295        sizeofExpr->set_env( maybeMutate( sizeofExpr->get_env(), *this ) );
    278296        sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) );
     
    285303}
    286304
    287 Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
     305Expression * Mutator::mutate( AlignofExpr *alignofExpr ) {
    288306        alignofExpr->set_env( maybeMutate( alignofExpr->get_env(), *this ) );
    289307        alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) );
     
    296314}
    297315
    298 Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
     316Expression * Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
    299317        offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) );
    300318        offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
     
    303321}
    304322
    305 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
     323Expression * Mutator::mutate( OffsetofExpr *offsetofExpr ) {
    306324        offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) );
    307325        offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
     
    311329}
    312330
    313 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
     331Expression * Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
    314332        offsetPackExpr->set_env( maybeMutate( offsetPackExpr->get_env(), *this ) );
    315333        offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) );
     
    318336}
    319337
    320 Expression *Mutator::mutate( AttrExpr *attrExpr ) {
     338Expression * Mutator::mutate( AttrExpr *attrExpr ) {
    321339        attrExpr->set_env( maybeMutate( attrExpr->get_env(), *this ) );
    322340        attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) );
     
    329347}
    330348
    331 Expression *Mutator::mutate( LogicalExpr *logicalExpr ) {
     349Expression * Mutator::mutate( LogicalExpr *logicalExpr ) {
    332350        logicalExpr->set_env( maybeMutate( logicalExpr->get_env(), *this ) );
    333351        logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) );
     
    337355}
    338356
    339 Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) {
     357Expression * Mutator::mutate( ConditionalExpr *conditionalExpr ) {
    340358        conditionalExpr->set_env( maybeMutate( conditionalExpr->get_env(), *this ) );
    341359        conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) );
     
    346364}
    347365
    348 Expression *Mutator::mutate( CommaExpr *commaExpr ) {
     366Expression * Mutator::mutate( CommaExpr *commaExpr ) {
    349367        commaExpr->set_env( maybeMutate( commaExpr->get_env(), *this ) );
    350368        commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) );
     
    354372}
    355373
    356 Expression *Mutator::mutate( TypeExpr *typeExpr ) {
     374Expression * Mutator::mutate( TypeExpr *typeExpr ) {
    357375        typeExpr->set_env( maybeMutate( typeExpr->get_env(), *this ) );
    358376        typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) );
     
    361379}
    362380
    363 Expression *Mutator::mutate( AsmExpr *asmExpr ) {
     381Expression * Mutator::mutate( AsmExpr *asmExpr ) {
    364382        asmExpr->set_env( maybeMutate( asmExpr->get_env(), *this ) );
    365383        asmExpr->set_inout( maybeMutate( asmExpr->get_inout(), *this ) );
     
    386404}
    387405
    388 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
     406Expression * Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
    389407        compLitExpr->set_env( maybeMutate( compLitExpr->get_env(), *this ) );
    390408        compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) );
     
    393411}
    394412
    395 Expression *Mutator::mutate( RangeExpr *rangeExpr ) {
     413Expression * Mutator::mutate( RangeExpr *rangeExpr ) {
    396414        rangeExpr->set_env( maybeMutate( rangeExpr->get_env(), *this ) );
    397415        rangeExpr->set_low( maybeMutate( rangeExpr->get_low(), *this ) );
     
    400418}
    401419
    402 Expression *Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
     420Expression * Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
    403421        tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    404422        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
     
    407425}
    408426
    409 Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
     427Expression * Mutator::mutate( TupleExpr *tupleExpr ) {
    410428        tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    411429        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
     
    414432}
    415433
    416 Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
     434Expression * Mutator::mutate( TupleIndexExpr *tupleExpr ) {
    417435        tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    418436        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
     
    421439}
    422440
    423 Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
     441Expression * Mutator::mutate( TupleAssignExpr *assignExpr ) {
    424442        assignExpr->set_env( maybeMutate( assignExpr->get_env(), *this ) );
    425443        assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
     
    428446}
    429447
    430 Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
     448Expression * Mutator::mutate( StmtExpr *stmtExpr ) {
    431449        stmtExpr->set_env( maybeMutate( stmtExpr->get_env(), *this ) );
    432450        stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
     
    437455}
    438456
    439 Expression *Mutator::mutate( UniqueExpr *uniqueExpr ) {
     457Expression * Mutator::mutate( UniqueExpr *uniqueExpr ) {
    440458        uniqueExpr->set_env( maybeMutate( uniqueExpr->get_env(), *this ) );
    441459        uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) );
     
    444462}
    445463
    446 Expression *Mutator::mutate( UntypedInitExpr * initExpr ) {
     464Expression * Mutator::mutate( UntypedInitExpr * initExpr ) {
    447465        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
    448466        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     
    452470}
    453471
    454 Expression *Mutator::mutate( InitExpr * initExpr ) {
     472Expression * Mutator::mutate( InitExpr * initExpr ) {
    455473        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
    456474        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     
    461479
    462480
    463 Type *Mutator::mutate( VoidType *voidType ) {
     481Type * Mutator::mutate( VoidType *voidType ) {
    464482        mutateAll( voidType->get_forall(), *this );
    465483        return voidType;
    466484}
    467485
    468 Type *Mutator::mutate( BasicType *basicType ) {
     486Type * Mutator::mutate( BasicType *basicType ) {
    469487        mutateAll( basicType->get_forall(), *this );
    470488        return basicType;
    471489}
    472490
    473 Type *Mutator::mutate( PointerType *pointerType ) {
     491Type * Mutator::mutate( PointerType *pointerType ) {
    474492        mutateAll( pointerType->get_forall(), *this );
    475493        pointerType->set_base( maybeMutate( pointerType->get_base(), *this ) );
     
    477495}
    478496
    479 Type *Mutator::mutate( ArrayType *arrayType ) {
     497Type * Mutator::mutate( ArrayType *arrayType ) {
    480498        mutateAll( arrayType->get_forall(), *this );
    481499        arrayType->set_dimension( maybeMutate( arrayType->get_dimension(), *this ) );
     
    484502}
    485503
    486 Type *Mutator::mutate( ReferenceType *refType ) {
     504Type * Mutator::mutate( ReferenceType * refType ) {
    487505        mutateAll( refType->get_forall(), *this );
    488506        refType->set_base( maybeMutate( refType->get_base(), *this ) );
     
    490508}
    491509
    492 Type *Mutator::mutate( FunctionType *functionType ) {
     510Type * Mutator::mutate( FunctionType * functionType ) {
    493511        mutateAll( functionType->get_forall(), *this );
    494512        mutateAll( functionType->get_returnVals(), *this );
     
    497515}
    498516
    499 Type *Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {
     517Type * Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {
    500518        mutateAll( aggregateUseType->get_forall(), *this );
    501519        mutateAll( aggregateUseType->get_parameters(), *this );
     
    503521}
    504522
    505 Type *Mutator::mutate( StructInstType *aggregateUseType ) {
     523Type * Mutator::mutate( StructInstType *aggregateUseType ) {
    506524        handleReferenceToType( aggregateUseType );
    507525        return aggregateUseType;
    508526}
    509527
    510 Type *Mutator::mutate( UnionInstType *aggregateUseType ) {
     528Type * Mutator::mutate( UnionInstType *aggregateUseType ) {
    511529        handleReferenceToType( aggregateUseType );
    512530        return aggregateUseType;
    513531}
    514532
    515 Type *Mutator::mutate( EnumInstType *aggregateUseType ) {
     533Type * Mutator::mutate( EnumInstType *aggregateUseType ) {
    516534        handleReferenceToType( aggregateUseType );
    517535        return aggregateUseType;
    518536}
    519537
    520 Type *Mutator::mutate( TraitInstType *aggregateUseType ) {
     538Type * Mutator::mutate( TraitInstType *aggregateUseType ) {
    521539        handleReferenceToType( aggregateUseType );
    522540        mutateAll( aggregateUseType->get_members(), *this );
     
    524542}
    525543
    526 Type *Mutator::mutate( TypeInstType *aggregateUseType ) {
     544Type * Mutator::mutate( TypeInstType *aggregateUseType ) {
    527545        handleReferenceToType( aggregateUseType );
    528546        return aggregateUseType;
    529547}
    530548
    531 Type *Mutator::mutate( TupleType *tupleType ) {
     549Type * Mutator::mutate( TupleType *tupleType ) {
    532550        mutateAll( tupleType->get_forall(), *this );
    533551        mutateAll( tupleType->get_types(), *this );
     
    536554}
    537555
    538 Type *Mutator::mutate( TypeofType *typeofType ) {
     556Type * Mutator::mutate( TypeofType *typeofType ) {
    539557        assert( typeofType->get_expr() );
    540558        typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) );
     
    542560}
    543561
    544 Type *Mutator::mutate( AttrType *attrType ) {
     562Type * Mutator::mutate( AttrType *attrType ) {
    545563        if ( attrType->get_isType() ) {
    546564                assert( attrType->get_type() );
     
    553571}
    554572
    555 Type *Mutator::mutate( VarArgsType *varArgsType ) {
     573Type * Mutator::mutate( VarArgsType *varArgsType ) {
    556574        mutateAll( varArgsType->get_forall(), *this );
    557575        return varArgsType;
    558576}
    559577
    560 Type *Mutator::mutate( ZeroType *zeroType ) {
     578Type * Mutator::mutate( ZeroType *zeroType ) {
    561579        mutateAll( zeroType->get_forall(), *this );
    562580        return zeroType;
    563581}
    564582
    565 Type *Mutator::mutate( OneType *oneType ) {
     583Type * Mutator::mutate( OneType *oneType ) {
    566584        mutateAll( oneType->get_forall(), *this );
    567585        return oneType;
     
    569587
    570588
    571 Designation *Mutator::mutate( Designation * designation ) {
     589Designation * Mutator::mutate( Designation * designation ) {
    572590        mutateAll( designation->get_designators(), *this );
    573591        return designation;
    574592}
    575593
    576 Initializer *Mutator::mutate( SingleInit *singleInit ) {
     594Initializer * Mutator::mutate( SingleInit *singleInit ) {
    577595        singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
    578596        return singleInit;
    579597}
    580598
    581 Initializer *Mutator::mutate( ListInit *listInit ) {
     599Initializer * Mutator::mutate( ListInit *listInit ) {
    582600        mutateAll( listInit->get_designations(), *this );
    583601        mutateAll( listInit->get_initializers(), *this );
     
    585603}
    586604
    587 Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
     605Initializer * Mutator::mutate( ConstructorInit *ctorInit ) {
    588606        ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
    589607        ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) );
     
    593611
    594612
    595 Subrange *Mutator::mutate( Subrange *subrange ) {
     613Subrange * Mutator::mutate( Subrange *subrange ) {
    596614        return subrange;
    597615}
    598616
    599617
    600 Constant *Mutator::mutate( Constant *constant ) {
     618Constant * Mutator::mutate( Constant *constant ) {
    601619        return constant;
    602620}
  • src/SynTree/Mutator.h

    r28e58fd r800d275  
    4949        virtual Statement* mutate( CatchStmt *catchStmt );
    5050        virtual Statement* mutate( FinallyStmt *catchStmt );
     51        virtual Statement* mutate( WaitForStmt *waitforStmt );
    5152        virtual NullStmt* mutate( NullStmt *nullStmt );
    5253        virtual Statement* mutate( DeclStmt *declStmt );
  • src/SynTree/Statement.cc

    r28e58fd r800d275  
    419419}
    420420
     421WaitForStmt::WaitForStmt( std::list<Label> labels ) : Statement( labels ) {
     422        timeout.time      = nullptr;
     423        timeout.statement = nullptr;
     424        timeout.condition = nullptr;
     425        orelse .statement = nullptr;
     426        orelse .condition = nullptr;
     427}
     428
     429WaitForStmt::WaitForStmt( const WaitForStmt & other ) : Statement( other ) {
     430        clauses.reserve( other.clauses.size() );
     431        for( auto & ocl : other.clauses ) {
     432                clauses.emplace_back();
     433                clauses.back().target.function = ocl.target.function->clone();
     434                cloneAll( ocl.target.arguments, clauses.back().target.arguments );
     435                clauses.back().statement = ocl.statement->clone();
     436                clauses.back().condition = ocl.condition->clone();
     437        }
     438
     439        timeout.time      = other.timeout.time     ->clone();
     440        timeout.statement = other.timeout.statement->clone();
     441        timeout.condition = other.timeout.condition->clone();
     442        orelse .statement = other.orelse .statement->clone();
     443        orelse .condition = other.orelse .condition->clone();
     444}
     445
     446WaitForStmt::~WaitForStmt() {
     447        for( auto & clause : clauses ) {
     448                delete clause.target.function;
     449                deleteAll( clause.target.arguments );
     450                delete clause.statement;
     451                delete clause.condition;
     452        }
     453
     454        delete timeout.time;
     455        delete timeout.statement;
     456        delete timeout.condition;
     457
     458        delete orelse.statement;
     459        delete orelse.condition;
     460}
     461
     462void WaitForStmt::print( std::ostream &os, int indent ) const {
     463        os << "Waitfor Statement" << endl;
     464        os << string( indent + 2, ' ' ) << "with block:" << endl;
     465        os << string( indent + 4, ' ' );
     466        // block->print( os, indent + 4 );
     467}
     468
    421469NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}
    422470NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}
  • src/SynTree/Statement.h

    r28e58fd r800d275  
    1919#include <list>                    // for list
    2020#include <memory>                  // for allocator
     21#include <vector>                        // for vector
    2122
    2223#include "BaseSyntaxNode.h"        // for BaseSyntaxNode
     
    392393};
    393394
     395class WaitForStmt : public Statement {
     396  public:
     397
     398        struct Target {
     399                Expression * function;
     400                std::list<Expression * > arguments;
     401        };
     402
     403        struct Clause {
     404                Target       target;
     405                Statement  * statement;
     406                Expression * condition;
     407        };
     408
     409        WaitForStmt( std::list<Label> labels = noLabels );
     410        WaitForStmt( const WaitForStmt & );
     411        virtual ~WaitForStmt();
     412
     413        std::vector<Clause> clauses;
     414
     415        struct {
     416                Expression * time;
     417                Statement  * statement;
     418                Expression * condition;
     419        } timeout;
     420
     421        struct {
     422                Statement  * statement;
     423                Expression * condition;
     424        } orelse;
     425
     426        virtual WaitForStmt *clone() const { return new WaitForStmt( *this ); }
     427        virtual void accept( Visitor &v ) { v.visit( this ); }
     428        virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     429        virtual void print( std::ostream &os, int indent = 0 ) const;
     430
     431};
     432
    394433
    395434// represents a declaration that occurs as part of a compound statement
  • src/SynTree/SynTree.h

    r28e58fd r800d275  
    5454class CatchStmt;
    5555class FinallyStmt;
     56class WaitForStmt;
    5657class NullStmt;
    5758class DeclStmt;
  • src/SynTree/Visitor.cc

    r28e58fd r800d275  
    155155}
    156156
     157void Visitor::visit( WaitForStmt *waitforStmt ) {
     158        for( auto & clause : waitforStmt->clauses ) {
     159                maybeAccept( clause.target.function, *this );
     160                acceptAll( clause.target.arguments, *this );
     161
     162                maybeAccept( clause.statement, *this );
     163                maybeAccept( clause.condition, *this );
     164        }
     165
     166        maybeAccept( waitforStmt->timeout.time, *this );
     167        maybeAccept( waitforStmt->timeout.statement, *this );
     168        maybeAccept( waitforStmt->timeout.condition, *this );
     169        maybeAccept( waitforStmt->orelse.statement, *this );
     170        maybeAccept( waitforStmt->orelse.condition, *this );
     171}
     172
    157173void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) {
    158174}
  • src/SynTree/Visitor.h

    r28e58fd r800d275  
    5151        virtual void visit( CatchStmt *catchStmt );
    5252        virtual void visit( FinallyStmt *finallyStmt );
     53        virtual void visit( WaitForStmt *waitforStmt );
    5354        virtual void visit( NullStmt *nullStmt );
    5455        virtual void visit( DeclStmt *declStmt );
  • src/libcfa/Makefile.am

    r28e58fd r800d275  
    3636         ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $<
    3737
    38 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
     38EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
    3939
    4040AM_CCASFLAGS = @CFA_FLAGS@
  • src/libcfa/Makefile.in

    r28e58fd r800d275  
    416416ARFLAGS = cr
    417417lib_LIBRARIES = $(am__append_1) $(am__append_2)
    418 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
     418EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
    419419AM_CCASFLAGS = @CFA_FLAGS@
    420420headers = fstream iostream iterator limits rational stdlib \
  • src/libcfa/concurrency/invoke.h

    r28e58fd r800d275  
    2828      #define thread_local _Thread_local
    2929
     30      typedef void (*fptr_t)();
     31
    3032      struct spinlock {
    3133            volatile int lock;
     
    5052            void append( struct __thread_queue_t *, struct thread_desc * );
    5153            struct thread_desc * pop_head( struct __thread_queue_t * );
     54            struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** );
    5255
    5356            void ?{}( struct __condition_stack_t & );
     
    8790            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    8891            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    89       };
     92
     93            struct __acceptable_t * acceptables;      // list of acceptable functions, null if any
     94            unsigned short acceptable_count;          // number of acceptable functions
     95            short accepted_index;                     // the index of the accepted function, -1 if none
     96       };
    9097
    9198      struct thread_desc {
     99            // Core threading fields
    92100            struct coroutine_desc cor;                // coroutine body used to store context
    93101            struct monitor_desc mon;                  // monitor body used for mutual exclusion
     102
     103            // Link lists fields
    94104            struct thread_desc * next;                // instrusive link field for threads
     105
     106            // Current status related to monitors
    95107            struct monitor_desc ** current_monitors;  // currently held monitors
    96108            unsigned short current_monitor_count;     // number of currently held monitors
    97       };
     109            fptr_t current_monitor_func;              // last function that acquired monitors
     110     };
    98111
    99112#endif //_INVOKE_H_
  • src/libcfa/concurrency/kernel.c

    r28e58fd r800d275  
    322322void ScheduleThread( thread_desc * thrd ) {
    323323        // if( !thrd ) return;
    324         assert( thrd );
    325         assert( thrd->cor.state != Halted );
     324        verify( thrd );
     325        verify( thrd->cor.state != Halted );
    326326
    327327        verify( disable_preempt_count > 0 );
     
    366366
    367367void BlockInternal( thread_desc * thrd ) {
     368        assert(thrd);
    368369        disable_interrupts();
    369370        assert( thrd->cor.state != Halted );
     
    379380
    380381void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     382        assert(thrd);
    381383        disable_interrupts();
    382384        this_processor->finish.action_code = Release_Schedule;
     
    666668}
    667669
     670thread_desc * remove( __thread_queue_t * this, thread_desc ** it ) {
     671        thread_desc * thrd = *it;
     672        verify( thrd );
     673
     674        (*it) = thrd->next;
     675
     676        if( this->tail == &thrd->next ) {
     677                this->tail = it;
     678        }
     679
     680        thrd->next = NULL;
     681
     682        verify( (this->head == NULL) == (&this->head == this->tail) );
     683        verify( *this->tail == NULL );
     684        return thrd;
     685}
     686
    668687void ?{}( __condition_stack_t & this ) {
    669688        this.top = NULL;
  • src/libcfa/concurrency/monitor

    r28e58fd r800d275  
    2323
    2424static inline void ?{}(monitor_desc & this) {
     25        (this.lock){};
    2526        this.owner = NULL;
     27        (this.entry_queue){};
     28        (this.signal_stack){};
    2629        this.recursion = 0;
     30        this.acceptables = NULL;
     31        this.acceptable_count = 0;
     32        this.accepted_index = -1;
    2733}
    2834
     
    3238        monitor_desc ** prev_mntrs;
    3339        unsigned short  prev_count;
     40        fptr_t          prev_func;
    3441};
    3542
     
    3845}
    3946
    40 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count );
     47void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
    4148void ^?{}( monitor_guard_t & this );
    4249
     
    8996uintptr_t front( condition * this );
    9097
     98//-----------------------------------------------------------------------------
     99// External scheduling
     100
    91101struct __acceptable_t {
    92         void (*func)(void);
     102        fptr_t func;
    93103        unsigned short count;
    94         monitor_desc * monitors[1];
     104        monitor_desc ** monitors;
    95105};
    96106
    97 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) );
     107int __accept_internal( unsigned short count, __acceptable_t * acceptables );
    98108
    99109// Local Variables: //
  • src/libcfa/concurrency/monitor.c

    r28e58fd r800d275  
    2525static inline void set_owner( monitor_desc * this, thread_desc * owner );
    2626static inline thread_desc * next_thread( monitor_desc * this );
     27static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() );
    2728
    2829static inline void lock_all( spinlock ** locks, unsigned short count );
     
    3435static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count );
    3536
     37static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     38static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     39
    3640static inline thread_desc * check_condition( __condition_criterion_t * );
    3741static inline void brand_condition( condition * );
    3842static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
    3943
     44static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );
     45
     46//-----------------------------------------------------------------------------
     47// Useful defines
     48#define wait_ctx(thrd, user_info)                               /* Create the necessary information to use the signaller stack       */ \
     49        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                   */ \
     50        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up          */ \
     51        init( count, monitors, &waiter, criteria );               /* Link everything together                                          */ \
     52
     53#define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack       */ \
     54        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                   */ \
     55        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up          */ \
     56        init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack              */ \
     57
     58#define monitor_ctx( mons, cnt )              /* Define that create the necessary struct for internal/external scheduling operations */ \
     59        monitor_desc ** monitors = mons;        /* Save the targeted monitors                                                          */ \
     60        unsigned short count = cnt;             /* Save the count to a local variable                                                  */ \
     61        unsigned int recursions[ count ];       /* Save the current recursion levels to restore them later                             */ \
     62        spinlock *   locks     [ count ];       /* We need to pass-in an array of locks to BlockInternal                               */ \
     63
    4064//-----------------------------------------------------------------------------
    4165// Enter/Leave routines
     
    4367
    4468extern "C" {
    45         void __enter_monitor_desc( monitor_desc * this ) {
     69        // Enter single monitor
     70        static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
     71                // Lock the monitor spinlock, lock_yield to reduce contention
    4672                lock_yield( &this->lock DEBUG_CTX2 );
    4773                thread_desc * thrd = this_thread;
    4874
    49                 // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    50 
     75                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     76
     77                this->accepted_index = -1;
    5178                if( !this->owner ) {
    52                         //No one has the monitor, just take it
     79                        // No one has the monitor, just take it
    5380                        set_owner( this, thrd );
     81
     82                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon is free \n");
    5483                }
    5584                else if( this->owner == thrd) {
    56                         //We already have the monitor, just not how many times we took it
     85                        // We already have the monitor, just not how many times we took it
    5786                        verify( this->recursion > 0 );
    5887                        this->recursion += 1;
     88
     89                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
     90                }
     91                else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) {
     92                        // Some one was waiting for us, enter
     93                        set_owner( this, thrd );
     94
     95                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts \n");
    5996                }
    6097                else {
    61                         //Some one else has the monitor, wait in line for it
     98                        LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
     99
     100                        // Some one else has the monitor, wait in line for it
    62101                        append( &this->entry_queue, thrd );
    63                         // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    64102                        BlockInternal( &this->lock );
    65103
    66                         //BlockInternal will unlock spinlock, no need to unlock ourselves
     104                        LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
     105
     106                        // BlockInternal will unlock spinlock, no need to unlock ourselves
    67107                        return;
    68108                }
    69109
     110                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
     111
     112                // Release the lock and leave
    70113                unlock( &this->lock );
    71114                return;
    72115        }
    73116
    74         // leave pseudo code :
    75         //      TODO
     117        // Leave single monitor
    76118        void __leave_monitor_desc( monitor_desc * this ) {
     119                // Lock the monitor spinlock, lock_yield to reduce contention
    77120                lock_yield( &this->lock DEBUG_CTX2 );
    78121
    79                 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);
    80122                verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
    81123
    82                 //Leaving a recursion level, decrement the counter
     124                // Leaving a recursion level, decrement the counter
    83125                this->recursion -= 1;
    84126
    85                 //If we haven't left the last level of recursion
    86                 //it means we don't need to do anything
     127                // If we haven't left the last level of recursion
     128                // it means we don't need to do anything
    87129                if( this->recursion != 0) {
    88130                        unlock( &this->lock );
     
    90132                }
    91133
     134                // Get the next thread, will be null on low contention monitor
    92135                thread_desc * new_owner = next_thread( this );
    93136
    94                 //We can now let other threads in safely
     137                // We can now let other threads in safely
    95138                unlock( &this->lock );
    96 
    97                 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
    98139
    99140                //We need to wake-up the thread
     
    101142        }
    102143
     144        // Leave the thread monitor
     145        // last routine called by a thread.
     146        // Should never return
    103147        void __leave_thread_monitor( thread_desc * thrd ) {
    104148                monitor_desc * this = &thrd->mon;
     149
     150                // Lock the monitor now
    105151                lock_yield( &this->lock DEBUG_CTX2 );
    106152
     
    111157                verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
    112158
    113                 //Leaving a recursion level, decrement the counter
     159                // Leaving a recursion level, decrement the counter
    114160                this->recursion -= 1;
    115161
    116                 //If we haven't left the last level of recursion
    117                 //it means we don't need to do anything
    118                 if( this->recursion != 0) {
    119                         unlock( &this->lock );
    120                         return;
    121                 }
    122 
     162                // If we haven't left the last level of recursion
     163                // it must mean there is an error
     164                if( this->recursion != 0) { abortf("Thread internal monitor has unbalanced recursion"); }
     165
     166                // Fetch the next thread, can be null
    123167                thread_desc * new_owner = next_thread( this );
    124168
     169                // Leave the thread, this will unlock the spinlock
     170                // Use leave thread instead of BlockInternal which is
     171                // specialized for this case and supports null new_owner
    125172                LeaveThread( &this->lock, new_owner );
    126         }
    127 }
    128 
    129 static inline void enter(monitor_desc ** monitors, int count) {
     173
     174                // Control flow should never reach here!
     175        }
     176}
     177
     178// Enter multiple monitor
     179// relies on the monitor array being sorted
     180static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) {
    130181        for(int i = 0; i < count; i++) {
    131                 __enter_monitor_desc( monitors[i] );
    132         }
    133 }
    134 
     182                __enter_monitor_desc( monitors[i], monitors, count, func );
     183        }
     184}
     185
     186// Leave multiple monitor
     187// relies on the monitor array being sorted
    135188static inline void leave(monitor_desc ** monitors, int count) {
    136189        for(int i = count - 1; i >= 0; i--) {
     
    139192}
    140193
    141 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count ) {
     194// Ctor for monitor guard
     195// Sorts monitors before entering
     196void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
     197        // Store current array
    142198        this.m = m;
    143199        this.count = count;
     200
     201        // Sort monitors based on address -> TODO use a sort specialized for small numbers
    144202        qsort(this.m, count);
    145         enter( this.m, this.count );
    146 
     203
     204        // Save previous thread context
    147205        this.prev_mntrs = this_thread->current_monitors;
    148206        this.prev_count = this_thread->current_monitor_count;
    149 
     207        this.prev_func  = this_thread->current_monitor_func;
     208
     209        // Update thread context (needed for conditions)
    150210        this_thread->current_monitors      = m;
    151211        this_thread->current_monitor_count = count;
    152 }
    153 
     212        this_thread->current_monitor_func  = func;
     213
     214        // Enter the monitors in order
     215        enter( this.m, this.count, func );
     216}
     217
     218
     219// Dtor for monitor guard
    154220void ^?{}( monitor_guard_t & this ) {
     221        // Leave the monitors in order
    155222        leave( this.m, this.count );
    156223
     224        // Restore thread context
    157225        this_thread->current_monitors      = this.prev_mntrs;
    158226        this_thread->current_monitor_count = this.prev_count;
    159 }
    160 
     227        this_thread->current_monitor_func  = this.prev_func;
     228}
     229
     230//-----------------------------------------------------------------------------
     231// Internal scheduling types
    161232void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
    162233        this.waiting_thread = waiting_thread;
     
    183254// Internal scheduling
    184255void wait( condition * this, uintptr_t user_info = 0 ) {
    185         // LIB_DEBUG_PRINT_SAFE("Waiting\n");
    186 
    187256        brand_condition( this );
    188257
    189         //Check that everything is as expected
     258        // Check that everything is as expected
    190259        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    191260        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    192261        verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
    193262
    194         unsigned short count = this->monitor_count;
    195         unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    196         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    197 
    198         // LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    199 
    200         __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };
    201 
    202         __condition_criterion_t criteria[count];
    203         for(int i = 0; i < count; i++) {
    204                 (criteria[i]){ this->monitors[i], &waiter };
    205                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    206         }
    207 
    208         waiter.criteria = criteria;
     263        // Create storage for monitor context
     264        monitor_ctx( this->monitors, this->monitor_count );
     265
     266        // Create the node specific to this wait operation
     267        wait_ctx( this_thread, user_info );
     268
     269        // Append the current wait operation to the ones already queued on the condition
     270        // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
    209271        append( &this->blocked, &waiter );
    210272
    211         lock_all( this->monitors, locks, count );
    212         save_recursion( this->monitors, recursions, count );
    213         //DON'T unlock, ask the kernel to do it
    214 
    215         //Find the next thread(s) to run
     273        // Lock all monitors (aggregates the lock them as well)
     274        lock_all( monitors, locks, count );
     275
     276        // DON'T unlock, ask the kernel to do it
     277
     278        // Save monitor state
     279        save_recursion( monitors, recursions, count );
     280
     281        // Find the next thread(s) to run
    216282        unsigned short thread_count = 0;
    217283        thread_desc * threads[ count ];
     
    220286        }
    221287
     288        // Remove any duplicate threads
    222289        for( int i = 0; i < count; i++) {
    223                 thread_desc * new_owner = next_thread( this->monitors[i] );
     290                thread_desc * new_owner = next_thread( monitors[i] );
    224291                thread_count = insert_unique( threads, thread_count, new_owner );
    225292        }
    226 
    227         // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    228         for(int i = 0; i < thread_count; i++) {
    229                 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    230         }
    231         // LIB_DEBUG_PRINT_SAFE("\n");
    232293
    233294        // Everything is ready to go to sleep
     
    235296
    236297
    237         //WE WOKE UP
    238 
    239 
    240         //We are back, restore the owners and recursions
     298        // WE WOKE UP
     299
     300
     301        // We are back, restore the owners and recursions
    241302        lock_all( locks, count );
    242         restore_recursion( this->monitors, recursions, count );
     303        restore_recursion( monitors, recursions, count );
    243304        unlock_all( locks, count );
    244305}
    245306
    246307bool signal( condition * this ) {
    247         if( is_empty( this ) ) {
    248                 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    249                 return false;
    250         }
     308        if( is_empty( this ) ) { return false; }
    251309
    252310        //Check that everything is as expected
    253311        verify( this->monitors );
    254312        verify( this->monitor_count != 0 );
    255 
    256         unsigned short count = this->monitor_count;
    257313
    258314        //Some more checking in debug
     
    261317                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    262318                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
    263                 } // if
     319                }
    264320
    265321                for(int i = 0; i < this->monitor_count; i++) {
    266322                        if ( this->monitors[i] != this_thrd->current_monitors[i] ) {
    267323                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] );
    268                         } // if
     324                        }
    269325                }
    270326        );
    271327
    272         //Lock all the monitors
     328        unsigned short count = this->monitor_count;
     329
     330        // Lock all monitors
    273331        lock_all( this->monitors, NULL, count );
    274         // LIB_DEBUG_PRINT_SAFE("Signalling");
    275332
    276333        //Pop the head of the waiting queue
     
    280337        for(int i = 0; i < count; i++) {
    281338                __condition_criterion_t * crit = &node->criteria[i];
    282                 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    283339                assert( !crit->ready );
    284340                push( &crit->target->signal_stack, crit );
    285341        }
    286342
    287         // LIB_DEBUG_PRINT_SAFE("\n");
    288 
    289343        //Release
    290344        unlock_all( this->monitors, count );
     
    294348
    295349bool signal_block( condition * this ) {
    296         if( !this->blocked.head ) {
    297                 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    298                 return false;
    299         }
     350        if( !this->blocked.head ) { return false; }
    300351
    301352        //Check that everything is as expected
     
    303354        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    304355
    305         unsigned short count = this->monitor_count;
    306         unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    307         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    308 
    309         lock_all( this->monitors, locks, count );
    310 
    311         //create creteria
    312         __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
    313 
    314         __condition_criterion_t criteria[count];
    315         for(int i = 0; i < count; i++) {
    316                 (criteria[i]){ this->monitors[i], &waiter };
    317                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    318                 push( &criteria[i].target->signal_stack, &criteria[i] );
    319         }
    320 
    321         waiter.criteria = criteria;
     356        // Create storage for monitor context
     357        monitor_ctx( this->monitors, this->monitor_count );
     358
     359        // Lock all monitors (aggregates the locks them as well)
     360        lock_all( monitors, locks, count );
     361
     362        // Create the node specific to this wait operation
     363        wait_ctx_primed( this_thread, 0 )
    322364
    323365        //save contexts
    324         save_recursion( this->monitors, recursions, count );
     366        save_recursion( monitors, recursions, count );
    325367
    326368        //Find the thread to run
    327369        thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
    328370        for(int i = 0; i < count; i++) {
    329                 set_owner( this->monitors[i], signallee );
    330         }
    331 
    332         LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" );
     371                set_owner( monitors[i], signallee );
     372        }
    333373
    334374        //Everything is ready to go to sleep
     
    336376
    337377
    338 
    339 
    340         LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
     378        // WE WOKE UP
     379
    341380
    342381        //We are back, restore the owners and recursions
    343382        lock_all( locks, count );
    344         restore_recursion( this->monitors, recursions, count );
     383        restore_recursion( monitors, recursions, count );
    345384        unlock_all( locks, count );
    346385
     
    348387}
    349388
     389// Access the user_info of the thread waiting at the front of the queue
    350390uintptr_t front( condition * this ) {
    351391        verifyf( !is_empty(this),
     
    358398//-----------------------------------------------------------------------------
    359399// Internal scheduling
    360 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    361         // thread_desc * this = this_thread;
    362 
    363         // unsigned short count = this->current_monitor_count;
    364         // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    365         // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
    366 
    367         // lock_all( this->current_monitors, locks, count );
    368 
    369 
    370 
    371 
    372 
    373         // // // Everything is ready to go to sleep
    374         // // BlockInternal( locks, count, threads, thread_count );
    375 
    376 
    377         // //WE WOKE UP
    378 
    379 
    380         // //We are back, restore the owners and recursions
    381         // lock_all( locks, count );
    382         // restore_recursion( this->monitors, recursions, count );
    383         // unlock_all( locks, count );
     400int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) {
     401        thread_desc * thrd = this_thread;
     402
     403        // Create storage for monitor context
     404        monitor_ctx( acceptables->monitors, acceptables->count );
     405
     406        // Lock all monitors (aggregates the lock them as well)
     407        lock_all( monitors, locks, count );
     408
     409        // Create the node specific to this wait operation
     410        wait_ctx_primed( thrd, 0 );
     411
     412        // Check if the entry queue
     413        thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count );
     414
     415        LIB_DEBUG_PRINT_SAFE("Owner(s) :");
     416        for(int i = 0; i < count; i++) {
     417                LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner );
     418        }
     419        LIB_DEBUG_PRINT_SAFE("\n");
     420
     421        LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next);
     422
     423        if( !next ) {
     424                // Update acceptables on the current monitors
     425                for(int i = 0; i < count; i++) {
     426                        monitors[i]->acceptables = acceptables;
     427                        monitors[i]->acceptable_count = acc_count;
     428                }
     429        }
     430        else {
     431                for(int i = 0; i < count; i++) {
     432                        set_owner( monitors[i], next );
     433                }
     434        }
     435
     436
     437        save_recursion( monitors, recursions, count );
     438
     439
     440        // Everything is ready to go to sleep
     441        BlockInternal( locks, count, &next, next ? 1 : 0 );
     442
     443
     444        //WE WOKE UP
     445
     446
     447        //We are back, restore the owners and recursions
     448        lock_all( locks, count );
     449        restore_recursion( monitors, recursions, count );
     450        int acc_idx = monitors[0]->accepted_index;
     451        unlock_all( locks, count );
     452
     453        return acc_idx;
    384454}
    385455
     
    415485}
    416486
     487static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
     488        __acceptable_t* accs = this->acceptables; // Optim
     489        int acc_cnt = this->acceptable_count;
     490
     491        // Check if there are any acceptable functions
     492        if( !accs ) return -1;
     493
     494        // If this isn't the first monitor to test this, there is no reason to repeat the test.
     495        if( this != group[0] ) return group[0]->accepted_index;
     496
     497        // For all acceptable functions check if this is the current function.
     498        OUT_LOOP:
     499        for( int i = 0; i < acc_cnt; i++ ) {
     500                __acceptable_t * acc = &accs[i];
     501
     502                // if function matches, check the monitors
     503                if( acc->func == func ) {
     504
     505                        // If the group count is different then it can't be a match
     506                        if( acc->count != group_cnt ) return -1;
     507
     508                        // Check that all the monitors match
     509                        for( int j = 0; j < group_cnt; j++ ) {
     510                                // If not a match, check next function
     511                                if( acc->monitors[j] != group[j] ) continue OUT_LOOP;
     512                        }
     513
     514                        // It's a complete match, accept the call
     515                        return i;
     516                }
     517        }
     518
     519        // No function matched
     520        return -1;
     521}
     522
     523static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
     524        for(int i = 0; i < count; i++) {
     525                (criteria[i]){ monitors[i], waiter };
     526        }
     527
     528        waiter->criteria = criteria;
     529}
     530
     531static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
     532        for(int i = 0; i < count; i++) {
     533                (criteria[i]){ monitors[i], waiter };
     534                push( &criteria[i].target->signal_stack, &criteria[i] );
     535        }
     536
     537        waiter->criteria = criteria;
     538}
     539
    417540static inline void lock_all( spinlock ** locks, unsigned short count ) {
    418541        for( int i = 0; i < count; i++ ) {
     
    505628}
    506629
     630
     631static inline bool match( __acceptable_t * acc, thread_desc * thrd ) {
     632        verify( thrd );
     633        verify( acc );
     634        if( acc->func != thrd->current_monitor_func ) return false;
     635
     636        return true;
     637}
     638
     639static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
     640
     641        __thread_queue_t * entry_queue = &monitors[0]->entry_queue;
     642
     643        // For each thread in the entry-queue
     644        for(    thread_desc ** thrd_it = &entry_queue->head;
     645                *thrd_it;
     646                thrd_it = &(*thrd_it)->next)
     647        {
     648                // For each acceptable check if it matches
     649                __acceptable_t * acc_end = acceptables + acc_count;
     650                for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) {
     651                        // Check if we have a match
     652                        if( match( acc_it, *thrd_it ) ) {
     653
     654                                // If we have a match return it
     655                                // after removeing it from the entry queue
     656                                return remove( entry_queue, thrd_it );
     657                        }
     658                }
     659        }
     660
     661        return NULL;
     662}
    507663void ?{}( __condition_blocked_queue_t & this ) {
    508664        this.head = NULL;
  • src/libcfa/concurrency/preemption.c

    r28e58fd r800d275  
    332332                assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int);
    333333
    334                 LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
     334                // LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
    335335                // Switch on the code (a.k.a. the sender) to
    336336                switch( info.si_code )
     
    340340                case SI_TIMER:
    341341                case SI_KERNEL:
    342                         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
     342                        // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
    343343                        lock( &event_kernel->lock DEBUG_CTX2 );
    344344                        tick_preemption();
  • src/libcfa/exception.h

    r28e58fd r800d275  
    2929                     struct __cfaehm__base_exception_t * other);
    3030        void (*free)(struct __cfaehm__base_exception_t *this);
    31         const char (*msg)(struct __cfaehm__base_exception_t *this);
     31        const char * (*msg)(struct __cfaehm__base_exception_t *this);
    3232};
    3333struct __cfaehm__base_exception_t {
  • src/tests/.expect/castError.txt

    r28e58fd r800d275  
    1 castError.c:7 error: Can't choose between 3 alternatives for expression Cast of:
     1castError.c:7:1 error: Cannot choose between 3 alternatives for expression Cast of:
    22  Name: f
    33
  • src/tests/.expect/completeTypeError.txt

    r28e58fd r800d275  
    1 completeTypeError.c:34 error: No reasonable alternatives for expression Applying untyped:
     1completeTypeError.c:34:1 error: No reasonable alternatives for expression Applying untyped:
    22  Name: *?
    33...to:
     
    55
    66
    7 completeTypeError.c:36 error: No reasonable alternatives for expression Applying untyped:
     7completeTypeError.c:36:1 error: No reasonable alternatives for expression Applying untyped:
    88  Name: baz
    99...to:
     
    1111
    1212
    13 completeTypeError.c:37 error: No reasonable alternatives for expression Applying untyped:
     13completeTypeError.c:37:1 error: No reasonable alternatives for expression Applying untyped:
    1414  Name: quux
    1515...to:
     
    1717
    1818
    19 completeTypeError.c:58 error: No reasonable alternatives for expression Applying untyped:
     19completeTypeError.c:58:1 error: No reasonable alternatives for expression Applying untyped:
    2020  Name: baz
    2121...to:
     
    2323
    2424
    25 completeTypeError.c:59 error: No reasonable alternatives for expression Applying untyped:
     25completeTypeError.c:59:1 error: No reasonable alternatives for expression Applying untyped:
    2626  Name: quux
    2727...to:
     
    2929
    3030
    31 completeTypeError.c:60 error: No reasonable alternatives for expression Applying untyped:
     31completeTypeError.c:60:1 error: No reasonable alternatives for expression Applying untyped:
    3232  Name: *?
    3333...to:
     
    3535
    3636
    37 completeTypeError.c:72 error: No reasonable alternatives for expression Applying untyped:
     37completeTypeError.c:72:1 error: No reasonable alternatives for expression Applying untyped:
    3838  Name: baz
    3939...to:
  • src/tests/.expect/declarationErrors.txt

    r28e58fd r800d275  
    1 declarationErrors.c:16 error: duplicate static in declaration of x1: static const volatile short int
     1declarationErrors.c:16:1 error: duplicate static in declaration of x1: static const volatile short int
    22
    3 declarationErrors.c:17 error: conflicting extern & static in declaration of x2: extern const volatile short int
     3declarationErrors.c:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int
    44
    5 declarationErrors.c:18 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int
     5declarationErrors.c:18:1 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int
    66
    7 declarationErrors.c:19 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
     7declarationErrors.c:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
    88  with members
    99   with body
    1010
    1111
    12 declarationErrors.c:20 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
     12declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
    1313  with members
    1414   with body
    1515
    1616
    17 declarationErrors.c:22 error: duplicate static in declaration of x6: static const volatile instance of type Int
     17declarationErrors.c:22:1 error: duplicate static in declaration of x6: static const volatile instance of type Int
    1818
    19 declarationErrors.c:24 error: duplicate const in declaration of f01: static inline function
     19declarationErrors.c:24:1 error: duplicate const in declaration of f01: static inline function
    2020  with no parameters
    2121  returning const volatile int
    2222
    2323
    24 declarationErrors.c:25 error: duplicate volatile in declaration of f02: static inline function
     24declarationErrors.c:25:1 error: duplicate volatile in declaration of f02: static inline function
    2525  with no parameters
    2626  returning const volatile int
    2727
    2828
    29 declarationErrors.c:26 error: duplicate const in declaration of f03: static inline function
     29declarationErrors.c:26:1 error: duplicate const in declaration of f03: static inline function
    3030  with no parameters
    3131  returning const volatile int
    3232
    3333
    34 declarationErrors.c:27 error: duplicate volatile in declaration of f04: static inline function
     34declarationErrors.c:27:1 error: duplicate volatile in declaration of f04: static inline function
    3535  with no parameters
    3636  returning const volatile int
    3737
    3838
    39 declarationErrors.c:28 error: duplicate const in declaration of f05: static inline function
     39declarationErrors.c:28:1 error: duplicate const in declaration of f05: static inline function
    4040  with no parameters
    4141  returning const volatile int
    4242
    4343
    44 declarationErrors.c:29 error: duplicate volatile in declaration of f06: static inline function
     44declarationErrors.c:29:1 error: duplicate volatile in declaration of f06: static inline function
    4545  with no parameters
    4646  returning const volatile int
    4747
    4848
    49 declarationErrors.c:30 error: duplicate const in declaration of f07: static inline function
     49declarationErrors.c:30:1 error: duplicate const in declaration of f07: static inline function
    5050  with no parameters
    5151  returning const volatile int
    5252
    5353
    54 declarationErrors.c:31 error: duplicate const, duplicate volatile in declaration of f08: static inline function
     54declarationErrors.c:31:1 error: duplicate const, duplicate volatile in declaration of f08: static inline function
    5555  with no parameters
    5656  returning const volatile int
    5757
    5858
    59 declarationErrors.c:33 error: duplicate const, duplicate volatile in declaration of f09: static inline function
     59declarationErrors.c:33:1 error: duplicate const, duplicate volatile in declaration of f09: static inline function
    6060  with no parameters
    6161  returning const volatile int
    6262
    6363
    64 declarationErrors.c:34 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
     64declarationErrors.c:34:1 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
    6565  with no parameters
    6666  returning const restrict volatile _Atomic int
  • src/tests/.expect/dtor-early-exit-ERR1.txt

    r28e58fd r800d275  
    1 dtor-early-exit.c:142 error: jump to label 'L1' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
     2
  • src/tests/.expect/dtor-early-exit-ERR2.txt

    r28e58fd r800d275  
    1 dtor-early-exit.c:142 error: jump to label 'L2' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
     2
  • src/tests/.expect/memberCtors-ERR1.txt

    r28e58fd r800d275  
    1 memberCtors.c:71 error: in void ?{}(B &b), field a2 used before being constructed
     1memberCtors.c:71:1 error: in void ?{}(B &b), field a2 used before being constructed
  • src/tests/.expect/scopeErrors.txt

    r28e58fd r800d275  
    1 scopeErrors.c:2 error: duplicate object definition for thisIsAnError: signed int
    2 scopeErrors.c:20 error: duplicate function definition for butThisIsAnError: function
     1scopeErrors.c:2:1 error: duplicate object definition for thisIsAnError: signed int
     2scopeErrors.c:20:1 error: duplicate function definition for butThisIsAnError: function
    33  with parameters
    44    double
    5   returning
     5  returning 
    66    _retval_butThisIsAnError:       Attribute with name: unused
    77double
    8   with body
     8  with body 
    99    CompoundStmt
     10
  • src/tests/gmp.c

    r28e58fd r800d275  
    1010// Created On       : Tue Apr 19 08:55:51 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 24 09:33:26 2017
    13 // Update Count     : 543
     12// Last Modified On : Fri Aug 25 12:50:01 2017
     13// Update Count     : 544
    1414//
     15
     16// NOTE: UBUNTU DOES NOT SUPPORT GMP MULTILIB, SO ONLY 64-BIT GMP IS TESTED.
    1517
    1618#include <gmp>
  • src/tests/multiDimension.c

    r28e58fd r800d275  
    5959}
    6060
     61// ensure constructed const arrays continue to compile
     62const int global[1] = { -2 };
     63
    6164int main() {
    6265  X abc[4][4] = {
  • src/tests/preempt_longrun/stack.c

    r28e58fd r800d275  
    1515
    1616void main(worker_t * this) {
    17         volatile long p = 5_021_609ul;
    18         volatile long a = 326_417ul;
    19         volatile long n = 1l;
    20         for (volatile long i = 0; i < p; i++) {
     17        volatile long long p = 5_021_609ul;
     18        volatile long long a = 326_417ul;
     19        volatile long long n = 1l;
     20        for (volatile long long i = 0; i < p; i++) {
    2121                n *= a;
    2222                n %= p;
  • src/tests/sched-int-disjoint.c

    r28e58fd r800d275  
    33#include <monitor>
    44#include <thread>
     5
     6#include <time.h>
    57
    68static const unsigned long N = 10_000ul;
     
    107109// Main loop
    108110int main(int argc, char* argv[]) {
     111        rand48seed( time( NULL ) );
    109112        all_done = false;
    110113        processor p;
  • src/tests/sched-int-wait.c

    r28e58fd r800d275  
    55#include <thread>
    66
    7 static const unsigned long N = 10_000ul;
     7#include <time.h>
     8
     9static const unsigned long N = 2_500ul;
    810
    911#ifndef PREEMPTION_RATE
     
    119121// Main
    120122int main(int argc, char* argv[]) {
     123        rand48seed( time( NULL ) );
    121124        waiter_left = 4;
    122125        processor p[2];
  • src/tests/switch.c

    r28e58fd r800d275  
    1010// Created On       : Tue Jul 12 06:50:22 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug  4 11:44:29 2016
    13 // Update Count     : 31
     12// Last Modified On : Sat Aug 26 10:14:21 2017
     13// Update Count     : 33
    1414//
    1515
    1616int f( int i ) { return i; }
    1717
    18 int main() {
     18int main( void ) {
    1919        int i = 0;
    2020        switch ( i ) case 3 : i = 1;
     
    100100                j = 5;
    101101        } // choose
    102 }
     102} // main
    103103
    104104// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.