Changeset 6d2af204
- Timestamp:
- Feb 5, 2023, 11:42:15 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 8fa77eb
- Parents:
- 9ef5516 (diff), 35d1de5 (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. - Files:
-
- 6 added
- 32 edited
-
libcfa/prelude/builtins.c (modified) (2 diffs)
-
libcfa/prelude/prelude-gen.cc (modified) (2 diffs)
-
libcfa/src/bits/containers.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/actor.hfa (modified) (14 diffs)
-
libcfa/src/concurrency/coroutine.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/locks.hfa (modified) (1 diff)
-
libcfa/src/concurrency/monitor.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/mutex.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/thread.hfa (modified) (2 diffs)
-
libcfa/src/containers/list.hfa (modified) (2 diffs)
-
libcfa/src/containers/vector.hfa (modified) (2 diffs)
-
libcfa/src/exception.h (modified) (3 diffs)
-
libcfa/src/iostream.hfa (modified) (7 diffs)
-
libcfa/src/iterator.hfa (modified) (3 diffs)
-
libcfa/src/math.trait.hfa (modified) (6 diffs)
-
libcfa/src/stdlib.hfa (modified) (2 diffs)
-
src/Common/ScopedMap.h (modified) (6 diffs)
-
src/Common/SemanticError.h (modified) (3 diffs)
-
src/Concurrency/Actors.cpp (modified) (12 diffs)
-
src/GenPoly/Box.cc (modified) (6 diffs)
-
src/GenPoly/ErasableScopedMap.h (modified) (4 diffs)
-
src/GenPoly/GenPoly.cc (modified) (4 diffs)
-
src/GenPoly/ScopedSet.h (modified) (1 diff)
-
src/GenPoly/ScrubTyVars.cc (modified) (1 diff)
-
src/Parser/parser.yy (modified) (3 diffs)
-
src/SymTab/Validate.cc (modified) (1 diff)
-
src/Validate/ReplaceTypedef.cpp (modified) (1 diff)
-
tests/.expect/forall.txt (modified) (1 diff)
-
tests/Makefile.am (modified) (3 diffs)
-
tests/concurrent/actors/.expect/dynamic.txt (added)
-
tests/concurrent/actors/.expect/executor.txt (added)
-
tests/concurrent/actors/.expect/static.txt (added)
-
tests/concurrent/actors/dynamic.cfa (added)
-
tests/concurrent/actors/executor.cfa (added)
-
tests/concurrent/actors/matrix.cfa (modified) (1 diff)
-
tests/concurrent/actors/static.cfa (added)
-
tests/concurrent/actors/types.cfa (modified) (3 diffs)
-
tests/forall.cfa (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/prelude/builtins.c
r9ef5516 r6d2af204 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 14 08:45:54 202113 // Update Count : 13 312 // Last Modified On : Thu Feb 2 11:33:56 2023 13 // Update Count : 135 14 14 // 15 15 … … 64 64 static inline void ^?{}(generator$ &) {} 65 65 66 trait is_generator(T &) { 66 forall( T & ) 67 trait is_generator { 67 68 void main(T & this); 68 69 generator$ * get_generator(T & this); -
libcfa/prelude/prelude-gen.cc
r9ef5516 r6d2af204 10 10 // Created On : Sat Feb 16 08:44:58 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Apr 2 17:18:24 201913 // Update Count : 3 712 // Last Modified On : Thu Feb 2 11:40:01 2023 13 // Update Count : 38 14 14 // 15 15 … … 159 159 int main() { 160 160 cout << "# 2 \"prelude.cfa\" // needed for error messages from this file" << endl; 161 cout << " trait sized(T &){};" << endl;161 cout << "forall( T & ) trait sized {};" << endl; 162 162 163 163 cout << "//////////////////////////" << endl; -
libcfa/src/bits/containers.hfa
r9ef5516 r6d2af204 10 10 // Created On : Tue Oct 31 16:38:50 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jan 15 07:42:35 202013 // Update Count : 2 812 // Last Modified On : Thu Feb 2 11:33:08 2023 13 // Update Count : 29 14 14 15 15 #pragma once … … 69 69 70 70 #ifdef __cforall 71 trait is_node(T &) { 71 forall( T & ) 72 trait is_node { 72 73 T *& get_next( T & ); 73 74 }; -
libcfa/src/concurrency/actor.hfa
r9ef5516 r6d2af204 1 #pragma once 2 1 3 #include <locks.hfa> 2 4 #include <limits.hfa> 3 5 #include <list.hfa> 6 #include <kernel.hfa> 4 7 5 8 #ifdef __CFA_DEBUG__ … … 21 24 // Define if executor is created in a separate cluster 22 25 #define __DEFAULT_EXECUTOR_SEPCLUS__ false 26 27 // when you flip this make sure to recompile compiler and flip the appropriate flag there too in Actors.cpp 28 #define __ALLOC 0 23 29 24 30 // forward decls … … 38 44 P9_EMBEDDED( request, dlink(request) ) 39 45 40 void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel41 void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) {46 static inline void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel 47 static inline void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) { 42 48 this.receiver = receiver; 43 49 this.msg = msg; … … 45 51 this.stop = false; 46 52 } 47 53 static inline void ?{}( request & this, request & copy ) { 54 this.receiver = copy.receiver; 55 this.msg = copy.msg; 56 this.fn = copy.fn; 57 this.stop = copy.stop; 58 } 59 60 // hybrid data structure. Copies until buffer is full and then allocates for intrusive list 61 struct copy_queue { 62 dlist( request ) list; 63 #if ! __ALLOC 64 request * buffer; 65 size_t count, buffer_size, index; 66 #endif 67 }; 68 static inline void ?{}( copy_queue & this ) {} 69 static inline void ?{}( copy_queue & this, size_t buf_size ) with(this) { 70 list{}; 71 #if ! __ALLOC 72 buffer_size = buf_size; 73 buffer = aalloc( buffer_size ); 74 count = 0; 75 index = 0; 76 #endif 77 } 78 static inline void ^?{}( copy_queue & this ) with(this) { 79 #if ! __ALLOC 80 adelete(buffer); 81 #endif 82 } 83 84 static inline void insert( copy_queue & this, request & elem ) with(this) { 85 #if ! __ALLOC 86 if ( count < buffer_size ) { // fast path ( no alloc ) 87 buffer[count]{ elem }; 88 count++; 89 return; 90 } 91 request * new_elem = alloc(); 92 (*new_elem){ elem }; 93 insert_last( list, *new_elem ); 94 #else 95 insert_last( list, elem ); 96 #endif 97 } 98 99 // once you start removing you need to remove all elements 100 // it is not supported to call insert() before the list is fully empty 101 // should_delete is an output param 102 static inline request & remove( copy_queue & this, bool & should_delete ) with(this) { 103 #if ! __ALLOC 104 if ( count > 0 ) { 105 count--; 106 should_delete = false; 107 size_t old_idx = index; 108 index = count == 0 ? 0 : index + 1; 109 return buffer[old_idx]; 110 } 111 #endif 112 should_delete = true; 113 return try_pop_front( list ); 114 } 115 116 static inline bool isEmpty( copy_queue & this ) with(this) { 117 #if ! __ALLOC 118 return count == 0 && list`isEmpty; 119 #else 120 return list`isEmpty; 121 #endif 122 } 123 124 static size_t __buffer_size = 10; // C_TODO: rework this to be passed from executor through ctors (no need for global) 48 125 struct work_queue { 49 futex_mutex mutex_lock; 50 dlist( request ) input; // unbounded list of work requests 126 __spinlock_t mutex_lock; 127 copy_queue owned_queue; 128 copy_queue * c_queue; // C_TODO: try putting this on the stack with ptr juggling 129 51 130 }; // work_queue 52 void ?{}( work_queue & this ) with(this) { input{}; mutex_lock{}; } 53 54 void insert( work_queue & this, request & elem ) with(this) { 55 lock( mutex_lock ); 56 insert_last( input, elem ); 131 static inline void ?{}( work_queue & this ) with(this) { 132 // c_queue = alloc(); 133 // (*c_queue){ __buffer_size }; 134 owned_queue{ __buffer_size }; 135 c_queue = &owned_queue; 136 } 137 // static inline void ^?{}( work_queue & this ) with(this) { delete( c_queue ); } 138 139 static inline void insert( work_queue & this, request & elem ) with(this) { 140 lock( mutex_lock __cfaabi_dbg_ctx2 ); 141 insert( *c_queue, elem ); 57 142 unlock( mutex_lock ); 58 143 } // insert 59 144 60 void transfer( work_queue & this, dlist(request) & transferTo ) with(this) { 61 lock( mutex_lock ); 62 63 //C_TODO CHANGE 64 // transferTo->transfer( input ); // transfer input to output 65 66 // this is awfully inefficient but Ill use it until transfer is implemented 67 request * r; 68 while ( ! input`isEmpty ) { 69 r = &try_pop_front( input ); 70 if ( r ) insert_last( transferTo, *r ); 71 } 72 73 // transfer( input, transferTo ); 74 145 static inline void transfer( work_queue & this, copy_queue ** transfer_to ) with(this) { 146 lock( mutex_lock __cfaabi_dbg_ctx2 ); 147 // swap copy queue ptrs 148 copy_queue * temp = *transfer_to; 149 *transfer_to = c_queue; 150 c_queue = temp; 75 151 unlock( mutex_lock ); 76 152 } // transfer 77 153 78 154 thread worker { 155 copy_queue owned_queue; 79 156 work_queue * request_queues; 80 dlist( request )current_queue;157 copy_queue * current_queue; 81 158 request & req; 82 159 unsigned int start, range; … … 86 163 ((thread &)this){ clu }; 87 164 this.request_queues = request_queues; 88 this.current_queue{}; 165 // this.current_queue = alloc(); 166 // (*this.current_queue){ __buffer_size }; 167 this.owned_queue{ __buffer_size }; 168 this.current_queue = &this.owned_queue; 89 169 this.start = start; 90 170 this.range = range; 91 171 } 172 // static inline void ^?{}( worker & mutex this ) with(this) { delete( current_queue ); } 92 173 93 174 struct executor { … … 100 181 }; // executor 101 182 102 static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues, bool seperate_clus ) with(this) {183 static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues, bool seperate_clus, size_t buf_size ) with(this) { 103 184 if ( nrqueues < nworkers ) abort( "nrqueues needs to be >= nworkers\n" ); 185 __buffer_size = buf_size; 104 186 this.nprocessors = nprocessors; 105 187 this.nworkers = nworkers; … … 127 209 } // for 128 210 } 129 211 static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues, bool seperate_clus ) { this{ nprocessors, nworkers, nrqueues, seperate_clus, __buffer_size }; } 130 212 static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues ) { this{ nprocessors, nworkers, nrqueues, __DEFAULT_EXECUTOR_SEPCLUS__ }; } 131 213 static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers ) { this{ nprocessors, nworkers, __DEFAULT_EXECUTOR_RQUEUES__ }; } … … 147 229 } // for 148 230 149 delete( workers );150 delete( request_queues );151 delete( processors );231 adelete( workers ); 232 adelete( request_queues ); 233 adelete( processors ); 152 234 if ( seperate_clus ) delete( cluster ); 153 235 } … … 170 252 }; 171 253 172 void ?{}( actor & this ) {254 static inline void ?{}( actor & this ) { 173 255 // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive 174 256 // member must be called to end it … … 178 260 __atomic_fetch_add( &__num_actors_, 1, __ATOMIC_SEQ_CST ); 179 261 } 180 void ^?{}( actor & this ) {}262 static inline void ^?{}( actor & this ) {} 181 263 182 264 static inline void check_actor( actor & this ) { … … 204 286 }; 205 287 206 void ?{}( message & this ) { this.allocation_ = Nodelete; }207 void ?{}( message & this, Allocation allocation ) { this.allocation_ = allocation; }208 void ^?{}( message & this ) {}288 static inline void ?{}( message & this ) { this.allocation_ = Nodelete; } 289 static inline void ?{}( message & this, Allocation allocation ) { this.allocation_ = allocation; } 290 static inline void ^?{}( message & this ) {} 209 291 210 292 static inline void check_message( message & this ) { … … 217 299 } 218 300 219 void deliver_request( request & this ) {301 static inline void deliver_request( request & this ) { 220 302 Allocation actor_allocation = this.fn( *this.receiver, *this.msg ); 221 303 this.receiver->allocation_ = actor_allocation; … … 225 307 226 308 void main( worker & this ) with(this) { 309 bool should_delete; 227 310 Exit: 228 311 for ( unsigned int i = 0;; i = (i + 1) % range ) { // cycle through set of request buffers 229 transfer( request_queues[i + start], current_queue ); 230 while ( ! current_queue`isEmpty ) { 231 &req = &try_pop_front( current_queue ); 312 // C_TODO: potentially check queue count instead of immediately trying to transfer 313 transfer( request_queues[i + start], ¤t_queue ); 314 while ( ! isEmpty( *current_queue ) ) { 315 &req = &remove( *current_queue, should_delete ); 232 316 if ( !&req ) continue; // possibly add some work stealing/idle sleep here 233 317 if ( req.stop ) break Exit; 234 318 deliver_request( req ); 235 319 236 delete( &req );320 if ( should_delete ) delete( &req ); 237 321 } // while 238 322 } // for … … 250 334 __actor_executor_thd = active_thread(); 251 335 __actor_executor_ = alloc(); 252 (*__actor_executor_){ 0, num_thds, num_thds * 16 };336 (*__actor_executor_){ 0, num_thds, num_thds == 1 ? 1 : num_thds * 16 }; 253 337 } 254 338 -
libcfa/src/concurrency/coroutine.hfa
r9ef5516 r6d2af204 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jan 6 16:33:16 202213 // Update Count : 1 212 // Last Modified On : Thu Feb 2 11:31:42 2023 13 // Update Count : 13 14 14 // 15 15 … … 38 38 // Anything that implements this trait can be resumed. 39 39 // Anything that is resumed is a coroutine. 40 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T))) { 40 forall( T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T)) ) 41 trait is_coroutine { 41 42 void main(T & this); 42 43 coroutine$ * get_coroutine(T & this); -
libcfa/src/concurrency/locks.hfa
r9ef5516 r6d2af204 640 640 //----------------------------------------------------------------------------- 641 641 // is_blocking_lock 642 trait is_blocking_lock(L & | sized(L)) { 642 forall( L & | sized(L) ) 643 trait is_blocking_lock { 643 644 // For synchronization locks to use when acquiring 644 645 void on_notify( L &, struct thread$ * ); -
libcfa/src/concurrency/monitor.hfa
r9ef5516 r6d2af204 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 4 07:55:32 201913 // Update Count : 1 112 // Last Modified On : Thu Feb 2 11:29:21 2023 13 // Update Count : 12 14 14 // 15 15 … … 22 22 #include "stdlib.hfa" 23 23 24 trait is_monitor(T &) { 24 forall( T & ) 25 trait is_monitor { 25 26 monitor$ * get_monitor( T & ); 26 27 void ^?{}( T & mutex ); -
libcfa/src/concurrency/mutex.hfa
r9ef5516 r6d2af204 12 12 // Created On : Fri May 25 01:24:09 2018 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Wed Dec 4 09:16:53 201915 // Update Count : 114 // Last Modified On : Thu Feb 2 11:46:08 2023 15 // Update Count : 2 16 16 // 17 17 … … 70 70 void unlock(recursive_mutex_lock & this) __attribute__((deprecated("use concurrency/locks.hfa instead"))); 71 71 72 trait is_lock(L & | sized(L)) { 72 forall( L & | sized(L) ) 73 trait is_lock { 73 74 void lock (L &); 74 75 void unlock(L &); -
libcfa/src/concurrency/thread.hfa
r9ef5516 r6d2af204 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Nov 22 22:18:34 202213 // Update Count : 3 512 // Last Modified On : Thu Feb 2 11:27:59 2023 13 // Update Count : 37 14 14 // 15 15 … … 27 27 //----------------------------------------------------------------------------- 28 28 // thread trait 29 trait is_thread(T &) { 29 forall( T & ) 30 trait is_thread { 30 31 void ^?{}(T& mutex this); 31 32 void main(T& this); -
libcfa/src/containers/list.hfa
r9ef5516 r6d2af204 9 9 // Author : Michael Brooks 10 10 // Created On : Wed Apr 22 18:00:00 2020 11 // Last Modified By : Michael Brooks12 // Last Modified On : Wed Apr 22 18:00:00 202013 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:32:26 2023 13 // Update Count : 2 14 14 // 15 15 … … 23 23 }; 24 24 25 trait embedded( tOuter &, tMid &, tInner & ) { 25 forall( tOuter &, tMid &, tInner & ) 26 trait embedded { 26 27 tytagref( tMid, tInner ) ?`inner( tOuter & ); 27 28 }; -
libcfa/src/containers/vector.hfa
r9ef5516 r6d2af204 10 10 // Created On : Tue Jul 5 18:00:07 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 17 11:02:46 202013 // Update Count : 412 // Last Modified On : Thu Feb 2 11:41:24 2023 13 // Update Count : 5 14 14 // 15 15 … … 50 50 //------------------------------------------------------------------------------ 51 51 //Declaration 52 trait allocator_c(T, allocator_t)53 {52 forall( T, allocator_t ) 53 trait allocator_c { 54 54 void realloc_storage(allocator_t*, size_t); 55 55 T* data(allocator_t*); -
libcfa/src/exception.h
r9ef5516 r6d2af204 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Th r Apr 8 15:20:00 202113 // Update Count : 1 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:20:19 2023 13 // Update Count : 13 14 14 // 15 15 … … 101 101 // implemented in the .c file either so they all have to be inline. 102 102 103 trait is_exception(exceptT &, virtualT &) { 103 forall( exceptT &, virtualT & ) 104 trait is_exception { 104 105 /* The first field must be a pointer to a virtual table. 105 106 * That virtual table must be a decendent of the base exception virtual table. … … 109 110 }; 110 111 111 trait is_termination_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) { 112 forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) ) 113 trait is_termination_exception { 112 114 void defaultTerminationHandler(exceptT &); 113 115 }; 114 116 115 trait is_resumption_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) { 117 forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) ) 118 trait is_resumption_exception { 116 119 void defaultResumptionHandler(exceptT &); 117 120 }; -
libcfa/src/iostream.hfa
r9ef5516 r6d2af204 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Oct 10 10:02:07 202113 // Update Count : 4 0712 // Last Modified On : Thu Feb 2 11:25:39 2023 13 // Update Count : 410 14 14 // 15 15 … … 22 22 23 23 24 trait basic_ostream( ostype & ) { 24 forall( ostype & ) 25 trait basic_ostream { 25 26 // private 26 27 bool sepPrt$( ostype & ); // get separator state (on/off) … … 51 52 }; // basic_ostream 52 53 53 trait ostream( ostype & | basic_ostream( ostype ) ) { 54 forall( ostype & | basic_ostream( ostype ) ) 55 trait ostream { 54 56 bool fail( ostype & ); // operation failed? 55 57 void clear( ostype & ); … … 60 62 }; // ostream 61 63 62 // trait writeable( T ) { 64 // forall( T ) 65 // trait writeable { 63 66 // forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype &, T ); 64 67 // }; // writeable 65 68 66 trait writeable( T, ostype & | ostream( ostype ) ) { 69 forall( T, ostype & | ostream( ostype ) ) 70 trait writeable { 67 71 ostype & ?|?( ostype &, T ); 68 72 }; // writeable … … 290 294 291 295 292 trait basic_istream( istype & ) { 296 forall( istype & ) 297 trait basic_istream { 293 298 // private 294 299 bool getANL$( istype & ); // get scan newline (on/off) … … 302 307 }; // basic_istream 303 308 304 trait istream( istype & | basic_istream( istype ) ) { 309 forall( istype & | basic_istream( istype ) ) 310 trait istream { 305 311 bool fail( istype & ); 306 312 void clear( istype & ); … … 310 316 }; // istream 311 317 312 trait readable( T ) { 318 forall( T ) 319 trait readable { 313 320 forall( istype & | istream( istype ) ) istype & ?|?( istype &, T ); 314 321 }; // readable -
libcfa/src/iterator.hfa
r9ef5516 r6d2af204 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 08:37:25 201713 // Update Count : 1 012 // Last Modified On : Thu Feb 2 11:21:50 2023 13 // Update Count : 11 14 14 // 15 15 … … 17 17 18 18 // An iterator can be used to traverse a data structure. 19 trait iterator( iterator_type, elt_type ) { 19 forall( iterator_type, elt_type ) 20 trait iterator { 20 21 // point to the next element 21 22 // iterator_type ?++( iterator_type & ); … … 31 32 }; 32 33 33 trait iterator_for( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) { 34 forall( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) 35 trait iterator_for { 34 36 // [ iterator_type begin, iterator_type end ] get_iterators( collection_type ); 35 37 iterator_type begin( collection_type ); -
libcfa/src/math.trait.hfa
r9ef5516 r6d2af204 10 10 // Created On : Fri Jul 16 15:40:52 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Jul 20 17:47:19 202113 // Update Count : 1912 // Last Modified On : Thu Feb 2 11:36:56 2023 13 // Update Count : 20 14 14 // 15 15 16 16 #pragma once 17 17 18 trait Not( U ) { 18 forall( U ) 19 trait Not { 19 20 void ?{}( U &, zero_t ); 20 21 int !?( U ); 21 22 }; // Not 22 23 23 trait Equality( T | Not( T ) ) { 24 forall( T | Not( T ) ) 25 trait Equality { 24 26 int ?==?( T, T ); 25 27 int ?!=?( T, T ); 26 28 }; // Equality 27 29 28 trait Relational( U | Equality( U ) ) { 30 forall( U | Equality( U ) ) 31 trait Relational { 29 32 int ?<?( U, U ); 30 33 int ?<=?( U, U ); … … 33 36 }; // Relational 34 37 35 trait Signed( T ) { 38 forall ( T ) 39 trait Signed { 36 40 T +?( T ); 37 41 T -?( T ); … … 39 43 }; // Signed 40 44 41 trait Additive( U | Signed( U ) ) { 45 forall( U | Signed( U ) ) 46 trait Additive { 42 47 U ?+?( U, U ); 43 48 U ?-?( U, U ); … … 46 51 }; // Additive 47 52 48 trait Incdec( T | Additive( T ) ) { 53 forall( T | Additive( T ) ) 54 trait Incdec { 49 55 void ?{}( T &, one_t ); 50 56 // T ?++( T & ); … … 54 60 }; // Incdec 55 61 56 trait Multiplicative( U | Incdec( U ) ) { 62 forall( U | Incdec( U ) ) 63 trait Multiplicative { 57 64 U ?*?( U, U ); 58 65 U ?/?( U, U ); … … 61 68 }; // Multiplicative 62 69 63 trait Arithmetic( T | Relational( T ) | Multiplicative( T ) ) { 70 forall( T | Relational( T ) | Multiplicative( T ) ) 71 trait Arithmetic { 64 72 }; // Arithmetic 65 73 -
libcfa/src/stdlib.hfa
r9ef5516 r6d2af204 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Dec 11 18:25:53 202213 // Update Count : 76 512 // Last Modified On : Thu Feb 2 11:30:04 2023 13 // Update Count : 766 14 14 // 15 15 … … 404 404 // calls( sprng ); 405 405 406 trait basic_prng( PRNG &, R ) { 406 forall( PRNG &, R ) 407 trait basic_prng { 407 408 void set_seed( PRNG & prng, R seed ); // set seed 408 409 R get_seed( PRNG & prng ); // get seed -
src/Common/ScopedMap.h
r9ef5516 r6d2af204 37 37 template<typename N> 38 38 Scope(N && n) : map(), note(std::forward<N>(n)) {} 39 39 40 40 Scope() = default; 41 41 Scope(const Scope &) = default; … … 46 46 typedef std::vector< Scope > ScopeList; 47 47 48 ScopeList scopes; ///< scoped list of maps 48 /// Scoped list of maps. 49 ScopeList scopes; 49 50 public: 50 51 typedef typename MapType::key_type key_type; … … 58 59 typedef typename MapType::const_pointer const_pointer; 59 60 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > { 61 friend class ScopedMap; 62 friend class const_iterator; 63 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 64 typedef typename ScopedMap::ScopeList scope_list; 65 typedef typename scope_list::size_type size_type; 66 67 /// Checks if this iterator points to a valid item 68 bool is_valid() const { 69 return it != (*scopes)[level].map.end(); 70 } 71 72 /// Increments on invalid 73 iterator & next_valid() { 74 if ( ! is_valid() ) { ++(*this); } 75 return *this; 76 } 77 78 /// Decrements on invalid 79 iterator & prev_valid() { 80 if ( ! is_valid() ) { --(*this); } 81 return *this; 82 } 83 84 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 85 : scopes(&_scopes), it(_it), level(inLevel) {} 86 public: 87 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 88 iterator & operator= (const iterator & that) { 89 scopes = that.scopes; level = that.level; it = that.it; 90 return *this; 91 } 92 93 reference operator* () { return *it; } 94 pointer operator-> () const { return it.operator->(); } 95 96 iterator & operator++ () { 97 if ( it == (*scopes)[level].map.end() ) { 98 if ( level == 0 ) return *this; 99 --level; 100 it = (*scopes)[level].map.begin(); 101 } else { 102 ++it; 103 } 104 return next_valid(); 105 } 106 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 107 108 iterator & operator-- () { 109 // may fail if this is the begin iterator; allowed by STL spec 110 if ( it == (*scopes)[level].map.begin() ) { 111 ++level; 112 it = (*scopes)[level].map.end(); 113 } 114 --it; 115 return prev_valid(); 116 } 117 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 118 119 bool operator== (const iterator & that) const { 120 return scopes == that.scopes && level == that.level && it == that.it; 121 } 122 bool operator!= (const iterator & that) const { return !( *this == that ); } 123 124 size_type get_level() const { return level; } 125 126 Note & get_note() { return (*scopes)[level].note; } 127 const Note & get_note() const { return (*scopes)[level].note; } 128 129 private: 130 scope_list *scopes; 131 wrapped_iterator it; 132 size_type level; 133 }; 134 135 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 136 value_type > { 137 friend class ScopedMap; 138 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 139 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator; 140 typedef typename ScopedMap::ScopeList scope_list; 141 typedef typename scope_list::size_type size_type; 142 143 /// Checks if this iterator points to a valid item 144 bool is_valid() const { 145 return it != (*scopes)[level].map.end(); 146 } 147 148 /// Increments on invalid 149 const_iterator & next_valid() { 150 if ( ! is_valid() ) { ++(*this); } 151 return *this; 152 } 153 154 /// Decrements on invalid 155 const_iterator & prev_valid() { 156 if ( ! is_valid() ) { --(*this); } 157 return *this; 158 } 159 160 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 161 : scopes(&_scopes), it(_it), level(inLevel) {} 162 public: 163 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 164 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 165 const_iterator & operator= (const iterator & that) { 166 scopes = that.scopes; level = that.level; it = that.it; 167 return *this; 168 } 169 const_iterator & operator= (const const_iterator & that) { 170 scopes = that.scopes; level = that.level; it = that.it; 171 return *this; 172 } 173 174 const_reference operator* () { return *it; } 175 const_pointer operator-> () { return it.operator->(); } 176 177 const_iterator & operator++ () { 178 if ( it == (*scopes)[level].map.end() ) { 179 if ( level == 0 ) return *this; 180 --level; 181 it = (*scopes)[level].map.begin(); 182 } else { 183 ++it; 184 } 185 return next_valid(); 186 } 187 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 188 189 const_iterator & operator-- () { 190 // may fail if this is the begin iterator; allowed by STL spec 191 if ( it == (*scopes)[level].map.begin() ) { 192 ++level; 193 it = (*scopes)[level].map.end(); 194 } 195 --it; 196 return prev_valid(); 197 } 198 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 199 200 bool operator== (const const_iterator & that) const { 201 return scopes == that.scopes && level == that.level && it == that.it; 202 } 203 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 204 205 size_type get_level() const { return level; } 206 207 const Note & get_note() const { return (*scopes)[level].note; } 208 209 private: 210 scope_list const *scopes; 211 wrapped_const_iterator it; 212 size_type level; 213 }; 61 // Both iterator types are complete bidrectional iterators, see below. 62 class iterator; 63 class const_iterator; 214 64 215 65 /// Starts a new scope … … 297 147 } 298 148 299 template< typename value_type_t >300 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {301 MapType & scope = (*at.scopes)[ at.level ].map;302 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );303 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );304 }305 306 149 template< typename value_t > 307 150 std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); } … … 324 167 } 325 168 326 iterator erase( iterator pos ) { 327 MapType & scope = (*pos.scopes)[ pos.level ].map; 328 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it ); 329 iterator it( *pos.scopes, new_it, pos.level ); 330 return it.next_valid(); 169 /// Erases element with key in the innermost scope that has it. 170 size_type erase( const Key & key ) { 171 for ( auto it = scopes.rbegin() ; it != scopes.rend() ; ++it ) { 172 if ( size_type i = it->map.erase( key ) ; 0 != i ) return i; 173 } 174 return 0; 331 175 } 332 176 … … 343 187 return c; 344 188 } 189 190 bool contains( const Key & key ) const { 191 return find( key ) != cend(); 192 } 193 }; 194 195 template<typename Key, typename Value, typename Note> 196 class ScopedMap<Key, Value, Note>::iterator : 197 public std::iterator< std::bidirectional_iterator_tag, value_type > { 198 friend class ScopedMap; 199 friend class const_iterator; 200 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 201 typedef typename ScopedMap::ScopeList scope_list; 202 typedef typename scope_list::size_type size_type; 203 204 /// Checks if this iterator points to a valid item 205 bool is_valid() const { 206 return it != (*scopes)[level].map.end(); 207 } 208 209 /// Increments on invalid 210 iterator & next_valid() { 211 if ( ! is_valid() ) { ++(*this); } 212 return *this; 213 } 214 215 /// Decrements on invalid 216 iterator & prev_valid() { 217 if ( ! is_valid() ) { --(*this); } 218 return *this; 219 } 220 221 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 222 : scopes(&_scopes), it(_it), level(inLevel) {} 223 public: 224 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 225 iterator & operator= (const iterator & that) { 226 scopes = that.scopes; level = that.level; it = that.it; 227 return *this; 228 } 229 230 reference operator* () { return *it; } 231 pointer operator-> () const { return it.operator->(); } 232 233 iterator & operator++ () { 234 if ( it == (*scopes)[level].map.end() ) { 235 if ( level == 0 ) return *this; 236 --level; 237 it = (*scopes)[level].map.begin(); 238 } else { 239 ++it; 240 } 241 return next_valid(); 242 } 243 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 244 245 iterator & operator-- () { 246 // may fail if this is the begin iterator; allowed by STL spec 247 if ( it == (*scopes)[level].map.begin() ) { 248 ++level; 249 it = (*scopes)[level].map.end(); 250 } 251 --it; 252 return prev_valid(); 253 } 254 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 255 256 bool operator== (const iterator & that) const { 257 return scopes == that.scopes && level == that.level && it == that.it; 258 } 259 bool operator!= (const iterator & that) const { return !( *this == that ); } 260 261 size_type get_level() const { return level; } 262 263 Note & get_note() { return (*scopes)[level].note; } 264 const Note & get_note() const { return (*scopes)[level].note; } 265 266 private: 267 scope_list *scopes; 268 wrapped_iterator it; 269 size_type level; 270 }; 271 272 template<typename Key, typename Value, typename Note> 273 class ScopedMap<Key, Value, Note>::const_iterator : 274 public std::iterator< std::bidirectional_iterator_tag, value_type > { 275 friend class ScopedMap; 276 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 277 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator; 278 typedef typename ScopedMap::ScopeList scope_list; 279 typedef typename scope_list::size_type size_type; 280 281 /// Checks if this iterator points to a valid item 282 bool is_valid() const { 283 return it != (*scopes)[level].map.end(); 284 } 285 286 /// Increments on invalid 287 const_iterator & next_valid() { 288 if ( ! is_valid() ) { ++(*this); } 289 return *this; 290 } 291 292 /// Decrements on invalid 293 const_iterator & prev_valid() { 294 if ( ! is_valid() ) { --(*this); } 295 return *this; 296 } 297 298 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 299 : scopes(&_scopes), it(_it), level(inLevel) {} 300 public: 301 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 302 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 303 const_iterator & operator= (const iterator & that) { 304 scopes = that.scopes; level = that.level; it = that.it; 305 return *this; 306 } 307 const_iterator & operator= (const const_iterator & that) { 308 scopes = that.scopes; level = that.level; it = that.it; 309 return *this; 310 } 311 312 const_reference operator* () { return *it; } 313 const_pointer operator-> () { return it.operator->(); } 314 315 const_iterator & operator++ () { 316 if ( it == (*scopes)[level].map.end() ) { 317 if ( level == 0 ) return *this; 318 --level; 319 it = (*scopes)[level].map.begin(); 320 } else { 321 ++it; 322 } 323 return next_valid(); 324 } 325 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 326 327 const_iterator & operator-- () { 328 // may fail if this is the begin iterator; allowed by STL spec 329 if ( it == (*scopes)[level].map.begin() ) { 330 ++level; 331 it = (*scopes)[level].map.end(); 332 } 333 --it; 334 return prev_valid(); 335 } 336 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 337 338 bool operator== (const const_iterator & that) const { 339 return scopes == that.scopes && level == that.level && it == that.it; 340 } 341 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 342 343 size_type get_level() const { return level; } 344 345 const Note & get_note() const { return (*scopes)[level].note; } 346 347 private: 348 scope_list const *scopes; 349 wrapped_const_iterator it; 350 size_type level; 345 351 }; 346 352 -
src/Common/SemanticError.h
r9ef5516 r6d2af204 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 4 14:08:26 202213 // Update Count : 3 512 // Last Modified On : Thu Feb 2 10:59:10 2023 13 // Update Count : 36 14 14 // 15 15 … … 54 54 55 55 constexpr WarningData WarningFormats[] = { 56 {"self-assign" , Severity::Warn , "self assignment of expression: %s" }, 57 {"reference-conversion" , Severity::Warn , "rvalue to reference conversion of rvalue: %s" }, 58 {"qualifiers-zero_t-one_t", Severity::Warn , "questionable use of type qualifier %s with %s" }, 59 {"aggregate-forward-decl" , Severity::Warn , "forward declaration of nested aggregate: %s" }, 60 {"superfluous-decl" , Severity::Warn , "declaration does not allocate storage: %s" }, 61 {"superfluous-else" , Severity::Warn , "else clause never executed for empty loop conditional" }, 62 {"gcc-attributes" , Severity::Warn , "invalid attribute: %s" }, 63 {"c++-like-copy" , Severity::Warn , "Constructor from reference is not a valid copy constructor" }, 56 {"self-assign" , Severity::Warn , "self assignment of expression: %s" }, 57 {"reference-conversion" , Severity::Warn , "rvalue to reference conversion of rvalue: %s" }, 58 {"qualifiers-zero_t-one_t" , Severity::Warn , "questionable use of type qualifier %s with %s" }, 59 {"aggregate-forward-decl" , Severity::Warn , "forward declaration of nested aggregate: %s" }, 60 {"superfluous-decl" , Severity::Warn , "declaration does not allocate storage: %s" }, 61 {"superfluous-else" , Severity::Warn , "else clause never executed for empty loop conditional" }, 62 {"gcc-attributes" , Severity::Warn , "invalid attribute: %s" }, 63 {"c++-like-copy" , Severity::Warn , "Constructor from reference is not a valid copy constructor" }, 64 {"depreciated-trait-syntax" , Severity::Warn , "trait type-parameters are now specified using the forall clause" }, 64 65 }; 65 66 … … 73 74 GccAttributes, 74 75 CppCopy, 76 DeprecTraitSyntax, 75 77 NUMBER_OF_WARNINGS, // This MUST be the last warning 76 78 }; -
src/Concurrency/Actors.cpp
r9ef5516 r6d2af204 21 21 #include "AST/TranslationUnit.hpp" 22 22 #include "AST/Expr.hpp" 23 #include <algorithm> 23 24 using namespace ast; 25 using namespace std; 24 26 25 27 namespace Concurrency { 26 28 27 29 struct CollectactorStructDecls : public ast::WithGuards { 28 std::map<const StructDecl *, int> & actorStructDecls;29 std::map<const StructDecl *, int> & messageStructDecls;30 unordered_set<const StructDecl *> & actorStructDecls; 31 unordered_set<const StructDecl *> & messageStructDecls; 30 32 const StructDecl ** requestDecl; 31 33 const EnumDecl ** allocationDecl; … … 34 36 StructDecl * parentDecl; 35 37 bool insideStruct = false; 36 38 bool namedDecl = false; 39 40 // finds and sets a ptr to the Allocation enum, which is needed in the next pass 37 41 void previsit( const EnumDecl * decl ) { 38 42 if( decl->name == "Allocation" ) *allocationDecl = decl; 39 43 } 40 44 45 // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass 41 46 void previsit( const StructDecl * decl ) { 42 47 GuardValue(insideStruct); … … 45 50 if( decl->name == "actor" ) *actorDecl = decl; 46 51 if( decl->name == "message" ) *msgDecl = decl; 47 if( decl->name == "request" ) *requestDecl = decl; 52 if( decl->name == "request" ) *requestDecl = decl; 48 53 } 49 54 55 // this catches structs of the form: 56 // struct dummy_actor { actor a; }; 57 // since they should be: 58 // struct dummy_actor { inline actor; }; 59 void previsit ( const ObjectDecl * decl ) { 60 if ( insideStruct && ! decl->name.empty() ) { 61 GuardValue(namedDecl); 62 namedDecl = true; 63 } 64 } 65 66 // this collects the valid actor and message struct decl pts 50 67 void postvisit( const StructInstType * node ) { 51 68 if ( ! *actorDecl || ! *msgDecl ) return; 52 if ( insideStruct ) {69 if ( insideStruct && !namedDecl ) { 53 70 if ( node->aggr() == *actorDecl ) { 54 actorStructDecls.insert( {parentDecl, 1});71 actorStructDecls.insert( parentDecl ); 55 72 } else if ( node->aggr() == *msgDecl ) { 56 messageStructDecls.insert( {parentDecl, 1});73 messageStructDecls.insert( parentDecl ); 57 74 } 58 75 } … … 60 77 61 78 public: 62 CollectactorStructDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,79 CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 63 80 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl ) 64 81 : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), … … 66 83 }; 67 84 85 // keeps track of all fwdDecls of message routines so that we can hoist them to right after the appropriate decls 86 class FwdDeclTable { 87 88 // tracks which decls we have seen so that we can hoist the FunctionDecl to the highest point possible 89 struct FwdDeclData { 90 const StructDecl * actorDecl; 91 const StructDecl * msgDecl; 92 FunctionDecl * fwdDecl; 93 bool actorFound; 94 bool msgFound; 95 96 bool readyToInsert() { return actorFound && msgFound; } 97 bool foundActor() { actorFound = true; return readyToInsert(); } 98 bool foundMsg() { msgFound = true; return readyToInsert(); } 99 100 FwdDeclData( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) : 101 actorDecl(actorDecl), msgDecl(msgDecl), fwdDecl(fwdDecl), actorFound(false), msgFound(false) {} 102 }; 103 104 // map indexed by actor struct ptr 105 // value is map of all FwdDeclData that contains said actor struct ptr 106 // inner map is indexed by the message struct ptr of FwdDeclData 107 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> actorMap; 108 109 // this map is the same except the outer map is indexed by message ptr and the inner is indexed by actor ptr 110 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> msgMap; 111 112 void insert( const StructDecl * decl, const StructDecl * otherDecl, unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map, FwdDeclData * data ) { 113 auto iter = map.find( decl ); 114 if ( iter != map.end() ) { // if decl exists in map append data to existing inner map 115 iter->second.emplace( make_pair( otherDecl, data ) ); 116 } else { // else create inner map for key 117 map.emplace( make_pair( decl, unordered_map<const StructDecl *, FwdDeclData *>( { make_pair( otherDecl, data ) } ) ) ); 118 } 119 } 120 121 public: 122 // insert decl into table so that we can fwd declare it later (average cost: O(1)) 123 void insertDecl( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) { 124 FwdDeclData * declToInsert = new FwdDeclData( actorDecl, msgDecl, fwdDecl ); 125 insert( actorDecl, msgDecl, actorMap, declToInsert ); 126 insert( msgDecl, actorDecl, msgMap, declToInsert ); 127 } 128 129 // returns list of decls to insert after current struct decl 130 // Over the entire pass the runtime of this routine is O(r) where r is the # of receive routines 131 list<FunctionDecl *> updateDecl( const StructDecl * decl, bool isMsg ) { 132 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map = isMsg ? msgMap : actorMap; 133 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & otherMap = isMsg ? actorMap : msgMap; 134 auto iter = map.find( decl ); 135 list<FunctionDecl *> toInsertAfter; // this is populated with decls that are ready to insert 136 if ( iter == map.end() ) return toInsertAfter; 137 138 // iterate over inner map 139 unordered_map<const StructDecl *, FwdDeclData *> & currInnerMap = iter->second; 140 for ( auto innerIter = currInnerMap.begin(); innerIter != currInnerMap.end(); ) { 141 FwdDeclData * currentDatum = innerIter->second; 142 bool readyToInsert = isMsg ? currentDatum->foundMsg() : currentDatum->foundActor(); 143 if ( ! readyToInsert ) { ++innerIter; continue; } 144 145 // readyToInsert is true so we are good to insert the forward decl of the message fn 146 toInsertAfter.push_back( currentDatum->fwdDecl ); 147 148 // need to remove from other map before deleting 149 // find inner map in other map ( other map is actor map if original is msg map and vice versa ) 150 const StructDecl * otherDecl = isMsg ? currentDatum->actorDecl : currentDatum->msgDecl; 151 auto otherMapIter = otherMap.find( otherDecl ); 152 153 unordered_map<const StructDecl *, FwdDeclData *> & otherInnerMap = otherMapIter->second; 154 155 // find the FwdDeclData we need to remove in the other inner map 156 auto otherInnerIter = otherInnerMap.find( decl ); 157 158 // remove references to deleted FwdDeclData from current inner map 159 innerIter = currInnerMap.erase( innerIter ); // this does the increment so no explicit inc needed 160 161 // remove references to deleted FwdDeclData from other inner map 162 otherInnerMap.erase( otherInnerIter ); 163 164 // if other inner map is now empty, remove key from other outer map 165 if ( otherInnerMap.empty() ) 166 otherMap.erase( otherDecl ); 167 168 // now we are safe to delete the FwdDeclData since we are done with it 169 // and we have removed all references to it from our data structures 170 delete currentDatum; 171 } 172 173 // if current inner map is now empty, remove key from outer map. 174 // Have to do this after iterating for safety 175 if ( currInnerMap.empty() ) 176 map.erase( decl ); 177 178 return toInsertAfter; 179 } 180 }; 181 182 #define __ALLOC 0 // C_TODO: complete swap to no-alloc version 183 68 184 struct GenReceiveDecls : public ast::WithDeclsToAdd<> { 69 std::map<const StructDecl *, int> & actorStructDecls;70 std::map<const StructDecl *, int> & messageStructDecls;185 unordered_set<const StructDecl *> & actorStructDecls; 186 unordered_set<const StructDecl *> & messageStructDecls; 71 187 const StructDecl ** requestDecl; 72 188 const EnumDecl ** allocationDecl; 73 189 const StructDecl ** actorDecl; 74 190 const StructDecl ** msgDecl; 75 std::vector<FunctionDecl *>& forwardDecls;191 FwdDeclTable & forwardDecls; 76 192 77 193 void postvisit( const FunctionDecl * decl ) { … … 90 206 91 207 // If the struct instances are derived actor and message types then generate the message send routine 92 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) { 208 auto actorIter = actorStructDecls.find( arg1InstType->aggr() ); 209 auto messageIter = messageStructDecls.find( arg2InstType->aggr() ); 210 if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) { 93 211 94 212 // check that we have found all the decls we need from <actor.hfa> … … 107 225 return receiver; 108 226 } 109 */ 227 */ // C_TODO: update this with new no alloc version 110 228 CompoundStmt * sendBody = new CompoundStmt( decl->location ); 111 229 230 #if __ALLOC 112 231 // Generates: request * new_req = alloc(); 113 232 sendBody->push_back( new DeclStmt( … … 120 239 ) 121 240 )); 241 #else 242 // Generates: request new_req; 243 sendBody->push_back( new DeclStmt( 244 decl->location, 245 new ObjectDecl( 246 decl->location, 247 "new_req", 248 new StructInstType( *requestDecl ) 249 ) 250 )); 251 #endif 122 252 123 253 // Function type is: Allocation (*)( derived_actor &, derived_msg & ) … … 160 290 )); 161 291 292 #if __ALLOC 162 293 // Generates: (*new_req){ &receiver, &msg, fn }; 163 294 sendBody->push_back( new ExprStmt( … … 189 320 ) 190 321 )); 322 #else 323 // Generates: new_req{ &receiver, &msg, fn }; 324 sendBody->push_back( new ExprStmt( 325 decl->location, 326 new UntypedExpr ( 327 decl->location, 328 new NameExpr( decl->location, "?{}" ), 329 { 330 new NameExpr( decl->location, "new_req" ), 331 new AddressExpr( new NameExpr( decl->location, "receiver" ) ), 332 new AddressExpr( new NameExpr( decl->location, "msg" ) ), 333 new NameExpr( decl->location, "fn" ) 334 } 335 ) 336 )); 337 338 // Generates: send( receiver, new_req ); 339 sendBody->push_back( new ExprStmt( 340 decl->location, 341 new UntypedExpr ( 342 decl->location, 343 new NameExpr( decl->location, "send" ), 344 { 345 { 346 new NameExpr( decl->location, "receiver" ), 347 new NameExpr( decl->location, "new_req" ) 348 } 349 } 350 ) 351 )); 352 #endif 191 353 192 354 // Generates: return receiver; … … 225 387 226 388 // forward decls to resolve use before decl problem for '|' routines 227 forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 389 forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) ); 390 // forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 228 391 229 392 sendOperatorFunction->stmts = sendBody; … … 233 396 234 397 public: 235 GenReceiveDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,398 GenReceiveDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 236 399 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 237 std::vector<FunctionDecl *>& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),400 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 238 401 requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {} 239 402 }; 240 403 241 404 struct GenFwdDecls : public ast::WithDeclsToAdd<> { 242 std::map<const StructDecl *, int> & actorStructDecls;243 std::map<const StructDecl *, int> & messageStructDecls;244 std::vector<FunctionDecl *>& forwardDecls;245 bool done; 246 247 void postvisit( const FunctionDecl * decl ) {248 if ( done ) return;249 // return if not of the form receive( param1, param2 ) or if it is a forwarddecl250 if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;251 252 // the params should be references 253 const ReferenceType * derivedActorRef = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());254 const ReferenceType * derivedMsgRef = dynamic_cast<const ReferenceType *>(decl->params.at(1)->get_type());255 if ( !derivedActorRef || !derivedMsgRef ) return;256 257 // the references should be to struct instances258 const StructInstType * arg1InstType = dynamic_cast<const StructInstType *>(derivedActorRef->base.get()); 259 const StructInstType * arg2InstType = dynamic_cast<const StructInstType *>(derivedMsgRef->base.get());260 if ( !arg1InstType || !arg2InstType ) return; 261 262 // If the struct instances are derived actor and message types then generate the message send routine263 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) {264 done = true; 265 for ( const auto & func : forwardDecls ) {266 declsToAddBefore.push_back( func );267 }405 unordered_set<const StructDecl *> & actorStructDecls; 406 unordered_set<const StructDecl *> & messageStructDecls; 407 FwdDeclTable & forwardDecls; 408 409 void postvisit( const StructDecl * decl ) { 410 list<FunctionDecl *> toAddAfter; 411 auto actorIter = actorStructDecls.find( decl ); 412 if ( actorIter != actorStructDecls.end() ) { // this is a derived actor decl 413 // get list of fwd decls that we can now insert 414 toAddAfter = forwardDecls.updateDecl( decl, false ); 415 416 // get rid of decl from actorStructDecls since we no longer need it 417 actorStructDecls.erase( actorIter ); 418 } else { 419 auto messageIter = messageStructDecls.find( decl ); 420 if ( messageIter == messageStructDecls.end() ) return; 421 422 toAddAfter = forwardDecls.updateDecl( decl, true ); 423 424 // get rid of decl from messageStructDecls since we no longer need it 425 messageStructDecls.erase( messageIter ); 426 } 427 428 // add the fwd decls to declsToAddAfter 429 for ( FunctionDecl * func : toAddAfter ) { 430 declsToAddAfter.push_back( func ); 268 431 } 269 432 } 270 433 271 434 public: 272 GenFwdDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,273 std::vector<FunctionDecl *>& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),274 forwardDecls(forwardDecls) , done(false){}435 GenFwdDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 436 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 437 forwardDecls(forwardDecls) {} 275 438 }; 276 439 277 440 void implementActors( TranslationUnit & translationUnit ) { 278 // maps to collect all derived actor and message types279 std::map<const StructDecl *, int> actorStructDecls;280 std::map<const StructDecl *, int> messageStructDecls;281 std::vector<FunctionDecl *>forwardDecls;441 // unordered_maps to collect all derived actor and message types 442 unordered_set<const StructDecl *> actorStructDecls; 443 unordered_set<const StructDecl *> messageStructDecls; 444 FwdDeclTable forwardDecls; 282 445 283 446 // for storing through the passes -
src/GenPoly/Box.cc
r9ef5516 r6d2af204 488 488 for ( FunctionType const * const funType : functions ) { 489 489 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 490 if ( adapters.find( mangleName ) == adapters.end() ) {490 if ( !adapters.contains( mangleName ) ) { 491 491 std::string adapterName = makeAdapterName( mangleName ); 492 492 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) ); … … 1487 1487 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 1488 1488 // do not try to monomorphize generic parameters 1489 if ( scopeTyVars. find( typeInst->get_name() ) != scopeTyVars.end() && ! genericParams.count( typeInst->name ) ) {1489 if ( scopeTyVars.contains( typeInst->get_name() ) && ! genericParams.count( typeInst->name ) ) { 1490 1490 // polymorphic aggregate members should be converted into monomorphic members. 1491 1491 // Using char[size_T] here respects the expected sizing rules of an aggregate type. … … 1696 1696 1697 1697 if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) { 1698 if ( scopeTyVars. find( typeInst->get_name() ) != scopeTyVars.end() ) {1698 if ( scopeTyVars.contains( typeInst->get_name() ) ) { 1699 1699 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set 1700 1700 return true; … … 1704 1704 // check if this type already has a layout generated for it 1705 1705 std::string typeName = mangleType( ty ); 1706 if ( knownLayouts. find( typeName ) != knownLayouts.end() ) return true;1706 if ( knownLayouts.contains( typeName ) ) return true; 1707 1707 1708 1708 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 1741 1741 // check if this type already has a layout generated for it 1742 1742 std::string typeName = mangleType( ty ); 1743 if ( knownLayouts. find( typeName ) != knownLayouts.end() ) return true;1743 if ( knownLayouts.contains( typeName ) ) return true; 1744 1744 1745 1745 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 1832 1832 } else { 1833 1833 std::string offsetName = offsetofName( mangleType( ty ) ); 1834 if ( knownOffsets. find( offsetName ) != knownOffsets.end() ) {1834 if ( knownOffsets.contains( offsetName ) ) { 1835 1835 // use the already-generated offsets for this type 1836 1836 ret = new NameExpr( offsetName ); -
src/GenPoly/ErasableScopedMap.h
r9ef5516 r6d2af204 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ScopedMap.h --7 // ErasableScopedMap.h -- 8 8 // 9 9 // Author : Aaron B. Moss … … 51 51 typedef typename Scope::const_pointer const_pointer; 52 52 53 // Both iterator types are complete bidirection iterators, definedbelow.53 // Both iterator types are complete bidirectional iterators, see below. 54 54 class iterator; 55 55 class const_iterator; … … 118 118 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 119 119 120 Value& operator[] ( const Key &key ) { 121 iterator slot = find( key ); 122 if ( slot != end() ) return slot->second; 123 return insert( key, Value() ).first->second; 124 } 125 120 126 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 121 127 size_type erase( const Key &key ) { … … 130 136 } 131 137 132 Value& operator[] ( const Key &key ) { 133 iterator slot = find( key ); 134 if ( slot != end() ) return slot->second; 135 return insert( key, Value() ).first->second; 138 bool contains( const Key & key ) const { 139 return find( key ) != cend(); 136 140 } 137 141 }; -
src/GenPoly/GenPoly.cc
r9ef5516 r6d2af204 172 172 173 173 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 174 if ( tyVars. find( typeInst->get_name() ) != tyVars.end() ) {174 if ( tyVars.contains( typeInst->get_name() ) ) { 175 175 return type; 176 176 } … … 189 189 190 190 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 191 return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr;191 if ( tyVars.contains( typeInst->typeString() ) ) return type; 192 192 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) { 193 193 return isPolyType( arrayType->base, env ); … … 205 205 206 206 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 207 if ( typeVars. find( *inst ) != typeVars.end() ) return type;207 if ( typeVars.contains( *inst ) ) return type; 208 208 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 209 209 return isPolyType( array->base, subst ); … … 393 393 394 394 if ( TypeInstType *typeInstType = dynamic_cast< TypeInstType * >( type ) ) { 395 if ( tyVars. find( typeInstType->get_name() ) != tyVars.end() ) {395 if ( tyVars.contains( typeInstType->get_name() ) ) { 396 396 return true; 397 397 } -
src/GenPoly/ScopedSet.h
r9ef5516 r6d2af204 21 21 22 22 namespace GenPoly { 23 /// A set where the items are placed into nested scopes; 24 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 25 template<typename Value> 26 class ScopedSet { 27 typedef std::set< Value > Scope; 28 typedef std::vector< Scope > ScopeList; 29 30 ScopeList scopes; ///< scoped list of sets 31 public: 32 typedef typename Scope::key_type key_type; 33 typedef typename Scope::value_type value_type; 34 typedef typename ScopeList::size_type size_type; 35 typedef typename ScopeList::difference_type difference_type; 36 typedef typename Scope::reference reference; 37 typedef typename Scope::const_reference const_reference; 38 typedef typename Scope::pointer pointer; 39 typedef typename Scope::const_pointer const_pointer; 40 41 class iterator : public std::iterator< std::bidirectional_iterator_tag, 42 value_type > { 43 friend class ScopedSet; 44 friend class const_iterator; 45 typedef typename std::set< Value >::iterator wrapped_iterator; 46 typedef typename std::vector< std::set< Value > > scope_list; 47 typedef typename scope_list::size_type size_type; 48 49 /// Checks if this iterator points to a valid item 50 bool is_valid() const { 51 return it != (*scopes)[i].end(); 52 } 53 54 /// Increments on invalid 55 iterator& next_valid() { 56 if ( ! is_valid() ) { ++(*this); } 57 return *this; 58 } 59 60 /// Decrements on invalid 61 iterator& prev_valid() { 62 if ( ! is_valid() ) { --(*this); } 63 return *this; 64 } 65 66 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 67 : scopes(&_scopes), it(_it), i(_i) {} 68 public: 69 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 70 iterator& operator= (const iterator &that) { 71 scopes = that.scopes; i = that.i; it = that.it; 72 return *this; 73 } 74 75 reference operator* () { return *it; } 76 pointer operator-> () { return it.operator->(); } 77 78 iterator& operator++ () { 79 if ( it == (*scopes)[i].end() ) { 80 if ( i == 0 ) return *this; 81 --i; 82 it = (*scopes)[i].begin(); 83 } else { 84 ++it; 85 } 86 return next_valid(); 87 } 88 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 89 90 iterator& operator-- () { 91 // may fail if this is the begin iterator; allowed by STL spec 92 if ( it == (*scopes)[i].begin() ) { 93 ++i; 94 it = (*scopes)[i].end(); 95 } 96 --it; 97 return prev_valid(); 98 } 99 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 100 101 bool operator== (const iterator &that) { 102 return scopes == that.scopes && i == that.i && it == that.it; 103 } 104 bool operator!= (const iterator &that) { return !( *this == that ); } 105 106 size_type get_level() const { return i; } 107 108 private: 109 scope_list const *scopes; 110 wrapped_iterator it; 111 size_type i; 112 }; 113 114 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 115 value_type > { 116 friend class ScopedSet; 117 typedef typename std::set< Value >::iterator wrapped_iterator; 118 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 119 typedef typename std::vector< std::set< Value > > scope_list; 120 typedef typename scope_list::size_type size_type; 121 122 /// Checks if this iterator points to a valid item 123 bool is_valid() const { 124 return it != (*scopes)[i].end(); 125 } 126 127 /// Increments on invalid 128 const_iterator& next_valid() { 129 if ( ! is_valid() ) { ++(*this); } 130 return *this; 131 } 132 133 /// Decrements on invalid 134 const_iterator& prev_valid() { 135 if ( ! is_valid() ) { --(*this); } 136 return *this; 137 } 138 139 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 140 : scopes(&_scopes), it(_it), i(_i) {} 141 public: 142 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 143 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 144 const_iterator& operator= (const iterator &that) { 145 scopes = that.scopes; i = that.i; it = that.it; 146 return *this; 147 } 148 const_iterator& operator= (const const_iterator &that) { 149 scopes = that.scopes; i = that.i; it = that.it; 150 return *this; 151 } 152 153 const_reference operator* () { return *it; } 154 const_pointer operator-> () { return it.operator->(); } 155 156 const_iterator& operator++ () { 157 if ( it == (*scopes)[i].end() ) { 158 if ( i == 0 ) return *this; 159 --i; 160 it = (*scopes)[i].begin(); 161 } else { 162 ++it; 163 } 164 return next_valid(); 165 } 166 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 167 168 const_iterator& operator-- () { 169 // may fail if this is the begin iterator; allowed by STL spec 170 if ( it == (*scopes)[i].begin() ) { 171 ++i; 172 it = (*scopes)[i].end(); 173 } 174 --it; 175 return prev_valid(); 176 } 177 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 178 179 bool operator== (const const_iterator &that) { 180 return scopes == that.scopes && i == that.i && it == that.it; 181 } 182 bool operator!= (const const_iterator &that) { return !( *this == that ); } 183 184 size_type get_level() const { return i; } 185 186 private: 187 scope_list const *scopes; 188 wrapped_const_iterator it; 189 size_type i; 190 }; 191 192 /// Starts a new scope 193 void beginScope() { 194 Scope scope; 195 scopes.push_back(scope); 196 } 197 198 /// Ends a scope; invalidates any iterators pointing to elements of that scope 199 void endScope() { 200 scopes.pop_back(); 201 } 202 203 /// Default constructor initializes with one scope 204 ScopedSet() { beginScope(); } 205 206 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 207 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 208 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 209 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 210 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 211 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 212 213 /// Gets the index of the current scope (counted from 1) 214 size_type currentScope() const { return scopes.size(); } 215 216 /// Finds the given key in the outermost scope it occurs; returns end() for none such 217 iterator find( const Value &key ) { 218 for ( size_type i = scopes.size() - 1; ; --i ) { 219 typename Scope::iterator val = scopes[i].find( key ); 220 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 221 if ( i == 0 ) break; 222 } 223 return end(); 224 } 225 const_iterator find( const Value &key ) const { 226 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 227 } 228 229 /// Finds the given key in the outermost scope inside the given scope where it occurs 230 iterator findNext( const_iterator &it, const Value &key ) { 231 if ( it.i == 0 ) return end(); 23 24 /// A set where the items are placed into nested scopes; 25 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 26 template<typename Value> 27 class ScopedSet { 28 typedef std::set< Value > Scope; 29 typedef std::vector< Scope > ScopeList; 30 31 /// Scoped list of sets. 32 ScopeList scopes; 33 public: 34 typedef typename Scope::key_type key_type; 35 typedef typename Scope::value_type value_type; 36 typedef typename ScopeList::size_type size_type; 37 typedef typename ScopeList::difference_type difference_type; 38 typedef typename Scope::reference reference; 39 typedef typename Scope::const_reference const_reference; 40 typedef typename Scope::pointer pointer; 41 typedef typename Scope::const_pointer const_pointer; 42 43 // Both iterator types are complete bidirectional iterators, see below. 44 class iterator; 45 class const_iterator; 46 47 /// Starts a new scope 48 void beginScope() { 49 Scope scope; 50 scopes.push_back(scope); 51 } 52 53 /// Ends a scope; invalidates any iterators pointing to elements of that scope 54 void endScope() { 55 scopes.pop_back(); 56 } 57 58 /// Default constructor initializes with one scope 59 ScopedSet() { beginScope(); } 60 61 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 62 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 63 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 64 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 65 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 66 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 67 68 /// Gets the index of the current scope (counted from 1) 69 size_type currentScope() const { return scopes.size(); } 70 71 /// Finds the given key in the outermost scope it occurs; returns end() for none such 72 iterator find( const Value &key ) { 73 for ( size_type i = scopes.size() - 1; ; --i ) { 74 typename Scope::iterator val = scopes[i].find( key ); 75 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 76 if ( i == 0 ) break; 77 } 78 return end(); 79 } 80 const_iterator find( const Value &key ) const { 81 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 82 } 83 84 /// Finds the given key in the outermost scope inside the given scope where it occurs 85 iterator findNext( const_iterator &it, const Value &key ) { 86 if ( it.i == 0 ) return end(); 232 87 for ( size_type i = it.i - 1; ; --i ) { 233 typename Scope::iterator val = scopes[i].find( key ); 234 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 235 if ( i == 0 ) break; 236 } 237 return end(); 238 } 239 const_iterator findNext( const_iterator &it, const Value &key ) const { 240 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 241 } 242 243 /// Inserts the given value into the outermost scope 244 std::pair< iterator, bool > insert( const value_type &value ) { 245 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 246 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 247 } 248 249 }; 88 typename Scope::iterator val = scopes[i].find( key ); 89 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 90 if ( i == 0 ) break; 91 } 92 return end(); 93 } 94 const_iterator findNext( const_iterator &it, const Value &key ) const { 95 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 96 } 97 98 /// Inserts the given value into the outermost scope 99 std::pair< iterator, bool > insert( const value_type &value ) { 100 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 101 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 102 } 103 104 bool contains( const Value & key ) const { 105 return find( key ) != cend(); 106 } 107 }; 108 109 template<typename Value> 110 class ScopedSet<Value>::iterator : 111 public std::iterator< std::bidirectional_iterator_tag, value_type > { 112 friend class ScopedSet; 113 friend class const_iterator; 114 typedef typename std::set< Value >::iterator wrapped_iterator; 115 typedef typename std::vector< std::set< Value > > scope_list; 116 typedef typename scope_list::size_type size_type; 117 118 /// Checks if this iterator points to a valid item 119 bool is_valid() const { 120 return it != (*scopes)[i].end(); 121 } 122 123 /// Increments on invalid 124 iterator& next_valid() { 125 if ( ! is_valid() ) { ++(*this); } 126 return *this; 127 } 128 129 /// Decrements on invalid 130 iterator& prev_valid() { 131 if ( ! is_valid() ) { --(*this); } 132 return *this; 133 } 134 135 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 136 : scopes(&_scopes), it(_it), i(_i) {} 137 public: 138 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 139 iterator& operator= (const iterator &that) { 140 scopes = that.scopes; i = that.i; it = that.it; 141 return *this; 142 } 143 144 reference operator* () { return *it; } 145 pointer operator-> () { return it.operator->(); } 146 147 iterator& operator++ () { 148 if ( it == (*scopes)[i].end() ) { 149 if ( i == 0 ) return *this; 150 --i; 151 it = (*scopes)[i].begin(); 152 } else { 153 ++it; 154 } 155 return next_valid(); 156 } 157 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 158 159 iterator& operator-- () { 160 // may fail if this is the begin iterator; allowed by STL spec 161 if ( it == (*scopes)[i].begin() ) { 162 ++i; 163 it = (*scopes)[i].end(); 164 } 165 --it; 166 return prev_valid(); 167 } 168 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 169 170 bool operator== (const iterator &that) { 171 return scopes == that.scopes && i == that.i && it == that.it; 172 } 173 bool operator!= (const iterator &that) { return !( *this == that ); } 174 175 size_type get_level() const { return i; } 176 177 private: 178 scope_list const *scopes; 179 wrapped_iterator it; 180 size_type i; 181 }; 182 183 template<typename Value> 184 class ScopedSet<Value>::const_iterator : 185 public std::iterator< std::bidirectional_iterator_tag, value_type > { 186 friend class ScopedSet; 187 typedef typename std::set< Value >::iterator wrapped_iterator; 188 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 189 typedef typename std::vector< std::set< Value > > scope_list; 190 typedef typename scope_list::size_type size_type; 191 192 /// Checks if this iterator points to a valid item 193 bool is_valid() const { 194 return it != (*scopes)[i].end(); 195 } 196 197 /// Increments on invalid 198 const_iterator& next_valid() { 199 if ( ! is_valid() ) { ++(*this); } 200 return *this; 201 } 202 203 /// Decrements on invalid 204 const_iterator& prev_valid() { 205 if ( ! is_valid() ) { --(*this); } 206 return *this; 207 } 208 209 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 210 : scopes(&_scopes), it(_it), i(_i) {} 211 public: 212 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 213 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 214 const_iterator& operator= (const iterator &that) { 215 scopes = that.scopes; i = that.i; it = that.it; 216 return *this; 217 } 218 const_iterator& operator= (const const_iterator &that) { 219 scopes = that.scopes; i = that.i; it = that.it; 220 return *this; 221 } 222 223 const_reference operator* () { return *it; } 224 const_pointer operator-> () { return it.operator->(); } 225 226 const_iterator& operator++ () { 227 if ( it == (*scopes)[i].end() ) { 228 if ( i == 0 ) return *this; 229 --i; 230 it = (*scopes)[i].begin(); 231 } else { 232 ++it; 233 } 234 return next_valid(); 235 } 236 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 237 238 const_iterator& operator-- () { 239 // may fail if this is the begin iterator; allowed by STL spec 240 if ( it == (*scopes)[i].begin() ) { 241 ++i; 242 it = (*scopes)[i].end(); 243 } 244 --it; 245 return prev_valid(); 246 } 247 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 248 249 bool operator== (const const_iterator &that) { 250 return scopes == that.scopes && i == that.i && it == that.it; 251 } 252 bool operator!= (const const_iterator &that) { return !( *this == that ); } 253 254 size_type get_level() const { return i; } 255 256 private: 257 scope_list const *scopes; 258 wrapped_const_iterator it; 259 size_type i; 260 }; 261 250 262 } // namespace GenPoly 251 263 -
src/GenPoly/ScrubTyVars.cc
r9ef5516 r6d2af204 178 178 179 179 ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) { 180 ast::TypeDecl::Kind kind; 180 181 // This implies that mode == ScrubMode::All. 181 182 if ( !typeVars ) { 182 if ( ast::TypeDecl::Ftype == type->kind ) { 183 return new ast::PointerType( 184 new ast::FunctionType( ast::FixedArgs ) ); 185 } else { 186 return new ast::PointerType( 187 new ast::VoidType( type->qualifiers ) ); 188 } 189 } 190 191 auto typeVar = typeVars->find( *type ); 192 if ( typeVar == typeVars->end() ) { 193 return type; 194 } 195 196 switch ( typeVar->second.kind ) { 197 case ::TypeDecl::Dtype: 198 case ::TypeDecl::Ttype: 183 kind = type->kind; 184 } else { 185 // Otherwise, only scrub the type var if it is in map. 186 auto typeVar = typeVars->find( *type ); 187 if ( typeVar == typeVars->end() ) { 188 return type; 189 } 190 kind = typeVar->second.kind; 191 } 192 193 switch ( kind ) { 194 case ast::TypeDecl::Dtype: 195 case ast::TypeDecl::Ttype: 199 196 return new ast::PointerType( 200 197 new ast::VoidType( type->qualifiers ) ); 201 case ::TypeDecl::Ftype:198 case ast::TypeDecl::Ftype: 202 199 return new ast::PointerType( 203 200 new ast::FunctionType( ast::VariableArgs ) ); 204 201 default: 205 assertf( false, 206 "Unhandled type variable kind: %d", typeVar->second.kind ); 202 assertf( false, "Unhandled type variable kind: %d", kind ); 207 203 throw; // Just in case the assert is removed, stop here. 208 204 } -
src/Parser/parser.yy
r9ef5516 r6d2af204 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 30 20:47:27202313 // Update Count : 58 5912 // Last Modified On : Thu Feb 2 21:36:16 2023 13 // Update Count : 5865 14 14 // 15 15 … … 2080 2080 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } 2081 2081 | forall 2082 { $$ = DeclarationNode::newForall( $1 ); } 2082 2083 ; 2083 2084 2084 2085 forall: 2085 2086 FORALL '(' type_parameter_list ')' // CFA 2086 { $$ = DeclarationNode::newForall( $3 ); }2087 { $$ = $3; } 2087 2088 ; 2088 2089 … … 2978 2979 trait_specifier: // CFA 2979 2980 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 2980 { $$ = DeclarationNode::newTrait( $2, $4, nullptr ); } 2981 | FORALL '(' type_parameter_list ')' TRAIT identifier_or_type_name '{' '}' // alternate 2982 { $$ = DeclarationNode::newTrait( $6, $3, nullptr ); } 2981 { 2982 SemanticWarning( yylloc, Warning::DeprecTraitSyntax, "" ); 2983 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 2984 } 2985 | forall TRAIT identifier_or_type_name '{' '}' // alternate 2986 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); } 2983 2987 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 2984 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 2985 | FORALL '(' type_parameter_list ')' TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 2986 { $$ = DeclarationNode::newTrait( $6, $3, $9 ); } 2988 { 2989 SemanticWarning( yylloc, Warning::DeprecTraitSyntax, "" ); 2990 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 2991 } 2992 | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 2993 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); } 2987 2994 ; 2988 2995 -
src/SymTab/Validate.cc
r9ef5516 r6d2af204 863 863 864 864 void ReplaceTypedef::premutate( TypeDecl * typeDecl ) { 865 TypedefMap::iterator i = typedefNames.find( typeDecl->name ); 866 if ( i != typedefNames.end() ) { 867 typedefNames.erase( i ) ; 868 } // if 869 865 typedefNames.erase( typeDecl->name ); 870 866 typedeclNames.insert( typeDecl->name, typeDecl ); 871 867 } -
src/Validate/ReplaceTypedef.cpp
r9ef5516 r6d2af204 186 186 187 187 void ReplaceTypedefCore::previsit( ast::TypeDecl const * decl ) { 188 TypedefMap::iterator iter = typedefNames.find( decl->name ); 189 if ( iter != typedefNames.end() ) { 190 typedefNames.erase( iter ); 191 } 188 typedefNames.erase( decl->name ); 192 189 typedeclNames.insert( decl->name, decl ); 193 190 } -
tests/.expect/forall.txt
r9ef5516 r6d2af204 1 forall.cfa:244:25: warning: Compiled 1 1 2 f 3 97 4 f 5 g 6 f 7 f 8 g 9 fT 10 fT 11 fT 12 fTU 13 fTU 14 fTU 15 1 2 16 2 1 17 1, 2 18 @ 0 2 0 4 6.4 6.4 6.4 6.4+3.i 4 19 3. 3. 20 45 21 12 3 -
tests/Makefile.am
r9ef5516 r6d2af204 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Sat Jun 5 14:49:25 202114 ## Update Count : 9 213 ## Last Modified On : Fri Feb 3 23:06:44 2023 14 ## Update Count : 94 15 15 ############################################################################### 16 16 … … 89 89 meta/fork+exec.hfa \ 90 90 concurrent/unified_locking/mutex_test.hfa \ 91 concurrent/channels/parallel_harness.hfa91 concurrent/channels/parallel_harness.hfa 92 92 93 93 dist-hook: … … 183 183 CFACOMPILE_SYNTAX = $(CFACOMPILETEST) -Wno-unused-variable -Wno-unused-label -c -fsyntax-only -o $(abspath ${@}) 184 184 185 SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator forall\185 SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator \ 186 186 init1 limits nested-types cast labelledExit array quasiKeyword include/stdincludes include/includes builtins/sync warnings/self-assignment 187 187 $(SYNTAX_ONLY_CODE): % : %.cfa $(CFACCBIN) -
tests/concurrent/actors/matrix.cfa
r9ef5516 r6d2af204 5 5 #include <stdio.h> 6 6 7 unsigned int xr = 100, xc = 100, yc = 100, Processors = 1; // default values7 unsigned int xr = 500, xc = 500, yc = 500, Processors = 1; // default values 8 8 9 9 struct derived_actor { -
tests/concurrent/actors/types.cfa
r9ef5516 r6d2af204 5 5 #include <stdio.h> 6 6 #include <mutex_stmt.hfa> 7 8 struct dummy_actor { actor a; }; // this won't work since the actor isn't inlined 7 9 8 10 struct derived_actor { … … 26 28 } 27 29 30 Allocation receive( derived_actor & receiver, d_msg & msg ) { 31 return receive( receiver, msg.num ); 32 } 33 28 34 struct derived_actor2 { 35 struct nested { int i; }; // testing nested before inline 29 36 inline actor; 30 37 }; 31 38 static inline void ?{}( derived_actor2 & this ) { ((actor &)this){}; } 39 40 Allocation receive( derived_actor2 & receiver, d_msg & msg ) { 41 mutex(sout) sout | msg.num; 42 return Finished; 43 } 32 44 33 45 struct derived_actor3 { … … 41 53 }; 42 54 static inline void ?{}( d_msg2 & this ) { ((message &)this){}; } 43 44 Allocation receive( derived_actor2 & receiver, d_msg & msg ) {45 mutex(sout) sout | msg.num;46 return Finished;47 }48 49 Allocation receive( derived_actor & receiver, d_msg & msg ) {50 return receive( receiver, msg.num );51 }52 55 53 56 Allocation receive( derived_actor3 & receiver, d_msg & msg ) { -
tests/forall.cfa
r9ef5516 r6d2af204 10 10 // Created On : Wed May 9 08:48:15 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jun 5 10:06:08 2021 13 // Update Count : 36 14 // 12 // Last Modified On : Sun Feb 5 07:54:43 2023 13 // Update Count : 90 14 // 15 16 #include <fstream.hfa> 15 17 16 18 void g1() { 17 forall( T ) T f( T ) {}; 18 void f( int ) {}; 19 void h( void (*p)(void) ) {}; 20 21 int x; 22 void (*y)(void); 23 char z; 24 float w; 19 forall( T ) T f( T p ) { sout | 'f'; return p; }; 20 void f( int p ) { sout | p; }; 21 void g( void ) { sout | 'g'; }; 22 void h( void (*p)(void) ) { p(); }; 23 24 int x = 1; 25 void (*y)(void) = g; 26 char z = 'a'; 27 float w = 3.5; 25 28 26 29 f( x ); … … 28 31 f( z ); 29 32 f( w ); 33 h( y ); 34 f( y ); 30 35 h( f( y ) ); 31 36 } 32 37 33 38 void g2() { 34 forall( T ) void f( T, T ) { }35 forall( T, U ) void f( T, U ) { }39 forall( T ) void f( T, T ) { sout | "fT"; } 40 forall( T, U ) void f( T, U ) { sout | "fTU"; } 36 41 37 42 int x; 38 43 float y; 39 int *z; 40 float *w; 41 44 int * z; 45 float * w; 46 47 f( x, x ); 48 f( y, y ); 49 f( w, w ); 42 50 f( x, y ); 43 51 f( z, w ); … … 50 58 51 59 forall( T ) 52 void swap( T left, T right ) { 53 T temp = left; 54 left = right; 55 right = temp; 56 } 57 58 trait sumable( T ) { 60 void swap( T & left, T & right ) { // by reference 61 T temp = left; 62 left = right; 63 right = temp; 64 } 65 66 forall( T ) 67 [ T, T ] swap( T i, T j ) { // by value 68 return [ j, i ]; 69 } 70 71 forall( T ) trait sumable { 59 72 void ?{}( T &, zero_t ); // 0 literal constructor 60 73 T ?+?( T, T ); // assortment of additions … … 64 77 }; // sumable 65 78 66 forall( T | sumable( T ) ) // use trait79 forall( T | sumable( T ) ) // use trait 67 80 T sum( size_t size, T a[] ) { 68 81 T total = 0; // initialize by 0 constructor … … 72 85 } // sum 73 86 74 forall( T | { T ?+?( T, T ); T ?++( T & ); [T] ?+=?( T &, T ); } )87 forall( T | { T ?+?( T, T ); T ?++( T & ); [T] ?+=?( T &, T ); } ) 75 88 T twice( T t ) { 76 89 return t + t; … … 82 95 } 83 96 84 intfred() {85 int x = 1, y = 2, a[10] ;97 void fred() { 98 int x = 1, y = 2, a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 86 99 float f; 87 100 101 sout | x | y; 88 102 swap( x, y ); 89 twice( x ); 103 sout | x | y | nl | swap( x, y ); 104 // [ x, y ] = swap( y, x ); 105 sout | twice( ' ' ) | ' ' | twice( 0hh ) | twice( 1h ) | twice( 0n ) | twice( 2 ) 106 | twice( 3.2f ) | twice( 3.2 ) | twice( 3.2d ) | twice( 3.2+1.5i ) | twice( x ); 90 107 f = min( 4.0, 3.0 ); 91 sum( 10, a ); 108 sout | f | min( 4.0, 3.0 ); 109 sout | sum( 10, a ); 92 110 } 93 111 … … 186 204 187 205 forall( T ) { 188 extern "C" {206 // extern "C" { 189 207 struct SS { T t; }; 190 T foo( T ) {}191 }208 T foo( T p ) { return p; } 209 // } 192 210 } 193 211 … … 195 213 W(int,int) w; 196 214 197 intjane() {215 void jane() { 198 216 // int j = bar( 3, 4 ); 199 217 int k = baz( 3, 4, 5 ); 200 218 int i = foo( 3 ); 219 sout | k | i; 201 220 } 202 221 … … 211 230 T t; 212 231 T t2 = t; 232 sout | &tr | tp; 213 233 } 214 234 … … 242 262 243 263 int main( void ) { 244 #pragma GCC warning "Compiled" // force non-empty .expect file, NO TABS!!! 264 g1(); 265 g2(); 266 fred(); 267 jane(); 245 268 } 246 269
Note:
See TracChangeset
for help on using the changeset viewer.