Changeset 41cde266
- Timestamp:
- Dec 17, 2020, 4:18:23 PM (2 years ago)
- Branches:
- ADT, arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 089b1a9, f4f79dd
- Parents:
- c5a98f3 (diff), 68a867ee (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:
-
- 1 added
- 3 deleted
- 61 edited
Legend:
- Unmodified
- Added
- Removed
-
Jenkins/tools.groovy
rc5a98f3 r41cde266 6 6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils 7 7 8 // Global for the stage name9 StageName = ''10 11 8 // wrapper around stage declaretion to be more verbose 12 9 // and allow showing as skipped in the UI 13 10 def BuildStage(String name, boolean run, Closure block ) { 14 StageName = name 15 echo " -------- ${StageName} -------- " 11 echo " -------- ${name} -------- " 16 12 if(run) { 17 13 stage(name, block) -
Jenkinsfile
rc5a98f3 r41cde266 54 54 //attach the build log to the email 55 55 catch (Exception caughtError) { 56 //rethrow error later 56 // Store the result of the build log 57 currentBuild.result = "FAILURE" 58 59 // An error has occured, the build log is relevent 60 log_needed = true 61 62 // rethrow error later 57 63 err = caughtError 58 64 65 // print the error so it shows in the log 59 66 echo err.toString() 60 61 //An error has occured, the build log is relevent62 log_needed = true63 64 //Store the result of the build log65 currentBuild.result = "${tools.StageName} FAILURE".trim()66 67 } 67 68 -
libcfa/src/bits/collection.hfa
rc5a98f3 r41cde266 1 1 #pragma once 2 #include <stdio.h> // REMOVE THIS AFTER DEBUGGING 3 2 4 3 5 struct Colable { 4 Colable * next; // next node in the list6 struct Colable * next; // next node in the list 5 7 // invariant: (next != 0) <=> listed() 6 8 }; 7 8 inline {9 #ifdef __cforall 10 static inline { 9 11 // PUBLIC 10 12 … … 28 30 } 29 31 30 // wrappers to make Collection have T 31 forall( dtype T ) { 32 T *& Next( T * n ) { 33 return (T *)Next( (Colable *)n ); 34 } 35 36 bool listed( T * n ) { 37 return Next( (Colable *)n ) != 0p; 38 } 39 } // distribution 32 // // wrappers to make Collection have T 33 // forall( dtype T ) { 34 // T *& Next( T * n ) { 35 // return (T *)Next( (Colable *)n ); 36 // } 37 // } // distribution 40 38 } // distribution 41 39 40 forall( dtype T | { T *& Next ( T * ); } ) { 41 bool listed( T * n ) { 42 return Next( n ) != 0p; 43 } 44 } 42 45 43 46 struct Collection { … … 45 48 }; 46 49 47 inline {50 static inline { 48 51 // class invariant: root == 0 & empty() | *root in *this 49 52 void ?{}( Collection &, const Collection & ) = void; // no copy … … 68 71 }; 69 72 70 inline {73 static inline { 71 74 void ?{}( ColIter & colIter ) with( colIter ) { 72 75 curr = 0p; … … 79 82 } // distribution 80 83 } // distribution 84 #endif -
libcfa/src/bits/containers.hfa
rc5a98f3 r41cde266 36 36 #define __small_array_t(T) __small_array(T) 37 37 #else 38 #define __small_array_t(T) struct__small_array38 #define __small_array_t(T) __small_array 39 39 #endif 40 40 -
libcfa/src/bits/defs.hfa
rc5a98f3 r41cde266 29 29 #define __cfa_anonymous_object(x) inline struct x 30 30 #else 31 #define __cfa_anonymous_object(x) x __cfa_anonymous_object31 #define __cfa_anonymous_object(x) struct x __cfa_anonymous_object 32 32 #endif 33 33 -
libcfa/src/bits/queue.hfa
rc5a98f3 r41cde266 3 3 #include "bits/collection.hfa" 4 4 5 forall( dtype T ) {5 forall( dtype T | { T *& Next ( T * ); } ) { 6 6 struct Queue { 7 7 inline Collection; // Plan 9 inheritance … … 64 64 T & t = head( q ); 65 65 if ( root ) { 66 root = Next( root );66 root = Next( (T *)root ); 67 67 if ( &head( q ) == &t ) { 68 68 root = last = 0p; // only one element … … 142 142 } // distribution 143 143 144 forall( dtype T ) {144 forall( dtype T | { T *& Next ( T * ); } ) { 145 145 struct QueueIter { 146 146 inline ColIter; // Plan 9 inheritance -
libcfa/src/bits/sequence.hfa
rc5a98f3 r41cde266 2 2 3 3 #include "bits/collection.hfa" 4 #include "bits/defs.hfa" 4 5 5 6 struct Seqable { 6 inline Colable;7 Seqable * back; // pointer to previous node in the list7 __cfa_anonymous_object(Colable); 8 struct Seqable * back; // pointer to previous node in the list 8 9 }; 9 10 10 inline { 11 #ifdef __cforall 12 static inline { 11 13 // PUBLIC 12 14 … … 26 28 } 27 29 28 // wrappers to make Collection have T29 forall( dtype T ) {30 T *& Back( T * n ) {31 return (T *)Back( (Seqable *)n );32 }33 } // distribution30 // // wrappers to make Collection have T 31 // forall( dtype T ) { 32 // T *& Back( T * n ) { 33 // return (T *)Back( (Seqable *)n ); 34 // } 35 // } // distribution 34 36 } // distribution 35 37 36 forall( dtype T ) {38 forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) { 37 39 struct Sequence { 38 40 inline Collection; // Plan 9 inheritance 39 41 }; 40 42 41 inline {43 static inline { 42 44 // wrappers to make Collection have T 43 45 T & head( Sequence(T) & s ) with( s ) { … … 184 186 T * toEnd = Back( &head( s ) ); 185 187 T * fromEnd = Back( &head( from ) ); 186 Back( root ) = fromEnd;188 Back( (T *)root ) = fromEnd; 187 189 Next( fromEnd ) = &head( s ); 188 Back( from.root ) = toEnd;190 Back( (T *)from.root ) = toEnd; 189 191 Next( toEnd ) = &head( from ); 190 192 } // if … … 214 216 } // distribution 215 217 216 forall( dtype T ) {218 forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) { 217 219 // SeqIter(T) is used to iterate over a Sequence(T) in head-to-tail order. 218 220 struct SeqIter { … … 224 226 }; 225 227 226 inline {228 static inline { 227 229 void ?{}( SeqIter(T) & si ) with( si ) { 228 230 ((ColIter &)si){}; … … 265 267 }; 266 268 267 inline {269 static inline { 268 270 void ?{}( SeqIterRev(T) & si ) with( si ) { 269 271 ((ColIter &)si){}; … … 298 300 } // distribution 299 301 } // distribution 302 303 #endif -
libcfa/src/bits/stack.hfa
rc5a98f3 r41cde266 3 3 #include "bits/collection.hfa" 4 4 5 forall( dtype T ) {5 forall( dtype T | { T *& Next ( T * ); } ) { 6 6 struct Stack { 7 7 inline Collection; // Plan 9 inheritance … … 44 44 T & t = head( s ); 45 45 if ( root ) { 46 root = ( T *)Next( root );46 root = ( T *)Next( (T *)root ); 47 47 if ( &head( s ) == &t ) root = 0p; // only one element ? 48 48 Next( &t ) = 0p; … … 58 58 59 59 60 forall( dtype T ) {60 forall( dtype T | { T *& Next ( T * ); } ) { 61 61 struct StackIter { 62 62 inline ColIter; // Plan 9 inheritance -
libcfa/src/concurrency/coroutine.cfa
rc5a98f3 r41cde266 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Oct 23 23:05:24 202013 // Update Count : 2 212 // Last Modified On : Tue Dec 15 12:06:04 2020 13 // Update Count : 23 14 14 // 15 15 … … 88 88 static const size_t MinStackSize = 1000; 89 89 extern size_t __page_size; // architecture pagesize HACK, should go in proper runtime singleton 90 extern int __map_prot; 90 91 91 92 void __stack_prepare( __stack_info_t * this, size_t create_size ); … … 206 207 __cfaabi_dbg_debug_do( 207 208 storage = (char*)(storage) - __page_size; 208 if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE) == -1 ) {209 if ( mprotect( storage, __page_size, __map_prot ) == -1 ) { 209 210 abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) ); 210 211 } -
libcfa/src/concurrency/invoke.h
rc5a98f3 r41cde266 189 189 struct __monitor_group_t monitors; 190 190 191 // used to put threads on user data structures 192 struct { 193 struct $thread * next; 194 struct $thread * back; 195 } seqable; 196 191 197 struct { 192 198 struct $thread * next; … … 218 224 } 219 225 226 static inline $thread *& Back( $thread * this ) __attribute__((const)) { 227 return this->seqable.back; 228 } 229 230 static inline $thread *& Next( $thread * this ) __attribute__((const)) { 231 return this->seqable.next; 232 } 233 234 static inline bool listed( $thread * this ) { 235 return this->seqable.next != 0p; 236 } 237 220 238 static inline void ?{}(__monitor_group_t & this) { 221 239 (this.data){0p}; -
libcfa/src/concurrency/kernel/startup.cfa
rc5a98f3 r41cde266 117 117 } 118 118 119 size_t __page_size = 0; 119 extern size_t __page_size; 120 extern int __map_prot; 120 121 121 122 //----------------------------------------------------------------------------- … … 161 162 /* paranoid */ verify( ! __preemption_enabled() ); 162 163 __cfadbg_print_safe(runtime_core, "Kernel : Starting\n"); 163 164 __page_size = sysconf( _SC_PAGESIZE );165 164 166 165 __cfa_dbg_global_clusters.list{ __get }; … … 681 680 #if CFA_PROCESSOR_USE_MMAP 682 681 stacksize = ceiling( stacksize, __page_size ) + __page_size; 683 stack = mmap(0p, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);682 stack = mmap(0p, stacksize, __map_prot, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 684 683 if(stack == ((void*)-1)) { 685 684 abort( "pthread stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) ); … … 727 726 } 728 727 #else 728 __cfaabi_dbg_debug_do( 729 // pthread has no mechanism to create the guard page in user supplied stack. 730 if ( mprotect( stack, __page_size, __map_prot ) == -1 ) { 731 abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) ); 732 } // if 733 ); 729 734 free( stack ); 730 735 #endif -
libcfa/src/concurrency/locks.cfa
rc5a98f3 r41cde266 29 29 30 30 void ^?{}( info_thread(L) & this ){ } 31 32 info_thread(L) *& Back( info_thread(L) * this ) { 33 return (info_thread(L) *)Back( (Seqable *)this ); 34 } 35 36 info_thread(L) *& Next( info_thread(L) * this ) { 37 return (info_thread(L) *)Next( (Colable *)this ); 38 } 39 40 bool listed( info_thread(L) * this ) { 41 return Next( (Colable *)this ) != 0p; 42 } 31 43 } 32 44 … … 58 70 abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); 59 71 } else if ( owner != 0p && owner != active_thread() ) { 60 a ppend( blocked_threads,active_thread() );72 addTail( blocked_threads, *active_thread() ); 61 73 wait_count++; 62 74 unlock( lock ); … … 96 108 97 109 void pop_and_set_new_owner( blocking_lock & this ) with( this ) { 98 $thread * t = pop_head( blocked_threads );110 $thread * t = &dropHead( blocked_threads ); 99 111 owner = t; 100 112 recursion_count = ( t ? 1 : 0 ); … … 128 140 lock( lock __cfaabi_dbg_ctx2 ); 129 141 if ( owner != 0p ) { 130 a ppend( blocked_threads,t );142 addTail( blocked_threads, *t ); 131 143 wait_count++; 132 144 unlock( lock ); … … 257 269 size_t recursion_count = 0; 258 270 if (i->lock) { 259 i->t->link.next = 1p;260 271 recursion_count = get_recursion_count(*i->lock); 261 272 remove_( *i->lock ); -
libcfa/src/concurrency/locks.hfa
rc5a98f3 r41cde266 43 43 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ); 44 44 void ^?{}( info_thread(L) & this ); 45 46 info_thread(L) *& Back( info_thread(L) * this ); 47 info_thread(L) *& Next( info_thread(L) * this ); 48 bool listed( info_thread(L) * this ); 45 49 } 46 50 … … 64 68 65 69 // List of blocked threads 66 __queue_t( $thread ) blocked_threads;70 Sequence( $thread ) blocked_threads; 67 71 68 72 // Count of current blocked threads -
libcfa/src/concurrency/thread.cfa
rc5a98f3 r41cde266 43 43 canary = 0x0D15EA5E0D15EA5Ep; 44 44 #endif 45 46 seqable.next = 0p; 47 seqable.back = 0p; 45 48 46 49 node.next = 0p; -
libcfa/src/heap.cfa
rc5a98f3 r41cde266 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Dec 13 22:04:10202013 // Update Count : 98412 // Last Modified On : Wed Dec 16 12:28:25 2020 13 // Update Count : 1023 14 14 // 15 15 16 16 #include <unistd.h> // sbrk, sysconf 17 #include <stdlib.h> // EXIT_FAILURE 17 18 #include <stdbool.h> // true, false 18 19 #include <stdio.h> // snprintf, fileno … … 71 72 // Define the default extension heap amount in units of bytes. When the uC++ supplied heap reaches the brk address, 72 73 // the brk address is extended by the extension amount. 73 __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024),74 __CFA_DEFAULT_HEAP_EXPANSION__ = (10 * 1024 * 1024), 74 75 75 76 // Define the mmap crossover point during allocation. Allocations less than this amount are allocated from buckets; … … 115 116 116 117 // statically allocated variables => zero filled. 117 static size_t pageSize; // architecture pagesize 118 size_t __page_size; // architecture pagesize 119 int __map_prot; // common mmap/mprotect protection 118 120 static size_t heapExpand; // sbrk advance 119 121 static size_t mmapStart; // cross over point for mmap … … 249 251 #endif // FASTLOOKUP 250 252 251 static int mmapFd = -1;// fake or actual fd for anonymous file253 static const off_t mmapFd = -1; // fake or actual fd for anonymous file 252 254 #ifdef __CFA_DEBUG__ 253 255 static bool heapBoot = 0; // detect recursion during boot … … 374 376 375 377 static inline bool setMmapStart( size_t value ) { // true => mmapped, false => sbrk 376 if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return false;378 if ( value < __page_size || bucketSizes[NoBucketSizes - 1] < value ) return false; 377 379 mmapStart = value; // set global 378 380 … … 436 438 header = headerAddr( addr ); 437 439 438 if ( unlikely( heapEnd < addr ) ) {// mmapped ?440 if ( unlikely( addr < heapBegin || heapEnd < addr ) ) { // mmapped ? 439 441 fakeHeader( header, alignment ); 440 442 size = header->kind.real.blockSize & -3; // mmap size … … 443 445 444 446 #ifdef __CFA_DEBUG__ 445 checkHeader( addr < heapBegin, name, addr );// bad low address ?447 checkHeader( header < (HeapManager.Storage.Header *)heapBegin, name, addr ); // bad low address ? 446 448 #endif // __CFA_DEBUG__ 447 449 … … 482 484 #endif // __CFA_DEBUG__ 483 485 486 484 487 #define NO_MEMORY_MSG "insufficient heap memory available for allocating %zd new bytes." 485 488 … … 490 493 // If the size requested is bigger than the current remaining storage, increase the size of the heap. 491 494 492 size_t increase = ceiling2( size > heapExpand ? size : heapExpand, pageSize ); 495 size_t increase = ceiling2( size > heapExpand ? size : heapExpand, __page_size ); 496 // Do not call abort or strerror( errno ) as they may call malloc. 493 497 if ( sbrk( increase ) == (void *)-1 ) { // failed, no memory ? 494 498 unlock( extlock ); 495 abort( NO_MEMORY_MSG, size ); // give up 496 } // if 497 if ( mprotect( (char *)heapEnd + heapRemaining, increase, PROT_READ | PROT_WRITE | PROT_EXEC ) ) { 498 enum { BufferSize = 128 }; 499 char helpText[BufferSize]; 500 // Do not call strerror( errno ) as it may call malloc. 501 int len = snprintf( helpText, BufferSize, "internal error, extend(), mprotect failure, heapEnd:%p size:%zd, errno:%d.", heapEnd, increase, errno ); 502 __cfaabi_bits_write( STDERR_FILENO, helpText, len ); 499 __cfaabi_bits_print_nolock( STDERR_FILENO, NO_MEMORY_MSG, size ); 500 _exit( EXIT_FAILURE ); 501 } // if 502 if ( mprotect( (char *)heapEnd + heapRemaining, increase, __map_prot ) ) { 503 unlock( extlock ); 504 __cfaabi_bits_print_nolock( STDERR_FILENO, "extend() : internal error, mprotect failure, heapEnd:%p size:%zd, errno:%d.\n", heapEnd, increase, errno ); 505 _exit( EXIT_FAILURE ); 503 506 } // if 504 507 #ifdef __STATISTICS__ … … 508 511 #ifdef __CFA_DEBUG__ 509 512 // Set new memory to garbage so subsequent uninitialized usages might fail. 510 //memset( (char *)heapEnd + heapRemaining, '\377', increase );511 Memset( (char *)heapEnd + heapRemaining, increase );513 memset( (char *)heapEnd + heapRemaining, '\xde', increase ); 514 //Memset( (char *)heapEnd + heapRemaining, increase ); 512 515 #endif // __CFA_DEBUG__ 513 516 rem = heapRemaining + increase - size; … … 568 571 block->header.kind.real.home = freeElem; // pointer back to free list of apropriate size 569 572 } else { // large size => mmap 570 if ( unlikely( size > ULONG_MAX - pageSize ) ) return 0p;571 tsize = ceiling2( tsize, pageSize ); // must be multiple of page size573 if ( unlikely( size > ULONG_MAX - __page_size ) ) return 0p; 574 tsize = ceiling2( tsize, __page_size ); // must be multiple of page size 572 575 #ifdef __STATISTICS__ 573 576 __atomic_add_fetch( &mmap_calls, 1, __ATOMIC_SEQ_CST ); … … 575 578 #endif // __STATISTICS__ 576 579 577 block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 );580 block = (HeapManager.Storage *)mmap( 0, tsize, __map_prot, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 ); 578 581 if ( block == (HeapManager.Storage *)MAP_FAILED ) { // failed ? 579 582 if ( errno == ENOMEM ) abort( NO_MEMORY_MSG, tsize ); // no memory … … 583 586 #ifdef __CFA_DEBUG__ 584 587 // Set new memory to garbage so subsequent uninitialized usages might fail. 585 //memset( block, '\377', tsize );586 Memset( block, tsize );588 memset( block, '\xde', tsize ); 589 //Memset( block, tsize ); 587 590 #endif // __CFA_DEBUG__ 588 591 block->header.kind.real.blockSize = tsize; // storage size for munmap … … 624 627 #endif // __STATISTICS__ 625 628 if ( munmap( header, size ) == -1 ) { 626 #ifdef __CFA_DEBUG__627 629 abort( "Attempt to deallocate storage %p not allocated or with corrupt header.\n" 628 630 "Possible cause is invalid pointer.", 629 631 addr ); 630 #endif // __CFA_DEBUG__631 632 } // if 632 633 } else { 633 634 #ifdef __CFA_DEBUG__ 634 635 // Set free memory to garbage so subsequent usages might fail. 635 //memset( ((HeapManager.Storage *)header)->data, '\377', freeElem->blockSize - sizeof( HeapManager.Storage ) );636 Memset( ((HeapManager.Storage *)header)->data, freeElem->blockSize - sizeof( HeapManager.Storage ) );636 memset( ((HeapManager.Storage *)header)->data, '\xde', freeElem->blockSize - sizeof( HeapManager.Storage ) ); 637 //Memset( ((HeapManager.Storage *)header)->data, freeElem->blockSize - sizeof( HeapManager.Storage ) ); 637 638 #endif // __CFA_DEBUG__ 638 639 … … 703 704 704 705 static void ?{}( HeapManager & manager ) with( manager ) { 705 pageSize = sysconf( _SC_PAGESIZE ); 706 __page_size = sysconf( _SC_PAGESIZE ); 707 __map_prot = PROT_READ | PROT_WRITE | PROT_EXEC; 706 708 707 709 for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists … … 723 725 724 726 char * end = (char *)sbrk( 0 ); 725 heapBegin = heapEnd = sbrk( (char *)ceiling2( (long unsigned int)end, pageSize ) - end ); // move start of heap to multiple of alignment727 heapBegin = heapEnd = sbrk( (char *)ceiling2( (long unsigned int)end, __page_size ) - end ); // move start of heap to multiple of alignment 726 728 } // HeapManager 727 729 … … 741 743 #ifdef __CFA_DEBUG__ 742 744 if ( heapBoot ) { // check for recursion during system boot 743 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.744 745 abort( "boot() : internal error, recursively invoked during system boot." ); 745 746 } // if … … 1028 1029 } // cmemalign 1029 1030 1031 1030 1032 // Same as memalign(), but ISO/IEC 2011 C11 Section 7.22.2 states: the value of size shall be an integral multiple 1031 1033 // of alignment. This requirement is universally ignored. … … 1045 1047 } // posix_memalign 1046 1048 1049 1047 1050 // Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of the 1048 1051 // page size. It is equivalent to memalign(sysconf(_SC_PAGESIZE),size). 1049 1052 void * valloc( size_t size ) { 1050 return memalign( pageSize, size );1053 return memalign( __page_size, size ); 1051 1054 } // valloc 1052 1055 … … 1054 1057 // Same as valloc but rounds size to multiple of page size. 1055 1058 void * pvalloc( size_t size ) { 1056 return memalign( pageSize, ceiling2( size, pageSize ) );1059 return memalign( __page_size, ceiling2( size, __page_size ) ); 1057 1060 } // pvalloc 1058 1061 … … 1193 1196 choose( option ) { 1194 1197 case M_TOP_PAD: 1195 heapExpand = ceiling2( value, pageSize ); return 1;1198 heapExpand = ceiling2( value, __page_size ); return 1; 1196 1199 case M_MMAP_THRESHOLD: 1197 1200 if ( setMmapStart( value ) ) return 1; -
src/AST/Convert.cpp
rc5a98f3 r41cde266 205 205 ftype->parameters = get<DeclarationWithType>().acceptL(node->params); 206 206 207 ftype->forall = get<TypeDecl>().acceptL( node->type->forall ); 207 ftype->forall = get<TypeDecl>().acceptL( node->type_params ); 208 if (!node->assertions.empty()) { 209 assert(!ftype->forall.empty()); 210 // find somewhere to place assertions back, for convenience it is the last slot 211 ftype->forall.back()->assertions = get<DeclarationWithType>().acceptL(node->assertions); 212 } 208 213 209 214 visitType(node->type, ftype); … … 602 607 603 608 for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) { 604 rslt->add( src_i->first ,609 rslt->add( src_i->first.typeString(), 605 610 get<Type>().accept1(src_i->second) ); 606 }607 608 for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {609 rslt->addVar( src_i->first,610 get<Expression>().accept1(src_i->second) );611 611 } 612 612 … … 1212 1212 // ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1213 1213 // ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1214 ty->forall = get<TypeDecl>().acceptL( node->forall ); 1214 1215 auto types = get<TypeInstType>().acceptL( node->forall ); 1216 for (auto t : types) { 1217 auto newT = new TypeDecl(*t->baseType); 1218 newT->name = t->name; // converted by typeString() 1219 for (auto asst : newT->assertions) delete asst; 1220 newT->assertions.clear(); 1221 ty->forall.push_back(newT); 1222 } 1223 auto assts = get<VariableExpr>().acceptL( node->assertions ); 1224 if (!assts.empty()) { 1225 assert(!types.empty()); 1226 for (auto asst : assts) { 1227 auto newDecl = new ObjectDecl(*strict_dynamic_cast<ObjectDecl*>(asst->var)); 1228 delete newDecl->type; 1229 newDecl->type = asst->result->clone(); 1230 newDecl->storageClasses.is_extern = true; // hack 1231 ty->forall.back()->assertions.push_back(newDecl); 1232 } 1233 } 1234 1215 1235 return visitType( node, ty ); 1216 1236 } … … 1299 1319 ty = new TypeInstType{ 1300 1320 cv( node ), 1301 node-> name,1321 node->typeString(), 1302 1322 get<TypeDecl>().accept1( node->base ), 1303 1323 get<Attribute>().acceptL( node->attributes ) … … 1306 1326 ty = new TypeInstType{ 1307 1327 cv( node ), 1308 node-> name,1328 node->typeString(), 1309 1329 node->kind == ast::TypeDecl::Ftype, 1310 1330 get<Attribute>().acceptL( node->attributes ) … … 1431 1451 /// at conversion stage, all created nodes are guaranteed to be unique, therefore 1432 1452 /// const_casting out of smart pointers is permitted. 1433 std::unordered_map< const BaseSyntaxNode *, ast:: ptr<ast::Node> > cache = {};1453 std::unordered_map< const BaseSyntaxNode *, ast::readonly<ast::Node> > cache = {}; 1434 1454 1435 1455 // Local Utilities: … … 1565 1585 // can function type have attributes? seems not to be the case. 1566 1586 // visitType(old->type, ftype); 1587 1588 // collect assertions and put directly in FunctionDecl 1589 std::vector<ast::ptr<ast::DeclWithType>> assertions; 1590 for (auto & param: forall) { 1591 for (auto & asst: param->assertions) { 1592 assertf(asst->unique(), "newly converted decl must be unique"); 1593 assertions.emplace_back(asst); 1594 } 1595 auto mut = param.get_and_mutate(); 1596 assertf(mut == param, "newly converted decl must be unique"); 1597 mut->assertions.clear(); 1598 } 1567 1599 1568 1600 auto decl = new ast::FunctionDecl{ … … 1584 1616 cache.emplace( old, decl ); 1585 1617 1618 decl->assertions = std::move(assertions); 1586 1619 decl->withExprs = GET_ACCEPT_V(withExprs, Expr); 1587 1620 decl->stmts = GET_ACCEPT_1(statements, CompoundStmt); … … 2066 2099 } 2067 2100 2101 // TypeSubstitution shouldn't exist yet in old. 2068 2102 ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) { 2069 2103 2070 2104 if (!old) return nullptr; 2071 2105 if (old->empty()) return nullptr; 2106 assert(false); 2107 2108 /* 2072 2109 ast::TypeSubstitution *rslt = new ast::TypeSubstitution(); 2073 2110 … … 2077 2114 } 2078 2115 2079 for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {2080 rslt->addVar( old_i->first,2081 getAccept1<ast::Expr>(old_i->second) );2082 }2083 2084 2116 return rslt; 2117 */ 2085 2118 } 2086 2119 … … 2610 2643 ty->params.emplace_back(v->get_type()); 2611 2644 } 2612 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 2645 // xxx - when will this be non-null? 2646 // will have to create dangling (no-owner) decls to be pointed to 2647 auto foralls = GET_ACCEPT_V( forall, TypeDecl ); 2648 2649 for (auto & param : foralls) { 2650 ty->forall.emplace_back(new ast::TypeInstType(param->name, param)); 2651 for (auto asst : param->assertions) { 2652 ty->assertions.emplace_back(new ast::VariableExpr({}, asst)); 2653 } 2654 } 2613 2655 visitType( old, ty ); 2614 2656 } -
src/AST/Decl.cpp
rc5a98f3 r41cde266 50 50 51 51 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 52 std::vector<ptr<TypeDecl>>&& forall, 53 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 54 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 55 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 56 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 57 stmts( stmts ) { 58 FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs)); 59 for (auto & param : this->params) { 60 ftype->params.emplace_back(param->get_type()); 61 } 62 for (auto & ret : this->returns) { 63 ftype->returns.emplace_back(ret->get_type()); 64 } 65 ftype->forall = std::move(forall); 66 this->type = ftype; 67 } 52 std::vector<ptr<TypeDecl>>&& forall, 53 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 54 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 55 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 56 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 57 type_params(std::move(forall)), stmts( stmts ) { 58 FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs)); 59 for (auto & param : this->params) { 60 ftype->params.emplace_back(param->get_type()); 61 } 62 for (auto & ret : this->returns) { 63 ftype->returns.emplace_back(ret->get_type()); 64 } 65 for (auto & tp : this->type_params) { 66 ftype->forall.emplace_back(new TypeInstType(tp->name, tp)); 67 } 68 this->type = ftype; 69 } 68 70 69 71 -
src/AST/Decl.hpp
rc5a98f3 r41cde266 127 127 std::vector<ptr<DeclWithType>> params; 128 128 std::vector<ptr<DeclWithType>> returns; 129 std::vector<ptr<TypeDecl>> type_params; 130 std::vector<ptr<DeclWithType>> assertions; 129 131 // declared type, derived from parameter declarations 130 132 ptr<FunctionType> type; 131 133 ptr<CompoundStmt> stmts; 132 134 std::vector< ptr<Expr> > withExprs; 135 133 136 134 137 FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall, -
src/AST/Expr.cpp
rc5a98f3 r41cde266 206 206 assert( aggregate->result ); 207 207 208 // Deep copy on result type avoids mutation on transitively multiply referenced object. 209 // 210 // Example, adapted from parts of builtins and bootloader: 211 // 212 // forall(dtype T) 213 // struct __Destructor { 214 // T * object; 215 // void (*dtor)(T *); 216 // }; 217 // 218 // forall(dtype S) 219 // void foo(__Destructor(S) &d) { 220 // if (d.dtor) { // here 221 // } 222 // } 223 // 224 // Let e be the "d.dtor" guard espression, which is MemberExpr after resolve. Let d be the 225 // declaration of member __Destructor.dtor (an ObjectDecl), as accessed via the top-level 226 // declaration of __Destructor. Consider the types e.result and d.type. In the old AST, one 227 // is a clone of the other. Ordinary new-AST use would set them up as a multiply-referenced 228 // object. 229 // 230 // e.result: PointerType 231 // .base: FunctionType 232 // .params.front(): ObjectDecl, the anonymous parameter of type T* 233 // .type: PointerType 234 // .base: TypeInstType 235 // let x = that 236 // let y = similar, except start from d.type 237 // 238 // Consider two code lines down, genericSubstitution(...).apply(result). 239 // 240 // Applying this chosen-candidate's type substitution means modifying x, substituting 241 // S for T. This mutation should affect x and not y. 242 243 result = deepCopy(mem->get_type()); 208 result = mem->get_type(); 244 209 245 210 // substitute aggregate generic parameters into member type -
src/AST/Pass.hpp
rc5a98f3 r41cde266 34 34 35 35 #include "AST/SymbolTable.hpp" 36 37 #include "AST/ForallSubstitutionTable.hpp"38 36 39 37 // Private prelude header, needed for some of the magic tricks this class pulls off … … 66 64 // | WithVisitorRef - provides an pointer to the templated visitor wrapper 67 65 // | WithSymbolTable - provides symbol table functionality 68 // | WithForallSubstitutor - maintains links between TypeInstType and TypeDecl under mutation69 66 // 70 67 // Other Special Members: … … 258 255 container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container ); 259 256 260 /// Mutate forall-list, accounting for presence of type substitution map261 template<typename node_t>262 void mutate_forall( const node_t *& );263 264 257 public: 265 258 /// Logic to call the accept and mutate the parent if needed, delegates call to accept … … 398 391 }; 399 392 400 /// Use when the templated visitor needs to keep TypeInstType instances properly linked to TypeDecl401 struct WithForallSubstitutor {402 ForallSubstitutionTable subs;403 };404 405 393 } 406 394 -
src/AST/Pass.impl.hpp
rc5a98f3 r41cde266 367 367 } 368 368 369 370 template< typename core_t >371 template< typename node_t >372 void ast::Pass< core_t >::mutate_forall( const node_t *& node ) {373 if ( auto subs = __pass::forall::subs( core, 0 ) ) {374 // tracking TypeDecl substitution, full clone375 if ( node->forall.empty() ) return;376 377 node_t * mut = __pass::mutate<core_t>( node );378 mut->forall = subs->clone( node->forall, *this );379 node = mut;380 } else {381 // not tracking TypeDecl substitution, just mutate382 maybe_accept( node, &node_t::forall );383 }384 }385 369 } 386 370 … … 504 488 __pass::symtab::addId( core, 0, func ); 505 489 VISIT( 506 // parameter declarations are now directly here490 // parameter declarations 507 491 maybe_accept( node, &FunctionDecl::params ); 508 492 maybe_accept( node, &FunctionDecl::returns ); 509 // foralls are still in function type 510 maybe_accept( node, &FunctionDecl::type ); 493 // type params and assertions 494 maybe_accept( node, &FunctionDecl::type_params ); 495 maybe_accept( node, &FunctionDecl::assertions ); 511 496 // First remember that we are now within a function. 512 497 ValueGuard< bool > oldInFunction( inFunction ); … … 1758 1743 1759 1744 VISIT({ 1760 guard_forall_subs forall_guard { *this, node }; 1761 mutate_forall( node ); 1745 // guard_forall_subs forall_guard { *this, node }; 1746 // mutate_forall( node ); 1747 maybe_accept( node, &FunctionType::assertions ); 1762 1748 maybe_accept( node, &FunctionType::returns ); 1763 1749 maybe_accept( node, &FunctionType::params ); … … 1981 1967 { 1982 1968 bool mutated = false; 1983 std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;1969 std::unordered_map< ast::TypeInstType::TypeEnvKey, ast::ptr< ast::Type > > new_map; 1984 1970 for ( const auto & p : node->typeEnv ) { 1985 1971 guard_symtab guard { *this }; … … 1994 1980 } 1995 1981 } 1996 1997 {1998 bool mutated = false;1999 std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;2000 for ( const auto & p : node->varEnv ) {2001 guard_symtab guard { *this };2002 auto new_node = p.second->accept( *this );2003 if (new_node != p.second) mutated = true;2004 new_map.insert({ p.first, new_node });2005 }2006 if (mutated) {2007 auto new_node = __pass::mutate<core_t>( node );2008 new_node->varEnv.swap( new_map );2009 node = new_node;2010 }2011 }2012 1982 ) 2013 1983 -
src/AST/Pass.proto.hpp
rc5a98f3 r41cde266 413 413 static inline auto leave( core_t &, long, const ast::FunctionType * ) {} 414 414 415 // Get the substitution table, if present416 template<typename core_t>417 static inline auto subs( core_t & core, int ) -> decltype( &core.subs ) {418 return &core.subs;419 }420 421 template<typename core_t>422 static inline ast::ForallSubstitutionTable * subs( core_t &, long ) { return nullptr; }423 424 415 // Replaces a TypeInstType's base TypeDecl according to the table 425 416 template<typename core_t> -
src/AST/Print.cpp
rc5a98f3 r41cde266 155 155 } 156 156 157 void print( const ast::FunctionType::AssertionList & assts ) { 158 if (assts.empty()) return; 159 os << "with assertions" << endl; 160 ++indent; 161 printAll(assts); 162 os << indent; 163 --indent; 164 } 165 157 166 void print( const std::vector<ptr<Attribute>> & attrs ) { 158 167 if ( attrs.empty() ) return; … … 206 215 void preprint( const ast::NamedTypeDecl * node ) { 207 216 if ( ! node->name.empty() ) { 208 if( deterministic_output && isUnboundType(node->name) ) os << "[unbound]:"; 209 else os << node->name << ": "; 217 os << node->name << ": "; 210 218 } 211 219 … … 261 269 void preprint( const ast::FunctionType * node ) { 262 270 print( node->forall ); 271 print( node->assertions ); 263 272 print( node->qualifiers ); 264 273 } … … 1375 1384 virtual const ast::Type * visit( const ast::TypeInstType * node ) override final { 1376 1385 preprint( node ); 1377 const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node-> name;1386 const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node->typeString(); 1378 1387 os << "instance of type " << _name 1379 1388 << " (" << (node->kind == ast::TypeDecl::Ftype ? "" : "not ") << "function type)"; … … 1502 1511 os << indent << "Types:" << endl; 1503 1512 for ( const auto& i : *node ) { 1504 os << indent+1 << i.first << " -> ";1513 os << indent+1 << i.first.typeString() << " -> "; 1505 1514 indent += 2; 1506 1515 safe_print( i.second ); 1507 indent -= 2;1508 os << endl;1509 }1510 os << indent << "Non-types:" << endl;1511 for ( auto i = node->beginVar(); i != node->endVar(); ++i ) {1512 os << indent+1 << i->first << " -> ";1513 indent += 2;1514 safe_print( i->second );1515 1516 indent -= 2; 1516 1517 os << endl; -
src/AST/SymbolTable.cpp
rc5a98f3 r41cde266 414 414 415 415 void SymbolTable::addFunction( const FunctionDecl * func ) { 416 addTypes( func->type->forall ); 416 for (auto & td : func->type_params) { 417 addType(td); 418 } 419 for (auto & asst : func->assertions) { 420 addId(asst); 421 } 422 // addTypes( func->type->forall ); 417 423 addIds( func->returns ); 418 424 addIds( func->params ); -
src/AST/Type.cpp
rc5a98f3 r41cde266 21 21 22 22 #include "Decl.hpp" 23 #include "ForallSubstitutor.hpp" // for substituteForall24 23 #include "Init.hpp" 25 24 #include "Common/utility.h" // for copy, move … … 92 91 // GENERATED END 93 92 94 // --- ParameterizedType95 96 void FunctionType::initWithSub(97 const FunctionType & o, Pass< ForallSubstitutor > & sub98 ) {99 forall = sub.core( o.forall );100 }101 102 93 // --- FunctionType 103 104 105 FunctionType::FunctionType( const FunctionType & o )106 : Type( o.qualifiers, copy( o.attributes ) ), returns(), params(),107 isVarArgs( o.isVarArgs ) {108 Pass< ForallSubstitutor > sub;109 initWithSub( o, sub ); // initialize substitution map110 returns = sub.core( o.returns ); // apply to return and parameter types111 params = sub.core( o.params );112 }113 114 94 namespace { 115 95 bool containsTtype( const std::vector<ptr<Type>> & l ) { … … 199 179 // TODO: once TypeInstType representation is updated, it should properly check 200 180 // if the context id is filled. this is a temporary hack for now 201 return isUnboundType(typeInst->name); 202 } 203 return false; 204 } 205 206 bool isUnboundType(const std::string & tname) { 207 // xxx - look for a type name produced by renameTyVars. 208 209 // TODO: once TypeInstType representation is updated, it should properly check 210 // if the context id is filled. this is a temporary hack for now 211 if (std::count(tname.begin(), tname.end(), '_') >= 3) { 212 return true; 181 return typeInst->formal_usage > 0; 213 182 } 214 183 return false; -
src/AST/Type.hpp
rc5a98f3 r41cde266 36 36 37 37 template< typename T > class Pass; 38 39 struct ForallSubstitutor;40 38 41 39 class Type : public Node { … … 272 270 /// Type of a function `[R1, R2](*)(P1, P2, P3)` 273 271 class FunctionType final : public Type { 274 protected: 275 /// initializes forall with substitutor 276 void initWithSub( const FunctionType & o, Pass< ForallSubstitutor > & sub ); 277 public: 278 using ForallList = std::vector<ptr<TypeDecl>>; 272 public: 273 using ForallList = std::vector<ptr<TypeInstType>>; 274 using AssertionList = std::vector<ptr<VariableExpr>>; 279 275 ForallList forall; 276 AssertionList assertions; 280 277 281 278 std::vector<ptr<Type>> returns; … … 292 289 : Type(q), returns(), params(), isVarArgs(va) {} 293 290 294 FunctionType( const FunctionType & o ) ;291 FunctionType( const FunctionType & o ) = default; 295 292 296 293 /// true if either the parameters or return values contain a tttype … … 397 394 public: 398 395 readonly<TypeDecl> base; 396 // previously from renameTyVars; now directly use integer fields instead of synthesized strings 397 // a nonzero value of formal_usage indicates a formal type (only used in function type) 398 // a zero value of formal_usage indicates an actual type (referenced inside body of parametric structs and functions) 399 399 TypeDecl::Kind kind; 400 int formal_usage = 0; 401 int expr_id = 0; 402 403 // compact representation used for map lookups. 404 struct TypeEnvKey { 405 const TypeDecl * base; 406 int formal_usage; 407 int expr_id; 408 409 TypeEnvKey() = default; 410 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0): base(base), formal_usage(formal_usage), expr_id(expr_id) {} 411 TypeEnvKey(const TypeInstType & inst): base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {} 412 std::string typeString() const { return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + base->name; } 413 bool operator==(const TypeEnvKey & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; } 414 415 }; 416 417 bool operator==(const TypeInstType & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; } 400 418 401 419 TypeInstType( … … 409 427 TypeInstType( const TypeInstType & o ) = default; 410 428 429 TypeInstType( const TypeEnvKey & key ) 430 : BaseInstType(key.base->name), base(key.base), kind(key.base->kind), formal_usage(key.formal_usage), expr_id(key.expr_id) {} 431 411 432 /// sets `base`, updating `kind` correctly 412 433 void set_base( const TypeDecl * ); … … 418 439 419 440 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 441 442 std::string typeString() const { 443 if (formal_usage > 0) return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + name; 444 else return name; 445 } 420 446 private: 421 447 TypeInstType * clone() const override { return new TypeInstType{ *this }; } … … 510 536 511 537 bool isUnboundType(const Type * type); 512 bool isUnboundType(const std::string & tname); 513 538 539 } 540 541 namespace std { 542 template<> 543 struct hash<typename ast::TypeInstType::TypeEnvKey> { 544 size_t operator() (const ast::TypeInstType::TypeEnvKey & x) const { 545 const size_t p = 1000007; 546 size_t res = reinterpret_cast<size_t>(x.base); 547 res = p * res + x.formal_usage; 548 res = p * res + x.expr_id; 549 return res; 550 } 551 }; 514 552 } 515 553 -
src/AST/TypeEnvironment.cpp
rc5a98f3 r41cde266 52 52 for ( const auto & i : open ) { 53 53 if ( first ) { first = false; } else { out << ' '; } 54 out << i.first << "(" << i.second << ")";54 out << i.first.typeString() << "(" << i.second << ")"; 55 55 } 56 56 } … … 62 62 if(first) first = false; 63 63 else out << " "; 64 if( deterministic_output && isUnboundType(var) ) out << "[unbound]"; 65 else out << var; 64 65 if( deterministic_output ) out << "[unbound]"; 66 else out << "_" << var.formal_usage << "_" << var.expr_id << "_"; 67 68 out << var.base->name; 66 69 } 67 70 out << ")"; … … 79 82 } 80 83 81 const EqvClass * TypeEnvironment::lookup( const std::string& var ) const {84 const EqvClass * TypeEnvironment::lookup( const TypeInstType::TypeEnvKey & var ) const { 82 85 for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) { 83 86 if ( i->vars.find( var ) != i->vars.end() ) return &*i; … … 106 109 107 110 void TypeEnvironment::add( const FunctionType::ForallList & tyDecls ) { 108 for ( const TypeDecl *tyDecl : tyDecls ) {111 for ( auto & tyDecl : tyDecls ) { 109 112 env.emplace_back( tyDecl ); 110 113 } … … 119 122 void TypeEnvironment::writeToSubstitution( TypeSubstitution & sub ) const { 120 123 for ( const auto & clz : env ) { 121 std::string clzRep; 124 TypeInstType::TypeEnvKey clzRep; 125 bool first = true; 122 126 for ( const auto & var : clz.vars ) { 123 127 if ( clz.bound ) { 124 128 sub.add( var, clz.bound ); 125 } else if ( clzRep.empty()) {129 } else if ( first ) { 126 130 clzRep = var; 131 first = false; 127 132 } else { 128 sub.add( var, new TypeInstType{ clzRep , clz.data.kind} );133 sub.add( var, new TypeInstType{ clzRep } ); 129 134 } 130 135 } … … 141 146 struct Occurs : public ast::WithVisitorRef<Occurs> { 142 147 bool result; 143 std:: set< std::string> vars;148 std::unordered_set< TypeInstType::TypeEnvKey > vars; 144 149 const TypeEnvironment & tenv; 145 150 146 Occurs( const std::string& var, const TypeEnvironment & env )151 Occurs( const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env ) 147 152 : result( false ), vars(), tenv( env ) { 148 153 if ( const EqvClass * clz = tenv.lookup( var ) ) { … … 154 159 155 160 void previsit( const TypeInstType * typeInst ) { 156 if ( vars.count( typeInst->name) ) {161 if ( vars.count( *typeInst ) ) { 157 162 result = true; 158 } else if ( const EqvClass * clz = tenv.lookup( typeInst->name) ) {163 } else if ( const EqvClass * clz = tenv.lookup( *typeInst ) ) { 159 164 if ( clz->bound ) { 160 165 clz->bound->accept( *visitor ); … … 165 170 166 171 /// true if `var` occurs in `ty` under `env` 167 bool occurs( const Type * ty, const std::string& var, const TypeEnvironment & env ) {172 bool occurs( const Type * ty, const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env ) { 168 173 Pass<Occurs> occur{ var, env }; 169 174 maybe_accept( ty, occur ); … … 280 285 // remove references from bound type, so that type variables can only bind to value types 281 286 ptr<Type> target = bindTo->stripReferences(); 282 auto tyvar = open.find( typeInst->name);287 auto tyvar = open.find( *typeInst ); 283 288 assert( tyvar != open.end() ); 284 289 if ( ! tyVarCompatible( tyvar->second, target ) ) return false; 285 if ( occurs( target, typeInst->name, *this ) ) return false;286 287 auto it = internal_lookup( typeInst->name);290 if ( occurs( target, *typeInst, *this ) ) return false; 291 292 auto it = internal_lookup( *typeInst ); 288 293 if ( it != env.end() ) { 289 294 if ( it->bound ) { … … 308 313 } else { 309 314 env.emplace_back( 310 typeInst->name, target, widen.first && widen.second, data );315 *typeInst, target, widen.first && widen.second, data ); 311 316 } 312 317 return true; … … 318 323 WidenMode widen, const SymbolTable & symtab 319 324 ) { 320 auto c1 = internal_lookup( var1->name);321 auto c2 = internal_lookup( var2->name);325 auto c1 = internal_lookup( *var1 ); 326 auto c2 = internal_lookup( *var2 ); 322 327 323 328 // exit early if variables already bound together … … 333 338 if ( c1 != env.end() ) { 334 339 if ( c1->bound ) { 335 if ( occurs( c1->bound, var2->name, *this ) ) return false;340 if ( occurs( c1->bound, *var2, *this ) ) return false; 336 341 type1 = c1->bound; 337 342 } … … 340 345 if ( c2 != env.end() ) { 341 346 if ( c2->bound ) { 342 if ( occurs( c2->bound, var1->name, *this ) ) return false;347 if ( occurs( c2->bound, *var1, *this ) ) return false; 343 348 type2 = c2->bound; 344 349 } … … 378 383 } else if ( c1 != env.end() ) { 379 384 // var2 unbound, add to env[c1] 380 c1->vars.emplace( var2->name);385 c1->vars.emplace( *var2 ); 381 386 c1->allowWidening = widen1; 382 387 c1->data.isComplete |= data.isComplete; 383 388 } else if ( c2 != env.end() ) { 384 389 // var1 unbound, add to env[c2] 385 c2->vars.emplace( var1->name);390 c2->vars.emplace( *var1 ); 386 391 c2->allowWidening = widen2; 387 392 c2->data.isComplete |= data.isComplete; 388 393 } else { 389 394 // neither var bound, create new class 390 env.emplace_back( var1->name, var2->name, widen1 && widen2, data );395 env.emplace_back( *var1, *var2, widen1 && widen2, data ); 391 396 } 392 397 … … 452 457 } 453 458 454 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string& var ) {459 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeInstType::TypeEnvKey & var ) { 455 460 for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) { 456 461 if ( i->vars.count( var ) ) return i; -
src/AST/TypeEnvironment.hpp
rc5a98f3 r41cde266 55 55 /// recorded. More investigation is needed. 56 56 struct AssertCompare { 57 bool operator()( const DeclWithType * d1, const DeclWithType* d2 ) const {58 int cmp = d1-> name.compare( d2->name );59 return cmp < 0 || ( cmp == 0 && d1-> get_type() < d2->get_type());57 bool operator()( const VariableExpr * d1, const VariableExpr * d2 ) const { 58 int cmp = d1->var->name.compare( d2->var->name ); 59 return cmp < 0 || ( cmp == 0 && d1->result < d2->result ); 60 60 } 61 61 }; … … 70 70 71 71 /// Set of assertions pending satisfaction 72 using AssertionSet = std::map< readonly<DeclWithType>, AssertionSetValue, AssertCompare >;72 using AssertionSet = std::map< const VariableExpr *, AssertionSetValue, AssertCompare >; 73 73 74 74 /// Set of open variables 75 using OpenVarSet = std::unordered_map< std::string, TypeDecl::Data >;75 using OpenVarSet = std::unordered_map< TypeInstType::TypeEnvKey, TypeDecl::Data >; 76 76 77 77 /// Merges one set of open vars into another … … 89 89 /// they bind to. 90 90 struct EqvClass { 91 std:: set< std::string> vars;91 std::unordered_set< TypeInstType::TypeEnvKey > vars; 92 92 ptr<Type> bound; 93 93 bool allowWidening; … … 101 101 102 102 /// Singleton class constructor from TypeDecl 103 EqvClass( const Type Decl * decl)104 : vars{ decl->name }, bound(), allowWidening( true ), data( decl) {}103 EqvClass( const TypeInstType * inst ) 104 : vars{ *inst }, bound(), allowWidening( true ), data( inst->base ) {} 105 105 106 106 /// Singleton class constructor from substitution 107 EqvClass( const std::string& v, const Type * b )107 EqvClass( const TypeInstType::TypeEnvKey & v, const Type * b ) 108 108 : vars{ v }, bound( b ), allowWidening( false ), data( TypeDecl::Dtype, false ) {} 109 109 110 110 /// Single-var constructor (strips qualifiers from bound type) 111 EqvClass( const std::string& v, const Type * b, bool w, const TypeDecl::Data & d )111 EqvClass( const TypeInstType::TypeEnvKey & v, const Type * b, bool w, const TypeDecl::Data & d ) 112 112 : vars{ v }, bound( b ), allowWidening( w ), data( d ) { 113 113 reset_qualifiers( bound ); … … 115 115 116 116 /// Double-var constructor 117 EqvClass( const std::string & v, const std::string& u, bool w, const TypeDecl::Data & d )117 EqvClass( const TypeInstType::TypeEnvKey & v, const TypeInstType::TypeEnvKey & u, bool w, const TypeDecl::Data & d ) 118 118 : vars{ v, u }, bound(), allowWidening( w ), data( d ) {} 119 119 … … 131 131 public: 132 132 /// Finds the equivalence class containing a variable; nullptr for none such 133 const EqvClass * lookup( const std::string& var ) const;133 const EqvClass * lookup( const TypeInstType::TypeEnvKey & var ) const; 134 134 135 135 /// Add a new equivalence class for each type variable … … 207 207 208 208 /// Private lookup API; returns array index of string, or env.size() for not found 209 ClassList::iterator internal_lookup( const std::string& );209 ClassList::iterator internal_lookup( const TypeInstType::TypeEnvKey & ); 210 210 }; 211 211 -
src/AST/TypeSubstitution.cpp
rc5a98f3 r41cde266 39 39 void TypeSubstitution::initialize( const TypeSubstitution &src, TypeSubstitution &dest ) { 40 40 dest.typeEnv.clear(); 41 dest.varEnv.clear();42 41 dest.add( src ); 43 42 } … … 47 46 typeEnv[ i->first ] = i->second; 48 47 } // for 49 for ( VarEnvType::const_iterator i = other.varEnv.begin(); i != other.varEnv.end(); ++i ) {50 varEnv[ i->first ] = i->second;51 } // for52 48 } 53 49 54 void TypeSubstitution::add( std::stringformalType, const Type *actualType ) {55 typeEnv[ formalType ] = actualType;50 void TypeSubstitution::add( const TypeInstType * formalType, const Type *actualType ) { 51 typeEnv[ *formalType ] = actualType; 56 52 } 57 53 58 void TypeSubstitution::add Var( std::string formalExpr, const Expr *actualExpr) {59 varEnv[ formalExpr ] = actualExpr;54 void TypeSubstitution::add( const TypeInstType::TypeEnvKey & key, const Type * actualType) { 55 typeEnv[ key ] = actualType; 60 56 } 61 57 62 void TypeSubstitution::remove( std::stringformalType ) {63 TypeEnvType::iterator i = typeEnv.find( formalType );58 void TypeSubstitution::remove( const TypeInstType * formalType ) { 59 TypeEnvType::iterator i = typeEnv.find( *formalType ); 64 60 if ( i != typeEnv.end() ) { 65 typeEnv.erase( formalType );61 typeEnv.erase( *formalType ); 66 62 } // if 67 63 } 68 64 69 const Type *TypeSubstitution::lookup( std::stringformalType ) const {70 TypeEnvType::const_iterator i = typeEnv.find( formalType );65 const Type *TypeSubstitution::lookup( const TypeInstType * formalType ) const { 66 TypeEnvType::const_iterator i = typeEnv.find( *formalType ); 71 67 72 68 // break on not in substitution set … … 75 71 // attempt to transitively follow TypeInstType links. 76 72 while ( const TypeInstType *actualType = i->second.as<TypeInstType>()) { 77 const std::string& typeName = actualType->name;78 79 73 // break cycles in the transitive follow 80 if ( formalType == typeName ) break;74 if ( *formalType == *actualType ) break; 81 75 82 76 // Look for the type this maps to, returning previous mapping if none-such 83 i = typeEnv.find( typeName );77 i = typeEnv.find( *actualType ); 84 78 if ( i == typeEnv.end() ) return actualType; 85 79 } … … 90 84 91 85 bool TypeSubstitution::empty() const { 92 return typeEnv.empty() && varEnv.empty();86 return typeEnv.empty(); 93 87 } 94 88 … … 98 92 TypeSubstitution * newEnv; 99 93 EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 100 void previsit( TypeDecl * tyDecl) {94 void previsit( FunctionType * ftype ) { 101 95 // transfer known bindings for seen type variables 102 if ( const Type * t = env->lookup( tyDecl->name ) ) { 103 newEnv->add( tyDecl->name, t ); 96 for (auto & formal : ftype->forall) { 97 if ( const Type * t = env->lookup( formal ) ) { 98 newEnv->add( formal, t ); 99 } 104 100 } 105 101 } … … 130 126 131 127 const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) { 132 BoundVarsType::const_iterator bound = boundVars.find( inst->name);128 BoundVarsType::const_iterator bound = boundVars.find( *inst ); 133 129 if ( bound != boundVars.end() ) return inst; 134 130 135 TypeEnvType::const_iterator i = sub.typeEnv.find( inst->name);131 TypeEnvType::const_iterator i = sub.typeEnv.find( *inst ); 136 132 if ( i == sub.typeEnv.end() ) { 137 133 return inst; … … 141 137 // TODO: investigate preventing type variables from being bound to themselves in the first place. 142 138 if ( const TypeInstType * replacement = i->second.as<TypeInstType>() ) { 143 if ( inst->name == replacement->name) {139 if ( *inst == *replacement ) { 144 140 return inst; 145 141 } … … 156 152 } 157 153 158 const Expr * TypeSubstitution::Substituter::postvisit( const NameExpr * nameExpr ) {159 VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name );160 if ( i == sub.varEnv.end() ) {161 return nameExpr;162 } else {163 subCount++;164 return i->second;165 } // if166 }167 168 154 void TypeSubstitution::Substituter::previsit( const FunctionType * ptype ) { 169 155 GuardValue( boundVars ); 170 156 // bind type variables from forall-qualifiers 171 157 if ( freeOnly ) { 172 for ( const TypeDecl *tyvar : ptype->forall ) {173 boundVars.insert( tyvar->name);158 for ( auto & tyvar : ptype->forall ) { 159 boundVars.insert( *tyvar ); 174 160 } // for 175 161 } // if 176 162 } 177 163 164 /* 178 165 void TypeSubstitution::Substituter::handleAggregateType( const BaseInstType * type ) { 179 166 GuardValue( boundVars ); … … 184 171 if ( ! type->params.empty() ) { 185 172 for ( const TypeDecl * tyvar : decl->params ) { 186 boundVars.insert( tyvar->name);173 boundVars.insert( *tyvar ); 187 174 } // for 188 175 } // if … … 198 185 handleAggregateType( aggregateUseType ); 199 186 } 187 */ 200 188 201 189 } // namespace ast -
src/AST/TypeSubstitution.hpp
rc5a98f3 r41cde266 69 69 } 70 70 71 void add( std::string formalType, const Type *actualType ); 71 void add( const TypeInstType * formalType, const Type *actualType ); 72 void add( const TypeInstType::TypeEnvKey & key, const Type *actualType ); 72 73 void add( const TypeSubstitution &other ); 73 void remove( std::stringformalType );74 const Type *lookup( std::stringformalType ) const;74 void remove( const TypeInstType * formalType ); 75 const Type *lookup( const TypeInstType * formalType ) const; 75 76 bool empty() const; 76 77 void addVar( std::string formalExpr, const Expr *actualExpr );78 77 79 78 template< typename FormalIterator, typename ActualIterator > … … 101 100 friend class Pass; 102 101 103 typedef std::unordered_map< std::string, ptr<Type> > TypeEnvType; 104 typedef std::unordered_map< std::string, ptr<Expr> > VarEnvType; 102 typedef std::unordered_map< TypeInstType::TypeEnvKey, ptr<Type> > TypeEnvType; 105 103 TypeEnvType typeEnv; 106 VarEnvType varEnv;107 104 108 105 public: … … 113 110 auto end() const -> decltype( typeEnv. end() ) { return typeEnv. end(); } 114 111 115 auto beginVar() -> decltype( varEnv.begin() ) { return varEnv.begin(); }116 auto endVar() -> decltype( varEnv. end() ) { return varEnv. end(); }117 auto beginVar() const -> decltype( varEnv.begin() ) { return varEnv.begin(); }118 auto endVar() const -> decltype( varEnv. end() ) { return varEnv. end(); }119 112 }; 120 113 114 // this is the only place where type parameters outside a function formal may be substituted. 121 115 template< typename FormalIterator, typename ActualIterator > 122 116 void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) { … … 129 123 if ( const TypeExpr *actual = actualIt->template as<TypeExpr>() ) { 130 124 if ( formal->name != "" ) { 131 typeEnv[ formal ->name] = actual->type;125 typeEnv[ formal ] = actual->type; 132 126 } // if 133 127 } else { … … 135 129 } // if 136 130 } else { 137 // TODO: type check the formal and actual parameters 138 if ( (*formalIt)->name != "" ) { 139 varEnv[ (*formalIt)->name ] = *actualIt; 140 } // if 131 141 132 } // if 142 133 } // for 143 134 } 135 136 144 137 145 138 template< typename FormalIterator, typename ActualIterator > … … 147 140 add( formalBegin, formalEnd, actualBegin ); 148 141 } 142 149 143 150 144 } // namespace ast … … 164 158 165 159 const Type * postvisit( const TypeInstType * aggregateUseType ); 166 const Expr * postvisit( const NameExpr * nameExpr );167 160 168 161 /// Records type variable bindings from forall-statements 169 162 void previsit( const FunctionType * type ); 170 163 /// Records type variable bindings from forall-statements and instantiations of generic types 171 void handleAggregateType( const BaseInstType * type );164 // void handleAggregateType( const BaseInstType * type ); 172 165 173 void previsit( const StructInstType * aggregateUseType );174 void previsit( const UnionInstType * aggregateUseType );166 // void previsit( const StructInstType * aggregateUseType ); 167 // void previsit( const UnionInstType * aggregateUseType ); 175 168 176 169 const TypeSubstitution & sub; 177 170 int subCount = 0; 178 171 bool freeOnly; 179 typedef std::unordered_set< std::string> BoundVarsType;172 typedef std::unordered_set< TypeInstType::TypeEnvKey > BoundVarsType; 180 173 BoundVarsType boundVars; 181 174 -
src/AST/module.mk
rc5a98f3 r41cde266 33 33 AST/Expr.cpp \ 34 34 AST/Expr.hpp \ 35 AST/ForallSubstitutionTable.cpp \36 AST/ForallSubstitutionTable.hpp \37 AST/ForallSubstitutor.hpp \38 35 AST/FunctionSpec.hpp \ 39 36 AST/Fwd.hpp \ -
src/GenPoly/GenPoly.cc
rc5a98f3 r41cde266 115 115 if (!env) return type; 116 116 if (auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) { 117 auto newType = env->lookup(typeInst ->name);117 auto newType = env->lookup(typeInst); 118 118 if (newType) return newType; 119 119 } … … 172 172 173 173 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 174 return tyVars.find(typeInst-> name) != tyVars.end() ? type : nullptr;174 return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr; 175 175 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) { 176 176 return isPolyType( arrayType->base, env ); … … 552 552 } 553 553 554 void addToTyVarMap( const ast::Type Decl* tyVar, TyVarMap & tyVarMap) {555 tyVarMap.insert(tyVar-> name, convData(ast::TypeDecl::Data{tyVar}));554 void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) { 555 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base})); 556 556 } 557 557 -
src/ResolvExpr/AdjustExprType.cc
rc5a98f3 r41cde266 133 133 const ast::Type * postvisit( const ast::TypeInstType * inst ) { 134 134 // replace known function-type-variables with pointer-to-function 135 if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name) ) {135 if ( const ast::EqvClass * eqvClass = tenv.lookup( *inst ) ) { 136 136 if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) { 137 137 return new ast::PointerType{ inst }; -
src/ResolvExpr/CandidateFinder.cpp
rc5a98f3 r41cde266 212 212 // mark type variable and specialization cost of forall clause 213 213 convCost.incVar( function->forall.size() ); 214 for ( const ast::TypeDecl * td : function->forall ) { 215 convCost.decSpec( td->assertions.size() ); 216 } 214 convCost.decSpec( function->assertions.size() ); 217 215 218 216 return convCost; … … 223 221 ast::AssertionSet & need 224 222 ) { 225 for ( const ast::TypeDecl *tyvar : type->forall ) {226 unifiableVars[ tyvar->name ] = ast::TypeDecl::Data{ tyvar};227 for ( const ast::DeclWithType * assn : tyvar->assertions ) {228 need[ assn ].isUsed = true;229 }223 for ( auto & tyvar : type->forall ) { 224 unifiableVars[ *tyvar ] = ast::TypeDecl::Data{ tyvar->base }; 225 } 226 for ( auto & assn : type->assertions ) { 227 need[ assn ].isUsed = true; 230 228 } 231 229 } … … 953 951 auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult ) 954 952 ) { 955 if ( const ast::EqvClass * clz = func->env.lookup( inst->name) ) {953 if ( const ast::EqvClass * clz = func->env.lookup( *inst ) ) { 956 954 if ( auto function = clz->bound.as< ast::FunctionType >() ) { 957 955 CandidateRef newFunc{ new Candidate{ *func } }; … … 1077 1075 assert( toType ); 1078 1076 toType = resolveTypeof( toType, symtab ); 1079 toType = SymTab::validateType( castExpr->location, toType, symtab );1077 // toType = SymTab::validateType( castExpr->location, toType, symtab ); 1080 1078 toType = adjustExprType( toType, tenv, symtab ); 1081 1079 … … 1162 1160 1163 1161 if(auto insttype = dynamic_cast<const ast::TypeInstType*>(expr)) { 1164 auto td = cand->env.lookup( insttype->name);1162 auto td = cand->env.lookup(*insttype); 1165 1163 if(!td) { continue; } 1166 1164 expr = td->bound.get(); … … 1568 1566 // calculate target type 1569 1567 const ast::Type * toType = resolveTypeof( initAlt.type, symtab ); 1570 toType = SymTab::validateType( initExpr->location, toType, symtab );1568 // toType = SymTab::validateType( initExpr->location, toType, symtab ); 1571 1569 toType = adjustExprType( toType, tenv, symtab ); 1572 1570 // The call to find must occur inside this loop, otherwise polymorphic return -
src/ResolvExpr/CastCost.cc
rc5a98f3 r41cde266 202 202 ) { 203 203 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 204 if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name) ) {204 if ( const ast::EqvClass * eqvClass = env.lookup( *typeInst ) ) { 205 205 // check cast cost against bound type, if present 206 206 if ( eqvClass->bound ) { -
src/ResolvExpr/CommonType.cc
rc5a98f3 r41cde266 713 713 const ast::Type * base = oPtr->base; 714 714 if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) { 715 auto entry = open.find( var->name);715 auto entry = open.find( *var ); 716 716 if ( entry != open.end() ) { 717 717 ast::AssertionSet need, have; -
src/ResolvExpr/ConversionCost.cc
rc5a98f3 r41cde266 498 498 ) { 499 499 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 500 if ( const ast::EqvClass * eqv = env.lookup( inst->name) ) {500 if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) { 501 501 if ( eqv->bound ) { 502 502 return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env ); … … 675 675 676 676 void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) { 677 if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {677 if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) { 678 678 cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env ); 679 679 } else if ( const ast::TypeInstType * dstAsInst = 680 680 dynamic_cast< const ast::TypeInstType * >( dst ) ) { 681 if ( typeInstType->name == dstAsInst->name) {681 if ( *typeInstType == *dstAsInst ) { 682 682 cost = Cost::zero; 683 683 } -
src/ResolvExpr/FindOpenVars.cc
rc5a98f3 r41cde266 112 112 // mark open/closed variables 113 113 if ( nextIsOpen ) { 114 for ( const ast::TypeDecl *decl : type->forall ) {115 open[ decl->name ] = ast::TypeDecl::Data{ decl};116 for ( const ast::DeclWithType * assert : decl->assertions ) {117 need[ assert ].isUsed = false;118 }114 for ( auto & decl : type->forall ) { 115 open[ *decl ] = ast::TypeDecl::Data{ decl->base }; 116 } 117 for ( auto & assert : type->assertions ) { 118 need[ assert ].isUsed = false; 119 119 } 120 120 } else { 121 for ( const ast::TypeDecl *decl : type->forall ) {122 closed[ decl->name ] = ast::TypeDecl::Data{ decl };123 for ( const ast::DeclWithType * assert : decl->assertions ) {124 have[ assert ].isUsed = false;125 }121 for ( auto & decl : type->forall ) { 122 closed[ *decl ] = ast::TypeDecl::Data{ decl->base }; 123 } 124 for ( auto & assert : type->assertions ) { 125 have[ assert ].isUsed = false; 126 126 } 127 127 } -
src/ResolvExpr/PolyCost.cc
rc5a98f3 r41cde266 68 68 69 69 void previsit( const ast::TypeInstType * type ) { 70 if ( const ast::EqvClass * eqv = env_.lookup( type->name ) ) /* && */ if ( eqv->bound ) {70 if ( const ast::EqvClass * eqv = env_.lookup( *type ) ) /* && */ if ( eqv->bound ) { 71 71 if ( const ast::TypeInstType * otherType = eqv->bound.as< ast::TypeInstType >() ) { 72 72 if ( symtab.lookupType( otherType->name ) ) { -
src/ResolvExpr/PtrsAssignable.cc
rc5a98f3 r41cde266 134 134 } 135 135 void postvisit( const ast::TypeInstType * inst ) { 136 if ( const ast::EqvClass * eqv = typeEnv.lookup( inst->name) ) {136 if ( const ast::EqvClass * eqv = typeEnv.lookup( *inst ) ) { 137 137 if ( eqv->bound ) { 138 138 // T * = S * for any S depends on the type bound to T … … 146 146 const ast::TypeEnvironment & env ) { 147 147 if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 148 if ( const ast::EqvClass * eqv = env.lookup( dstAsInst->name) ) {148 if ( const ast::EqvClass * eqv = env.lookup( *dstAsInst ) ) { 149 149 return ptrsAssignable( src, eqv->bound, env ); 150 150 } -
src/ResolvExpr/PtrsCastable.cc
rc5a98f3 r41cde266 180 180 } 181 181 } 182 } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name) ) {182 } else if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) { 183 183 if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) { 184 184 return -1; … … 283 283 ) { 284 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 285 if ( const ast::EqvClass * eqvClass = env.lookup( inst->name) ) {285 if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) { 286 286 return ptrsAssignable( src, eqvClass->bound, env ); 287 287 } -
src/ResolvExpr/RenameVars.cc
rc5a98f3 r41cde266 19 19 #include <utility> // for pair 20 20 21 #include "AST/ForallSubstitutionTable.hpp"22 21 #include "AST/Pass.hpp" 23 22 #include "AST/Type.hpp" … … 39 38 int level = 0; 40 39 int resetCount = 0; 40 41 int next_expr_id = 1; 42 int next_usage_id = 1; 41 43 ScopedMap< std::string, std::string > nameMap; 44 ScopedMap< std::string, ast::TypeInstType::TypeEnvKey > idMap; 42 45 public: 43 ast::ForallSubstitutionTable subs;44 45 46 void reset() { 46 47 level = 0; … … 53 54 type->name = it->second; 54 55 } 56 } 57 58 void nextUsage() { 59 ++next_usage_id; 55 60 } 56 61 … … 78 83 79 84 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 80 // re-linking of base type handled by WithForallSubstitutor81 82 85 // rename 83 auto it = nameMap.find( type->name ); 84 if ( it != nameMap.end() ) { 85 // unconditionally mutate because map will *always* have different name, 86 // if this mutates, will *always* have been mutated by ForallSubstitutor above 87 ast::TypeInstType * mut = ast::mutate( type ); 88 mut->name = it->second; 86 auto it = idMap.find( type->name ); 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; 89 94 type = mut; 90 95 } … … 93 98 } 94 99 95 const ast::FunctionType * openLevel( const ast::FunctionType * type ) {100 const ast::FunctionType * openLevel( const ast::FunctionType * type, RenameMode mode ) { 96 101 if ( type->forall.empty() ) return type; 97 98 nameMap.beginScope(); 102 idMap.beginScope(); 99 103 100 104 // Load new names from this forall clause and perform renaming. 101 auto mutType = ast::mutate( type ); 102 assert( type == mutType && "mutated type must be unique from ForallSubstitutor" ); 103 for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) { 104 assertf(dynamic_cast<ast::FunctionType *>(mutType), "renaming vars in non-function type"); 105 std::ostringstream output; 106 output << "_" << resetCount << "_" << level << "_" << td->name; 107 std::string newname = output.str(); 108 nameMap[ td->name ] = newname; 109 ++level; 110 111 ast::TypeDecl * mutDecl = ast::mutate( td.get() ); 112 assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" ); 113 mutDecl->name = newname; 114 // assertion above means `td = mutDecl;` is unnecessary 115 } 116 // assertion above means `type = mutType;` is unnecessary 117 118 return type; 105 auto mutType = ast::shallowCopy( type ); 106 // assert( type == mutType && "mutated type must be unique from ForallSubstitutor" ); 107 for ( auto & td : mutType->forall ) { 108 auto mut = ast::shallowCopy( td.get() ); 109 // assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" ); 110 111 if (mode == GEN_EXPR_ID) { 112 mut->expr_id = next_expr_id; 113 mut->formal_usage = -1; 114 ++next_expr_id; 115 } 116 else if (mode == GEN_USAGE) { 117 assertf(mut->expr_id, "unfilled expression id in generating candidate type"); 118 mut->formal_usage = next_usage_id; 119 } 120 else { 121 assert(false); 122 } 123 idMap[ td->name ] = ast::TypeInstType::TypeEnvKey(*mut); 124 125 td = mut; 126 } 127 128 return mutType; 119 129 } 120 130 121 131 void closeLevel( const ast::FunctionType * type ) { 122 132 if ( type->forall.empty() ) return; 123 124 nameMap.endScope(); 133 idMap.endScope(); 125 134 } 126 135 }; … … 142 151 }; 143 152 144 struct RenameVars_new /*: public ast::WithForallSubstitutor*/ { 145 #warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor 146 ast::ForallSubstitutionTable & subs = renaming.subs; 153 struct RenameVars_new : public ast::PureVisitor /*: public ast::WithForallSubstitutor*/ { 154 RenameMode mode; 147 155 148 156 const ast::FunctionType * previsit( const ast::FunctionType * type ) { 149 return renaming.openLevel( type );157 return renaming.openLevel( type, mode ); 150 158 } 151 159 … … 163 171 164 172 const ast::TypeInstType * previsit( const ast::TypeInstType * type ) { 173 if (mode == GEN_USAGE && !type->formal_usage) return type; // do not rename an actual type 165 174 return renaming.rename( type ); 166 175 } … … 177 186 } 178 187 179 const ast::Type * renameTyVars( const ast::Type * t ) {180 ast::Type *tc = ast::deepCopy(t);188 const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode ) { 189 // ast::Type *tc = ast::deepCopy(t); 181 190 ast::Pass<RenameVars_new> renamer; 182 // return t->accept( renamer ); 183 return tc->accept( renamer ); 191 renamer.core.mode = mode; 192 if (mode == GEN_USAGE) { 193 renaming.nextUsage(); 194 } 195 return t->accept( renamer ); 184 196 } 185 197 -
src/ResolvExpr/RenameVars.h
rc5a98f3 r41cde266 30 30 /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID 31 31 void renameTyVars( Type * ); 32 const ast::Type * renameTyVars( const ast::Type * ); 32 33 enum RenameMode { 34 GEN_USAGE, // for type in VariableExpr 35 GEN_EXPR_ID // for type in decl 36 }; 37 const ast::Type * renameTyVars( const ast::Type *, RenameMode mode = GEN_USAGE ); 33 38 34 39 /// resets internal state of renamer to avoid overflow 35 40 void resetTyVarRenaming(); 41 42 36 43 } // namespace ResolvExpr 37 44 -
src/ResolvExpr/ResolveTypeof.cc
rc5a98f3 r41cde266 15 15 16 16 #include "ResolveTypeof.h" 17 #include "RenameVars.h" 17 18 18 19 #include <cassert> // for assert … … 218 219 mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables 219 220 221 mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID); 220 222 mutDecl->isTypeFixed = true; 221 223 return mutDecl; -
src/ResolvExpr/Resolver.cc
rc5a98f3 r41cde266 986 986 }; 987 987 } // anonymous namespace 988 989 988 /// Check if this expression is or includes a deleted expression 990 989 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { … … 1375 1374 } 1376 1375 1377 // handle assertions . (seems deep)1376 // handle assertions 1378 1377 1379 1378 symtab.enterScope(); 1380 for (auto & typeParam : mutType->forall) { 1381 auto mutParam = typeParam.get_and_mutate(); 1382 symtab.addType(mutParam); 1383 for (auto & asst : mutParam->assertions) { 1384 asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab); 1385 symtab.addId(asst); 1386 } 1387 typeParam = mutParam; 1379 mutType->forall.clear(); 1380 mutType->assertions.clear(); 1381 for (auto & typeParam : mutDecl->type_params) { 1382 symtab.addType(typeParam); 1383 mutType->forall.emplace_back(new ast::TypeInstType(typeParam->name, typeParam)); 1384 } 1385 for (auto & asst : mutDecl->assertions) { 1386 asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab); 1387 symtab.addId(asst); 1388 mutType->assertions.emplace_back(new ast::VariableExpr(functionDecl->location, asst)); 1388 1389 } 1389 1390 … … 1407 1408 mutType->returns = std::move(returnTypes); 1408 1409 1410 auto renamedType = strict_dynamic_cast<const ast::FunctionType *>(renameTyVars(mutType, RenameMode::GEN_EXPR_ID)); 1411 1409 1412 std::list<ast::ptr<ast::Stmt>> newStmts; 1410 1413 resolveWithExprs (mutDecl->withExprs, newStmts); … … 1418 1421 symtab.leaveScope(); 1419 1422 1423 mutDecl->type = renamedType; 1420 1424 mutDecl->mangleName = Mangle::mangle(mutDecl); 1421 1425 mutDecl->isTypeFixed = true; … … 1534 1538 const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) { 1535 1539 if ( type->dimension ) { 1536 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1537 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1540 ast::ptr< ast::Type > sizeType = ast::sizeType; 1538 1541 ast::mutate_field( 1539 1542 type, &PtrType::dimension, -
src/ResolvExpr/SatisfyAssertions.cpp
rc5a98f3 r41cde266 69 69 /// Reference to a single deferred item 70 70 struct DeferRef { 71 const ast:: DeclWithType * decl;71 const ast::VariableExpr * expr; 72 72 const ast::AssertionSetValue & info; 73 73 const AssnCandidate & match; … … 77 77 /// Acts like an indexed list of DeferRef 78 78 struct DeferItem { 79 const ast:: DeclWithType * decl;79 const ast::VariableExpr * expr; 80 80 const ast::AssertionSetValue & info; 81 81 AssnCandidateList matches; 82 82 83 83 DeferItem( 84 const ast:: DeclWithType* d, const ast::AssertionSetValue & i, AssnCandidateList && ms )85 : decl( d ), info( i ), matches( std::move( ms ) ) {}84 const ast::VariableExpr * d, const ast::AssertionSetValue & i, AssnCandidateList && ms ) 85 : expr( d ), info( i ), matches( std::move( ms ) ) {} 86 86 87 87 bool empty() const { return matches.empty(); } … … 89 89 AssnCandidateList::size_type size() const { return matches.size(); } 90 90 91 DeferRef operator[] ( unsigned i ) const { return { decl, info, matches[i] }; }91 DeferRef operator[] ( unsigned i ) const { return { expr, info, matches[i] }; } 92 92 }; 93 93 … … 138 138 void addToSymbolTable( const ast::AssertionSet & have, ast::SymbolTable & symtab ) { 139 139 for ( auto & i : have ) { 140 if ( i.second.isUsed ) { symtab.addId( i.first ); }140 if ( i.second.isUsed ) { symtab.addId( i.first->var ); } 141 141 } 142 142 } … … 144 144 /// Binds a single assertion, updating satisfaction state 145 145 void bindAssertion( 146 const ast:: DeclWithType * decl, const ast::AssertionSetValue & info, CandidateRef & cand,146 const ast::VariableExpr * expr, const ast::AssertionSetValue & info, CandidateRef & cand, 147 147 AssnCandidate & match, InferCache & inferred 148 148 ) { … … 156 156 157 157 // place newly-inferred assertion in proper location in cache 158 inferred[ info.resnSlot ][ decl->uniqueId ] = ast::ParamEntry{159 candidate->uniqueId, candidate, match.adjType, decl->get_type(), varExpr };158 inferred[ info.resnSlot ][ expr->var->uniqueId ] = ast::ParamEntry{ 159 candidate->uniqueId, candidate, match.adjType, expr->result, varExpr }; 160 160 } 161 161 … … 169 169 170 170 std::vector<ast::SymbolTable::IdData> candidates; 171 auto kind = ast::SymbolTable::getSpecialFunctionKind(assn.first-> name);171 auto kind = ast::SymbolTable::getSpecialFunctionKind(assn.first->var->name); 172 172 if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) { 173 173 // prefilter special decls by argument type, if already known 174 ast::ptr<ast::Type> thisArgType = strict_dynamic_cast<const ast::PointerType *>(assn.first->get_type())->base174 ast::ptr<ast::Type> thisArgType = assn.first->result.strict_as<ast::PointerType>()->base 175 175 .strict_as<ast::FunctionType>()->params[0] 176 176 .strict_as<ast::ReferenceType>()->base; … … 184 184 } 185 185 else { 186 candidates = sat.symtab.lookupId(assn.first-> name);186 candidates = sat.symtab.lookupId(assn.first->var->name); 187 187 } 188 188 for ( const ast::SymbolTable::IdData & cdata : candidates ) { … … 200 200 ast::TypeEnvironment newEnv{ sat.cand->env }; 201 201 ast::OpenVarSet newOpen{ sat.cand->open }; 202 ast::ptr< ast::Type > toType = assn.first-> get_type();202 ast::ptr< ast::Type > toType = assn.first->result; 203 203 ast::ptr< ast::Type > adjType = 204 204 renameTyVars( adjustExprType( candidate->get_type(), newEnv, sat.symtab ) ); … … 337 337 // compute conversion cost from satisfying decl to assertion 338 338 cost += computeConversionCost( 339 assn.match.adjType, assn. decl->get_type(), false, symtab, env );339 assn.match.adjType, assn.expr->result, false, symtab, env ); 340 340 341 341 // mark vars+specialization on function-type assertions … … 350 350 cost.incVar( func->forall.size() ); 351 351 352 for ( const ast::TypeDecl * td : func->forall ) { 353 cost.decSpec( td->assertions.size() ); 354 } 352 cost.decSpec( func->assertions.size() ); 355 353 } 356 354 } … … 451 449 ss << (tabs-1) << "Too many non-unique satisfying assignments for assertions:\n"; 452 450 for ( const auto & d : sat.deferred ) { 453 ast::print( ss, d. decl, tabs );451 ast::print( ss, d.expr, tabs ); 454 452 } 455 453 … … 469 467 ss << (tabs-1) << "No mutually-compatible satisfaction for assertions:\n"; 470 468 for ( const auto& d : sat.deferred ) { 471 ast::print( ss, d. decl, tabs );469 ast::print( ss, d.expr, tabs ); 472 470 } 473 471 … … 501 499 nextNewNeed.insert( match.need.begin(), match.need.end() ); 502 500 503 bindAssertion( r. decl, r.info, nextCand, match, nextInferred );501 bindAssertion( r.expr, r.info, nextCand, match, nextInferred ); 504 502 } 505 503 -
src/ResolvExpr/Unify.cc
rc5a98f3 r41cde266 773 773 774 774 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 775 if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name) ) {775 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) { 776 776 // expand ttype parameter into its actual type 777 777 if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) { … … 888 888 } 889 889 890 static void markAssertionSet( ast::AssertionSet & assns, const ast:: DeclWithType* assn ) {890 static void markAssertionSet( ast::AssertionSet & assns, const ast::VariableExpr * assn ) { 891 891 auto i = assns.find( assn ); 892 892 if ( i != assns.end() ) { … … 900 900 const ast::FunctionType * type 901 901 ) { 902 for ( const auto & tyvar : type->forall ) { 903 for ( const ast::DeclWithType * assert : tyvar->assertions ) { 904 markAssertionSet( assn1, assert ); 905 markAssertionSet( assn2, assert ); 906 } 902 for ( auto & assert : type->assertions ) { 903 markAssertionSet( assn1, assert ); 904 markAssertionSet( assn2, assert ); 907 905 } 908 906 } … … 1030 1028 1031 1029 void postvisit( const ast::TypeInstType * typeInst ) { 1032 assert( open.find( typeInst->name) == open.end() );1030 assert( open.find( *typeInst ) == open.end() ); 1033 1031 handleRefType( typeInst, type2 ); 1034 1032 } … … 1171 1169 auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 ); 1172 1170 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name) : open.end(),1174 entry2 = var2 ? open.find( var2->name) : open.end();1171 entry1 = var1 ? open.find( *var1 ) : open.end(), 1172 entry2 = var2 ? open.find( *var2 ) : open.end(); 1175 1173 bool isopen1 = entry1 != open.end(); 1176 1174 bool isopen2 = entry2 != open.end(); -
src/SymTab/Mangler.cc
rc5a98f3 r41cde266 671 671 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 672 672 mangleName += Encoding::forall; 673 for ( const ast::TypeDecl *decl : ptype->forall ) {673 for ( auto & decl : ptype->forall ) { 674 674 switch ( decl->kind ) { 675 675 case ast::TypeDecl::Kind::Dtype: … … 686 686 } // switch 687 687 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 688 for ( const ast::DeclWithType * assert : decl->assertions ) {689 ast::Pass<Mangler_new> sub_mangler(690 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );691 assert->accept( sub_mangler);692 assertionNames.push_back( sub_mangler.core.get_mangleName());693 acount++;694 } // for688 } // for 689 for ( auto & assert : ptype->assertions ) { 690 ast::Pass<Mangler_new> sub_mangler( 691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 692 assert->var->accept( sub_mangler ); 693 assertionNames.push_back( sub_mangler.core.get_mangleName() ); 694 acount++; 695 695 } // for 696 696 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_"; -
src/SymTab/Validate.cc
rc5a98f3 r41cde266 1463 1463 } 1464 1464 1465 /* 1466 1465 1467 /// Associates forward declarations of aggregates with their definitions 1466 1468 class LinkReferenceToTypes_new final … … 1844 1846 } 1845 1847 }; 1848 */ 1846 1849 } // anonymous namespace 1847 1850 1851 /* 1848 1852 const ast::Type * validateType( 1849 1853 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { … … 1854 1858 return type->accept( lrt )->accept( fpd ); 1855 1859 } 1860 */ 1856 1861 1857 1862 } // namespace SymTab -
src/Tuples/TupleAssignment.cc
rc5a98f3 r41cde266 504 504 505 505 std::vector< ast::ptr< ast::Expr > > match() override { 506 // temporary workaround for new and old ast to coexist and avoid name collision 507 static UniqueName lhsNamer( "__massassign_Ln" ); 508 static UniqueName rhsNamer( "__massassign_Rn" ); 506 static UniqueName lhsNamer( "__massassign_L" ); 507 static UniqueName rhsNamer( "__massassign_R" ); 509 508 // empty tuple case falls into this matcher 510 509 assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 ); … … 535 534 536 535 std::vector< ast::ptr< ast::Expr > > match() override { 537 // temporary workaround for new and old ast to coexist and avoid name collision 538 static UniqueName lhsNamer( "__multassign_Ln" ); 539 static UniqueName rhsNamer( "__multassign_Rn" ); 536 static UniqueName lhsNamer( "__multassign_L" ); 537 static UniqueName rhsNamer( "__multassign_R" ); 540 538 541 539 if ( lhs.size() != rhs.size() ) return {}; -
tests/.expect/KRfunctions.nast.x86.txt
rc5a98f3 r41cde266 86 86 __attribute__ ((unused)) signed int (*_X11_retval_f11PA0i_1)[]; 87 87 } 88 signed int (*_X3f12FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned longint )10)]{89 __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned longint )10)];88 signed int (*_X3f12FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned int )10)]{ 89 __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned int )10)]; 90 90 } 91 signed int (*_X3f13FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned longint )10)]{92 __attribute__ ((unused)) signed int (*_X11_retval_f13PA0A0i_1)[][((unsigned longint )10)];91 signed int (*_X3f13FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned int )10)]{ 92 __attribute__ ((unused)) signed int (*_X11_retval_f13PA0A0i_1)[][((unsigned int )10)]; 93 93 } 94 signed int (*_X3f14FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned longint )10)]{95 __attribute__ ((unused)) signed int (*_X11_retval_f14PA0A0i_1)[][((unsigned longint )10)];94 signed int (*_X3f14FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned int )10)]{ 95 __attribute__ ((unused)) signed int (*_X11_retval_f14PA0A0i_1)[][((unsigned int )10)]; 96 96 } 97 97 signed int _X3f15Fi_iii__1(signed int _X1ai_1, signed int _X1bi_1, signed int _X1ci_1){ -
tests/.expect/attributes.nast.x86.txt
rc5a98f3 r41cde266 623 623 __attribute__ ((used,used,used,used)) const signed int *_X3vd3PKi_1; 624 624 __attribute__ ((used,used,unused,used,unused)) const signed int *_X3vd4PKi_1; 625 __attribute__ ((used,used,used)) const signed int _X3vd5A0Ki_1[((unsigned longint )5)];626 __attribute__ ((used,used,unused,used)) const signed int _X3vd6A0Ki_1[((unsigned longint )5)];625 __attribute__ ((used,used,used)) const signed int _X3vd5A0Ki_1[((unsigned int )5)]; 626 __attribute__ ((used,used,unused,used)) const signed int _X3vd6A0Ki_1[((unsigned int )5)]; 627 627 __attribute__ ((used,used,used,used)) const signed int (*_X3vd7Fi___1)(); 628 628 __attribute__ ((used,used,unused,used,used)) const signed int (*_X3vd8Fi___1)(); … … 647 647 __attribute__ ((unused,unused,used)) signed int _X2t1i_2; 648 648 __attribute__ ((unused,unused,unused,unused,unused)) signed int **_X2t2PPi_2; 649 __attribute__ ((unused,unused,unused)) signed int _X2t3A0i_2[((unsigned longint )5)];650 __attribute__ ((unused,unused,unused,unused,unused)) signed int **_X2t4A0PPi_2[((unsigned longint )5)];649 __attribute__ ((unused,unused,unused)) signed int _X2t3A0i_2[((unsigned int )5)]; 650 __attribute__ ((unused,unused,unused,unused,unused)) signed int **_X2t4A0PPi_2[((unsigned int )5)]; 651 651 __attribute__ ((unused,unused,unused)) signed int _X2t5Fi___2(); 652 652 __attribute__ ((unused,unused,unused,unused)) signed int *_X2t6FPi___2(); … … 671 671 signed int _X4tpr2Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **_X3FooPPi_1); 672 672 signed int _X4tpr3Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *_X3FooPi_1); 673 signed int _X4tpr4Fi_Fi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object1)(signed int __param_0[((unsigned longint )5)]));673 signed int _X4tpr4Fi_Fi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object1)(signed int __param_0[((unsigned int )5)])); 674 674 signed int _X4tpr5Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*_X3FooFi___1)()); 675 675 signed int _X4tpr6Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*_X3FooFi___1)()); … … 679 679 __attribute__ ((used,unused)) signed int _X3ad1i_2; 680 680 __attribute__ ((unused,unused,unused)) signed int *_X3ad2Pi_2; 681 __attribute__ ((unused,unused,unused)) signed int _X3ad3A0i_2[((unsigned longint )5)];682 __attribute__ ((unused,unused,unused,unused,unused)) signed int (*_X3ad4PA0i_2)[((unsigned longint )10)];681 __attribute__ ((unused,unused,unused)) signed int _X3ad3A0i_2[((unsigned int )5)]; 682 __attribute__ ((unused,unused,unused,unused,unused)) signed int (*_X3ad4PA0i_2)[((unsigned int )10)]; 683 683 __attribute__ ((unused,unused,unused,unused,used)) signed int _X3ad5i_2; 684 684 __attribute__ ((unused,unused,unused,unused,unused)) signed int _X3ad6Fi___2(); -
tests/.expect/functions.nast.x86.txt
rc5a98f3 r41cde266 46 46 __attribute__ ((unused)) signed int (*_X11_retval_f10PA0i_1)[]; 47 47 } 48 signed int (*_X3f11FPA0A0i___1())[][((unsigned longint )3)]{49 __attribute__ ((unused)) signed int (*_X11_retval_f11PA0A0i_1)[][((unsigned longint )3)];50 } 51 signed int (*_X3f12FPA0A0i___1())[][((unsigned longint )3)]{52 __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned longint )3)];48 signed int (*_X3f11FPA0A0i___1())[][((unsigned int )3)]{ 49 __attribute__ ((unused)) signed int (*_X11_retval_f11PA0A0i_1)[][((unsigned int )3)]; 50 } 51 signed int (*_X3f12FPA0A0i___1())[][((unsigned int )3)]{ 52 __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned int )3)]; 53 53 } 54 54 signed int _X4fII1Fi_i__1(signed int _X1ii_1){ … … 250 250 signed int _X1fFi_Fi_ii_Fi_i___1(__attribute__ ((unused)) signed int (*__anonymous_object20)(signed int __param_0, signed int __param_1), __attribute__ ((unused)) signed int (*__anonymous_object21)(signed int __param_0)){ 251 251 __attribute__ ((unused)) signed int _X9_retval_fi_1; 252 signed int (*(*_X2pcPA0A0PA0A0i_2)[][((unsigned long int )10)])[][((unsigned longint )3)];253 signed int (*(*_X1pPA0A0PA0A0i_2)[][((unsigned long int )10)])[][((unsigned longint )3)];252 signed int (*(*_X2pcPA0A0PA0A0i_2)[][((unsigned int )10)])[][((unsigned int )3)]; 253 signed int (*(*_X1pPA0A0PA0A0i_2)[][((unsigned int )10)])[][((unsigned int )3)]; 254 254 signed int (*(*_X1pPA0Fi_i__2)[])(signed int __param_0); 255 255 } -
tests/errors/.expect/completeType.nast.x64.txt
rc5a98f3 r41cde266 12 12 Application of 13 13 Variable Expression: *?: forall 14 DT: data type14 instance of type DT (not function type) 15 15 function 16 16 ... with parameters … … 21 21 ... with resolved type: 22 22 pointer to forall 23 [unbound]:data type23 instance of type [unbound] (not function type) 24 24 function 25 25 ... with parameters … … 41 41 void 42 42 ) 43 Environment:([unbound] ) -> instance of struct A without body (no widening)43 Environment:([unbound]DT) -> instance of struct A without body (no widening) 44 44 45 45 … … 47 47 Application of 48 48 Variable Expression: *?: forall 49 DT: data type49 instance of type DT (not function type) 50 50 function 51 51 ... with parameters … … 56 56 ... with resolved type: 57 57 pointer to forall 58 [unbound]:data type58 instance of type [unbound] (not function type) 59 59 function 60 60 ... with parameters … … 76 76 void 77 77 ) 78 Environment:([unbound] ) -> instance of struct B with body (no widening)78 Environment:([unbound]DT) -> instance of struct B with body (no widening) 79 79 80 80 … … 113 113 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of 114 114 Variable Expression: baz: forall 115 T: sized data type 116 ... with assertions 117 ?=?: pointer to function 115 instance of type T (not function type) 116 with assertions 117 Variable Expression: ?=?: pointer to function 118 ... with parameters 119 reference to instance of type T (not function type) 120 instance of type T (not function type) 121 ... returning 122 instance of type T (not function type) 123 124 ... with resolved type: 125 pointer to function 118 126 ... with parameters 119 127 reference to instance of type T (not function type) … … 122 130 instance of type T (not function type) 123 131 124 ?{}: pointer to function 125 ... with parameters 126 reference to instance of type T (not function type) 127 ... returning nothing 128 129 ?{}: pointer to function 130 ... with parameters 131 reference to instance of type T (not function type) 132 instance of type T (not function type) 133 ... returning nothing 134 135 ^?{}: pointer to function 136 ... with parameters 137 reference to instance of type T (not function type) 138 ... returning nothing 139 132 Variable Expression: ?{}: pointer to function 133 ... with parameters 134 reference to instance of type T (not function type) 135 ... returning nothing 136 137 ... with resolved type: 138 pointer to function 139 ... with parameters 140 reference to instance of type T (not function type) 141 ... returning nothing 142 143 Variable Expression: ?{}: pointer to function 144 ... with parameters 145 reference to instance of type T (not function type) 146 instance of type T (not function type) 147 ... returning nothing 148 149 ... with resolved type: 150 pointer to function 151 ... with parameters 152 reference to instance of type T (not function type) 153 instance of type T (not function type) 154 ... returning nothing 155 156 Variable Expression: ^?{}: pointer to function 157 ... with parameters 158 reference to instance of type T (not function type) 159 ... returning nothing 160 161 ... with resolved type: 162 pointer to function 163 ... with parameters 164 reference to instance of type T (not function type) 165 ... returning nothing 140 166 141 167 function … … 146 172 ... with resolved type: 147 173 pointer to forall 148 [unbound]:sized data type 149 ... with assertions 150 ?=?: pointer to function 174 instance of type [unbound] (not function type) 175 with assertions 176 Variable Expression: ?=?: pointer to function 177 ... with parameters 178 reference to instance of type T (not function type) 179 instance of type T (not function type) 180 ... returning 181 instance of type T (not function type) 182 183 ... with resolved type: 184 pointer to function 151 185 ... with parameters 152 186 reference to instance of type [unbound] (not function type) … … 155 189 instance of type [unbound] (not function type) 156 190 157 ?{}: pointer to function 191 Variable Expression: ?{}: pointer to function 192 ... with parameters 193 reference to instance of type T (not function type) 194 ... returning nothing 195 196 ... with resolved type: 197 pointer to function 158 198 ... with parameters 159 199 reference to instance of type [unbound] (not function type) 160 200 ... returning nothing 161 201 162 ?{}: pointer to function 202 Variable Expression: ?{}: pointer to function 203 ... with parameters 204 reference to instance of type T (not function type) 205 instance of type T (not function type) 206 ... returning nothing 207 208 ... with resolved type: 209 pointer to function 163 210 ... with parameters 164 211 reference to instance of type [unbound] (not function type) … … 166 213 ... returning nothing 167 214 168 ^?{}: pointer to function 215 Variable Expression: ^?{}: pointer to function 216 ... with parameters 217 reference to instance of type T (not function type) 218 ... returning nothing 219 220 ... with resolved type: 221 pointer to function 169 222 ... with parameters 170 223 reference to instance of type [unbound] (not function type) 171 224 ... returning nothing 172 173 225 174 226 function … … 188 240 void 189 241 ) 190 Environment:([unbound] ) -> instance of type T (not function type) (no widening)242 Environment:([unbound]T) -> instance of type T (not function type) (no widening) 191 243 192 244 Could not satisfy assertion: 193 ?=?: pointer to function245 Variable Expression: ?=?: pointer to function 194 246 ... with parameters 195 reference to instance of type [unbound](not function type)196 instance of type [unbound](not function type)247 reference to instance of type T (not function type) 248 instance of type T (not function type) 197 249 ... returning 198 instance of type [unbound] (not function type) 199 250 instance of type T (not function type) 251 252 ... with resolved type: 253 pointer to function 254 ... with parameters 255 reference to instance of type [unbound] (not function type) 256 instance of type [unbound] (not function type) 257 ... returning 258 instance of type [unbound] (not function type) 259 -
tests/errors/.expect/completeType.nast.x86.txt
rc5a98f3 r41cde266 12 12 Application of 13 13 Variable Expression: *?: forall 14 DT: data type14 instance of type DT (not function type) 15 15 function 16 16 ... with parameters … … 21 21 ... with resolved type: 22 22 pointer to forall 23 [unbound]:data type23 instance of type [unbound] (not function type) 24 24 function 25 25 ... with parameters … … 41 41 void 42 42 ) 43 Environment:([unbound] ) -> instance of struct A without body (no widening)43 Environment:([unbound]DT) -> instance of struct A without body (no widening) 44 44 45 45 … … 47 47 Application of 48 48 Variable Expression: *?: forall 49 DT: data type49 instance of type DT (not function type) 50 50 function 51 51 ... with parameters … … 56 56 ... with resolved type: 57 57 pointer to forall 58 [unbound]:data type58 instance of type [unbound] (not function type) 59 59 function 60 60 ... with parameters … … 76 76 void 77 77 ) 78 Environment:([unbound] ) -> instance of struct B with body (no widening)78 Environment:([unbound]DT) -> instance of struct B with body (no widening) 79 79 80 80 … … 113 113 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of 114 114 Variable Expression: baz: forall 115 T: sized data type 116 ... with assertions 117 ?=?: pointer to function 115 instance of type T (not function type) 116 with assertions 117 Variable Expression: ?=?: pointer to function 118 ... with parameters 119 reference to instance of type T (not function type) 120 instance of type T (not function type) 121 ... returning 122 instance of type T (not function type) 123 124 ... with resolved type: 125 pointer to function 118 126 ... with parameters 119 127 reference to instance of type T (not function type) … … 122 130 instance of type T (not function type) 123 131 124 ?{}: pointer to function 125 ... with parameters 126 reference to instance of type T (not function type) 127 ... returning nothing 128 129 ?{}: pointer to function 130 ... with parameters 131 reference to instance of type T (not function type) 132 instance of type T (not function type) 133 ... returning nothing 134 135 ^?{}: pointer to function 136 ... with parameters 137 reference to instance of type T (not function type) 138 ... returning nothing 139 132 Variable Expression: ?{}: pointer to function 133 ... with parameters 134 reference to instance of type T (not function type) 135 ... returning nothing 136 137 ... with resolved type: 138 pointer to function 139 ... with parameters 140 reference to instance of type T (not function type) 141 ... returning nothing 142 143 Variable Expression: ?{}: pointer to function 144 ... with parameters 145 reference to instance of type T (not function type) 146 instance of type T (not function type) 147 ... returning nothing 148 149 ... with resolved type: 150 pointer to function 151 ... with parameters 152 reference to instance of type T (not function type) 153 instance of type T (not function type) 154 ... returning nothing 155 156 Variable Expression: ^?{}: pointer to function 157 ... with parameters 158 reference to instance of type T (not function type) 159 ... returning nothing 160 161 ... with resolved type: 162 pointer to function 163 ... with parameters 164 reference to instance of type T (not function type) 165 ... returning nothing 140 166 141 167 function … … 146 172 ... with resolved type: 147 173 pointer to forall 148 [unbound]:sized data type 149 ... with assertions 150 ?=?: pointer to function 174 instance of type [unbound] (not function type) 175 with assertions 176 Variable Expression: ?=?: pointer to function 177 ... with parameters 178 reference to instance of type T (not function type) 179 instance of type T (not function type) 180 ... returning 181 instance of type T (not function type) 182 183 ... with resolved type: 184 pointer to function 151 185 ... with parameters 152 186 reference to instance of type [unbound] (not function type) … … 155 189 instance of type [unbound] (not function type) 156 190 157 ?{}: pointer to function 191 Variable Expression: ?{}: pointer to function 192 ... with parameters 193 reference to instance of type T (not function type) 194 ... returning nothing 195 196 ... with resolved type: 197 pointer to function 158 198 ... with parameters 159 199 reference to instance of type [unbound] (not function type) 160 200 ... returning nothing 161 201 162 ?{}: pointer to function 202 Variable Expression: ?{}: pointer to function 203 ... with parameters 204 reference to instance of type T (not function type) 205 instance of type T (not function type) 206 ... returning nothing 207 208 ... with resolved type: 209 pointer to function 163 210 ... with parameters 164 211 reference to instance of type [unbound] (not function type) … … 166 213 ... returning nothing 167 214 168 ^?{}: pointer to function 215 Variable Expression: ^?{}: pointer to function 216 ... with parameters 217 reference to instance of type T (not function type) 218 ... returning nothing 219 220 ... with resolved type: 221 pointer to function 169 222 ... with parameters 170 223 reference to instance of type [unbound] (not function type) 171 224 ... returning nothing 172 173 225 174 226 function … … 188 240 void 189 241 ) 190 Environment:([unbound] ) -> instance of type T (not function type) (no widening)242 Environment:([unbound]T) -> instance of type T (not function type) (no widening) 191 243 192 244 Could not satisfy assertion: 193 ?=?: pointer to function245 Variable Expression: ?=?: pointer to function 194 246 ... with parameters 195 reference to instance of type [unbound](not function type)196 instance of type [unbound](not function type)247 reference to instance of type T (not function type) 248 instance of type T (not function type) 197 249 ... returning 198 instance of type [unbound] (not function type) 199 250 instance of type T (not function type) 251 252 ... with resolved type: 253 pointer to function 254 ... with parameters 255 reference to instance of type [unbound] (not function type) 256 instance of type [unbound] (not function type) 257 ... returning 258 instance of type [unbound] (not function type) 259 -
tests/heap.cfa
rc5a98f3 r41cde266 10 10 // Created On : Tue Nov 6 17:54:56 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 25 15:21:52202013 // Update Count : 7 312 // Last Modified On : Tue Dec 15 12:11:51 2020 13 // Update Count : 79 14 14 // 15 15 … … 27 27 // } 28 28 29 #define __U_DEFAULT_MMAP_START__ (512 * 1024 + 1) 30 size_t default_mmap_start() __attribute__(( weak )) { 31 return __U_DEFAULT_MMAP_START__; 29 size_t default_heap_expansion() { 30 return 10 * 1024 * 1024; 31 } // default_heap_expansion 32 33 size_t default_mmap_start() { 34 return 512 * 1024 + 1; 32 35 } // default_mmap_start 33 36 -
tests/multi_list.cfa
rc5a98f3 r41cde266 19 19 } 20 20 21 TaskDL *& Back( TaskDL * n ) { 22 return (TaskDL *)Back( (Seqable *)n ); 23 } 24 25 TaskDL *& Next( TaskDL * n ) { 26 return (TaskDL *)Next( (Colable *)n ); 27 } 28 21 29 struct TaskSL { 22 30 inline Colable; … … 29 37 Task & task( TaskSL & this ) with( this ) { // getter routine for containing node 30 38 return node; 39 } 40 41 TaskSL *& Next( TaskSL * n ) { 42 return (TaskSL *)Next( (Colable *)n ); 31 43 } 32 44 -
tests/queue.cfa
rc5a98f3 r41cde266 13 13 void ?{}( Fred & fred, int p ) with( fred ) { 14 14 i = p; 15 } 16 Fred *& Next( Fred * n ) { 17 return (Fred *)Next( (Colable *)n ); 15 18 } 16 19 … … 68 71 } 69 72 73 Mary *& Next( Mary * n ) { 74 return (Mary *)Next( (Fred *)n ); 75 } 76 70 77 Queue(Mary) mary; 71 78 QueueIter(Mary) maryIter = { mary }; -
tests/raii/.expect/ctor-autogen-ERR1.nast.txt
rc5a98f3 r41cde266 70 70 ... with environment: 71 71 Types: 72 Non-types:73 72 74 73 -
tests/sequence.cfa
rc5a98f3 r41cde266 13 13 void ?{}( Fred & fred, int p ) with( fred ) { 14 14 i = p; 15 } 16 17 Fred *& Back( Fred * n ) { 18 return (Fred *)Back( (Seqable *)n ); 19 } 20 21 Fred *& Next( Fred * n ) { 22 return (Fred *)Next( (Colable *)n ); 15 23 } 16 24 … … 76 84 } 77 85 86 Mary *& Back( Mary * n ) { 87 return (Mary *)Back( (Fred *)n ); 88 } 89 90 Mary *& Next( Mary * n ) { 91 return (Mary *)Next( (Fred *)n ); 92 } 93 78 94 Sequence(Mary) mary; 79 95 Sequence(Mary) baz; -
tests/stack.cfa
rc5a98f3 r41cde266 13 13 void ?{}( Fred & fred, int p ) with( fred ) { 14 14 i = p; 15 } 16 Fred *& Next( Fred * n ) { 17 return (Fred *)Next( (Colable *)n ); 15 18 } 16 19 … … 68 71 } 69 72 73 Mary *& Next( Mary * n ) { 74 return (Mary *)Next( (Fred *)n ); 75 } 76 70 77 Stack(Mary) mary; 71 78 StackIter(Mary) maryIter = { mary };
Note: See TracChangeset
for help on using the changeset viewer.