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