Changes in / [ad861ef:466787a]


Ignore:
Files:
30 added
46 deleted
51 edited

Legend:

Unmodified
Added
Removed
  • configure.ac

    rad861ef r466787a  
    226226AC_PROG_YACC
    227227if test "${YACC}" = "yacc" ; then echo "Error: bison required." ; exit 1 ; fi
    228 AC_PROG_LEX(yywrap)
     228AC_PROG_LEX
    229229if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi
    230 LT_INIT
     230AC_PROG_LIBTOOL
    231231AC_PROG_INSTALL
    232232
     
    284284                tools/Makefile
    285285                tools/prettyprinter/Makefile
    286                 benchmark/Cargo.toml
    287286        ])
     287
     288        AC_OUTPUT(benchmark/Cargo.toml)
    288289])
    289290
    290291AC_CONFIG_LINKS([tests/test.py:tests/test.py])
    291 AC_CONFIG_FILES([tests/config.py])
    292 
    293 AC_OUTPUT
     292
     293AC_OUTPUT(tests/config.py)
    294294
    295295# Final text
  • libcfa/configure.ac

    rad861ef r466787a  
    122122AC_PROG_CC
    123123AM_PROG_AS
    124 LT_INIT
     124AC_PROG_LIBTOOL
    125125AC_PROG_INSTALL
    126126AC_PROG_MAKE_SET
     
    246246AC_CONFIG_HEADERS(prelude/defines.hfa)
    247247
    248 AC_OUTPUT
     248AC_OUTPUT()
    249249
    250250# Final text
  • libcfa/src/Makefile.am

    rad861ef r466787a  
    113113        concurrency/once.hfa \
    114114        concurrency/kernel/fwd.hfa \
    115         concurrency/mutex_stmt.hfa \
    116     concurrency/select.hfa \
    117     concurrency/channel.hfa
     115        concurrency/mutex_stmt.hfa
    118116
    119117inst_thread_headers_src = \
  • libcfa/src/concurrency/clib/cfathread.cfa

    rad861ef r466787a  
    439439        // Mutex
    440440        struct cfathread_mutex {
    441                 exp_backoff_then_block_lock impl;
     441                linear_backoff_then_block_lock impl;
    442442        };
    443443        int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; }
     
    454454        // Condition
    455455        struct cfathread_condition {
    456                 condition_variable(exp_backoff_then_block_lock) impl;
     456                condition_variable(linear_backoff_then_block_lock) impl;
    457457        };
    458458        int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; }
  • libcfa/src/concurrency/future.hfa

    rad861ef r466787a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // concurrency/future.hfa --
     7// io/types.hfa --
    88//
    9 // Author           : Thierry Delisle & Peiran Hong & Colby Parsons
     9// Author           : Thierry Delisle & Peiran Hong
    1010// Created On       : Wed Jan 06 17:33:18 2021
    1111// Last Modified By :
     
    1414//
    1515
    16 // #pragma once
     16#pragma once
    1717
    1818#include "bits/locks.hfa"
    1919#include "monitor.hfa"
    20 #include "select.hfa"
    21 
    22 //----------------------------------------------------------------------------
    23 // future
    24 // I don't use future_t here since I need to use a lock for this future
    25 //  since it supports multiple consumers
    26 //  future_t is lockfree and uses atomics which aren't needed given we use locks here
    27 forall( T ) {
    28     // enum(int) { FUTURE_EMPTY = 0, FUTURE_FULFILLED = 1 }; // Enums seem to be broken so feel free to add this back afterwards
    29 
    30     // temporary enum replacement
    31     const int FUTURE_EMPTY = 0;
    32     const int FUTURE_FULFILLED = 1;
    33 
    34         struct future {
    35                 int state;
    36                 T result;
    37                 dlist( select_node ) waiters;
    38         futex_mutex lock;
    39         };
    40 
    41     struct future_node {
    42         inline select_node;
    43         T * my_result;
    44     };
    45 
    46     // C_TODO: perhaps allow exceptions to be inserted like uC++?
    47 
    48         static inline {
    49 
    50         void ?{}( future_node(T) & this, thread$ * blocked_thread, T * my_result ) {
    51             ((select_node &)this){ blocked_thread };
    52             this.my_result = my_result;
    53         }
    54 
    55         void ?{}(future(T) & this) {
    56                         this.waiters{};
    57             this.state = FUTURE_EMPTY;
    58             this.lock{};
    59                 }
    60 
    61                 // Reset future back to original state
    62                 void reset(future(T) & this) with(this)
    63         {
    64             lock( lock );
    65             if( ! waiters`isEmpty )
    66                 abort("Attempting to reset a future with blocked waiters");
    67             state = FUTURE_EMPTY;
    68             unlock( lock );
    69         }
    70 
    71                 // check if the future is available
    72         // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected
    73                 bool available( future(T) & this ) { return this.state; }
    74 
    75 
    76         // memcpy wrapper to help copy values
    77         void copy_T( T & from, T & to ) {
    78             memcpy((void *)&to, (void *)&from, sizeof(T));
    79         }
    80 
    81         // internal helper to signal waiters off of the future
    82         void _internal_flush( future(T) & this ) with(this) {
    83             while( ! waiters`isEmpty ) {
    84                 select_node &s = try_pop_front( waiters );
    85 
    86                 if ( s.race_flag == 0p )
    87                     // poke in result so that woken threads do not need to reacquire any locks
    88                     // *(((future_node(T) &)s).my_result) = result;
    89                     copy_T( result, *(((future_node(T) &)s).my_result) );
    90                 else if ( !install_select_winner( s, &this ) ) continue;
    91                
    92                 // only unpark if future is not selected
    93                 // or if it is selected we only unpark if we win the race
    94                 unpark( s.blocked_thread );
    95             }
    96         }
    97 
    98                 // Fulfil the future, returns whether or not someone was unblocked
    99                 bool fulfil( future(T) & this, T & val ) with(this) {
    100             lock( lock );
    101             if( state != FUTURE_EMPTY )
    102                 abort("Attempting to fulfil a future that has already been fulfilled");
    103 
    104             copy_T( val, result );
    105 
    106             bool ret_val = ! waiters`isEmpty;
    107             state = FUTURE_FULFILLED;
    108                         _internal_flush( this );
    109             unlock( lock );
    110             return ret_val;
    111                 }
    112 
    113                 // Wait for the future to be fulfilled
    114                 // Also return whether the thread had to block or not
    115                 [T, bool] get( future(T) & this ) with( this ) {
    116             lock( lock );
    117             T ret_val;
    118             if( state == FUTURE_FULFILLED ) {
    119                 copy_T( result, ret_val );
    120                 unlock( lock );
    121                 return [ret_val, false];
    122             }
    123 
    124             future_node(T) node = { active_thread(), &ret_val };
    125             insert_last( waiters, ((select_node &)node) );
    126             unlock( lock );
    127             park( );
    128 
    129                         return [ret_val, true];
    130                 }
    131 
    132                 // Wait for the future to be fulfilled
    133                 T get( future(T) & this ) {
    134                         [T, bool] tt;
    135                         tt = get(this);
    136                         return tt.0;
    137                 }
    138 
    139         // Gets value if it is available and returns [ val, true ]
    140         // otherwise returns [ default_val, false]
    141         // will not block
    142         [T, bool] try_get( future(T) & this ) with(this) {
    143             lock( lock );
    144             T ret_val;
    145             if( state == FUTURE_FULFILLED ) {
    146                 copy_T( result, ret_val );
    147                 unlock( lock );
    148                 return [ret_val, true];
    149             }
    150             unlock( lock );
    151            
    152             return [ret_val, false];
    153         }
    154 
    155         void * register_select( future(T) & this, select_node & s ) with(this) {
    156             lock( lock );
    157 
    158             // future not ready -> insert select node and return 0p
    159             if( state == FUTURE_EMPTY ) {
    160                 insert_last( waiters, s );
    161                 unlock( lock );
    162                 return 0p;
    163             }
    164 
    165             // future ready and we won race to install it as the select winner return 1p
    166             if ( install_select_winner( s, &this ) ) {
    167                 unlock( lock );
    168                 return 1p;
    169             }
    170 
    171             unlock( lock );
    172             // future ready and we lost race to install it as the select winner
    173             return 2p;
    174         }
    175 
    176         void unregister_select( future(T) & this, select_node & s ) with(this) {
    177             lock( lock );
    178             if ( s`isListed ) remove( s );
    179             unlock( lock );
    180         }
    181                
    182         }
    183 }
    184 
    185 //--------------------------------------------------------------------------------------------------------
    186 // These futures below do not support select statements so they may not be as useful as 'future'
    187 //  however the 'single_future' is cheap and cheerful and is most likely more performant than 'future'
    188 //  since it uses raw atomics and no locks afaik
    189 //
    190 // As far as 'multi_future' goes I can't see many use cases as it will be less performant than 'future'
    191 //  since it is monitor based and also is not compatible with select statements
    192 //--------------------------------------------------------------------------------------------------------
    19320
    19421forall( T ) {
    195         struct single_future {
     22        struct future {
    19623                inline future_t;
    19724                T result;
     
    20027        static inline {
    20128                // Reset future back to original state
    202                 void reset(single_future(T) & this) { reset( (future_t&)this ); }
     29                void reset(future(T) & this) { reset( (future_t&)this ); }
    20330
    20431                // check if the future is available
    205                 bool available( single_future(T) & this ) { return available( (future_t&)this ); }
     32                bool available( future(T) & this ) { return available( (future_t&)this ); }
    20633
    20734                // Mark the future as abandoned, meaning it will be deleted by the server
    20835                // This doesn't work beause of the potential need for a destructor
    209                 void abandon( single_future(T) & this );
     36                void abandon( future(T) & this );
    21037
    21138                // Fulfil the future, returns whether or not someone was unblocked
    212                 thread$ * fulfil( single_future(T) & this, T result ) {
     39                thread$ * fulfil( future(T) & this, T result ) {
    21340                        this.result = result;
    21441                        return fulfil( (future_t&)this );
     
    21744                // Wait for the future to be fulfilled
    21845                // Also return whether the thread had to block or not
    219                 [T, bool] wait( single_future(T) & this ) {
     46                [T, bool] wait( future(T) & this ) {
    22047                        bool r = wait( (future_t&)this );
    22148                        return [this.result, r];
     
    22350
    22451                // Wait for the future to be fulfilled
    225                 T wait( single_future(T) & this ) {
     52                T wait( future(T) & this ) {
    22653                        [T, bool] tt;
    22754                        tt = wait(this);
  • libcfa/src/concurrency/locks.hfa

    rad861ef r466787a  
    3838#include <unistd.h>
    3939
    40 // C_TODO: cleanup this and locks.cfa
    41 // - appropriate separation of interface and impl
    42 // - clean up unused/unneeded locks
    43 // - change messy big blocking lock from inheritance to composition to remove need for flags
     40// undef to make a number of the locks not reacquire upon waking from a condlock
     41#define REACQ 1
    4442
    4543//-----------------------------------------------------------------------------
     
    251249static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); }
    252250static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; }
    253 static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); }
    254 
    255 
    256 //-----------------------------------------------------------------------------
    257 // Exponential backoff then block lock
    258 struct exp_backoff_then_block_lock {
     251static inline void on_wakeup(clh_lock & this, size_t recursion ) {
     252        #ifdef REACQ
     253        lock(this);
     254        #endif
     255}
     256
     257
     258//-----------------------------------------------------------------------------
     259// Linear backoff Spinlock
     260struct linear_backoff_then_block_lock {
    259261        // Spin lock used for mutual exclusion
    260262        __spinlock_t spinlock;
     
    267269};
    268270
    269 static inline void  ?{}( exp_backoff_then_block_lock & this ) {
     271static inline void  ?{}( linear_backoff_then_block_lock & this ) {
    270272        this.spinlock{};
    271273        this.blocked_threads{};
    272274        this.lock_value = 0;
    273275}
    274 static inline void ^?{}( exp_backoff_then_block_lock & this ) {}
    275 // static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
    276 // static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
    277 
    278 static inline bool internal_try_lock(exp_backoff_then_block_lock & this, size_t & compare_val) with(this) {
     276static inline void ^?{}( linear_backoff_then_block_lock & this ) {}
     277// static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
     278// static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
     279
     280static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) {
    279281        if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
    280282                return true;
     
    283285}
    284286
    285 static inline bool try_lock(exp_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
    286 
    287 static inline bool try_lock_contention(exp_backoff_then_block_lock & this) with(this) {
     287static inline bool try_lock(linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
     288
     289static inline bool try_lock_contention(linear_backoff_then_block_lock & this) with(this) {
    288290        if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) {
    289291                return true;
     
    292294}
    293295
    294 static inline bool block(exp_backoff_then_block_lock & this) with(this) {
     296static inline bool block(linear_backoff_then_block_lock & this) with(this) {
    295297        lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC)
    296298        if (lock_value != 2) {
     
    304306}
    305307
    306 static inline void lock(exp_backoff_then_block_lock & this) with(this) {
     308static inline void lock(linear_backoff_then_block_lock & this) with(this) {
    307309        size_t compare_val = 0;
    308310        int spin = 4;
     
    322324}
    323325
    324 static inline void unlock(exp_backoff_then_block_lock & this) with(this) {
     326static inline void unlock(linear_backoff_then_block_lock & this) with(this) {
    325327    if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return;
    326328        lock( spinlock __cfaabi_dbg_ctx2 );
     
    330332}
    331333
    332 static inline void on_notify(exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
    333 static inline size_t on_wait(exp_backoff_then_block_lock & this) { unlock(this); return 0; }
    334 static inline void on_wakeup(exp_backoff_then_block_lock & this, size_t recursion ) { lock(this); }
     334static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
     335static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; }
     336static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) {
     337        #ifdef REACQ
     338        lock(this);
     339        #endif
     340}
    335341
    336342//-----------------------------------------------------------------------------
     
    384390
    385391static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) {
    386     lock( lock __cfaabi_dbg_ctx2 );
    387     insert_last( blocked_threads, *t );
    388     unlock( lock );
     392        #ifdef REACQ
     393                lock( lock __cfaabi_dbg_ctx2 );
     394                insert_last( blocked_threads, *t );
     395                unlock( lock );
     396        #else
     397                unpark(t);
     398        #endif
    389399}
    390400static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; }
     
    543553}
    544554static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; }
    545 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { lock(this); }
     555static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) {
     556        #ifdef REACQ
     557        lock(this);
     558        #endif
     559}
    546560
    547561
     
    584598static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); }
    585599static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; }
    586 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {lock(this); }
     600static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {
     601        #ifdef REACQ
     602        lock(this);
     603        #endif
     604}
    587605
    588606//-----------------------------------------------------------------------------
     
    622640
    623641static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) {
     642  #ifdef REACQ
    624643        // first we acquire internal fast_block_lock
    625644        lock( lock __cfaabi_dbg_ctx2 );
     
    633652        unlock( lock );
    634653
     654  #endif
    635655        unpark(t);
     656       
    636657}
    637658static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; }
    638659static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) {
     660  #ifdef REACQ
    639661        // now we acquire the entire block_spin_lock upon waking up
    640662        while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
    641663        __atomic_store_n(&held, true, __ATOMIC_RELEASE);
    642664        unlock( lock ); // Now we release the internal fast_spin_lock
     665  #endif
    643666}
    644667
  • src/AST/Expr.cpp

    rad861ef r466787a  
    3030#include "Common/SemanticError.h"
    3131#include "GenPoly/Lvalue.h"        // for referencesPermissable
    32 #include "ResolvExpr/Unify.h"      // for extractResultType
     32#include "ResolvExpr/typeops.h"    // for extractResultType
    3333#include "Tuples/Tuples.h"         // for makeTupleType
    3434
  • src/AST/Node.hpp

    rad861ef r466787a  
    1919#include <cstddef>     // for nullptr_t
    2020#include <iosfwd>
     21#include <type_traits> // for remove_reference
    2122
    2223#include "Common/ErrorObjects.h"  // for SemanticErrorException
     
    3536        Node(const Node&) : strong_count(0), weak_count(0) {}
    3637        Node(Node&&) : strong_count(0), weak_count(0) {}
    37         Node& operator=(const Node&) = delete;
    38         Node& operator=(Node&&) = delete;
     38        Node& operator= (const Node&) = delete;
     39        Node& operator= (Node&&) = delete;
    3940        virtual ~Node() {}
    4041
  • src/AST/SymbolTable.cpp

    rad861ef r466787a  
    2222#include "Inspect.hpp"
    2323#include "Type.hpp"
    24 #include "CodeGen/OperatorTable.h"         // for isCtorDtorAssign
     24#include "CodeGen/OperatorTable.h"  // for isCtorDtorAssign
    2525#include "Common/SemanticError.h"
    2626#include "Common/Stats/Counter.h"
     
    2828#include "InitTweak/InitTweak.h"
    2929#include "ResolvExpr/Cost.h"
    30 #include "ResolvExpr/CandidateFinder.hpp"  // for referenceToRvalueConversion
    31 #include "ResolvExpr/Unify.h"
     30#include "ResolvExpr/typeops.h"
    3231#include "SymTab/Mangler.h"
    3332
  • src/CodeGen/CodeGenerator.cc

    rad861ef r466787a  
    273273        }
    274274
    275         template<typename pass_type>
    276         inline void genEnumInitializer( PassVisitor<pass_type> * visitor, Type * baseType, std::ostream & output,
    277         Initializer * init, long long * cur_val, Options options) {
    278                 auto baseTypeAsBasic = baseType ? dynamic_cast<BasicType *>( baseType ) : nullptr;
    279                 if ( init ) { // If value has an explicit initiazatior
    280                         output << " = ";
    281                         output << "(" << genType(baseType, "", options) << ")";
    282                         init->accept( *visitor );
    283                         if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // if it is an integral type and initilizer offered,
    284                         // need to update the cur_val
    285                                 Expression* expr = ((SingleInit *)(init))->value;
    286                                 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast
    287                                         expr = temp->arg;
    288                                 }
    289                                 *cur_val = ((ConstantExpr *)expr)->constant.get_ival()+1;
    290                         }
    291                 } else if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // integral implicitly init to cur_val + 1
    292                         output << " = " << "(" << genType(baseType, "", options) << ")";
    293                         output << (*cur_val)++;
    294                 }
    295         }
    296 
    297275        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    298276                extension( enumDecl );
    299277                std::list< Declaration* > &memb = enumDecl->get_members();
    300278                if (enumDecl->base && ! memb.empty()) {
    301                         long long cur_val = 0;
     279                        unsigned long long last_val = -1; // if the first enum value has no explicit initializer,
     280                        // as other
    302281                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    303282                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
    304283                                assert( obj );
    305284                                output << "static ";
    306                                 output << genType(enumDecl->base, mangleName( obj ), options);
    307                                 genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options);
     285                                output << genType(enumDecl->base, "", options) << " const ";
     286                                output << mangleName( obj ) << " ";
     287                                output << " = ";
     288                                output << "(" << genType(enumDecl->base, "", options) << ")";
     289                                if ( (BasicType *)(enumDecl->base) && ((BasicType *)(enumDecl->base))->isWholeNumber() ) {
     290                                        if ( obj->get_init() ) {
     291                                                obj->get_init()->accept( *visitor );
     292                                                Expression* expr = ((SingleInit *)(obj->init))->value;
     293                                                while ( auto temp = dynamic_cast<CastExpr *>(expr) ) {
     294                                                        expr = temp->arg;
     295                                                }
     296                                                last_val = ((ConstantExpr *)expr)->constant.get_ival();
     297                                        } else {
     298                                                output << ++last_val;
     299                                        } // if
     300                                } else {
     301                                        if ( obj->get_init() ) {
     302                                                obj->get_init()->accept( *visitor );
     303                                        } else {
     304                                                // Should not reach here!
     305                                        }
     306                                }
    308307                                output << ";" << endl;
    309308                        } // for
  • src/CodeGen/GenType.cc

    rad861ef r466787a  
    255255        void GenType::postvisit( EnumInstType * enumInst ) {
    256256                if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    257                         typeString = genType(enumInst->baseEnum->base, typeString, options);
     257                        typeString = genType(enumInst->baseEnum->base, "", options) + typeString;
    258258                } else {
    259259                        typeString = enumInst->name + " " + typeString;
  • src/GenPoly/Box.cc

    rad861ef r466787a  
    1414//
    1515
    16 #include "Box.h"
    17 
    1816#include <algorithm>                     // for mismatch
    1917#include <cassert>                       // for assert, strict_dynamic_cast
     
    2523#include <string>                        // for string, allocator, basic_string
    2624#include <utility>                       // for pair
     25
     26#include "Box.h"
    2727
    2828#include "CodeGen/OperatorTable.h"
     
    3737#include "InitTweak/InitTweak.h"         // for getFunctionName, isAssignment
    3838#include "Lvalue.h"                      // for generalizedLvalue
    39 #include "ResolvExpr/Unify.h"            // for typesCompatible
     39#include "ResolvExpr/typeops.h"          // for typesCompatible
    4040#include "ScopedSet.h"                   // for ScopedSet, ScopedSet<>::iter...
    4141#include "ScrubTyVars.h"                 // for ScrubTyVars
     
    911911
    912912                        for ( FunctionType const * const funType : functions ) {
    913                                 std::string mangleName = SymTab::Mangler::mangle( funType );
     913                                FunctionType *originalFunction = funType->clone();
     914                                FunctionType *realFunction = funType->clone();
     915                                std::string mangleName = SymTab::Mangler::mangle( realFunction );
    914916
    915917                                // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
    916918                                // pre-substitution parameter function type.
    917919                                // The second part of the insert result is "is the value new".
    918                                 if ( !adaptersDone.insert( mangleName ).second ) continue;
    919 
    920                                 // Apply substitution to type variables to figure out what the adapter's type should look like.
    921                                 assert( env );
    922                                 FunctionType *realType = funType->clone();
    923                                 env->apply( realType );
    924                                 mangleName = SymTab::Mangler::mangle( realType );
    925                                 mangleName += makePolyMonoSuffix( funType, exprTyVars );
    926 
    927                                 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
    928                                 AdapterIter adapter = adapters.find( mangleName );
    929                                 if ( adapter == adapters.end() ) {
    930                                         // Adapter has not been created yet in the current scope, so define it.
    931                                         FunctionDecl *newAdapter = makeAdapter( funType, realType, mangleName, exprTyVars );
    932                                         std::pair< AdapterIter, bool > answer = adapters.insert( mangleName, newAdapter );
    933                                         adapter = answer.first;
    934                                         stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
     920                                if ( adaptersDone.insert( mangleName ).second ) {
     921
     922                                        // apply substitution to type variables to figure out what the adapter's type should look like
     923                                        assert( env );
     924                                        env->apply( realFunction );
     925                                        mangleName = SymTab::Mangler::mangle( realFunction );
     926                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
     927
     928                                        typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
     929                                        AdapterIter adapter = adapters.find( mangleName );
     930                                        if ( adapter == adapters.end() ) {
     931                                                // adapter has not been created yet in the current scope, so define it
     932                                                FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars );
     933                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
     934                                                adapter = answer.first;
     935                                                stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
     936                                        } // if
     937                                        assert( adapter != adapters.end() );
     938
     939                                        // add the appropriate adapter as a parameter
     940                                        appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
    935941                                } // if
    936                                 assert( adapter != adapters.end() );
    937 
    938                                 // Add the appropriate adapter as a parameter.
    939                                 appExpr->args.push_front( new VariableExpr( adapter->second ) );
    940942                        } // for
    941943                } // passAdapters
  • src/GenPoly/GenPoly.cc

    rad861ef r466787a  
    2424#include <vector>                       // for vector
    2525
    26 #include "AST/Expr.hpp"
    2726#include "AST/Type.hpp"
    28 #include "AST/TypeSubstitution.hpp"
    2927#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
    3028#include "ResolvExpr/typeops.h"         // for flatten
     
    492490                }
    493491
    494                 /// Flattens a list of types.
    495                 // There is another flattenList in Unify.
    496492                void flattenList( vector<ast::ptr<ast::Type>> const & src,
    497493                                vector<ast::ptr<ast::Type>> & out ) {
  • src/GenPoly/InstantiateGeneric.cc

    rad861ef r466787a  
    2828#include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
    2929#include "InitTweak/InitTweak.h"
    30 #include "ResolvExpr/AdjustExprType.hpp"  // for adjustExprType
    31 #include "ResolvExpr/Unify.h"          // for typesCompatible
     30#include "ResolvExpr/typeops.h"
    3231#include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
    3332#include "ScrubTyVars.h"               // for ScrubTyVars
  • src/GenPoly/InstantiateGenericNew.cpp

    rad861ef r466787a  
    3232#include "GenPoly/GenPoly.h"           // for isPolyType, typesPolyCompatible
    3333#include "GenPoly/ScrubTyVars.h"       // for scrubAll
    34 #include "ResolvExpr/AdjustExprType.hpp"  // for adjustExprType
    35 #include "ResolvExpr/Unify.h"          // for typesCompatible
     34#include "ResolvExpr/typeops.h"        // for typesCompatible
    3635
    3736namespace GenPoly {
  • src/InitTweak/FixInit.cc

    rad861ef r466787a  
    3939#include "InitTweak.h"                 // for getFunctionName, getCallArg
    4040#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    41 #include "ResolvExpr/Unify.h"          // for typesCompatible
     41#include "ResolvExpr/typeops.h"        // for typesCompatible
    4242#include "SymTab/Autogen.h"            // for genImplicitCall
    4343#include "SymTab/Indexer.h"            // for Indexer
  • src/InitTweak/FixInitNew.cpp

    rad861ef r466787a  
    2626#include "GenPoly/GenPoly.h"           // for getFunctionType
    2727#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    28 #include "ResolvExpr/Unify.h"          // for typesCompatible
     28#include "ResolvExpr/typeops.h"        // for typesCompatible
    2929#include "SymTab/Autogen.h"            // for genImplicitCall
    3030#include "SymTab/Indexer.h"            // for Indexer
  • src/InitTweak/InitTweak.cc

    rad861ef r466787a  
    3535#include "GenPoly/GenPoly.h"       // for getFunctionType
    3636#include "InitTweak.h"
    37 #include "ResolvExpr/Unify.h"      // for typesCompatibleIgnoreQualifiers
     37#include "ResolvExpr/typeops.h"    // for typesCompatibleIgnoreQualifiers
    3838#include "SymTab/Autogen.h"
    3939#include "SymTab/Indexer.h"        // for Indexer
  • src/Parser/TypeData.cc

    rad861ef r466787a  
    933933                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
    934934                } else if ( !cur->initializer ) {
    935                         if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
     935                        if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
    936936                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    937937                        }
  • src/ResolvExpr/AlternativeFinder.cc

    rad861ef r466787a  
    1414//
    1515
    16 #include "AlternativeFinder.h"
    17 
    1816#include <algorithm>               // for copy
    1917#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2826
    2927#include "CompilationState.h"      // for resolvep
    30 #include "AdjustExprType.hpp"      // for adjustExprType
    3128#include "Alternative.h"           // for AltList, Alternative
     29#include "AlternativeFinder.h"
    3230#include "AST/Expr.hpp"
    3331#include "AST/SymbolTable.hpp"
    3432#include "AST/Type.hpp"
    35 #include "CastCost.hpp"            // for castCost
    3633#include "Common/SemanticError.h"  // for SemanticError
    3734#include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
    38 #include "ConversionCost.h"        // for conversionCost
    3935#include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
    4036#include "ExplodedActual.h"        // for ExplodedActual
    4137#include "InitTweak/InitTweak.h"   // for getFunctionName
    42 #include "PolyCost.hpp"            // for polyCost
    4338#include "RenameVars.h"            // for RenameVars, global_renamer
    4439#include "ResolveAssertions.h"     // for resolveAssertions
    4540#include "ResolveTypeof.h"         // for resolveTypeof
    4641#include "Resolver.h"              // for resolveStmtExpr
    47 #include "SpecCost.hpp"            // for specCost
    4842#include "SymTab/Indexer.h"        // for Indexer
    4943#include "SymTab/Mangler.h"        // for Mangler
     
    5751#include "Tuples/Explode.h"        // for explode
    5852#include "Tuples/Tuples.h"         // for isTtype, handleTupleAssignment
    59 #include "typeops.h"               // for combos
    6053#include "Unify.h"                 // for unify
     54#include "typeops.h"               // for adjustExprType, polyCost, castCost
    6155
    6256#define PRINT( text ) if ( resolvep ) { text }
  • src/ResolvExpr/AlternativeFinder.h

    rad861ef r466787a  
    3434namespace ResolvExpr {
    3535        struct ArgPack;
    36 
    37         Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
    38                 const SymTab::Indexer & indexer, const TypeEnvironment & env );
    39 
    40         void referenceToRvalueConversion( Expression *& expr, Cost & cost );
    4136
    4237        /// First index is which argument, second index is which alternative for that argument,
  • src/ResolvExpr/CandidateFinder.cpp

    rad861ef r466787a  
    2323#include <vector>
    2424
    25 #include "AdjustExprType.hpp"
    2625#include "Candidate.hpp"
    27 #include "CastCost.hpp"           // for castCost
    2826#include "CompilationState.h"
    29 #include "ConversionCost.h"       // for conversionCast
    3027#include "Cost.h"
    3128#include "ExplodedArg.hpp"
    32 #include "PolyCost.hpp"
    3329#include "RenameVars.h"           // for renameTyVars
    3430#include "Resolver.h"
    3531#include "ResolveTypeof.h"
    3632#include "SatisfyAssertions.hpp"
    37 #include "SpecCost.hpp"
    38 #include "typeops.h"              // for combos
     33#include "typeops.h"              // for adjustExprType, conversionCost, polyCost, specCost
    3934#include "Unify.h"
    4035#include "AST/Expr.hpp"
  • src/ResolvExpr/CandidateFinder.hpp

    rad861ef r466787a  
    6363        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    6464
    65 /// Create an expression that preforms reference to rvalue conversion on
    66 /// the given expression and update the cost of the expression.
    67 const ast::Expr * referenceToRvalueConversion(
    68         const ast::Expr * expr, Cost & cost );
    69 
    7065} // namespace ResolvExpr
    7166
  • src/ResolvExpr/CastCost.cc

    rad861ef r466787a  
    1313// Update Count     : 9
    1414//
    15 
    16 #include "CastCost.hpp"
    1715
    1816#include <cassert>                       // for assert
     
    2422#include "ConversionCost.h"              // for ConversionCost
    2523#include "Cost.h"                        // for Cost, Cost::infinity
    26 #include "ResolvExpr/ConversionCost.h"   // for conversionCost
    27 #include "ResolvExpr/PtrsCastable.hpp"   // for ptrsCastable
    2824#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment, EqvClass
    29 #include "ResolvExpr/typeops.h"          // for ptrsCastable
    30 #include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
    3125#include "SymTab/Indexer.h"              // for Indexer
    3226#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
    3327#include "SynTree/Type.h"                // for PointerType, Type, TypeInstType
     28#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
    3429
    3530#if 0
  • src/ResolvExpr/CommonType.cc

    rad861ef r466787a  
    1313// Update Count     : 24
    1414//
    15 
    16 #include "CommonType.hpp"
    1715
    1816#include <cassert>                       // for strict_dynamic_cast
  • src/ResolvExpr/ConversionCost.cc

    rad861ef r466787a  
    2222#include "ResolvExpr/Cost.h"             // for Cost
    2323#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    24 #include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
    25 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
     24#include "ResolvExpr/Unify.h"
    2625#include "SymTab/Indexer.h"              // for Indexer
    2726#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
    2827#include "SynTree/Type.h"                // for Type, BasicType, TypeInstType
     28#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
    2929
    3030
  • src/ResolvExpr/ConversionCost.h

    rad861ef r466787a  
    3232namespace ResolvExpr {
    3333        class TypeEnvironment;
    34 
    35         Cost conversionCost(
    36                 const Type * src, const Type * dest, bool srcIsLvalue,
    37                 const SymTab::Indexer & indexer, const TypeEnvironment & env );
    3834
    3935        typedef std::function<Cost(const Type *, const Type *, bool,
     
    8480        const ast::SymbolTable &, const ast::TypeEnvironment &)>;
    8581
    86 Cost conversionCost(
    87         const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    88         const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    89 
    90 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
    91         bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,
    92         PtrsCalculation func );
    93 
    9482#warning when the old ConversionCost is removed, get ride of the _new suffix.
    9583class ConversionCost_new : public ast::WithShortCircuiting {
     
    131119};
    132120
     121Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
     122        bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,
     123        PtrsCalculation func );
     124
    133125} // namespace ResolvExpr
    134126
  • src/ResolvExpr/PtrsAssignable.cc

    rad861ef r466787a  
    1414//
    1515
    16 #include "PtrsAssignable.hpp"
     16#include "typeops.h"
    1717
    1818#include "AST/Pass.hpp"
  • src/ResolvExpr/PtrsCastable.cc

    rad861ef r466787a  
    1414//
    1515
    16 #include "PtrsCastable.hpp"
    17 
    1816#include "AST/Decl.hpp"
    1917#include "AST/Pass.hpp"
     
    2119#include "AST/TypeEnvironment.hpp"
    2220#include "Common/PassVisitor.h"
    23 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
    2421#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    2522#include "SymTab/Indexer.h"              // for Indexer
     
    2724#include "SynTree/Type.h"                // for TypeInstType, Type, BasicType
    2825#include "SynTree/Visitor.h"             // for Visitor
     26#include "typeops.h"                     // for ptrsAssignable
    2927
    3028namespace ResolvExpr {
     
    293291                return objectCast( src, env, symtab );
    294292        } else {
    295                 return ast::Pass<PtrsCastable_new>::read( src, dst, env, symtab );
     293                ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
     294                src->accept( ptrs );
     295                return ptrs.core.result;
    296296        }
    297297}
  • src/ResolvExpr/RenameVars.cc

    rad861ef r466787a  
    8383
    8484                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
     85                        // rename
    8586                        auto it = idMap.find( type->name );
    86                         if ( it == idMap.end() ) return type;
    87 
    88                         // Unconditionally mutate because map will *always* have different name.
    89                         ast::TypeInstType * mut = ast::shallowCopy( type );
    90                         // Reconcile base node since some copies might have been made.
    91                         mut->base = it->second.base;
    92                         mut->formal_usage = it->second.formal_usage;
    93                         mut->expr_id = it->second.expr_id;
    94                         return mut;
     87                        if ( it != idMap.end() ) {
     88                                // unconditionally mutate because map will *always* have different name
     89                                ast::TypeInstType * mut = ast::shallowCopy( type );
     90                                // reconcile base node since some copies might have been made
     91                                mut->base = it->second.base;
     92                                mut->formal_usage = it->second.formal_usage;
     93                                mut->expr_id = it->second.expr_id;
     94                    type = mut;
     95                        }
     96
     97                        return type;
    9598                }
    9699
     
    184187
    185188const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) {
     189        // ast::Type *tc = ast::deepCopy(t);
    186190        ast::Pass<RenameVars_new> renamer;
    187191        renamer.core.mode = mode;
  • src/ResolvExpr/ResolveAssertions.cc

    rad861ef r466787a  
    2626#include <vector>                   // for vector
    2727
    28 #include "AdjustExprType.hpp"       // for adjustExprType
    2928#include "Alternative.h"            // for Alternative, AssertionItem, AssertionList
    3029#include "Common/FilterCombos.h"    // for filterCombos
     
    3231#include "Common/utility.h"         // for sort_mins
    3332#include "GenPoly/GenPoly.h"        // for getFunctionType
    34 #include "ResolvExpr/AlternativeFinder.h"  // for computeConversionCost
    3533#include "ResolvExpr/RenameVars.h"  // for renameTyVars
    36 #include "SpecCost.hpp"             // for specCost
    3734#include "SymTab/Indexer.h"         // for Indexer
    3835#include "SymTab/Mangler.h"         // for Mangler
    3936#include "SynTree/Expression.h"     // for InferredParams
    4037#include "TypeEnvironment.h"        // for TypeEnvironment, etc.
     38#include "typeops.h"                // for adjustExprType, specCost
    4139#include "Unify.h"                  // for unify
    4240
  • src/ResolvExpr/SatisfyAssertions.cpp

    rad861ef r466787a  
    2323#include <vector>
    2424
    25 #include "AdjustExprType.hpp"
    2625#include "Candidate.hpp"
    2726#include "CandidateFinder.hpp"
    28 #include "CommonType.hpp"
    2927#include "Cost.h"
    3028#include "RenameVars.h"
    31 #include "SpecCost.hpp"
    3229#include "typeops.h"
    3330#include "Unify.h"
  • src/ResolvExpr/Unify.cc

    rad861ef r466787a  
    3333#include "AST/TypeEnvironment.hpp"
    3434#include "Common/PassVisitor.h"     // for PassVisitor
    35 #include "CommonType.hpp"           // for commonType
    3635#include "FindOpenVars.h"           // for findOpenVars
    37 #include "SpecCost.hpp"             // for SpecCost
    3836#include "SynTree/LinkageSpec.h"    // for C
    3937#include "SynTree/Constant.h"       // for Constant
     
    4543#include "Tuples/Tuples.h"          // for isTtype
    4644#include "TypeEnvironment.h"        // for EqvClass, AssertionSet, OpenVarSet
    47 #include "typeops.h"                // for flatten, occurs
     45#include "typeops.h"                // for flatten, occurs, commonType
    4846
    4947namespace ast {
     
    5250
    5351namespace SymTab {
    54         class Indexer;
     52class Indexer;
    5553}  // namespace SymTab
    5654
     
    5856
    5957namespace ResolvExpr {
    60 
    61 // Template Helpers:
    62 template< typename Iterator1, typename Iterator2 >
    63 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
    64         for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    65                 Type *commonType = 0;
    66                 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    67                         return false;
    68                 } // if
    69                 commonTypes.push_back( commonType );
    70         } // for
    71         return ( list1Begin == list1End && list2Begin == list2End );
    72 }
    73 
    74 template< typename Iterator1, typename Iterator2 >
    75 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    76         std::list< Type* > commonTypes;
    77         if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions,  openVars, indexer, commonTypes ) ) {
    78                 deleteAll( commonTypes );
    79                 return true;
    80         } else {
    81                 return false;
    82         } // if
    83 }
    8458
    8559        struct Unify_old : public WithShortCircuiting {
  • src/ResolvExpr/Unify.h

    rad861ef r466787a  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 13:09:04 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jan 17 11:12:00 2023
    13 // Update Count     : 5
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    3737
    3838namespace ResolvExpr {
     39        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     40        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
     41        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     42        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
    3943
    40 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    41 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
    42 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    43 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
     44        template< typename Iterator1, typename Iterator2 >
     45        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
     46                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     47                        Type *commonType = 0;
     48                        if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     49                                return false;
     50                        } // if
     51                        commonTypes.push_back( commonType );
     52                } // for
     53                if ( list1Begin != list1End || list2Begin != list2End ) {
     54                        return false;
     55                } else {
     56                        return true;
     57                } // if
     58        }
    4459
    45 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    46 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     60        template< typename Iterator1, typename Iterator2 >
     61        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     62                std::list< Type* > commonTypes;
     63                if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
     64                        deleteAll( commonTypes );
     65                        return true;
     66                } else {
     67                        return false;
     68                } // if
     69        }
    4770
    48 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    49         TypeEnvironment env;
    50         return typesCompatible( t1, t2, indexer, env );
    51 }
     71        bool unify(
     72                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     73                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     74                ast::OpenVarSet & open, const ast::SymbolTable & symtab );
    5275
    53 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    54         TypeEnvironment env;
    55         return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
    56 }
     76        bool unify(
     77                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     78                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     79                ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
    5780
    58 bool unify(
    59         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    60         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    61         ast::OpenVarSet & open, const ast::SymbolTable & symtab );
     81        bool unifyExact(
     82                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     83                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     84                WidenMode widen, const ast::SymbolTable & symtab );
    6285
    63 bool unify(
    64         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    65         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    66         ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
    67 
    68 bool unifyExact(
    69         const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    70         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    71         WidenMode widen, const ast::SymbolTable & symtab );
    72 
    73 bool unifyInexact(
    74         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    75         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    76         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
    77         ast::ptr<ast::Type> & common );
    78 
    79 bool typesCompatible(
    80         const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
    81         const ast::TypeEnvironment & env = {} );
    82 
    83 bool typesCompatibleIgnoreQualifiers(
    84         const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
    85         const ast::TypeEnvironment & env = {} );
    86 
    87 /// Creates the type represented by the list of returnVals in a FunctionType.
    88 /// The caller owns the return value.
    89 Type * extractResultType( FunctionType * functionType );
    90 /// Creates or extracts the type represented by returns in a `FunctionType`.
    91 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
    92 
    93 std::vector<ast::ptr<ast::Type>> flattenList(
    94         const std::vector<ast::ptr<ast::Type>> & src, ast::TypeEnvironment & env
    95 );
     86        bool unifyInexact(
     87                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     88                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     89                const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     90                ast::ptr<ast::Type> & common );
    9691
    9792} // namespace ResolvExpr
  • src/ResolvExpr/WidenMode.h

    rad861ef r466787a  
    1919        struct WidenMode {
    2020                WidenMode( bool first, bool second ): first( first ), second( second ) {}
    21 
     21               
    2222                WidenMode &operator|=( const WidenMode &other ) {
    2323                        first |= other.first; second |= other.second; return *this;
     
    3535                        WidenMode newWM( *this ); newWM &= other; return newWM;
    3636                }
    37 
     37               
    3838                operator bool() { return first && second; }
    3939
  • src/ResolvExpr/module.mk

    rad861ef r466787a  
    1717SRC_RESOLVEXPR = \
    1818      ResolvExpr/AdjustExprType.cc \
    19       ResolvExpr/AdjustExprType.hpp \
    2019      ResolvExpr/Alternative.cc \
    2120      ResolvExpr/AlternativeFinder.cc \
     
    2726      ResolvExpr/Candidate.hpp \
    2827      ResolvExpr/CastCost.cc \
    29       ResolvExpr/CastCost.hpp \
    3028      ResolvExpr/CommonType.cc \
    31       ResolvExpr/CommonType.hpp \
    3229      ResolvExpr/ConversionCost.cc \
    3330      ResolvExpr/ConversionCost.h \
     
    4340      ResolvExpr/Occurs.cc \
    4441      ResolvExpr/PolyCost.cc \
    45       ResolvExpr/PolyCost.hpp \
    4642      ResolvExpr/PtrsAssignable.cc \
    47       ResolvExpr/PtrsAssignable.hpp \
    4843      ResolvExpr/PtrsCastable.cc \
    49       ResolvExpr/PtrsCastable.hpp \
    5044      ResolvExpr/RenameVars.cc \
    5145      ResolvExpr/RenameVars.h \
     
    6054      ResolvExpr/SatisfyAssertions.hpp \
    6155      ResolvExpr/SpecCost.cc \
    62       ResolvExpr/SpecCost.hpp \
    6356      ResolvExpr/TypeEnvironment.cc \
    6457      ResolvExpr/TypeEnvironment.h \
  • src/ResolvExpr/typeops.h

    rad861ef r466787a  
    1010// Created On       : Sun May 17 07:28:22 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jan 18 11:54:00 2023
    13 // Update Count     : 7
     12// Last Modified On : Tue Oct  1 09:45:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    1818#include <vector>
    1919
     20#include "Cost.h"
     21#include "TypeEnvironment.h"
     22#include "WidenMode.h"
     23#include "AST/Fwd.hpp"
     24#include "AST/Node.hpp"
     25#include "AST/SymbolTable.hpp"
    2026#include "AST/Type.hpp"
     27#include "AST/TypeEnvironment.hpp"
     28#include "SynTree/SynTree.h"
    2129#include "SynTree/Type.h"
    2230
     
    2634
    2735namespace ResolvExpr {
    28         class TypeEnvironment;
    29 
    3036        // combos: takes a list of sets and returns a set of lists representing every possible way of forming a list by
    3137        // picking one element out of each set
     
    5561        }
    5662
     63        // in AdjustExprType.cc
     64        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
     65        void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     66
     67        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
     68        void adjustExprType( Type *& type );
     69
     70        template< typename ForwardIterator >
     71        void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
     72                while ( begin != end ) {
     73                        adjustExprType( *begin++, env, indexer );
     74                } // while
     75        }
     76
     77        /// Replaces array types with equivalent pointer, and function types with a pointer-to-function
     78        const ast::Type * adjustExprType(
     79                const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
     80
     81        // in CastCost.cc
     82        Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
     83                const SymTab::Indexer & indexer, const TypeEnvironment & env );
     84        Cost castCost(
     85                const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
     86                const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
     87
     88        // in ConversionCost.cc
     89        Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
     90                const SymTab::Indexer & indexer, const TypeEnvironment & env );
     91        Cost conversionCost(
     92                const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
     93                const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
     94
     95        // in AlternativeFinder.cc
     96        Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
     97                const SymTab::Indexer & indexer, const TypeEnvironment & env );
     98
     99        // in PtrsAssignable.cc
     100        int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
     101        int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
     102                const ast::TypeEnvironment & env );
     103
     104        // in PtrsCastable.cc
     105        int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     106        int ptrsCastable(
     107                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     108                const ast::TypeEnvironment & env );
     109
     110        // in Unify.cc
     111        bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     112        bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     113
     114        inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
     115                TypeEnvironment env;
     116                return typesCompatible( t1, t2, indexer, env );
     117        }
     118
     119        inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
     120                TypeEnvironment env;
     121                return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
     122        }
     123
     124        bool typesCompatible(
     125                const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
     126                const ast::TypeEnvironment & env = {} );
     127
     128        bool typesCompatibleIgnoreQualifiers(
     129                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     130                const ast::TypeEnvironment & env = {} );
     131
     132        /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
     133        Type * extractResultType( FunctionType * functionType );
     134        /// Creates or extracts the type represented by the list of returns in a `FunctionType`.
     135        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
     136
     137        // in CommonType.cc
     138        Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
     139        ast::ptr< ast::Type > commonType(
     140                const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
     141                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     142                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab
     143        );
     144        // in Unify.cc
     145        std::vector< ast::ptr< ast::Type > > flattenList(
     146                const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
     147        );
     148
     149        // in PolyCost.cc
     150        int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     151        int polyCost(
     152                const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
     153
     154        // in SpecCost.cc
     155        int specCost( Type * type );
     156        int specCost( const ast::Type * type );
     157
    57158        // in Occurs.cc
    58159        bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env );
     
    67168                return false;
    68169        }
     170
     171        // in AlternativeFinder.cc
     172        void referenceToRvalueConversion( Expression *& expr, Cost & cost );
     173        // in CandidateFinder.cpp
     174        const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost );
    69175
    70176        /// flatten tuple type into list of types
     
    112218                }
    113219
     220
    114221                return new ast::TupleType{ std::move(types) };
    115222        }
     
    120227                return tupleFromTypes( tys.begin(), tys.end() );
    121228        }
     229
     230       
    122231
    123232        // in TypeEnvironment.cc
  • src/SymTab/Indexer.cc

    rad861ef r466787a  
    3131#include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
    3232#include "Mangler.h"               // for Mangler
    33 #include "ResolvExpr/AlternativeFinder.h"  // for referenceToRvalueConversion
    34 #include "ResolvExpr/Unify.h"      // for typesCompatible
     33#include "ResolvExpr/typeops.h"    // for typesCompatible
    3534#include "SynTree/LinkageSpec.h"   // for isMangled, isOverridable, Spec
    3635#include "SynTree/Constant.h"      // for Constant
  • src/SymTab/Mangler.cc

    rad861ef r466787a  
    439439                  private:
    440440                        void mangleDecl( const ast::DeclWithType *declaration );
    441                         void mangleRef( const ast::BaseInstType *refType, const std::string & prefix );
     441                        void mangleRef( const ast::BaseInstType *refType, std::string prefix );
    442442
    443443                        void printQualifiers( const ast::Type *type );
     
    535535                }
    536536
     537                __attribute__((unused))
     538                inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
     539                        std::vector< ast::ptr< ast::Type > > ret;
     540                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
     541                                                        std::mem_fun( &ast::DeclWithType::get_type ) );
     542                        return ret;
     543                }
     544
    537545                void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
    538546                        printQualifiers( functionType );
     
    550558                }
    551559
    552                 void Mangler_new::mangleRef(
    553                                 const ast::BaseInstType * refType, const std::string & prefix ) {
     560                void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) {
    554561                        printQualifiers( refType );
    555562
    556563                        mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
    557564
    558                         if ( mangleGenericParams && ! refType->params.empty() ) {
    559                                 mangleName += "_";
    560                                 for ( const ast::Expr * param : refType->params ) {
    561                                         auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
    562                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
    563                                         maybeAccept( paramType->type.get(), *visitor );
     565                        if ( mangleGenericParams ) {
     566                                if ( ! refType->params.empty() ) {
     567                                        mangleName += "_";
     568                                        for ( const ast::Expr * param : refType->params ) {
     569                                                auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
     570                                                assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
     571                                                maybeAccept( paramType->type.get(), *visitor );
     572                                        }
     573                                        mangleName += "_";
    564574                                }
    565                                 mangleName += "_";
    566575                        }
    567576                }
     
    647656                }
    648657
    649                 // For debugging:
    650658                __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
    651659                        for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     
    657665                        // skip if not including qualifiers
    658666                        if ( typeMode ) return;
    659                         auto funcType = dynamic_cast<const ast::FunctionType *>( type );
    660                         if ( funcType && !funcType->forall.empty() ) {
    661                                 std::list< std::string > assertionNames;
    662                                 int dcount = 0, fcount = 0, vcount = 0, acount = 0;
    663                                 mangleName += Encoding::forall;
    664                                 for ( auto & decl : funcType->forall ) {
    665                                         switch ( decl->kind ) {
    666                                         case ast::TypeDecl::Dtype:
    667                                                 dcount++;
    668                                                 break;
    669                                         case ast::TypeDecl::Ftype:
    670                                                 fcount++;
    671                                                 break;
    672                                         case ast::TypeDecl::Ttype:
    673                                                 vcount++;
    674                                                 break;
    675                                         default:
    676                                                 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
    677                                         } // switch
    678                                         varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
    679                                 } // for
    680                                 for ( auto & assert : funcType->assertions ) {
    681                                         assertionNames.push_back( ast::Pass<Mangler_new>::read(
    682                                                 assert->var.get(),
    683                                                 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
    684                                         acount++;
    685                                 } // for
    686                                 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
    687                                 for ( const auto & a : assertionNames ) mangleName += a;
    688                                 mangleName += "_";
     667                        if ( auto ptype = dynamic_cast< const ast::FunctionType * >(type) ) {
     668                                if ( ! ptype->forall.empty() ) {
     669                                        std::list< std::string > assertionNames;
     670                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     671                                        mangleName += Encoding::forall;
     672                                        for ( auto & decl : ptype->forall ) {
     673                                                switch ( decl->kind ) {
     674                                                  case ast::TypeDecl::Kind::Dtype:
     675                                                        dcount++;
     676                                                        break;
     677                                                  case ast::TypeDecl::Kind::Ftype:
     678                                                        fcount++;
     679                                                        break;
     680                                                  case ast::TypeDecl::Kind::Ttype:
     681                                                        vcount++;
     682                                                        break;
     683                                                  default:
     684                                                        assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
     685                                                } // switch
     686                                                varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
     687                                        } // for
     688                                        for ( auto & assert : ptype->assertions ) {
     689                                                assertionNames.push_back( ast::Pass<Mangler_new>::read(
     690                                                        assert->var.get(),
     691                                                        mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
     692                                                acount++;
     693                                        } // for
     694                                        mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
     695                                        for(const auto & a : assertionNames) mangleName += a;
     696//                                      std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
     697                                        mangleName += "_";
     698                                } // if
    689699                        } // if
    690700                        if ( ! inFunctionType ) {
  • src/SymTab/Validate.cc

    rad861ef r466787a  
    6363#include "InitTweak/GenInit.h"         // for fixReturnStatements
    6464#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    65 #include "ResolvExpr/typeops.h"        // for extractResultType
    66 #include "ResolvExpr/Unify.h"          // for typesCompatible
     65#include "ResolvExpr/typeops.h"        // for typesCompatible
    6766#include "ResolvExpr/Resolver.h"       // for findSingleExpression
    6867#include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
  • src/SynTree/ApplicationExpr.cc

    rad861ef r466787a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ApplicationExpr.cc --
     7// ApplicationExpr.cc.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2626#include "Expression.h"          // for ParamEntry, ApplicationExpr, Expression
    2727#include "InitTweak/InitTweak.h" // for getFunction
    28 #include "ResolvExpr/Unify.h"    // for extractResultType
     28#include "ResolvExpr/typeops.h"  // for extractResultType
    2929#include "Type.h"                // for Type, PointerType, FunctionType
    3030
  • src/SynTree/BasicType.cc

    rad861ef r466787a  
    2929}
    3030
     31bool BasicType::isWholeNumber() const {
     32        return kind == Bool ||
     33                kind ==Char ||
     34                kind == SignedChar ||
     35                kind == UnsignedChar ||
     36                kind == ShortSignedInt ||
     37                kind == ShortUnsignedInt ||
     38                kind == SignedInt ||
     39                kind == UnsignedInt ||
     40                kind == LongSignedInt ||
     41                kind == LongUnsignedInt ||
     42                kind == LongLongSignedInt ||
     43                kind ==LongLongUnsignedInt ||
     44                kind == SignedInt128 ||
     45                kind == UnsignedInt128;
     46}
     47
    3148bool BasicType::isInteger() const {
    3249        return kind <= UnsignedInt128;
  • src/SynTree/Type.h

    rad861ef r466787a  
    271271        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    272272        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     273        bool isWholeNumber() const;
    273274        bool isInteger() const;
    274275};
  • src/Validate/FixReturnTypes.cpp

    rad861ef r466787a  
    2020#include "AST/Type.hpp"
    2121#include "CodeGen/CodeGenerator.h"
    22 #include "ResolvExpr/Unify.h"
     22#include "ResolvExpr/typeops.h"
    2323
    2424namespace ast {
  • src/Validate/ReplaceTypedef.cpp

    rad861ef r466787a  
    2020#include "Common/UniqueName.h"
    2121#include "Common/utility.h"
    22 #include "ResolvExpr/Unify.h"
     22#include "ResolvExpr/typeops.h"
    2323
    2424namespace Validate {
  • tests/Makefile.am

    rad861ef r466787a  
    8888        io/.in/many_read.data \
    8989        meta/fork+exec.hfa \
    90         concurrent/unified_locking/mutex_test.hfa \
    91     concurrent/channels/parallel_harness.hfa
     90        unified_locking/mutex_test.hfa
    9291
    9392dist-hook:
  • tests/concurrent/futures/typed.cfa

    rad861ef r466787a  
    55thread Server {
    66        int cnt;
    7         single_future(int) * requests[NFUTURES];
     7        future(int) * requests[NFUTURES];
    88};
    99
     
    2424void process( Server & this, int i ) {
    2525        if( this.requests[i] == 0p ) return;
    26         single_future(int) * f = this.requests[i];
     26        future(int) * f = this.requests[i];
    2727        this.requests[i] = 0p;
    2828        this.cnt--;
     
    3030}
    3131
    32 void call( Server & mutex this, single_future(int) & f ) {
     32void call( Server & mutex this, future(int) & f ) {
    3333        for(i; NFUTURES) {
    3434                if( this.requests[i] == 0p ) {
     
    7070
    7171void work(void) {
    72         single_future(int) mine;
     72        future(int) mine;
    7373        call( *the_server, mine );
    7474        wait( mine );
  • tests/concurrent/mutexstmt/locks.cfa

    rad861ef r466787a  
    7272
    7373single_acquisition_lock l1;
    74 exp_backoff_then_block_lock l2;
     74linear_backoff_then_block_lock l2;
    7575owner_lock l3;
    7676
  • tests/enum_tests/.expect/typedIntEnum.txt

    rad861ef r466787a  
    1 0=0
    2 1=1
    3 1000=1000
    4 1001=1001
    5 2000=2000
    6 2001=2001
    7 2002=2002
     10
     21
     31000
     41001
     52000
     62001
     72002
  • tests/enum_tests/pointerEnum.cfa

    rad861ef r466787a  
    1111int main() {
    1212    E * v = First;
    13     // sout | "v: " | e.x;
     13    sout | "v: " | e.x;
    1414}
  • tests/enum_tests/typedIntEnum.cfa

    rad861ef r466787a  
    1212
    1313int main() {
    14     printf("0=%d\n", zero);
    15     printf("1=%d\n", one);
    16     printf("1000=%d\n", thousand);
    17     printf("1001=%d\n", thousand_one);
    18     printf("2000=%d\n", two_thousand);
    19     printf("2001=%d\n", two_thousand_one);
    20     printf("2002=%d\n", two_thousand_two);
     14    printf("%d\n", zero);
     15    printf("%d\n", one);
     16    printf("%d\n", thousand);
     17    printf("%d\n", thousand_one);
     18    printf("%d\n", two_thousand);
     19    printf("%d\n", two_thousand_one);
     20    printf("%d\n", two_thousand_two);
    2121    return 0;
    2222}
Note: See TracChangeset for help on using the changeset viewer.