Changeset 6840e7c
- Timestamp:
- Oct 19, 2017, 12:01:04 PM (8 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 837ce06
- Parents:
- b96ec83 (diff), a15b72c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 26 added
- 4 deleted
- 148 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/lstlang.sty
rb96ec83 r6840e7c 2 2 %% 3 3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 %% 5 %% lstlang.sty -- 6 %% 4 %% 5 %% lstlang.sty -- 6 %% 7 7 %% Author : Peter A. Buhr 8 8 %% Created On : Sat May 13 16:34:42 2017 … … 110 110 __attribute__, auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, 111 111 __const, __const__, disable, dtype, enable, __extension__, fallthrough, fallthru, 112 finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t, 113 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 114 __typeof__, virtual, w aitfor, when, with, zero_t},112 finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t, 113 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 114 __typeof__, virtual, with, zero_t}, 115 115 morekeywords=[2]{ 116 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, 117 resume, suspend, thread, _Thread_local, yield},116 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, or, 117 resume, suspend, thread, _Thread_local, waitfor, when, yield}, 118 118 moredirectives={defined,include_next}% 119 119 } -
doc/proposals/concurrency/Makefile
rb96ec83 r6840e7c 16 16 text/basics \ 17 17 text/concurrency \ 18 text/internals \ 18 19 text/parallelism \ 20 text/together \ 21 text/future \ 19 22 } 20 23 … … 23 26 ext_monitor \ 24 27 int_monitor \ 28 dependency \ 25 29 }} 26 30 -
doc/proposals/concurrency/annex/glossary.tex
rb96ec83 r6840e7c 13 13 } 14 14 15 \longnewglossaryentry{ group-acquire}16 {name={bulk 15 \longnewglossaryentry{bulk-acq} 16 {name={bulk-acquiring}} 17 17 { 18 18 Implicitly acquiring several monitors when entering a monitor. 19 } 20 21 \longnewglossaryentry{multi-acq} 22 {name={multiple-acquisition}} 23 { 24 Any locking technique which allow any single thread to acquire a lock multiple times. 19 25 } 20 26 … … 101 107 \newacronym{api}{API}{Application Program Interface} 102 108 \newacronym{raii}{RAII}{Ressource Acquisition Is Initialization} 109 \newacronym{numa}{NUMA}{Non-Uniform Memory Access} -
doc/proposals/concurrency/figures/ext_monitor.fig
rb96ec83 r6840e7c 14 14 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 2160 d\001 15 15 -6 16 6 5 850 1650 6150 195017 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 190518 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\00116 6 5100 2100 5400 2400 17 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 2250 105 105 5250 2250 5355 2250 18 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2295 X\001 19 19 -6 20 20 6 5100 1800 5400 2100 … … 22 22 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2010 Y\001 23 23 -6 24 6 5 100 2100 5400 240025 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 2250 105 105 5250 2250 5355 225026 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2295 X\00124 6 5850 1650 6150 1950 25 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 1905 26 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\001 27 27 -6 28 6 30 00 5400 7200 570028 6 3070 5445 7275 5655 29 29 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3150 5550 80 80 3150 5550 3230 5630 30 30 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4500 5550 105 105 4500 5550 4605 5655 … … 32 32 4 0 -1 0 0 0 12 0.0000 2 135 1035 4725 5625 blocked task\001 33 33 4 0 -1 0 0 0 12 0.0000 2 135 870 3300 5625 active task\001 34 4 0 -1 0 0 0 12 0.0000 2 1 80 930 6225 5625 routine ptrs\00134 4 0 -1 0 0 0 12 0.0000 2 135 1050 6225 5625 routine mask\001 35 35 -6 36 36 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3300 3600 105 105 3300 3600 3405 3705 … … 43 43 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 44 4050 2925 5475 2925 5475 3225 4050 3225 4050 2925 45 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 246 5850 2850 6075 300047 45 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 48 46 3150 3750 3750 3750 3750 4050 3150 4050 … … 66 64 2 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5 67 65 5850 4200 5850 3300 4350 3300 4350 4200 5850 4200 68 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 369 5250 2850 5850 2850 5850 165070 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 471 3150 3150 3750 3150 3750 2850 5325 285072 66 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 73 67 1 1 1.00 60.00 120.00 74 68 7 1 1.00 60.00 120.00 75 69 5250 3150 5250 2400 70 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 71 3150 3150 3750 3150 3750 2850 5850 2850 5850 1650 72 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 73 5850 2850 6150 3000 76 74 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 77 75 5100 1800 5400 1800 5400 2400 5100 2400 5100 1800 -
doc/proposals/concurrency/style/cfa-format.tex
rb96ec83 r6840e7c 108 108 belowskip=3pt, 109 109 keepspaces=true, 110 tabsize=4, 110 111 % frame=lines, 111 112 literate=, … … 133 134 belowskip=3pt, 134 135 keepspaces=true, 136 tabsize=4, 135 137 % frame=lines, 136 138 literate=, … … 150 152 keywordstyle=\bfseries\color{blue}, 151 153 keywordstyle=[2]\bfseries\color{Plum}, 152 commentstyle=\ itshape\color{OliveGreen},% green and italic comments154 commentstyle=\sf\itshape\color{OliveGreen}, % green and italic comments 153 155 identifierstyle=\color{identifierCol}, 154 156 stringstyle=\sf\color{Mahogany}, % use sanserif font … … 158 160 belowskip=3pt, 159 161 keepspaces=true, 162 tabsize=4, 160 163 % frame=lines, 161 164 literate=, -
doc/proposals/concurrency/text/basics.tex
rb96ec83 r6840e7c 1 1 % ====================================================================== 2 2 % ====================================================================== 3 \chapter{ Basics}\label{basics}3 \chapter{Concurrency Basics}\label{basics} 4 4 % ====================================================================== 5 5 % ====================================================================== 6 Before any detailed discussion of the concurrency and parallelism in \CFA, it is important to describe the basics of concurrency and how they are expressed in \CFA user 6 Before any detailed discussion of the concurrency and parallelism in \CFA, it is important to describe the basics of concurrency and how they are expressed in \CFA user-code. 7 7 8 8 \section{Basics of concurrency} 9 At its core, concurrency is based on having call-stacks and potentially multiple threads of execution for these stacks. Concurrency without parallelism only requires having multiple call stacks (or contexts) for a single thread of execution, and switching between these call stacks on a regular basis. A minimal concurrency product can be achieved by creating coroutines, which instead of context switching between each other, always ask an oracle where to context switch next. While coroutines do not technically require a stack, stackfull coroutines are the closest abstraction to a practical "naked"" call stack. When writing concurrency in terms of coroutines, the oracle effectively becomes a scheduler and the whole system now follows a cooperative threading-model \cit. The oracle/scheduler can either be a stackless or stackfull entity and correspondingly require one or two context switches to run a different coroutine. In any case, a subset of concurrency related challenges start to appear. For the complete set of concurrency challenges to occur, the only feature missing is preemption. Indeed, concurrency challenges appear with non-determinism. Guaranteeing mutual-exclusion or synchronisation are simply ways of limiting the lack of determinism in a system. A scheduler introduces order of execution uncertainty, while preemption introduces incertainty about where context-switches occur. Now it is important to understand that uncertainty is not necessarily undesireable; uncertainty can often be used by systems to significantly increase performance and is often the basis of giving a user the illusion that tasks are running in parallel. Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows\cit. 9 At its core, concurrency is based on having multiple call-stacks and scheduling among threads of execution executing on these stacks. Concurrency without parallelism only requires having multiple call stacks (or contexts) for a single thread of execution. 10 11 Indeed, while execution with a single thread and multiple stacks where the thread is self-scheduling deterministically across the stacks is called coroutining, execution with a single and multiple stacks but where the thread is scheduled by an oracle (non-deterministic from the thread perspective) across the stacks is called concurrency. 12 13 Therefore, a minimal concurrency system can be achieved by creating coroutines, which instead of context switching among each other, always ask an oracle where to context switch next. While coroutines can execute on the caller's stack-frame, stackfull coroutines allow full generality and are sufficient as the basis for concurrency. The aforementioned oracle is a scheduler and the whole system now follows a cooperative threading-model \cit. The oracle/scheduler can either be a stackless or stackfull entity and correspondingly require one or two context switches to run a different coroutine. In any case, a subset of concurrency related challenges start to appear. For the complete set of concurrency challenges to occur, the only feature missing is preemption. Indeed, concurrency challenges appear with non-determinism. Using mutual-exclusion or synchronisation are ways of limiting the lack of determinism in a system. A scheduler introduces order of execution uncertainty, while preemption introduces uncertainty about where context-switches occur. Now it is important to understand that uncertainty is not undesireable; uncertainty can often be used by systems to significantly increase performance and is often the basis of giving a user the illusion that tasks are running in parallel. Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows\cit. 10 14 11 15 \section{\protect\CFA 's Thread Building Blocks} 12 One of the important features that is missing in C is threading. On modern architectures, a lack of threading is becoming less and less forgivable\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write performant concurrent and/or parallel programs. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers used toimperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay.16 One of the important features that is missing in C is threading. On modern architectures, a lack of threading is unacceptable\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write performant concurrent and/or parallel programs. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay. 13 17 14 18 \section{Coroutines: A stepping stone}\label{coroutine} 15 While the main focus of this proposal is concurrency and parallelism, as mentionned above it is important to adress coroutines, which are actually a significant underlying aspect of a concurrency system. Indeed, while having nothing to do with parallelism and arguably little to do with concurrency, coroutines need to deal with context-switchs and other context-management operations. Therefore, this proposal includes coroutines both as an intermediate step for the implementation of threads, and a first class feature of \CFA. Furthermore, many design challenges of threads are at least partially present in designing coroutines, which makes the design effort that much more relevant. The core API of coroutines revolve around two features: independent call stacks and \code{suspend}/\code{resume}. 16 17 Here is an example of a solution to the fibonnaci problem using \CFA coroutines: 18 \begin{cfacode} 19 coroutine Fibonacci { 20 int fn; // used for communication 21 }; 22 23 void ?{}(Fibonacci & this) { // constructor 24 this.fn = 0; 25 } 26 27 // main automacically called on first resume 28 void main(Fibonacci & this) { 29 int fn1, fn2; // retained between resumes 30 this.fn = 0; 31 fn1 = this.fn; 32 suspend(this); // return to last resume 33 34 this.fn = 1; 19 While the main focus of this proposal is concurrency and parallelism, it is important to address coroutines, which are actually a significant building block of a concurrency system. Coroutines need to deal with context-switchs and other context-management operations. Therefore, this proposal includes coroutines both as an intermediate step for the implementation of threads, and a first class feature of \CFA. Furthermore, many design challenges of threads are at least partially present in designing coroutines, which makes the design effort that much more relevant. The core \acrshort{api} of coroutines revolve around two features: independent call stacks and \code{suspend}/\code{resume}. 20 21 A good example of a problem made easier with coroutines is genereting the fibonacci sequence. This problem comes with the challenge of decoupling how a sequence is generated and how it is used. Figure \ref{fig:fibonacci-c} shows conventional approaches to writing generators in C. All three of these approach suffer from strong coupling. The left and center approaches require that the generator have knowledge of how the sequence will be used, while the rightmost approach requires to user to hold internal state between calls on behalf of th sequence generator and makes it much harder to handle corner cases like the Fibonacci seed. 22 \begin{figure} 23 \label{fig:fibonacci-c} 24 \begin{center} 25 \begin{tabular}{c @{\hskip 0.025in}|@{\hskip 0.025in} c @{\hskip 0.025in}|@{\hskip 0.025in} c} 26 \begin{ccode}[tabsize=2] 27 //Using callbacks 28 void fibonacci_func( 29 int n, 30 void (*callback)(int) 31 ) { 32 int first = 0; 33 int second = 1; 34 int next, i; 35 for(i = 0; i < n; i++) 36 { 37 if(i <= 1) 38 next = i; 39 else { 40 next = f1 + f2; 41 f1 = f2; 42 f2 = next; 43 } 44 callback(next); 45 } 46 } 47 \end{ccode}&\begin{ccode}[tabsize=2] 48 //Using output array 49 void fibonacci_array( 50 int n, 51 int * array 52 ) { 53 int f1 = 0; int f2 = 1; 54 int next, i; 55 for(i = 0; i < n; i++) 56 { 57 if(i <= 1) 58 next = i; 59 else { 60 next = f1 + f2; 61 f1 = f2; 62 f2 = next; 63 } 64 *array = next; 65 array++; 66 } 67 } 68 \end{ccode}&\begin{ccode}[tabsize=2] 69 //Using external state 70 typedef struct { 71 int f1, f2; 72 } iterator_t; 73 74 int fibonacci_state( 75 iterator_t * it 76 ) { 77 int f; 78 f = it->f1 + it->f2; 79 it->f2 = it->f1; 80 it->f1 = f; 81 return f; 82 } 83 84 85 86 87 88 89 \end{ccode} 90 \end{tabular} 91 \end{center} 92 \caption{Different implementations of a fibonacci sequence generator in C.} 93 \end{figure} 94 95 96 Figure \ref{fig:fibonacci-cfa} is an example of a solution to the fibonnaci problem using \CFA coroutines, using the coroutine stack to hold sufficient state for the generation. This solution has the advantage of having very strong decoupling between how the sequence is generated and how it is used. Indeed, this version is a easy to use as the \code{fibonacci_state} solution, while the imlpementation is very similar to the \code{fibonacci_func} example. 97 98 \begin{figure} 99 \label{fig:fibonacci-cfa} 100 \begin{cfacode} 101 coroutine Fibonacci { 102 int fn; //used for communication 103 }; 104 105 void ?{}(Fibonacci & this) { //constructor 106 this.fn = 0; 107 } 108 109 //main automacically called on first resume 110 void main(Fibonacci & this) { 111 int fn1, fn2; //retained between resumes 112 this.fn = 0; 113 fn1 = this.fn; 114 suspend(this); //return to last resume 115 116 this.fn = 1; 117 fn2 = fn1; 118 fn1 = this.fn; 119 suspend(this); //return to last resume 120 121 for ( ;; ) { 122 this.fn = fn1 + fn2; 35 123 fn2 = fn1; 36 124 fn1 = this.fn; 37 suspend(this); // return to last resume 38 39 for ( ;; ) { 40 this.fn = fn1 + fn2; 41 fn2 = fn1; 42 fn1 = this.fn; 43 suspend(this); // return to last resume 44 } 45 } 46 47 int next(Fibonacci & this) { 48 resume(this); // transfer to last suspend 49 return this.fn; 50 } 51 52 void main() { // regular program main 53 Fibonacci f1, f2; 54 for ( int i = 1; i <= 10; i += 1 ) { 55 sout | next( f1 ) | next( f2 ) | endl; 56 } 57 } 58 \end{cfacode} 125 suspend(this); //return to last resume 126 } 127 } 128 129 int next(Fibonacci & this) { 130 resume(this); //transfer to last suspend 131 return this.fn; 132 } 133 134 void main() { //regular program main 135 Fibonacci f1, f2; 136 for ( int i = 1; i <= 10; i += 1 ) { 137 sout | next( f1 ) | next( f2 ) | endl; 138 } 139 } 140 \end{cfacode} 141 \caption{Implementation of fibonacci using coroutines} 142 \end{figure} 59 143 60 144 \subsection{Construction} 61 One important design challenge for coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs . In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling. However, the underlying challenge remains the same for coroutines and threads.62 63 The runtime system needs to create the coroutine's stack and more importantly prepare it for the first resumption. The timing of the creation is non-trivial since users both expect to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor. Like for regular objects, constructors can stillleak coroutines before they are ready. There are several solutions to this problem but the chosen options effectively forces the design of the coroutine.145 One important design challenge for coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs to connect the object into the system. In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling. However, the underlying challenge remains the same for coroutines and threads. 146 147 The runtime system needs to create the coroutine's stack and more importantly prepare it for the first resumption. The timing of the creation is non-trivial since users both expect to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor. As regular objects, constructors can leak coroutines before they are ready. There are several solutions to this problem but the chosen options effectively forces the design of the coroutine. 64 148 65 149 Furthermore, \CFA faces an extra challenge as polymorphic routines create invisible thunks when casted to non-polymorphic routines and these thunks have function scope. For example, the following code, while looking benign, can run into undefined behaviour because of thunks: … … 78 162 } 79 163 \end{cfacode} 164 80 165 The generated C code\footnote{Code trimmed down for brevity} creates a local thunk to hold type information: 81 166 … … 95 180 } 96 181 \end{ccode} 97 The problem in this example is a race condition between the start of the execution of \code{noop} on the other thread and the stack frame of \code{bar} being destroyed. This extra challenge limits which solutions are viable because storing the function pointer for too long only increases the chances that the race will end inundefined behavior; i.e. the stack based thunk being destroyed before it was used. This challenge is an extension of challenges that come with second-class routines. Indeed, GCC nested routines also have the limitation that the routines cannot be passed outside of the scope of the functions these were declared in. The case of coroutines and threads is simply an extension of this problem to multiple call-stacks.182 The problem in this example is a storage management issue, the function pointer \code{_thunk0} is only valid until the end of the block. This extra challenge limits which solutions are viable because storing the function pointer for too long causes undefined behavior; i.e. the stack based thunk being destroyed before it was used. This challenge is an extension of challenges that come with second-class routines. Indeed, GCC nested routines also have the limitation that the routines cannot be passed outside of the scope of the functions these were declared in. The case of coroutines and threads is simply an extension of this problem to multiple call-stacks. 98 183 99 184 \subsection{Alternative: Composition} 100 One solution to this challenge would be to use composition/containement, 101 102 \begin{cfacode} 103 struct Fibonacci { 104 int fn; // used for communication 105 coroutine c; //composition 106 }; 107 108 void ?{}(Fibonacci & this) { 109 this.fn = 0; 110 (this.c){}; 111 } 112 \end{cfacode} 113 There are two downsides to this approach. The first, which is relatively minor, is that the base class needs to be made aware of the main routine pointer, regardless of whether a parameter or a virtual pointer is used, this means the coroutine data must be made larger to store a value that is actually a compile time constant (address of the main routine). The second problem, which is both subtle and significant, is that now users can get the initialisation order of there coroutines wrong. Indeed, every field of a \CFA struct is constructed but in declaration order, unless users explicitly write otherwise. This semantics means that users who forget to initialize a the coroutine may resume the coroutine with an uninitilized object. For coroutines, this is unlikely to be a problem, for threads however, this is a significant problem. 185 One solution to this challenge is to use composition/containement, where uses add insert a coroutine field which contains the necessary information to manage the coroutine. 186 187 \begin{cfacode} 188 struct Fibonacci { 189 int fn; //used for communication 190 coroutine c; //composition 191 }; 192 193 void ?{}(Fibonacci & this) { 194 this.fn = 0; 195 (this.c){}; //Call constructor to initialize coroutine 196 } 197 \end{cfacode} 198 There are two downsides to this approach. The first, which is relatively minor, made aware of the main routine pointer. This information must either be store in the coroutine runtime data or in its static type structure. When using composition, all coroutine handles have the same static type structure which means the pointer to the main needs to be part of the runtime data. This requirement means the coroutine data must be made larger to store a value that is actually a compile time constant (address of the main routine). The second problem, which is both subtle and significant, is that now users can get the initialisation order of coroutines wrong. Indeed, every field of a \CFA struct is constructed but in declaration order, unless users explicitly write otherwise. This semantics means that users who forget to initialize the coroutine handle may resume the coroutine with an uninitilized object. For coroutines, this is unlikely to be a problem, for threads however, this is a significant problem. Figure \ref{fig:fmt-line} shows the \code{Format} coroutine which rearranges text in order to group characters into blocks of fixed size. This is a good example where the control flow is made much simpler from being able to resume the coroutine from the constructor and highlights the idea that interesting control flow can occor in the constructor. 199 \begin{figure} 200 \label{fig:fmt-line} 201 \begin{cfacode}[tabsize=3] 202 //format characters into blocks of 4 and groups of 5 blocks per line 203 coroutine Format { 204 char ch; //used for communication 205 int g, b; //global because used in destructor 206 }; 207 208 void ?{}(Format & fmt) { 209 resume( fmt ); //prime (start) coroutine 210 } 211 212 void ^?{}(Format & fmt) with fmt { 213 if ( fmt.g != 0 || fmt.b != 0 ) 214 sout | endl; 215 } 216 217 void main(Format & fmt) with fmt { 218 for ( ;; ) { //for as many characters 219 for(g = 0; g < 5; g++) { //groups of 5 blocks 220 for(b = 0; b < 4; fb++) { //blocks of 4 characters 221 suspend(); 222 sout | ch; //print character 223 } 224 sout | " "; //print block separator 225 } 226 sout | endl; //print group separator 227 } 228 } 229 230 void prt(Format & fmt, char ch) { 231 fmt.ch = ch; 232 resume(fmt); 233 } 234 235 int main() { 236 Format fmt; 237 char ch; 238 Eof: for ( ;; ) { //read until end of file 239 sin | ch; //read one character 240 if(eof(sin)) break Eof; //eof ? 241 prt(fmt, ch); //push character for formatting 242 } 243 } 244 \end{cfacode} 245 \caption{Formatting text into lines of 5 blocks of 4 characters.} 246 \end{figure} 247 114 248 115 249 \subsection{Alternative: Reserved keyword} … … 117 251 118 252 \begin{cfacode} 119 coroutine Fibonacci { 120 int fn; // used for communication 121 }; 122 \end{cfacode} 123 This mean the compiler can solve problems by injecting code where needed. The downside of this approach is that it makes coroutine a special case in the language. Users who would want to extend coroutines or build their own for various reasons can only do so in ways offered by the language. Furthermore, implementing coroutines without language supports also displays the power of \CFA. 124 While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can both be constructed by users without using the language support. The reserved keywords are only present to improve ease of use for the common cases. 253 coroutine Fibonacci { 254 int fn; //used for communication 255 }; 256 \end{cfacode} 257 This mean the compiler can solve problems by injecting code where needed. The downside of this approach is that it makes coroutine a special case in the language. Users who would want to extend coroutines or build their own for various reasons can only do so in ways offered by the language. Furthermore, implementing coroutines without language supports also displays the power of the programming language used. While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can both be constructed by users without using the language support. The reserved keywords are only present to improve ease of use for the common cases. 125 258 126 259 \subsection{Alternative: Lamda Objects} … … 159 292 coroutine_desc * get_coroutine(T & this); 160 293 }; 161 \end{cfacode} 162 This ensures an object is not a coroutine until \code{resume} (or \code{prime}) is called on the object. Correspondingly, any object that is passed to \code{resume} is a coroutine since it must satisfy the \code{is_coroutine} trait to compile. The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory foot print of a coroutine is trivial when implementing the \code{get_coroutine} routine. The \CFA keyword \code{coroutine} only has the effect of implementing the getter and forward declarations required for users to only have to implement the main routine. 294 295 forall( dtype T | is_coroutine(T) ) void suspend(T &); 296 forall( dtype T | is_coroutine(T) ) void resume (T &); 297 \end{cfacode} 298 This ensures an object is not a coroutine until \code{resume} is called on the object. Correspondingly, any object that is passed to \code{resume} is a coroutine since it must satisfy the \code{is_coroutine} trait to compile. The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory layout of a coroutine is trivial when implementing the \code{get_coroutine} routine. The \CFA keyword \code{coroutine} only has the effect of implementing the getter and forward declarations required for users to only have to implement the main routine. 163 299 164 300 \begin{center} … … 186 322 \end{center} 187 323 188 The combination of these two approaches allows users new to co ncurrency to have a easy and concise method while more advanced users can expose themselves to otherwise hidden pitfalls at the benefit oftighter control on memory layout and initialization.324 The combination of these two approaches allows users new to coroutinning and concurrency to have an easy and concise specification, while more advanced users have tighter control on memory layout and initialization. 189 325 190 326 \section{Thread Interface}\label{threads} … … 192 328 193 329 \begin{cfacode} 194 330 thread foo {}; 195 331 \end{cfacode} 196 332 … … 205 341 \end{cfacode} 206 342 207 Obviously, for this thread implementation to be usefull it must run some user code. Several other threading interfaces use a function-pointer representation as the interface of threads (for example \Csharp~\cite{Csharp} and Scala~\cite{Scala}). However, this proposal considers that statically tying a \code{main} routine to a thread superseeds this approach. Since the \code{main} routine is already a special routine in \CFA (where the program begins), it is possible naturally extend the semantics using overloading to declare mains for different threads (the normal main being the main of the initial thread). As such the \code{main} routine of a thread can be defined as 208 \begin{cfacode} 209 thread foo {}; 210 211 void main(foo & this) { 212 sout | "Hello World!" | endl; 213 } 214 \end{cfacode} 215 216 In this example, threads of type \code{foo} start execution in the \code{void main(foo*)} routine which prints \code{"Hello World!"}. While this proposoal encourages this approach to enforce strongly-typed programming, users may prefer to use the routine based thread semantics for the sake of simplicity. With these semantics it is trivial to write a thread type that takes a function pointer as parameter and executes it on its stack asynchronously 217 \begin{cfacode} 218 typedef void (*voidFunc)(void); 219 220 thread FuncRunner { 221 voidFunc func; 222 }; 223 224 //ctor 225 void ?{}(FuncRunner & this, voidFunc inFunc) { 226 this.func = inFunc; 227 } 228 229 //main 230 void main(FuncRunner & this) { 231 this.func(); 232 } 233 \end{cfacode} 234 235 An advantage of the overloading approach to main is to clearly highlight where and what memory is required to pass parameters and return values to/from a thread. 236 237 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} once the constructor has completed and \code{join} before the destructor runs. 343 Obviously, for this thread implementation to be usefull it must run some user code. Several other threading interfaces use a function-pointer representation as the interface of threads (for example \Csharp~\cite{Csharp} and Scala~\cite{Scala}). However, this proposal considers that statically tying a \code{main} routine to a thread superseeds this approach. Since the \code{main} routine is already a special routine in \CFA (where the program begins), it is a natural extension of the semantics using overloading to declare mains for different threads (the normal main being the main of the initial thread). As such the \code{main} routine of a thread can be defined as 344 \begin{cfacode} 345 thread foo {}; 346 347 void main(foo & this) { 348 sout | "Hello World!" | endl; 349 } 350 \end{cfacode} 351 352 In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!"}. While this thesis encourages this approach to enforce strongly-typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. With these semantics it is trivial to write a thread type that takes a function pointer as a parameter and executes it on its stack asynchronously 353 \begin{cfacode} 354 typedef void (*voidFunc)(int); 355 356 thread FuncRunner { 357 voidFunc func; 358 int arg; 359 }; 360 361 void ?{}(FuncRunner & this, voidFunc inFunc, int arg) { 362 this.func = inFunc; 363 } 364 365 void main(FuncRunner & this) { 366 this.func( this.arg ); 367 } 368 \end{cfacode} 369 370 An consequence of the strongly typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \acrshort{api}. 371 372 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} after the constructor has completed and \code{join} before the destructor runs. 238 373 \begin{cfacode} 239 374 thread World; … … 254 389 \end{cfacode} 255 390 256 This semantic has several advantages over explicit semantics typesafety is guaranteed, a thread is always started and stopped exaclty once and users cannot make any progamming errors. Another advantage of this semantic is that it naturally scaleto multiple threads meaning basic synchronisation is very simple391 This semantic has several advantages over explicit semantics: a thread is always started and stopped exaclty once and users cannot make any progamming errors and it naturally scales to multiple threads meaning basic synchronisation is very simple 257 392 258 393 \begin{cfacode} … … 276 411 \end{cfacode} 277 412 278 However, one of the apparent drawbacks of this system is that threads now always form a lattice, that is they are always destroyed in opposite order of construction because of block structure. However, storage allocation is not limited to blocks; dynamic allocation can create threads that outlive the scope in which the thread is createdmuch like dynamically allocating memory lets objects outlive the scope in which they are created413 However, one of the drawbacks of this approach is that threads now always form a lattice, that is they are always destroyed in opposite order of construction because of block structure. This restriction is relaxed by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created 279 414 280 415 \begin{cfacode} … … 283 418 }; 284 419 285 //main286 420 void main(MyThread & this) { 287 421 //... … … 291 425 MyThread * long_lived; 292 426 { 427 //Start a thread at the beginning of the scope 293 428 MyThread short_lived; 294 //Start a thread at the beginning of the scope295 296 DoStuff();297 429 298 430 //create another thread that will outlive the thread in this scope 299 431 long_lived = new MyThread; 300 432 433 DoStuff(); 434 301 435 //Wait for the thread short_lived to finish 302 436 } 303 437 DoMoreStuff(); 304 438 305 //Now wait for the short_lived to finish439 //Now wait for the long_lived to finish 306 440 delete long_lived; 307 441 } -
doc/proposals/concurrency/text/cforall.tex
rb96ec83 r6840e7c 5 5 % ====================================================================== 6 6 7 As mentionned in the introduction, the document presents the design for the concurrency features in \CFA. Since it is a new language here is a quick review of the languagespecifically tailored to the features needed to support concurrency.7 This thesis presents the design for a set of concurrency features in \CFA. Since it is a new dialect of C, the following is a quick introduction to the language, specifically tailored to the features needed to support concurrency. 8 8 9 \CFA is a extension of ISO C and therefore supports much of the same paradigms as C. It is a non-object oriented system level language, meaning it has very most of the major abstractions have either no runtime cost or can be opt-out easily. Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over assembly. The vast majority of the code produced by a \CFA compiler respects memory-layouts and calling-conventions laid out by C. However, while \CFA is not an object-oriented language according to a strict definition. It does have some notion of objects, most importantly construction and destruction of objects. Most of the following pieces of code can be found as is on the \CFA website :\cite{www-cfa}9 \CFA is a extension of ISO-C and therefore supports all of the same paradigms as C. It is a non-object oriented system language, meaning most of the major abstractions have either no runtime overhead or can be opt-out easily. Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code. The vast majority of the code produced by the \CFA translator respects memory-layouts and calling-conventions laid out by C. Interestingly, while \CFA is not an object-oriented language, lacking the concept of a received (e.g.: this), it does have some notion of objects\footnote{C defines the term objects as : [Where to I get the C11 reference manual?]}, most importantly construction and destruction of objects. Most of the following pieces of code can be found on the \CFA website \cite{www-cfa} 10 10 11 11 \section{References} 12 12 13 Like \CC, \CFA introduces references as an alternative to pointers. In regards to concurrency, the semantics difference between pointers and references are n't particularly relevant but since this document uses mostly references here is a quick overview of the semantics :13 Like \CC, \CFA introduces references as an alternative to pointers. In regards to concurrency, the semantics difference between pointers and references are not particularly relevant but since this document uses mostly references here is a quick overview of the semantics : 14 14 \begin{cfacode} 15 15 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2, 16 16 &r1 = x, &&r2 = r1, &&&r3 = r2; 17 ***p3 = 3; // change x 18 r3 = 3; // change x, ***r3 19 **p3 = ...; // change p1 20 &r3 = ...; // change r1, (&*)**r3 21 *p3 = ...; // change p2 22 &&r3 = ...; // change r2, (&(&*)*)*r3 23 &&&r3 = p3; // change r3 to p3, (&(&(&*)*)*)r3 24 int y, z, & ar[3] = { x, y, z }; // initialize array of references 25 &ar[1] = &z; // change reference array element 26 typeof( ar[1] ) p; // is int, i.e., the type of referenced object 27 typeof( &ar[1] ) q; // is int &, i.e., the type of reference 28 sizeof( ar[1] ) == sizeof( int ); // is true, i.e., the size of referenced object 29 sizeof( &ar[1] ) == sizeof( int *); // is true, i.e., the size of a reference 17 ***p3 = 3; //change x 18 r3 = 3; //change x, ***r3 19 **p3 = ...; //change p1 20 *p3 = ...; //change p2 21 int y, z, & ar[3] = {x, y, z}; //initialize array of references 22 typeof( ar[1]) p; //is int, i.e., the type of referenced object 23 typeof(&ar[1]) q; //is int &, i.e., the type of reference 24 sizeof( ar[1]) == sizeof(int); //is true, i.e., the size of referenced object 25 sizeof(&ar[1]) == sizeof(int *); //is true, i.e., the size of a reference 30 26 \end{cfacode} 31 27 The important thing to take away from this code snippet is that references offer a handle to an object much like pointers but which is automatically derefferenced when convinient. … … 33 29 \section{Overloading} 34 30 35 Another important feature \CFA has in common with \CC is function overloading :31 Another important feature of \CFA is function overloading as in Java and \CC, where routine with the same name are selected based on the numbers and type of the arguments. As well, \CFA uses the return type as part of the selection criteria, as in Ada\cite{Ada}. For routines with multiple parameters and returns, the selection is complex. 36 32 \begin{cfacode} 37 // 38 void f( void ); //(1)39 void f( char ); //(2)40 void f( int, double ); //(3)41 f(); //select (1)42 f( 'a' ); //select (2)43 f( 3, 5.2 ); //select (3)33 //selection based on type and number of parameters 34 void f(void); //(1) 35 void f(char); //(2) 36 void f(int, double); //(3) 37 f(); //select (1) 38 f('a'); //select (2) 39 f(3, 5.2); //select (3) 44 40 45 // selection based on type and number of returns 46 char f( int ); // (1) 47 double f( int ); // (2) 48 [ int, double ] f( int ); // (3) 49 char c = f( 3 ); // select (1) 50 double d = f( 4 ); // select (2) 51 [ int, double ] t = f( 5 ); // select (3) 41 //selection based on type and number of returns 42 char f(int); //(1) 43 double f(int); //(2) 44 char c = f(3); //select (1) 45 double d = f(4); //select (2) 52 46 \end{cfacode} 53 This feature is particularly important for concurrency since the runtime system relies on creating different types do represent concurrency objects. Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent clashes. As seen in chapter \ref{basics}, the main is an example of routine that benefits from overloading when concurrency in introduced.47 This feature is particularly important for concurrency since the runtime system relies on creating different types to represent concurrency objects. Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent name clashes. As seen in chapter \ref{basics}, routines main is an example that benefits from overloading. 54 48 55 49 \section{Operators} 56 50 Overloading also extends to operators. The syntax for denoting operator-overloading is to name a routine with the symbol of the operator and question marks where the arguments of the operation would be, like so : 57 51 \begin{cfacode} 58 int ++? ( int op ); //unary prefix increment59 int ?++ ( int op ); //unary postfix increment60 int ?+? ( int op1, int op2 ); //binary plus61 int ?<=?( int op1, int op2 ); //binary less than62 int ?=? ( int & op1, int op2 ); //binary assignment63 int ?+=?( int & op1, int op2 ); //binary plus-assignment52 int ++? (int op); //unary prefix increment 53 int ?++ (int op); //unary postfix increment 54 int ?+? (int op1, int op2); //binary plus 55 int ?<=?(int op1, int op2); //binary less than 56 int ?=? (int & op1, int op2); //binary assignment 57 int ?+=?(int & op1, int op2); //binary plus-assignment 64 58 65 struct S { int i, j;};66 S ?+?( S op1, S op2 ) { //add two structures67 return (S){ op1.i + op2.i, op1.j + op2.j};59 struct S {int i, j;}; 60 S ?+?(S op1, S op2) { //add two structures 61 return (S){op1.i + op2.i, op1.j + op2.j}; 68 62 } 69 S s1 = { 1, 2 }, s2 = { 2, 3}, s3;70 s3 = s1 + s2; // compute sum: s3 == { 2, 5}63 S s1 = {1, 2}, s2 = {2, 3}, s3; 64 s3 = s1 + s2; //compute sum: s3 == {2, 5} 71 65 \end{cfacode} 72 73 Since concurrency does not use operator overloading, this feature is more important as an introduction for the syntax of constructors. 66 While concurrency does not use operator overloading directly, this feature is more important as an introduction for the syntax of constructors. 74 67 75 68 \section{Constructors/Destructors} 76 \CFA uses the following syntax for constructors and destructors :69 Object life-time is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object life-time as a mean of synchronization and/or mutual exclusion. Since \CFA relies heavily on the life time of objects, constructors and destructors are a core feature required for concurrency and parallelism. \CFA uses the following syntax for constructors and destructors : 77 70 \begin{cfacode} 78 71 struct S { … … 80 73 int * ia; 81 74 }; 82 void ?{}( S & s, int asize ) with s { //constructor operator83 s ize = asize; //initialize fields84 ia = calloc( size, sizeof( S ));75 void ?{}(S & s, int asize) { //constructor operator 76 s.size = asize; //initialize fields 77 s.ia = calloc(size, sizeof(S)); 85 78 } 86 void ^?{}( S & s ) with s { //destructor operator87 free( ia ); //de-initialization fields79 void ^?{}(S & s) { //destructor operator 80 free(ia); //de-initialization fields 88 81 } 89 82 int main() { 90 S x = { 10 }, y = { 100 }; // implict calls: ?{}( x, 10 ), ?{}( y, 100)91 ... //use x and y92 ^x{}; ^y{}; // 93 x{ 20 }; y{ 200 }; //explicit calls to reinitialize94 ... //reuse x and y95 } // implict calls: ^?{}( y ), ^?{}( x)83 S x = {10}, y = {100}; //implict calls: ?{}(x, 10), ?{}(y, 100) 84 ... //use x and y 85 ^x{}; ^y{}; //explicit calls to de-initialize 86 x{20}; y{200}; //explicit calls to reinitialize 87 ... //reuse x and y 88 } //implict calls: ^?{}(y), ^?{}(x) 96 89 \end{cfacode} 97 The language guarantees that every object and all their fields are constructed. Like \CC construction is automatically done on declaration and destruction done when the declared variables reach the end of its scope. 90 The language guarantees that every object and all their fields are constructed. Like \CC, construction of an object is automatically done on allocation and destruction of the object is done on deallocation. Allocation and deallocation can occur on the stack or on the heap. 91 \begin{cfacode} 92 { 93 struct S s = {10}; //allocation, call constructor 94 ... 95 } //deallocation, call destructor 96 struct S * s = new(); //allocation, call constructor 97 ... 98 delete(s); //deallocation, call destructor 99 \end{cfacode} 100 Note that like \CC, \CFA introduces \code{new} and \code{delete}, which behave like \code{malloc} and \code{free} in addition to constructing and destructing objects, after calling \code{malloc} and before calling \code{free} respectively. 98 101 99 For more information see \cite{cforall-ug,rob-thesis,www-cfa}. 102 \section{Parametric Polymorphism} 103 Routines in \CFA can also be reused for multiple types. This is done using the \code{forall} clause which gives \CFA it's name. \code{forall} clauses allow seperatly compiled routines to support generic usage over multiple types. For example, the following sum function will work for any type which support construction from 0 and addition : 104 \begin{cfacode} 105 //constraint type, 0 and + 106 forall(otype T | { void ?{}(T *, zero_t); T ?+?(T, T); }) 107 T sum(T a[ ], size_t size) { 108 T total = 0; //construct T from 0 109 for(size_t i = 0; i < size; i++) 110 total = total + a[i]; //select appropriate + 111 return total; 112 } 113 114 S sa[5]; 115 int i = sum(sa, 5); //use S's 0 construction and + 116 \end{cfacode} 117 118 Since writing constraints on types can become cumbersome for more constrained functions, \CFA also has the concept of traits. Traits are named collection of constraints which can be used both instead and in addition to regular constraints: 119 \begin{cfacode} 120 trait sumable( otype T ) { 121 void ?{}(T *, zero_t); //constructor from 0 literal 122 T ?+?(T, T); //assortment of additions 123 T ?+=?(T *, T); 124 T ++?(T *); 125 T ?++(T *); 126 }; 127 forall( otype T | sumable(T) ) //use trait 128 T sum(T a[], size_t size); 129 \end{cfacode} 130 131 \section{with Clause/Statement} 132 Since \CFA lacks the concept of a receiver, certain functions end-up needing to repeat variable names often, to solve this \CFA offers the \code{with} statement which opens an aggregate scope making its fields directly accessible (like Pascal). 133 \begin{cfacode} 134 struct S { int i, j; }; 135 int mem(S & this) with this //with clause 136 i = 1; //this->i 137 j = 2; //this->j 138 } 139 int foo() { 140 struct S1 { ... } s1; 141 struct S2 { ... } s2; 142 with s1 //with statement 143 { 144 //access fields of s1 145 //without qualification 146 with s2 //nesting 147 { 148 //access fields of s1 and s2 149 //without qualification 150 } 151 } 152 with s1, s2 //scopes open in parallel 153 { 154 //access fields of s1 and s2 155 //without qualification 156 } 157 } 158 \end{cfacode} 159 160 For more information on \CFA see \cite{cforall-ug,rob-thesis,www-cfa}. -
doc/proposals/concurrency/text/concurrency.tex
rb96ec83 r6840e7c 4 4 % ====================================================================== 5 5 % ====================================================================== 6 Several tool can be used to solve concurrency challenges. Since many of these challenges appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms thatclosely relate to networking concepts (channels\cit for example). However, in languages that use routine calls as their core abstraction-mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine call). This distinction in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. While this distinction can be hidden away in library code, effective use of the librairy still has to take both paradigms into account.6 Several tool can be used to solve concurrency challenges. Since many of these challenges appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (channels\cit for example). However, in languages that use routine calls as their core abstraction-mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine call). This distinction in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. While this distinction can be hidden away in library code, effective use of the librairy still has to take both paradigms into account. 7 7 8 8 Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and shared objects. At the lowest level, concurrent paradigms are implemented as atomic operations and locks. Many such mechanisms have been proposed, including semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}. However, for productivity reasons it is desireable to have a higher-level construct be the core concurrency paradigm~\cite{HPP:Study}. 9 9 10 An approach that is worth mentionning because it is gaining in popularity is transactionnal memory~\cite{Dice10}[Check citation]. While this approach is even pursued by system languages like \CC\cit, the performance and feature set is currently too restrictive to be the main concurrency paradigm for general purposelanguage, which is why it was rejected as the core paradigm for concurrency in \CFA.11 12 One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared 10 An approach that is worth mentionning because it is gaining in popularity is transactionnal memory~\cite{Dice10}[Check citation]. While this approach is even pursued by system languages like \CC\cit, the performance and feature set is currently too restrictive to be the main concurrency paradigm for systems language, which is why it was rejected as the core paradigm for concurrency in \CFA. 11 12 One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared-memory systems, is the \emph{monitor}. Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. Many programming languages---e.g., Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs. In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors. For these reasons, this project proposes monitors as the core concurrency-construct. 13 13 14 14 \section{Basics} 15 Non-determinism requires concurrent systems to offer support for mutual-exclusion and synchronisation. Mutual-exclusion is the concept that only a fixed number of threads can access a critical section at any given time, where a critical section is a group of instructions on an associated portion of data that requires the restricted access. On the other hand, synchronization enforces relative ordering of execution and synchronization tools numerous mechanisms to establish timing relationships among threads.15 Non-determinism requires concurrent systems to offer support for mutual-exclusion and synchronisation. Mutual-exclusion is the concept that only a fixed number of threads can access a critical section at any given time, where a critical section is a group of instructions on an associated portion of data that requires the restricted access. On the other hand, synchronization enforces relative ordering of execution and synchronization tools provide numerous mechanisms to establish timing relationships among threads. 16 16 17 17 \subsection{Mutual-Exclusion} 18 As mentionned above, mutual-exclusion is the guarantee that only a fix number of threads can enter a critical section at once. However, many solution exists for mutual exclusion which vary in terms of performance, flexibility and ease of use. Methods range from low-level locks, which are fast and flexible but require significant attention to be correct, to higher-level mutual-exclusion methods, which sacrifice some performance in order to improve ease of use. Ease of use comes by either guaranteeing some problems cannot occur (e.g., being deadlock free) or by offering a more explicit coupling between data and corresponding critical section. For example, the \CC \code{std::atomic<T>} which offer an easy way to express mutual-exclusion on a restricted set of operations (.e.g: reading/writing large types atomically). Another challenge with low-level locks is composability. Locks are not composablebecause it takes careful organising for multiple locks to be used while preventing deadlocks. Easing composability is another feature higher-level mutual-exclusion mechanisms often offer.18 As mentionned above, mutual-exclusion is the guarantee that only a fix number of threads can enter a critical section at once. However, many solutions exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use. Methods range from low-level locks, which are fast and flexible but require significant attention to be correct, to higher-level mutual-exclusion methods, which sacrifice some performance in order to improve ease of use. Ease of use comes by either guaranteeing some problems cannot occur (e.g., being deadlock free) or by offering a more explicit coupling between data and corresponding critical section. For example, the \CC \code{std::atomic<T>} offers an easy way to express mutual-exclusion on a restricted set of operations (e.g.: reading/writing large types atomically). Another challenge with low-level locks is composability. Locks have restricted composability because it takes careful organising for multiple locks to be used while preventing deadlocks. Easing composability is another feature higher-level mutual-exclusion mechanisms often offer. 19 19 20 20 \subsection{Synchronization} 21 As for mutual-exclusion, low level synchronisation primitive often offer good performance and good flexibility at the cost of ease of use. Again, higher-level mechanism often simplify usage by adding better coupling between synchronization and data, .eg., message passing, or offering simple solution to otherwise involved challenges. An example of this is barging. As mentionned above synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}. Most of the time synchronisation happens around a critical section, where threads most acquire said critical section in a certain order. However, it may also be desired to be able to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}. This is called barging, where event \textit{X} tries to effect event \textit{Y} but anoter thread races to grab the critical section and emits \textit{Z} before \textit{Y}. Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs.21 As for mutual-exclusion, low-level synchronisation primitives often offer good performance and good flexibility at the cost of ease of use. Again, higher-level mechanism often simplify usage by adding better coupling between synchronization and data, e.g.: message passing, or offering simple solution to otherwise involved challenges. An example is barging. As mentioned above, synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}. Most of the time, synchronisation happens around a critical section, where threads must acquire critical sections in a certain order. However, it may also be desirable to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}. Not satisfying this property called barging. For example, where event \textit{X} tries to effect event \textit{Y} but another thread acquires the critical section and emits \textit{Z} before \textit{Y}. Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs. This challenge is often split into two different methods, barging avoidance and barging prevention. Algorithms that use status flags and other flag variables to detect barging threads are said to be using barging avoidance while algorithms that baton-passing locks between threads instead of releasing the locks are said to be using barging prevention. 22 22 23 23 % ====================================================================== … … 28 28 A monitor is a set of routines that ensure mutual exclusion when accessing shared state. This concept is generally associated with Object-Oriented Languages like Java~\cite{Java} or \uC~\cite{uC++book} but does not strictly require OO semantics. The only requirements is the ability to declare a handle to a shared object and a set of routines that act on it : 29 29 \begin{cfacode} 30 31 32 33 34 35 36 30 typedef /*some monitor type*/ monitor; 31 int f(monitor & m); 32 33 int main() { 34 monitor m; //Handle m 35 f(m); //Routine using handle 36 } 37 37 \end{cfacode} 38 38 … … 47 47 48 48 \begin{cfacode} 49 monitor counter_t { /*...see section $\ref{data}$...*/ }; 50 51 void ?{}(counter_t & nomutex this); //constructor 52 size_t ++?(counter_t & mutex this); //increment 53 54 //need for mutex is platform dependent 55 void ?{}(size_t * this, counter_t & mutex cnt); //conversion 56 \end{cfacode} 57 58 Here, the constructor(\code{?\{\}}) uses the \code{nomutex} keyword to signify that it does not acquire the monitor mutual-exclusion when constructing. This semantics is because an object not yet constructed should never be shared and therefore does not require mutual exclusion. The prefix increment operator uses \code{mutex} to protect the incrementing process from race conditions. Finally, there is a conversion operator from \code{counter_t} to \code{size_t}. This conversion may or may not require the \code{mutex} keyword depending on whether or not reading an \code{size_t} is an atomic operation. 59 60 Having both \code{mutex} and \code{nomutex} keywords is redundant based on the meaning of a routine having neither of these keywords. For example, given a routine without qualifiers \code{void foo(counter_t & this)}, then it is reasonable that it should default to the safest option \code{mutex}, whereas assuming \code{nomutex} is unsafe and may cause subtle errors. In fact, \code{nomutex} is the "normal" parameter behaviour, with the \code{nomutex} keyword effectively stating explicitly that "this routine is not special". Another alternative is to make having exactly one of these keywords mandatory, which would provide the same semantics but without the ambiguity of supporting routines neither keyword. Mandatory keywords would also have the added benefit of being self-documented but at the cost of extra typing. While there are several benefits to mandatory keywords, they do bring a few challenges. Mandatory keywords in \CFA would imply that the compiler must know without a doubt wheter or not a parameter is a monitor or not. Since \CFA relies heavily on traits as an abstraction mechanism, the distinction between a type that is a monitor and a type that looks like a monitor can become blurred. For this reason, \CFA only has the \code{mutex} keyword. 61 62 63 The next semantic decision is to establish when \code{mutex} may be used as a type qualifier. Consider the following declarations: 64 \begin{cfacode} 65 int f1(monitor & mutex m); 66 int f2(const monitor & mutex m); 67 int f3(monitor ** mutex m); 68 int f4(monitor * mutex m []); 69 int f5(graph(monitor*) & mutex m); 70 \end{cfacode} 71 The problem is to indentify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to indentify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C, and even then making sure objects are only acquired once becomes none-trivial. This can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To keep everyone as sane as possible~\cite{Chicken}, this projects imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter with one level of indirection (ignoring potential qualifiers). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is be acquired, passing an array to this routine would be type safe and yet result in undefined behavior because only the first element of the array is acquired. This is specially true for non-copyable objects like monitors, where an array of pointers is simplest way to express a group of monitors. However, this ambiguity is part of the C type-system with respects to arrays. For this reason, \code{mutex} is disallowed in the context where arrays may be passed: 72 73 \begin{cfacode} 74 int f1(monitor & mutex m); //Okay : recommanded case 75 int f2(monitor * mutex m); //Okay : could be an array but probably not 76 int f3(monitor mutex m []); //Not Okay : Array of unkown length 77 int f4(monitor ** mutex m); //Not Okay : Could be an array 78 int f5(monitor * mutex m []); //Not Okay : Array of unkown length 79 \end{cfacode} 80 81 Unlike object-oriented monitors, where calling a mutex member \emph{implicitly} acquires mutual-exclusion, \CFA uses an explicit mechanism to acquire mutual-exclusion. A consequence of this approach is that it extends naturally to multi-monitor calls. 82 \begin{cfacode} 83 int f(MonitorA & mutex a, MonitorB & mutex b); 84 85 MonitorA a; 86 MonitorB b; 87 f(a,b); 88 \end{cfacode} 89 The capacity to acquire multiple locks before entering a critical section is called \emph{\gls{group-acquire}}. In practice, writing multi-locking routines that do not lead to deadlocks is tricky. Having language support for such a feature is therefore a significant asset for \CFA. In the case presented above, \CFA guarantees that the order of aquisition is consistent across calls to routines using the same monitors as arguments. However, since \CFA monitors use multi-acquisition locks, users can effectively force the acquiring order. For example, notice which routines use \code{mutex}/\code{nomutex} and how this affects aquiring order: 90 \begin{cfacode} 91 void foo(A & mutex a, B & mutex b) { //acquire a & b 92 ... 93 } 94 95 void bar(A & mutex a, B & /*nomutex*/ b) { //acquire a 96 ... foo(a, b); ... //acquire b 97 } 98 99 void baz(A & /*nomutex*/ a, B & mutex b) { //acquire b 100 ... foo(a, b); ... //acquire a 101 } 102 \end{cfacode} 103 The multi-acquisition monitor lock allows a monitor lock to be acquired by both \code{bar} or \code{baz} and acquired again in \code{foo}. In the calls to \code{bar} and \code{baz} the monitors are acquired in opposite order. 104 105 However, such use leads the lock acquiring order problem. In the example above, the user uses implicit ordering in the case of function \code{foo} but explicit ordering in the case of \code{bar} and \code{baz}. This subtle mistake means that calling these routines concurrently may lead to deadlock and is therefore undefined behavior. As shown on several occasion\cit, solving this problem requires: 106 \begin{enumerate} 107 \item Dynamically tracking of the monitor-call order. 108 \item Implement rollback semantics. 109 \end{enumerate} 110 While the first requirement is already a significant constraint on the system, implementing a general rollback semantics in a C-like language is prohibitively complex \cit. In \CFA, users simply need to be carefull when acquiring multiple monitors at the same time. 111 112 Finally, for convenience, monitors support multiple acquiring, that is acquiring a monitor while already holding it does not cause a deadlock. It simply increments an internal counter which is then used to release the monitor after the number of acquires and releases match up. This is particularly usefull when monitor routines use other monitor routines as helpers or for recursions. For example: 113 \begin{cfacode} 114 monitor bank { 115 int money; 116 log_t usr_log; 117 }; 118 119 void deposit( bank & mutex b, int deposit ) { 120 b.money += deposit; 121 b.usr_log | "Adding" | deposit | endl; 122 } 123 124 void transfer( bank & mutex mybank, bank & mutex yourbank, int me2you) { 125 deposit( mybank, -me2you ); 126 deposit( yourbank, me2you ); 127 } 128 \end{cfacode} 129 130 % ====================================================================== 131 % ====================================================================== 132 \subsection{Data semantics} \label{data} 133 % ====================================================================== 134 % ====================================================================== 135 Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contain shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appropriate protection. For example, here is a complete version of the counter showed in section \ref{call}: 136 \begin{cfacode} 137 monitor counter_t { 138 int value; 139 }; 140 141 void ?{}(counter_t & this) { 142 this.cnt = 0; 143 } 144 145 int ?++(counter_t & mutex this) { 146 return ++this.value; 147 } 148 149 //need for mutex is platform dependent here 150 void ?{}(int * this, counter_t & mutex cnt) { 151 *this = (int)cnt; 152 } 153 \end{cfacode} 154 49 monitor counter_t { /*...see section $\ref{data}$...*/ }; 50 51 void ?{}(counter_t & nomutex this); //constructor 52 size_t ++?(counter_t & mutex this); //increment 53 54 //need for mutex is platform dependent 55 void ?{}(size_t * this, counter_t & mutex cnt); //conversion 56 \end{cfacode} 155 57 This counter is used as follows: 156 58 \begin{center} … … 171 73 Notice how the counter is used without any explicit synchronisation and yet supports thread-safe semantics for both reading and writting. 172 74 173 % ====================================================================== 174 % ====================================================================== 175 \subsection{Implementation Details: Interaction with polymorphism} 176 % ====================================================================== 177 % ====================================================================== 178 Depending on the choice of semantics for when monitor locks are acquired, interaction between monitors and \CFA's concept of polymorphism can be complex to support. However, it is shown that entry-point locking solves most of the issues. 179 180 First of all, interaction between \code{otype} polymorphism and monitors is impossible since monitors do not support copying. Therefore, the main question is how to support \code{dtype} polymorphism. Since a monitor's main purpose is to ensure mutual exclusion when accessing shared data, this implies that mutual exclusion is only required for routines that do in fact access shared data. However, since \code{dtype} polymorphism always handles incomplete types (by definition), no \code{dtype} polymorphic routine can access shared data since the data requires knowledge about the type. Therefore, the only concern when combining \code{dtype} polymorphism and monitors is to protect access to routines. 181 182 Before looking into complex control-flow, it is important to present the difference between the two acquiring options : callsite and entry-point locking, i.e. acquiring the monitors before making a mutex routine call or as the first operation of the mutex routine-call. For example: 75 Here, the constructor(\code{?\{\}}) uses the \code{nomutex} keyword to signify that it does not acquire the monitor mutual-exclusion when constructing. This semantics is because an object not yet constructed should never be shared and therefore does not require mutual exclusion. The prefix increment operator uses \code{mutex} to protect the incrementing process from race conditions. Finally, there is a conversion operator from \code{counter_t} to \code{size_t}. This conversion may or may not require the \code{mutex} keyword depending on whether or not reading a \code{size_t} is an atomic operation. 76 77 For maximum usability, monitors use \gls{multi-acq} semantics, which means a single thread can acquire multiple times the same monitor without deadlock. For example, figure \ref{fig:search} uses recursion and \gls{multi-acq} to print values inside a binary tree. 78 \begin{figure} 79 \label{fig:search} 80 \begin{cfacode} 81 monitor printer { ... }; 82 struct tree { 83 tree * left, right; 84 char * value; 85 }; 86 void print(printer & mutex p, char * v); 87 88 void print(printer & mutex p, tree * t) { 89 print(p, t->value); 90 print(p, t->left ); 91 print(p, t->right); 92 } 93 \end{cfacode} 94 \caption{Recursive printing algorithm using \gls{multi-acq}.} 95 \end{figure} 96 97 Having both \code{mutex} and \code{nomutex} keywords is redundant based on the meaning of a routine having neither of these keywords. For example, given a routine without qualifiers \code{void foo(counter_t & this)}, then it is reasonable that it should default to the safest option \code{mutex}, whereas assuming \code{nomutex} is unsafe and may cause subtle errors. In fact, \code{nomutex} is the "normal" parameter behaviour, with the \code{nomutex} keyword effectively stating explicitly that "this routine is not special". Another alternative is making exactly one of these keywords mandatory, which would provide the same semantics but without the ambiguity of supporting routines with neither keyword. Mandatory keywords would also have the added benefit of being self-documented but at the cost of extra typing. While there are several benefits to mandatory keywords, they do bring a few challenges. Mandatory keywords in \CFA would imply that the compiler must know without doubt whether or not a parameter is a monitor or not. Since \CFA relies heavily on traits as an abstraction mechanism, the distinction between a type that is a monitor and a type that looks like a monitor can become blurred. For this reason, \CFA only has the \code{mutex} keyword and uses no keyword to mean \code{nomutex}. 98 99 The next semantic decision is to establish when \code{mutex} may be used as a type qualifier. Consider the following declarations: 100 \begin{cfacode} 101 int f1(monitor & mutex m); 102 int f2(const monitor & mutex m); 103 int f3(monitor ** mutex m); 104 int f4(monitor * mutex m []); 105 int f5(graph(monitor*) & mutex m); 106 \end{cfacode} 107 The problem is to indentify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to indentify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C, and even then making sure objects are only acquired once becomes none-trivial. This problem can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To make the issue tractable, this project imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter with at most one level of indirection (ignoring potential qualifiers). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is be acquired, passing an array to this routine would be type safe and yet result in undefined behavior because only the first element of the array is acquired. However, this ambiguity is part of the C type-system with respects to arrays. For this reason, \code{mutex} is disallowed in the context where arrays may be passed: 108 \begin{cfacode} 109 int f1(monitor & mutex m); //Okay : recommanded case 110 int f2(monitor * mutex m); //Okay : could be an array but probably not 111 int f3(monitor mutex m []); //Not Okay : Array of unkown length 112 int f4(monitor ** mutex m); //Not Okay : Could be an array 113 int f5(monitor * mutex m []); //Not Okay : Array of unkown length 114 \end{cfacode} 115 Note that not all array functions are actually distinct in the type system sense. However, even the code generation could tell the difference, the extra information is still not sufficient to extend meaningfully the monitor call semantic. 116 117 Unlike object-oriented monitors, where calling a mutex member \emph{implicitly} acquires mutual-exclusion often receives an object, \CFA uses an explicit mechanism to acquire mutual-exclusion. A consequence of this approach is that it extends naturally to multi-monitor calls. 118 \begin{cfacode} 119 int f(MonitorA & mutex a, MonitorB & mutex b); 120 121 MonitorA a; 122 MonitorB b; 123 f(a,b); 124 \end{cfacode} 125 The capacity to acquire multiple locks before entering a critical section is called \emph{\gls{bulk-acq}}. In practice, writing multi-locking routines that do not lead to deadlocks is tricky. Having language support for such a feature is therefore a significant asset for \CFA. In the case presented above, \CFA guarantees that the order of aquisition is consistent across calls to routines using the same monitors as arguments. However, since \CFA monitors use \gls{multi-acq} locks, users can effectively force the acquiring order. For example, notice which routines use \code{mutex}/\code{nomutex} and how this affects aquiring order: 126 \begin{cfacode} 127 void foo(A & mutex a, B & mutex b) { //acquire a & b 128 ... 129 } 130 131 void bar(A & mutex a, B & /*nomutex*/ b) { //acquire a 132 ... foo(a, b); ... //acquire b 133 } 134 135 void baz(A & /*nomutex*/ a, B & mutex b) { //acquire b 136 ... foo(a, b); ... //acquire a 137 } 138 \end{cfacode} 139 The \gls{multi-acq} monitor lock allows a monitor lock to be acquired by both \code{bar} or \code{baz} and acquired again in \code{foo}. In the calls to \code{bar} and \code{baz} the monitors are acquired in opposite order. 140 141 However, such use leads to the lock acquiring order problem. In the example above, the user uses implicit ordering in the case of function \code{foo} but explicit ordering in the case of \code{bar} and \code{baz}. This subtle mistake means that calling these routines concurrently may lead to deadlock and is therefore undefined behavior. As shown on several occasion\cit, solving this problem requires: 142 \begin{enumerate} 143 \item Dynamically tracking of the monitor-call order. 144 \item Implement rollback semantics. 145 \end{enumerate} 146 While the first requirement is already a significant constraint on the system, implementing a general rollback semantics in a C-like language is prohibitively complex \cit. In \CFA, users simply need to be carefull when acquiring multiple monitors at the same time or only use \gls{bulk-acq} of all the monitors. 147 148 \Gls{multi-acq} and \gls{bulk-acq} can be used together in interesting ways, for example: 149 \begin{cfacode} 150 monitor bank { ... }; 151 152 void deposit( bank & mutex b, int deposit ); 153 154 void transfer( bank & mutex mybank, bank & mutex yourbank, int me2you) { 155 deposit( mybank, -me2you ); 156 deposit( yourbank, me2you ); 157 } 158 \end{cfacode} 159 This example shows a trivial solution to the bank account transfer problem\cit. Without \gls{multi-acq} and \gls{bulk-acq}, the solution to this problem is much more involved and requires carefull engineering. 160 161 \subsubsection{\code{mutex} statement} \label{mutex-stmt} 162 163 The call semantics discussed aboved have one software engineering issue, only a named routine can acquire the mutual-exclusion of a set of monitor. \CFA offers the \code{mutex} statement to workaround the need for unnecessary names, avoiding a major software engineering problem\cit. Listing \ref{lst:mutex-stmt} shows an example of the \code{mutex} statement, which introduces a new scope in which the mutual-exclusion of a set of monitor is acquired. Beyond naming, the \code{mutex} statement has no semantic difference from a routine call with \code{mutex} parameters. 164 165 \begin{figure} 183 166 \begin{center} 184 \setlength\tabcolsep{1.5pt} 185 \begin{tabular}{|c|c|c|} 186 Code & \gls{callsite-locking} & \gls{entry-point-locking} \\ 187 \CFA & pseudo-code & pseudo-code \\ 167 \begin{tabular}{|c|c|} 168 function call & \code{mutex} statement \\ 188 169 \hline 189 170 \begin{cfacode}[tabsize=3] 190 void foo(monitor& mutex a){ 191 192 193 194 //Do Work 195 //... 196 197 } 198 199 void main() { 200 monitor a; 201 202 203 204 foo(a); 205 206 } 207 \end{cfacode} & \begin{pseudo}[tabsize=3] 208 foo(& a) { 209 210 211 212 //Do Work 213 //... 214 215 } 216 217 main() { 218 monitor a; 219 //calling routine 220 //handles concurrency 221 acquire(a); 222 foo(a); 223 release(a); 224 } 225 \end{pseudo} & \begin{pseudo}[tabsize=3] 226 foo(& a) { 227 //called routine 228 //handles concurrency 229 acquire(a); 230 //Do Work 231 //... 232 release(a); 233 } 234 235 main() { 236 monitor a; 237 238 239 240 foo(a); 241 242 } 243 \end{pseudo} 171 monitor M {}; 172 void foo( M & mutex m ) { 173 //critical section 174 } 175 176 void bar( M & m ) { 177 foo( m ); 178 } 179 \end{cfacode}&\begin{cfacode}[tabsize=3] 180 monitor M {}; 181 void bar( M & m ) { 182 mutex(m) { 183 //critical section 184 } 185 } 186 187 188 \end{cfacode} 244 189 \end{tabular} 245 190 \end{center} 246 247 \Gls{callsite-locking} is inefficient, since any \code{dtype} routine may have to obtain some lock before calling a routine, depending on whether or not the type passed is a monitor. However, with \gls{entry-point-locking} calling a monitor routine becomes exactly the same as calling it from anywhere else. 248 249 Note the \code{mutex} keyword relies on the resolver, which means that in cases where a generic monitor routine is actually desired, writing a mutex routine is possible with the proper trait. This is possible because monitors are designed in terms a trait. For example: 250 \begin{cfacode} 251 //Incorrect 252 //T is not a monitor 253 forall(dtype T) 254 void foo(T * mutex t); 255 256 //Correct 257 //this function only works on monitors 258 //(any monitor) 259 forall(dtype T | is_monitor(T)) 260 void bar(T * mutex t)); 191 \caption{Regular call semantics vs. \code{mutex} statement} 192 \label{lst:mutex-stmt} 193 \end{figure} 194 195 % ====================================================================== 196 % ====================================================================== 197 \subsection{Data semantics} \label{data} 198 % ====================================================================== 199 % ====================================================================== 200 Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contain shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appropriate protection. For example, here is a complete version of the counter showed in section \ref{call}: 201 \begin{cfacode} 202 monitor counter_t { 203 int value; 204 }; 205 206 void ?{}(counter_t & this) { 207 this.cnt = 0; 208 } 209 210 int ?++(counter_t & mutex this) { 211 return ++this.value; 212 } 213 214 //need for mutex is platform dependent here 215 void ?{}(int * this, counter_t & mutex cnt) { 216 *this = (int)cnt; 217 } 261 218 \end{cfacode} 262 219 … … 267 224 % ====================================================================== 268 225 % ====================================================================== 269 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronisation. With monitors, this is generally achieved with internal or external scheduling as in\cit. Since internal scheduling of single monitors is mostly a solved problem, this proposal concentraits on extending internal scheduling to multiple monitors at once. Indeed, like the \gls{group-acquire} semantics, internal scheduling extends to multiple monitors at oncein a way that is natural to the user but requires additional complexity on the implementation side.226 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronisation. With monitors, this capability is generally achieved with internal or external scheduling as in\cit. Since internal scheduling within a single monitor is mostly a solved problem, this thesis concentrates on extending internal scheduling to multiple monitors. Indeed, like the \gls{bulk-acq} semantics, internal scheduling extends to multiple monitors in a way that is natural to the user but requires additional complexity on the implementation side. 270 227 271 228 First, here is a simple example of such a technique: 272 229 273 230 \begin{cfacode} 274 275 276 277 278 279 280 //Wait for cooperation from bar()281 282 283 284 285 286 //Provide cooperation for foo()287 288 // Unblock foo at scope exit289 290 291 \end{cfacode} 292 293 There are two details to note here. First, the re \code{signal} is a delayed operation, it only unblocks the waiting thread when it reaches the end of the critical section. This is needed to respect mutual-exclusion. Second, in \CFA, \code{condition} have no particular need to be stored inside a monitor, beyond any software engineering reasons. Here routine \code{foo} waits for the \code{signal} from \code{bar} before making further progress, effectively ensuring a basic ordering.294 295 An important aspect to take into account hereis that \CFA does not allow barging, which means that once function \code{bar} releases the monitor, foo is guaranteed to resume immediately after (unless some other thread waited on the same condition). This guarantees offers the benefit of not having to loop arount waits in order to guarantee that a condition is still met. The main reason \CFA offers this guarantee is that users can easily introduce barging if it becomes a necessity but adding barging prevention or barging avoidance is more involved without language support. Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design of \CFA concurrency.231 monitor A { 232 condition e; 233 } 234 235 void foo(A & mutex a) { 236 ... 237 //Wait for cooperation from bar() 238 wait(a.e); 239 ... 240 } 241 242 void bar(A & mutex a) { 243 //Provide cooperation for foo() 244 ... 245 //Unblock foo 246 signal(a.e); 247 } 248 \end{cfacode} 249 250 There are two details to note here. First, the \code{signal} is a delayed operation, it only unblocks the waiting thread when it reaches the end of the critical section. This semantic is needed to respect mutual-exclusion. Second, in \CFA, a \code{condition} variable can be stored/created independently of a monitor. Here routine \code{foo} waits for the \code{signal} from \code{bar} before making further progress, effectively ensuring a basic ordering. 251 252 An important aspect of the implementation is that \CFA does not allow barging, which means that once function \code{bar} releases the monitor, foo is guaranteed to resume immediately after (unless some other thread waited on the same condition). This guarantees offers the benefit of not having to loop arount waits in order to guarantee that a condition is still met. The main reason \CFA offers this guarantee is that users can easily introduce barging if it becomes a necessity but adding barging prevention or barging avoidance is more involved without language support. Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design of \CFA concurrency. 296 253 297 254 % ====================================================================== … … 300 257 % ====================================================================== 301 258 % ====================================================================== 302 It is easier to understand the problem of multi-monitor scheduling using a series of pseudo-code. Note that for simplicity in the following snippets of pseudo-code, waiting and signalling is done using an implicit condition variable, like Java built-in monitors. 259 It is easier to understand the problem of multi-monitor scheduling using a series of pseudo-code. Note that for simplicity in the following snippets of pseudo-code, waiting and signalling is done using an implicit condition variable, like Java built-in monitors. Indeed, \code{wait} statements always use a single condition as paremeter and waits on the monitors associated with the condition. 303 260 304 261 \begin{multicols}{2} … … 319 276 \end{pseudo} 320 277 \end{multicols} 321 The example shows the simple case of having two threads (one for each column) and a single monitor A. One thread acquires before waiting (atomically blocking and releasing A) and the other acquires before signalling. There is an important thing to note here, both \code{wait} and \code{signal} must be called with the proper monitor(s) already acquired. This restriction is hidden on the user side in \uC, as itis a logical requirement for barging prevention.322 323 A direct extension of the previous example is the \gls{group-acquire} version:278 The example shows the simple case of having two threads (one for each column) and a single monitor A. One thread acquires before waiting (atomically blocking and releasing A) and the other acquires before signalling. It is important to note here that both \code{wait} and \code{signal} must be called with the proper monitor(s) already acquired. This semantic is a logical requirement for barging prevention. 279 280 A direct extension of the previous example is a \gls{bulk-acq} version: 324 281 325 282 \begin{multicols}{2} … … 338 295 \end{pseudo} 339 296 \end{multicols} 340 This version uses \gls{group-acquire} (denoted using the \& symbol), but the presence of multiple monitors does not add a particularly new meaning. Synchronization happens between the two threads in exactly the same way and order. The only difference is that mutual exclusion covers more monitors. On the implementation side, handling multiple monitors does add a degree of complexity as the next few examples demonstrate. 341 342 While deadlock issues can occur when nesting monitors, these issues are only a symptom of the fact that locks, and by extension monitors, are not perfectly composable. However, for monitors as for locks, it is possible to write a program using nesting without encountering any problems if nested is done correctly. For example, the next pseudo-code snippet acquires monitors A then B before waiting while only acquiring B when signalling, effectively avoiding the nested monitor problem. 343 297 This version uses \gls{bulk-acq} (denoted using the \& symbol), but the presence of multiple monitors does not add a particularly new meaning. Synchronization happens between the two threads in exactly the same way and order. The only difference is that mutual exclusion covers more monitors. On the implementation side, handling multiple monitors does add a degree of complexity as the next few examples demonstrate. 298 299 While deadlock issues can occur when nesting monitors, these issues are only a symptom of the fact that locks, and by extension monitors, are not perfectly composable. For monitors, a well known deadlock problem is the Nested Monitor Problem\cit, which occurs when a \code{wait} is made on a thread that holds more than one monitor. For example, the following pseudo-code will run into the nested monitor problem : 344 300 \begin{multicols}{2} 345 301 \begin{pseudo} … … 354 310 355 311 \begin{pseudo} 312 acquire A 313 acquire B 314 signal B 315 release B 316 release A 317 \end{pseudo} 318 \end{multicols} 319 However, for monitors as for locks, it is possible to write a program using nesting without encountering any problems if nesting is done correctly. For example, the next pseudo-code snippet acquires monitors {\sf A} then {\sf B} before waiting, while only acquiring {\sf B} when signalling, effectively avoiding the nested monitor problem. 320 321 \begin{multicols}{2} 322 \begin{pseudo} 323 acquire A 324 acquire B 325 wait B 326 release B 327 release A 328 \end{pseudo} 329 330 \columnbreak 331 332 \begin{pseudo} 356 333 357 334 acquire B … … 362 339 \end{multicols} 363 340 364 The next example is where \gls{group-acquire} adds a significant layer of complexity to the internal signalling semantics. 365 341 Listing \ref{lst:int-bulk-pseudo} shows an example where \gls{bulk-acq} adds a significant layer of complexity to the internal signalling semantics. Listing \ref{lst:int-bulk-cfa} shows the corresponding \CFA code which implements the pseudo-code in listing \ref{lst:int-bulk-pseudo}. Note that listing \ref{lst:int-bulk-cfa} uses non-\code{mutex} parameter to introduce monitor \code{b} into context. However, for the purpose of translating the given pseudo-code into \CFA-code any method of introducing new monitors into context, other than a \code{mutex} parameter, is acceptable, e.g. global variables, pointer parameters or using locals with the \code{mutex}-statement. 342 343 \begin{figure}[!b] 366 344 \begin{multicols}{2} 367 345 Waiting thread 368 346 \begin{pseudo}[numbers=left] 369 347 acquire A 370 // 348 //Code Section 1 371 349 acquire A & B 372 // 350 //Code Section 2 373 351 wait A & B 374 // 352 //Code Section 3 375 353 release A & B 376 // 354 //Code Section 4 377 355 release A 378 356 \end{pseudo} … … 383 361 \begin{pseudo}[numbers=left, firstnumber=10] 384 362 acquire A 385 // 363 //Code Section 5 386 364 acquire A & B 387 // 365 //Code Section 6 388 366 signal A & B 389 // 367 //Code Section 7 390 368 release A & B 391 // Code Section 8 392 release A 393 \end{pseudo} 394 \end{multicols} 395 \begin{center} 396 Listing 1 397 \end{center} 398 399 It is particularly important to pay attention to code sections 8 and 4, which are where the existing semantics of internal scheduling need to be extended for multiple monitors. The root of the problem is that \gls{group-acquire} is used in a context where one of the monitors is already acquired and is why it is important to define the behaviour of the previous pseudo-code. When the signaller thread reaches the location where it should "release A \& B" (line 16), it must actually transfer ownership of monitor B to the waiting thread. This ownership trasnfer is required in order to prevent barging. Since the signalling thread still needs the monitor A, simply waking up the waiting thread is not an option because it would violate mutual exclusion. There are three options: 369 //Code Section 8 370 release A 371 \end{pseudo} 372 \end{multicols} 373 \caption{Internal scheduling with \gls{bulk-acq}} 374 \label{lst:int-bulk-pseudo} 375 \end{figure} 376 377 \begin{figure}[!b] 378 \begin{multicols}{2} 379 Waiting thread 380 \begin{cfacode} 381 monitor A; 382 monitor B; 383 extern condition c; 384 void foo(A & mutex a, B & b) { 385 //Code Section 1 386 mutex(a, b) { 387 //Code Section 2 388 wait(c); 389 //Code Section 3 390 } 391 //Code Section 4 392 } 393 \end{cfacode} 394 395 \columnbreak 396 397 Signalling thread 398 \begin{cfacode} 399 monitor A; 400 monitor B; 401 extern condition c; 402 void foo(A & mutex a, B & b) { 403 //Code Section 5 404 mutex(a, b) { 405 //Code Section 6 406 signal(c); 407 //Code Section 7 408 } 409 //Code Section 8 410 } 411 \end{cfacode} 412 \end{multicols} 413 \caption{Equivalent \CFA code for listing \ref{lst:int-bulk-pseudo}} 414 \label{lst:int-bulk-cfa} 415 \end{figure} 416 417 It is particularly important to pay attention to code sections 4 and 8, which are where the existing semantics of internal scheduling need to be extended for multiple monitors. The root of the problem is that \gls{bulk-acq} is used in a context where one of the monitors is already acquired and is why it is important to define the behaviour of the previous pseudo-code. When the signaller thread reaches the location where it should "release A \& B" (line 16), it must actually transfer ownership of monitor B to the waiting thread. This ownership trasnfer is required in order to prevent barging. Since the signalling thread still needs monitor A, simply waking up the waiting thread is not an option because it would violate mutual exclusion. There are three options. 400 418 401 419 \subsubsection{Delaying signals} 402 The first more obvious solution to solve the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. It can be argued that that moment is the correct time to transfer ownership when the last lock is no longer needed because this semantics fits most closely to the behaviour of single monitor scheduling. This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from mutiple objects to a single group of object , effectively making the existing single monitor semantic viable by simply changing monitors to monitor collections.420 The first more obvious solution to solve the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. It can be argued that that moment is the correct time to transfer ownership when the last lock is no longer needed because this semantics fits most closely to the behaviour of single monitor scheduling. This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from mutiple objects to a single group of objects, effectively making the existing single monitor semantic viable by simply changing monitors to monitor groups. 403 421 \begin{multicols}{2} 404 422 Waiter … … 424 442 \end{pseudo} 425 443 \end{multicols} 426 However, this solution can become much more complicated depending on what is executed while secretly holding B (at line 10). Indeed, nothing prevents a user from signalling monitor A on a different condition variable: 427 \newpage 444 However, this solution can become much more complicated depending on what is executed while secretly holding B (at line 10). Indeed, nothing prevents signalling monitor A on a different condition variable: 428 445 \begin{multicols}{2} 429 446 Thread 1 … … 446 463 447 464 Thread 3 448 \begin{pseudo}[numbers=left, firstnumber= 10]465 \begin{pseudo}[numbers=left, firstnumber=9] 449 466 acquire A 450 467 acquire A & B … … 467 484 Note that ordering is not determined by a race condition but by whether signalled threads are enqueued in FIFO or FILO order. However, regardless of the answer, users can move line 15 before line 11 and get the reverse effect. 468 485 469 In both cases, the threads need to be able to distinguish on a per monitor basis which ones need to be released and which ones need to be transferred. Which means monitors cannot be handled as a single homogenous group.486 In both cases, the threads need to be able to distinguish, on a per monitor basis, which ones need to be released and which ones need to be transferred, which means monitors cannot be handled as a single homogenous group and therefore invalidates the main benefit of this approach. 470 487 471 488 \subsubsection{Dependency graphs} 472 In the Listing 1 pseudo-code, there is a solution which statisfies both barging prevention and mutual exclusion. If ownership of both monitors is transferred to the waiter when the signaller releases A and then the waiter transfers back ownership of A when it releases it then the problem is solved. Dynamically finding the correct order is therefore the second possible solution. The problem it encounters is that it effectively boils down to resolving a dependency graph of ownership requirements. Here even the simplest of code snippets requires two transfers and it seems to increase in a manner closer to polynomial. For example, the following code, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions:489 In the Listing 1 pseudo-code, there is a solution which statisfies both barging prevention and mutual exclusion. If ownership of both monitors is transferred to the waiter when the signaller releases A and then the waiter transfers back ownership of A when it releases it, then the problem is solved. Dynamically finding the correct order is therefore the second possible solution. The problem it encounters is that it effectively boils down to resolving a dependency graph of ownership requirements. Here even the simplest of code snippets requires two transfers and it seems to increase in a manner closer to polynomial. For example, the following code, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions: 473 490 474 491 \begin{multicols}{2} … … 495 512 \end{pseudo} 496 513 \end{multicols} 497 Resolving dependency graph being a complex and expensive endeavour, this solution is not the preffered one. 498 499 \subsubsection{Partial signalling} \label{partial-sig} 500 Finally, the solution that is chosen for \CFA is to use partial signalling. Consider the following case: 501 502 \begin{multicols}{2} 503 \begin{pseudo}[numbers=left] 514 515 \begin{figure} 516 \begin{multicols}{3} 517 Thread $\alpha$ 518 \begin{pseudo}[numbers=left, firstnumber=1] 504 519 acquire A 505 520 acquire A & B … … 511 526 \columnbreak 512 527 513 \begin{pseudo}[numbers=left, firstnumber=6] 528 Thread $\gamma$ 529 \begin{pseudo}[numbers=left, firstnumber=1] 514 530 acquire A 515 531 acquire A & B 516 532 signal A & B 517 533 release A & B 518 // ... More code 519 release A 520 \end{pseudo} 521 \end{multicols} 522 The partial signalling solution transfers ownership of monitor B at lines 10 but does not wake the waiting thread since it is still using monitor A. Only when it reaches line 11 does it actually wakeup the waiting thread. This solution has the benefit that complexity is encapsulated into only two actions, passing monitors to the next owner when they should be release and conditionnaly waking threads if all conditions are met. Contrary to the other solutions, this solution quickly hits an upper bound on complexity of implementation. 534 signal A 535 release A 536 \end{pseudo} 537 538 \columnbreak 539 540 Thread $\beta$ 541 \begin{pseudo}[numbers=left, firstnumber=1] 542 acquire A 543 wait A 544 release A 545 \end{pseudo} 546 547 \end{multicols} 548 \caption{Dependency graph} 549 \label{lst:dependency} 550 \end{figure} 551 552 \begin{figure} 553 \begin{center} 554 \input{dependency} 555 \end{center} 556 \label{fig:dependency} 557 \caption{Dependency graph of the statements in listing \ref{lst:dependency}} 558 \end{figure} 559 560 Listing \ref{lst:dependency} is the three thread example rewritten for dependency graphs as well as the corresponding dependency graph. Figure \ref{fig:dependency} shows the corresponding dependency graph that results, where every node is a statement of one of the three threads, and the arrows the dependency of that statement. The extra challenge is that this dependency graph is effectively post-mortem, but the run time system needs to be able to build and solve these graphs as the dependency unfolds. Resolving dependency graph being a complex and expensive endeavour, this solution is not the preffered one. 561 562 \subsubsection{Partial signalling} \label{partial-sig} 563 Finally, the solution that is chosen for \CFA is to use partial signalling. Consider the following case: 564 565 \begin{multicols}{2} 566 \begin{pseudo}[numbers=left] 567 acquire A 568 acquire A & B 569 wait A & B 570 release A & B 571 release A 572 \end{pseudo} 573 574 \columnbreak 575 576 \begin{pseudo}[numbers=left, firstnumber=6] 577 acquire A 578 acquire A & B 579 signal A & B 580 release A & B 581 //... More code 582 release A 583 \end{pseudo} 584 \end{multicols} 585 The partial signalling solution transfers ownership of monitor B at lines 10 but does not wake the waiting thread since it is still using monitor A. Only when it reaches line 11 does it actually wakeup the waiting thread. This solution has the benefit that complexity is encapsulated into only two actions, passing monitors to the next owner when they should be release and conditionally waking threads if all conditions are met. This solution has a much simpler implementation than a dependency graph solving algorithm which is why it was chosen. 523 586 524 587 % ====================================================================== … … 529 592 An important note is that, until now, signalling a monitor was a delayed operation. The ownership of the monitor is transferred only when the monitor would have otherwise been released, not at the point of the \code{signal} statement. However, in some cases, it may be more convenient for users to immediately transfer ownership to the thread that is waiting for cooperation, which is achieved using the \code{signal_block} routine\footnote{name to be discussed}. 530 593 531 For example here is an example highlighting the difference in behaviour: 532 \begin{ center}594 The example in listing \ref{lst:datingservice} highlights the difference in behaviour. As mentioned, \code{signal} only transfers ownership once the current critical section exits, this behaviour cause the need for additional synchronisation when a two-way handshake is needed. To avoid this extraneous synchronisation, the \code{condition} type offers the \code{signal_block} routine which handle two-way handshakes as shown in the example. This removes the need for a second condition variables and simplifies programming. Like every other monitor semantic, \code{signal_block} uses barging prevention which means mutual-exclusion is baton-passed both on the frond-end and the back-end of the call to \code{signal_block}, meaning no other thread can acquire the monitor neither before nor after the call. 595 \begin{figure} 533 596 \begin{tabular}{|c|c|} 534 597 \code{signal} & \code{signal_block} \\ 535 598 \hline 536 \begin{cfacode} 537 monitor M { int val; }; 538 539 void foo(M & mutex m ) { 540 m.val++; 541 sout| "Foo:" | m.val |endl; 542 543 wait( c ); 544 545 m.val++; 546 sout| "Foo:" | m.val |endl; 547 } 548 549 void bar(M & mutex m ) { 550 m.val++; 551 sout| "Bar:" | m.val |endl; 552 553 signal( c ); 554 555 m.val++; 556 sout| "Bar:" | m.val |endl; 557 } 558 \end{cfacode}&\begin{cfacode} 559 monitor M { int val; }; 560 561 void foo(M & mutex m ) { 562 m.val++; 563 sout| "Foo:" | m.val |endl; 564 565 wait( c ); 566 567 m.val++; 568 sout| "Foo:" | m.val |endl; 569 } 570 571 void bar(M & mutex m ) { 572 m.val++; 573 sout| "Bar:" | m.val |endl; 574 575 signal_block( c ); 576 577 m.val++; 578 sout| "Bar:" | m.val |endl; 599 \begin{cfacode}[tabsize=3] 600 monitor DatingService 601 { 602 //compatibility codes 603 enum{ CCodes = 20 }; 604 605 int girlPhoneNo 606 int boyPhoneNo; 607 }; 608 609 condition girls[CCodes]; 610 condition boys [CCodes]; 611 condition exchange; 612 613 int girl(int phoneNo, int ccode) 614 { 615 //no compatible boy ? 616 if(empty(boys[ccode])) 617 { 618 //wait for boy 619 wait(girls[ccode]); 620 621 //make phone number available 622 girlPhoneNo = phoneNo; 623 624 //wake boy fron chair 625 signal(exchange); 626 } 627 else 628 { 629 //make phone number available 630 girlPhoneNo = phoneNo; 631 632 //wake boy 633 signal(boys[ccode]); 634 635 //sit in chair 636 wait(exchange); 637 } 638 return boyPhoneNo; 639 } 640 641 int boy(int phoneNo, int ccode) 642 { 643 //same as above 644 //with boy/girl interchanged 645 } 646 \end{cfacode}&\begin{cfacode}[tabsize=3] 647 monitor DatingService 648 { 649 //compatibility codes 650 enum{ CCodes = 20 }; 651 652 int girlPhoneNo; 653 int boyPhoneNo; 654 }; 655 656 condition girls[CCodes]; 657 condition boys [CCodes]; 658 //exchange is not needed 659 660 int girl(int phoneNo, int ccode) 661 { 662 //no compatible boy ? 663 if(empty(boys[ccode])) 664 { 665 //wait for boy 666 wait(girls[ccode]); 667 668 //make phone number available 669 girlPhoneNo = phoneNo; 670 671 //wake boy fron chair 672 signal(exchange); 673 } 674 else 675 { 676 //make phone number available 677 girlPhoneNo = phoneNo; 678 679 //wake boy 680 signal_block(boys[ccode]); 681 682 //second handshake unnecessary 683 684 } 685 return boyPhoneNo; 686 } 687 688 int boy(int phoneNo, int ccode) 689 { 690 //same as above 691 //with boy/girl interchanged 579 692 } 580 693 \end{cfacode} 581 694 \end{tabular} 582 \end{center} 583 Assuming that \code{val} is initialized at 0, that each routine are called from seperate thread and that \code{foo} is always called first. The previous code would yield the following output: 584 585 \begin{center} 586 \begin{tabular}{|c|c|} 587 \code{signal} & \code{signal_block} \\ 588 \hline 589 \begin{pseudo} 590 Foo: 0 591 Bar: 1 592 Bar: 2 593 Foo: 3 594 \end{pseudo}&\begin{pseudo} 595 Foo: 0 596 Bar: 1 597 Foo: 2 598 Bar: 3 599 \end{pseudo} 600 \end{tabular} 601 \end{center} 602 603 As mentionned, \code{signal} only transfers ownership once the current critical section exits, resulting in the second "Bar" line to be printed before the second "Foo" line. On the other hand, \code{signal_block} immediately transfers ownership to \code{bar}, causing an inversion of output. Obviously this means that \code{signal_block} is a blocking call, which will only be resumed once the signalled function exits the critical section. 604 605 % ====================================================================== 606 % ====================================================================== 607 \subsection{Internal scheduling: Implementation} \label{inschedimpl} 608 % ====================================================================== 609 % ====================================================================== 610 There are several challenges specific to \CFA when implementing internal scheduling. These challenges are direct results of \gls{group-acquire} and loose object definitions. These two constraints are to root cause of most design decisions in the implementation of internal scheduling. Furthermore, to avoid the head-aches of dynamically allocating memory in a concurrent environment, the internal-scheduling design is entirely free of mallocs and other dynamic memory allocation scheme. This is to avoid the chicken and egg problem of having a memory allocator that relies on the threading system and a threading system that relies on the runtime. This extra goal, means that memory management is a constant concern in the design of the system. 611 612 The main memory concern for concurrency is queues. All blocking operations are made by parking threads onto queues. These queues need to be intrinsic\cit to avoid the need memory allocation. This entails that all the fields needed to keep track of all needed information. Since internal scheduling can use an unbound amount of memory (depending on \gls{group-acquire}) statically defining information information in the intrusive fields of threads is insufficient. The only variable sized container that does not require memory allocation is the callstack, which is heavily used in the implementation of internal scheduling. Particularly the GCC extension variable length arrays which is used extensively. 613 614 Since stack allocation is based around scope, the first step of the implementation is to identify the scopes that are available to store the information, and which of these can have a variable length. In the case of external scheduling, the threads and the condition both allow a fixed amount of memory to be stored, while mutex-routines and the actual blocking call allow for an unbound amount (though adding too much to the mutex routine stack size can become expansive faster). 615 616 The following figure is the traditionnal illustration of a monitor : 617 618 \begin{center} 619 {\resizebox{0.4\textwidth}{!}{\input{monitor}}} 620 \end{center} 621 622 For \CFA, the previous picture does not have support for blocking multiple monitors on a single condition. To support \gls{group-acquire} two changes to this picture are required. First, it doesn't make sense to tie the condition to a single monitor since blocking two monitors as one would require arbitrarily picking a monitor to hold the condition. Secondly, the object waiting on the conditions and AS-stack cannot simply contain the waiting thread since a single thread can potentially wait on multiple monitors. As mentionned in section \ref{inschedimpl}, the handling in multiple monitors is done by partially passing, which entails that each concerned monitor needs to have a node object. However, for waiting on the condition, since all threads need to wait together, a single object needs to be queued in the condition. Moving out the condition and updating the node types yields : 623 624 \begin{center} 625 {\resizebox{0.8\textwidth}{!}{\input{int_monitor}}} 626 \end{center} 627 628 \newpage 629 630 This picture and the proper entry and leave algorithms is the fundamental implementation of internal scheduling. 631 632 \begin{multicols}{2} 633 Entry 634 \begin{pseudo}[numbers=left] 635 if monitor is free 636 enter 637 elif I already own the monitor 638 continue 639 else 640 block 641 increment recursion 642 643 \end{pseudo} 644 \columnbreak 645 Exit 646 \begin{pseudo}[numbers=left, firstnumber=8] 647 decrement recursion 648 if recursion == 0 649 if signal_stack not empty 650 set_owner to thread 651 if all monitors ready 652 wake-up thread 653 654 if entry queue not empty 655 wake-up thread 656 \end{pseudo} 657 \end{multicols} 658 659 Some important things to notice about the exit routine. The solution discussed in \ref{inschedimpl} can be seen on line 11 of the previous pseudo code. Basically, the solution boils down to having a seperate data structure for the condition queue and the AS-stack, and unconditionally transferring ownership of the monitors but only unblocking the thread when the last monitor has trasnferred ownership. This solution is safe as well as preventing any potential barging. 695 \caption{Dating service example using \code{signal} and \code{signal_block}. } 696 \label{lst:datingservice} 697 \end{figure} 660 698 661 699 % ====================================================================== … … 700 738 \end{tabular} 701 739 \end{center} 702 This method is more constrained and explicit, which may help users tone down the undeterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occuring. External scheduling can generally be done either in terms of control flow (e.g., \uC) or in terms of data (e.g. Go). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control-flow semantics were chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multi-monitor routines. The previous example shows a simple use \code{_Accept} versus \code{wait}/\code{signal} and its advantages. Note that while other languages often use \code{accept} as the core external scheduling keyword, \CFA uses \code{waitfor} to prevent name collisions with existing socket APIs.703 704 In the case of internal scheduling, the call to \code{wait} only guarantees that \code{V} is the last routine to access the monitor. This entails that the routine \code{V}may have acquired mutual exclusion several times while routine \code{P} was waiting. On the other hand, external scheduling guarantees that while routine \code{P} was waiting, no routine other than \code{V} could acquire the monitor.740 This method is more constrained and explicit, which helps users tone down the undeterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occuring. External scheduling can generally be done either in terms of control flow (e.g., \uC with \code{_Accept}) or in terms of data (e.g. Go with channels). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control-flow semantics were chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multi-monitor routines. The previous example shows a simple use \code{_Accept} versus \code{wait}/\code{signal} and its advantages. Note that while other languages often use \code{accept}/\code{select} as the core external scheduling keyword, \CFA uses \code{waitfor} to prevent name collisions with existing socket \acrshort{api}s. 741 742 In the case of internal scheduling, the call to \code{wait} only guarantees that \code{V} is the last routine to access the monitor. This entails that a third routine, say \code{isInUse()}, may have acquired mutual exclusion several times while routine \code{P} was waiting. On the other hand, external scheduling guarantees that while routine \code{P} was waiting, no routine other than \code{V} could acquire the monitor. 705 743 706 744 % ====================================================================== … … 712 750 713 751 \begin{cfacode} 714 monitor A {}; 715 716 void f(A & mutex a); 717 void f(int a, float b); 718 void g(A & mutex a) { 719 waitfor(f); // Less obvious which f() to wait for 720 } 752 monitor A {}; 753 754 void f(A & mutex a); 755 void g(A & mutex a) { 756 waitfor(f); //Obvious which f() to wait for 757 } 758 759 void f(A & mutex a, int); //New different F added in scope 760 void h(A & mutex a) { 761 waitfor(f); //Less obvious which f() to wait for 762 } 721 763 \end{cfacode} 722 764 … … 728 770 if monitor is free 729 771 enter 730 elif Ialready own the monitor772 elif already own the monitor 731 773 continue 732 774 elif monitor accepts me … … 738 780 \end{center} 739 781 740 For the fi st two conditions, it is easy to implement a check that can evaluate the condition in a few instruction. However, a fast check for \pscode{monitor accepts me} is much harder to implement depending on the constraints put on the monitors. Indeed, monitors are often expressed as an entry queue and some acceptor queue as in the following figure:782 For the first two conditions, it is easy to implement a check that can evaluate the condition in a few instruction. However, a fast check for \pscode{monitor accepts me} is much harder to implement depending on the constraints put on the monitors. Indeed, monitors are often expressed as an entry queue and some acceptor queue as in the following figure: 741 783 742 784 \begin{center} … … 744 786 \end{center} 745 787 746 There are other alternatives to these pictures but in the case of this pictureimplementing a fast accept check is relatively easy. Indeed simply updating a bitmask when the acceptor queue changes is enough to have a check that executes in a single instruction, even with a fairly large number (e.g. 128) of mutex members. This technique cannot be used in \CFA because it relies on the fact that the monitor type declares all the acceptable routines. For OO languages this does not compromise much since monitors already have an exhaustive list of member routines. However, for \CFA this is not the case; routines can be added to a type anywhere after its declaration. Its important to note that the bitmask approach does not actually require an exhaustive list of routines, but it requires a dense unique ordering of routines with an upper-bound and that ordering must be consistent across translation units.747 The alternative would be to have a picture more like this one:788 There are other alternatives to these pictures, but in the case of this picture, implementing a fast accept check is relatively easy. Indeed simply updating a bitmask when the acceptor queue changes is enough to have a check that executes in a single instruction, even with a fairly large number (e.g. 128) of mutex members. This technique cannot be used in \CFA because it relies on the fact that the monitor type declares all the acceptable routines. For OO languages this does not compromise much since monitors already have an exhaustive list of member routines. However, for \CFA this is not the case; routines can be added to a type anywhere after its declaration. Its important to note that the bitmask approach does not actually require an exhaustive list of routines, but it requires a dense unique ordering of routines with an upper-bound and that ordering must be consistent across translation units. 789 The alternative is to have a picture like this one: 748 790 749 791 \begin{center} … … 751 793 \end{center} 752 794 753 Not storing the queues inside the monitor means that the storage can vary between routines, allowing for more flexibility and extensions. Storing an array of function-pointers would solve the issue of uniquely identifying acceptable routines. However, the single instruction bitmask compare has been replaced by dereferencing a pointer followed by a linear search. Furthermore, supporting nested external scheduling may now require additionnal searches on calls to waitfor to check if a routine is already queued in.754 755 At this point we must make a decision between flexibility and performance. Many design decisions in \CFA achieve both flexibility and performance, for example polymorphic routines add significant flexibility but inlining them means the optimizer can easily remove any runtime cost. Here however, the cost of flexibility cannot be trivially removed. In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be prohibitively hard to write. This is based on the assumption that writing fast but inflexible locks is closer to a solved problems than writing locks that are as flexible as external scheduling in \CFA.756 757 A nother aspect to consider is what happens if multiple overloads of the same routine are used. For the time being it is assumed that multiple overloads of the same routine are considered as distinct routines. However, this could easily be extended in the future.795 Not storing the mask inside the monitor means that the storage for the mask information can vary between calls to \code{waitfor}, allowing for more flexibility and extensions. Storing an array of function-pointers would solve the issue of uniquely identifying acceptable routines. However, the single instruction bitmask compare has been replaced by dereferencing a pointer followed by a linear search. Furthermore, supporting nested external scheduling may now require additionnal searches on calls to waitfor to check if a routine is already queued in. 796 797 Note that in the second picture, tasks need to always keep track of through which routine they are attempting to acquire the monitor and the routine mask needs to have both a function pointer and a set of monitors, as will be discussed in the next section. These details where omitted from the picture for the sake of simplifying the representation. 798 799 At this point we must make a decision between flexibility and performance. Many design decisions in \CFA achieve both flexibility and performance, for example polymorphic routines add significant flexibility but inlining them means the optimizer can easily remove any runtime cost. Here however, the cost of flexibility cannot be trivially removed. In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be prohibitively hard to write. This decision is based on the assumption that writing fast but inflexible locks is closer to a solved problems than writing locks that are as flexible as external scheduling in \CFA. 758 800 759 801 % ====================================================================== … … 763 805 % ====================================================================== 764 806 765 External scheduling, like internal scheduling, becomes orders of magnitude more complex when we start introducing multi-monitor syntax. Even in the simplest possible casesome new semantics need to be established:766 \begin{cfacode} 767 mutex struct A{};768 769 mutex struct B {};770 771 void g(A & mutex a, B& mutex b) {772 waitfor(f); //ambiguous, which monitor773 807 External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax. Even in the simplest possible case, some new semantics need to be established: 808 \begin{cfacode} 809 monitor M {}; 810 811 void f(M & mutex a); 812 813 void g(M & mutex a, M & mutex b) { 814 waitfor(f); //ambiguous, keep a pass b or other way around? 815 } 774 816 \end{cfacode} 775 817 … … 777 819 778 820 \begin{cfacode} 779 mutex struct A {}; 780 781 mutex struct B {}; 782 783 void g(A & mutex a, B & mutex b) { 784 waitfor( f, b ); 785 } 786 \end{cfacode} 787 788 This is unambiguous. Both locks will be acquired and kept, when routine \code{f} is called the lock for monitor \code{b} will be temporarily transferred from \code{g} to \code{f} (while \code{g} still holds lock \code{a}). This behavior can be extended to multi-monitor waitfor statment as follows. 789 790 \begin{cfacode} 791 mutex struct A {}; 792 793 mutex struct B {}; 794 795 void g(A & mutex a, B & mutex b) { 796 waitfor( f, a, b); 797 } 798 \end{cfacode} 799 800 Note that the set of monitors passed to the \code{waitfor} statement must be entirely contained in the set of monitor already acquired in the routine. \code{waitfor} used in any other context is Undefined Behaviour. 801 802 An important behavior to note is that what happens when set of monitors only match partially : 803 804 \begin{cfacode} 805 mutex struct A {}; 806 807 mutex struct B {}; 808 809 void g(A & mutex a, B & mutex b) { 810 waitfor(f, a, b); 811 } 812 813 A a1, a2; 814 B b; 815 816 void foo() { 817 g(a1, b); 818 } 819 820 void bar() { 821 f(a2, b); 822 } 823 \end{cfacode} 824 825 While the equivalent can happen when using internal scheduling, the fact that conditions are branded on first use means that users have to use two different condition variables. In both cases, partially matching monitor sets will not wake-up the waiting thread. It is also important to note that in the case of external scheduling, as for routine calls, the order of parameters is important; \code{waitfor(f,a,b)} and \code{waitfor(f,b,a)} are to distinct waiting condition. 826 827 % ====================================================================== 828 % ====================================================================== 829 \subsection{Implementation Details: External scheduling queues} 830 % ====================================================================== 831 % ====================================================================== 832 To support multi-monitor external scheduling means that some kind of entry-queues must be used that is aware of both monitors. However, acceptable routines must be aware of the entry queues which means they must be stored inside at least one of the monitors that will be acquired. This in turn adds the requirement a systematic algorithm of disambiguating which queue is relavant regardless of user ordering. The proposed algorithm is to fall back on monitors lock ordering and specify that the monitor that is acquired first is the lock with the relevant entry queue. This assumes that the lock acquiring order is static for the lifetime of all concerned objects but that is a reasonable constraint. This algorithm choice has two consequences, the entry queue of the highest priority monitor is no longer a true FIFO queue and the queue of the lowest priority monitor is both required and probably unused. The queue can no longer be a FIFO queue because instead of simply containing the waiting threads in order arrival, they also contain the second mutex. Therefore, another thread with the same highest priority monitor but a different lowest priority monitor may arrive first but enter the critical section after a thread with the correct pairing. Secondly, since it may not be known at compile time which monitor will be the lowest priority monitor, every monitor needs to have the correct queues even though it is probable that half the multi-monitor queues will go unused for the entire duration of the program. 833 834 % ====================================================================== 835 % ====================================================================== 836 \section{Other concurrency tools} 837 % ====================================================================== 838 % ====================================================================== 839 % \TODO 821 monitor M {}; 822 823 void f(M & mutex a); 824 825 void g(M & mutex a, M & mutex b) { 826 waitfor( f, b ); 827 } 828 \end{cfacode} 829 830 This syntax is unambiguous. Both locks are acquired and kept. When routine \code{f} is called, the lock for monitor \code{b} is temporarily transferred from \code{g} to \code{f} (while \code{g} still holds lock \code{a}). This behavior can be extended to multi-monitor waitfor statement as follows. 831 832 \begin{cfacode} 833 monitor M {}; 834 835 void f(M & mutex a, M & mutex b); 836 837 void g(M & mutex a, M & mutex b) { 838 waitfor( f, a, b); 839 } 840 \end{cfacode} 841 842 Note that the set of monitors passed to the \code{waitfor} statement must be entirely contained in the set of monitors already acquired in the routine. \code{waitfor} used in any other context is Undefined Behaviour. 843 844 An important behavior to note is that what happens when a set of monitors only match partially : 845 846 \begin{cfacode} 847 mutex struct A {}; 848 849 mutex struct B {}; 850 851 void g(A & mutex a, B & mutex b) { 852 waitfor(f, a, b); 853 } 854 855 A a1, a2; 856 B b; 857 858 void foo() { 859 g(a1, b); //block on accept 860 } 861 862 void bar() { 863 f(a2, b); //fufill cooperation 864 } 865 \end{cfacode} 866 867 While the equivalent can happen when using internal scheduling, the fact that conditions are specific to a set of monitors means that users have to use two different condition variables. In both cases, partially matching monitor sets does not wake-up the waiting thread. It is also important to note that in the case of external scheduling, as for routine calls, the order of parameters is important; \code{waitfor(f,a,b)} and \code{waitfor(f,b,a)} are to distinct waiting condition. 868 869 % ====================================================================== 870 % ====================================================================== 871 \subsection{\code{waitfor} semantics} 872 % ====================================================================== 873 % ====================================================================== 874 875 Syntactically, the \code{waitfor} statement takes a function identifier and a set of monitors. While the set of monitors can be any list of expression, the function name is more restricted. This is because the compiler validates at compile time the validity of the waitfor statement. It checks that the set of monitor passed in matches the requirements for a function call. Listing \ref{lst:waitfor} shows various usage of the waitfor statement and which are acceptable. The choice of the function type is made ignoring any non-\code{mutex} parameter. One limitation of the current implementation is that it does not handle overloading. 876 \begin{figure} 877 \begin{cfacode} 878 monitor A{}; 879 monitor B{}; 880 881 void f1( A & mutex ); 882 void f2( A & mutex, B & mutex ); 883 void f3( A & mutex, int ); 884 void f4( A & mutex, int ); 885 void f4( A & mutex, double ); 886 887 void foo( A & mutex a1, A & mutex a2, B & mutex b1, B & b2 ) { 888 A * ap = & a1; 889 void (*fp)( A & mutex ) = f1; 890 891 waitfor(f1, a1); //Correct : 1 monitor case 892 waitfor(f2, a1, b1); //Correct : 2 monitor case 893 waitfor(f3, a1); //Correct : non-mutex arguments are ignored 894 waitfor(f1, *ap); //Correct : expression as argument 895 896 waitfor(f1, a1, b1); //Incorrect : Too many mutex arguments 897 waitfor(f2, a1); //Incorrect : Too few mutex arguments 898 waitfor(f2, a1, a2); //Incorrect : Mutex arguments don't match 899 waitfor(f1, 1); //Incorrect : 1 not a mutex argument 900 waitfor(f4, a1); //Incorrect : f9 not a function 901 waitfor(*fp, a1 ); //Incorrect : fp not a identifier 902 waitfor(f4, a1); //Incorrect : f4 ambiguous 903 904 waitfor(f2, a1, b2); //Undefined Behaviour : b2 may not acquired 905 } 906 \end{cfacode} 907 \caption{Various correct and incorrect uses of the waitfor statement} 908 \label{lst:waitfor} 909 \end{figure} 910 911 Finally, for added flexibility, \CFA supports constructing complex waitfor mask using the \code{or}, \code{timeout} and \code{else}. Indeed, multiple \code{waitfor} can be chained together using \code{or}; this chain will form a single statement which will baton-pass to any one function that fits one of the function+monitor set which was passed in. To eanble users to tell which was the accepted function, \code{waitfor}s are followed by a statement (including the null statement \code{;}) or a compound statement. When multiple \code{waitfor} are chained together, only the statement corresponding to the accepted function is executed. A \code{waitfor} chain can also be followed by a \code{timeout}, to signify an upper bound on the wait, or an \code{else}, to signify that the call should be non-blocking, that is only check of a matching function already arrived and return immediately otherwise. Any and all of these clauses can be preceded by a \code{when} condition to dynamically construct the mask based on some current state. Listing \ref{lst:waitfor2}, demonstrates several complex masks and some incorrect ones. 912 913 \begin{figure} 914 \begin{cfacode} 915 monitor A{}; 916 917 void f1( A & mutex ); 918 void f2( A & mutex ); 919 920 void foo( A & mutex a, bool b, int t ) { 921 //Correct : blocking case 922 waitfor(f1, a); 923 924 //Correct : block with statement 925 waitfor(f1, a) { 926 sout | "f1" | endl; 927 } 928 929 //Correct : block waiting for f1 or f2 930 waitfor(f1, a) { 931 sout | "f1" | endl; 932 } or waitfor(f2, a) { 933 sout | "f2" | endl; 934 } 935 936 //Correct : non-blocking case 937 waitfor(f1, a); or else; 938 939 //Correct : non-blocking case 940 waitfor(f1, a) { 941 sout | "blocked" | endl; 942 } or else { 943 sout | "didn't block" | endl; 944 } 945 946 //Correct : block at most 10 seconds 947 waitfor(f1, a) { 948 sout | "blocked" | endl; 949 } or timeout( 10`s) { 950 sout | "didn't block" | endl; 951 } 952 953 //Correct : block only if b == true 954 //if b == false, don't even make the call 955 when(b) waitfor(f1, a); 956 957 //Correct : block only if b == true 958 //if b == false, make non-blocking call 959 waitfor(f1, a); or when(!b) else; 960 961 //Correct : block only of t > 1 962 waitfor(f1, a); or when(t > 1) timeout(t); or else; 963 964 //Incorrect : timeout clause is dead code 965 waitfor(f1, a); or timeout(t); or else; 966 967 //Incorrect : order must be 968 //waitfor [or waitfor... [or timeout] [or else]] 969 timeout(t); or waitfor(f1, a); or else; 970 } 971 \end{cfacode} 972 \caption{Various correct and incorrect uses of the or, else, and timeout clause around a waitfor statement} 973 \label{lst:waitfor2} 974 \end{figure} -
doc/proposals/concurrency/text/intro.tex
rb96ec83 r6840e7c 3 3 % ====================================================================== 4 4 5 This proposal provides a minimal concurrency API that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of the concurrency, in \CFA. Indeed, for highly productive parallel programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. Therefore a high-level approach is adapted in \CFA5 This thesis provides a minimal concurrency \acrshort{api} that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of concurrency. Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. The high-level approach and its minimal \acrshort{api} are tested in a dialect of C, call \CFA. [Is there value to say that this thesis is also an early definition of the \CFA language and library in regards to concurrency?] 6 6 7 There are actually two problems that need to be solved in the design of concurrency for a programming language: which concurrency and which parallelism tools are available to the users. While these two concepts are often combined, they are in fact distinct concepts that requiredifferent tools~\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization, while parallelism tools are about performance, cost and resource utilization.7 There are actually two problems that need to be solved in the design of concurrency for a programming language: which concurrency and which parallelism tools are available to the programmer. While these two concepts are often combined, they are in fact distinct, requiring different tools~\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization, while parallelism tools are about performance, cost and resource utilization. -
doc/proposals/concurrency/text/parallelism.tex
rb96ec83 r6840e7c 11 11 \section{Paradigm} 12 12 \subsection{User-level threads} 13 A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provide but can be used on a much larger scale. This approach is the most powerfull solution as it allows all the features of multi-threading, while removing several of the more expensive s costs of using kernel threads. The down side is that almost none of the low-level threading problems are hidden,users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong garantees but the parallelism toolkit offers very little to reduce complexity in itself.13 A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provide but can be used on a much larger scale. This approach is the most powerfull solution as it allows all the features of multi-threading, while removing several of the more expensive costs of kernel threads. The down side is that almost none of the low-level threading problems are hidden; users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong garantees but the parallelism toolkit offers very little to reduce complexity in itself. 14 14 15 15 Examples of languages that support \glspl{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}. 16 16 17 17 \subsection{Fibers : user-level threads without preemption} 18 A popular varient of \glspl{uthread} is what is often ref fered to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantical differences with \glspl{uthread}. Advocates of \glspl{fiber} list their high performance and ease of implementation as majors strenghts of \glspl{fiber} but the performance difference between \glspl{uthread} and \glspl{fiber} is controversialand the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignore fibers.18 A popular varient of \glspl{uthread} is what is often refered to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantical differences with \glspl{uthread}. Advocates of \glspl{fiber} list their high performance and ease of implementation as majors strenghts of \glspl{fiber} but the performance difference between \glspl{uthread} and \glspl{fiber} is controversial, and the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignore fibers. 19 19 20 20 An example of a language that uses fibers is Go~\cite{Go} 21 21 22 22 \subsection{Jobs and thread pools} 23 The approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly limitsthe interaction that can occur among jobs. Indeed, any \gls{job} that blocks also blocks the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant amount of blocked jobs always results in idles cores.23 An approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work, called jobs, and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly limit the interaction that can occur among jobs. Indeed, any \gls{job} that blocks also blocks the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant amount of blocked jobs always results in idles cores. 24 24 25 25 The gold standard of this implementation is Intel's TBB library~\cite{TBB}. 26 26 27 27 \subsection{Paradigm performance} 28 While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pindown the performance implications of chosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantess that the \gls{pool} based system has the best performance thanks to the lower memory overhead . However, interactions between jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilisation, but context switches will be more expansive and the extra control means users need to tweak more variables to get the desired performance. Furthermore, if the units of uninterrupted work are large enough the paradigm choice is largely amorticised by the actual work done.28 While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pindown the performance implications of chosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantess that the \gls{pool} based system has the best performance thanks to the lower memory overhead (i.e., not thread stack per job). However, interactions among jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilisation, but a context switch is more expensive and the extra control means users need to tweak more variables to get the desired performance. Finally, if the units of uninterrupted work are large enough the paradigm choice is largely amortised by the actual work done. 29 29 30 \newpage31 30 \TODO 32 \subsection{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel} 31 32 \section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel} 33 33 34 34 35 \subsection{Future Work: Machine setup}\label{machine} 36 While this was not done in the context of this thesis, another important aspect of clusters is affinity. While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heteregenous setups. For example, system using \acrshort{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certains CPU cores. OS support for CPU affinity is now common \cit, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity. 37 35 38 \subsection{Paradigms}\label{cfaparadigms} 36 Given these building blocks we can then reproduce the all three of the popular paradigms. Indeed, we get \glspl{uthread} as the default paradigm in \CFA. However, disabling \glspl{preemption} on the \gls{cfacluster} means \glspl{cfathread} effectively become \glspl{fiber}. Since several \glspl{cfacluster} with different scheduling policy can coexist in the same application, this allows \glspl{fiber} and \glspl{uthread} to coexist in the runtime of an application. 37 38 % \subsection{High-level options}\label{tasks} 39 % 40 % \subsubsection{Thread interface} 41 % constructors destructors 42 % initializer lists 43 % monitors 44 % 45 % \subsubsection{Futures} 46 % 47 % \subsubsection{Implicit threading} 48 % Finally, simpler applications can benefit greatly from having implicit parallelism. That is, parallelism that does not rely on the user to write concurrency. This type of parallelism can be achieved both at the language level and at the system level. 49 % 50 % \begin{center} 51 % \begin{tabular}[t]{|c|c|c|} 52 % Sequential & System Parallel & Language Parallel \\ 53 % \begin{lstlisting} 54 % void big_sum(int* a, int* b, 55 % int* out, 56 % size_t length) 57 % { 58 % for(int i = 0; i < length; ++i ) { 59 % out[i] = a[i] + b[i]; 60 % } 61 % } 62 % 63 % 64 % 65 % 66 % 67 % int* a[10000]; 68 % int* b[10000]; 69 % int* c[10000]; 70 % //... fill in a and b ... 71 % big_sum(a, b, c, 10000); 72 % \end{lstlisting} &\begin{lstlisting} 73 % void big_sum(int* a, int* b, 74 % int* out, 75 % size_t length) 76 % { 77 % range ar(a, a + length); 78 % range br(b, b + length); 79 % range or(out, out + length); 80 % parfor( ai, bi, oi, 81 % [](int* ai, int* bi, int* oi) { 82 % oi = ai + bi; 83 % }); 84 % } 85 % 86 % int* a[10000]; 87 % int* b[10000]; 88 % int* c[10000]; 89 % //... fill in a and b ... 90 % big_sum(a, b, c, 10000); 91 % \end{lstlisting}&\begin{lstlisting} 92 % void big_sum(int* a, int* b, 93 % int* out, 94 % size_t length) 95 % { 96 % for (ai, bi, oi) in (a, b, out) { 97 % oi = ai + bi; 98 % } 99 % } 100 % 101 % 102 % 103 % 104 % 105 % int* a[10000]; 106 % int* b[10000]; 107 % int* c[10000]; 108 % //... fill in a and b ... 109 % big_sum(a, b, c, 10000); 110 % \end{lstlisting} 111 % \end{tabular} 112 % \end{center} 113 % 114 % \subsection{Machine setup}\label{machine} 115 % Threads are all good and well but wee still some OS support to fully utilize available hardware. 116 % 117 % \textbf{\large{Work in progress...}} Do wee need something beyond specifying the number of kernel threads? 39 Given these building blocks, it is possible to reproduce all three of the popular paradigms. Indeed, \glspl{uthread} is the default paradigm in \CFA. However, disabling \glspl{preemption} on the \gls{cfacluster} means \glspl{cfathread} effectively become \glspl{fiber}. Since several \glspl{cfacluster} with different scheduling policy can coexist in the same application, this allows \glspl{fiber} and \glspl{uthread} to coexist in the runtime of an application. Finally, it is possible to build executors for thread pools from \glspl{uthread} or \glspl{fiber}. -
doc/proposals/concurrency/thesis.tex
rb96ec83 r6840e7c 1 1 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 2 3 % inline code ©...©(copyright symbol) emacs: C-q M-)4 % red highlighting ®...®(registered trademark symbol) emacs: C-q M-.5 % blue highlighting ß...ß(sharp s symbol) emacs: C-q M-_6 % green highlighting ¢...¢(cent symbol) emacs: C-q M-"7 % LaTex escape §...§(section symbol) emacs: C-q M-'8 % keyword escape ¶...¶(pilcrow symbol) emacs: C-q M-^3 % inline code �...� (copyright symbol) emacs: C-q M-) 4 % red highlighting �...� (registered trademark symbol) emacs: C-q M-. 5 % blue highlighting �...� (sharp s symbol) emacs: C-q M-_ 6 % green highlighting �...� (cent symbol) emacs: C-q M-" 7 % LaTex escape �...� (section symbol) emacs: C-q M-' 8 % keyword escape �...� (pilcrow symbol) emacs: C-q M-^ 9 9 % math escape $...$ (dollar symbol) 10 10 … … 27 27 \usepackage{multicol} 28 28 \usepackage[acronym]{glossaries} 29 \usepackage{varioref} 29 \usepackage{varioref} 30 30 \usepackage{listings} % format program code 31 31 \usepackage[flushmargin]{footmisc} % support label/reference in footnote … … 70 70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 71 72 \setcounter{secnumdepth}{ 3} % number subsubsections73 \setcounter{tocdepth}{ 3} % subsubsections in table of contents72 \setcounter{secnumdepth}{2} % number subsubsections 73 \setcounter{tocdepth}{2} % subsubsections in table of contents 74 74 % \linenumbers % comment out to turn off line numbering 75 75 \makeindex … … 103 103 \input{parallelism} 104 104 105 \chapter{Putting it all together} 105 \input{internals} 106 107 \input{together} 108 109 \input{future} 106 110 107 111 \chapter{Conclusion} 108 109 \chapter{Future work}110 Concurrency and parallelism is still a very active field that strongly benefits from hardware advances. As such certain features that aren't necessarily mature enough in their current state could become relevant in the lifetime of \CFA.111 \subsection{Transactions}112 112 113 113 \section*{Acknowledgements} -
doc/proposals/concurrency/version
rb96ec83 r6840e7c 1 0. 9.1801 0.10.212 -
src/CodeGen/CodeGenerator.cc
rb96ec83 r6840e7c 287 287 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 288 288 assertf( ! genC, "TypeDecls should not reach code generation." ); 289 output << typeDecl->genTypeString() << " " << typeDecl-> get_name();290 if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl-> get_sized()) {291 output << " | sized(" << typeDecl-> get_name()<< ")";292 } 293 if ( ! typeDecl-> get_assertions().empty() ) {289 output << typeDecl->genTypeString() << " " << typeDecl->name; 290 if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->sized ) { 291 output << " | sized(" << typeDecl->name << ")"; 292 } 293 if ( ! typeDecl->assertions.empty() ) { 294 294 output << " | { "; 295 genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() ); 295 for ( DeclarationWithType * assert : typeDecl->assertions ) { 296 assert->accept( *visitor ); 297 output << "; "; 298 } 296 299 output << " }"; 297 300 } … … 946 949 output << ";"; 947 950 } 951 void CodeGenerator::postvisit( CatchStmt * stmt ) { 952 assertf( ! genC, "Catch statements should not reach code generation." ); 953 954 output << ((stmt->get_kind() == CatchStmt::Terminate) ? 955 "catch" : "catchResume"); 956 output << "( "; 957 stmt->decl->accept( *visitor ); 958 output << " ) "; 959 960 if( stmt->cond ) { 961 output << "if/when(?) ("; 962 stmt->cond->accept( *visitor ); 963 output << ") "; 964 } 965 stmt->body->accept( *visitor ); 966 } 967 968 void CodeGenerator::postvisit( WaitForStmt * stmt ) { 969 assertf( ! genC, "Waitfor statements should not reach code generation." ); 970 971 bool first = true; 972 for( auto & clause : stmt->clauses ) { 973 if(first) { output << "or "; first = false; } 974 if( clause.condition ) { 975 output << "when("; 976 stmt->timeout.condition->accept( *visitor ); 977 output << ") "; 978 } 979 output << "waitfor("; 980 clause.target.function->accept( *visitor ); 981 for( Expression * expr : clause.target.arguments ) { 982 output << ","; 983 expr->accept( *visitor ); 984 } 985 output << ") "; 986 clause.statement->accept( *visitor ); 987 } 988 989 if( stmt->timeout.statement ) { 990 output << "or "; 991 if( stmt->timeout.condition ) { 992 output << "when("; 993 stmt->timeout.condition->accept( *visitor ); 994 output << ") "; 995 } 996 output << "timeout("; 997 stmt->timeout.time->accept( *visitor ); 998 output << ") "; 999 stmt->timeout.statement->accept( *visitor ); 1000 } 1001 1002 if( stmt->orelse.statement ) { 1003 output << "or "; 1004 if( stmt->orelse.condition ) { 1005 output << "when("; 1006 stmt->orelse.condition->accept( *visitor ); 1007 output << ")"; 1008 } 1009 output << "else "; 1010 stmt->orelse.statement->accept( *visitor ); 1011 } 1012 } 1013 948 1014 949 1015 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { … … 1024 1090 } 1025 1091 } // namespace CodeGen 1092 1093 1094 unsigned Indenter::tabsize = 2; 1026 1095 1027 1096 std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) { -
src/CodeGen/CodeGenerator.h
rb96ec83 r6840e7c 100 100 void postvisit( ReturnStmt * ); 101 101 void postvisit( ThrowStmt * ); 102 void postvisit( CatchStmt * ); 103 void postvisit( WaitForStmt * ); 102 104 void postvisit( WhileStmt * ); 103 105 void postvisit( ForStmt * ); -
src/CodeGen/FixNames.cc
rb96ec83 r6840e7c 66 66 ); 67 67 68 main Decl->get_functionType()->get_parameters().push_back(68 main_type->get_parameters().push_back( 69 69 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 70 70 ); 71 71 72 main Decl->get_functionType()->get_parameters().push_back(72 main_type->get_parameters().push_back( 73 73 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 74 74 new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), -
src/CodeGen/GenType.cc
rb96ec83 r6840e7c 210 210 211 211 std::string GenType::handleGeneric( ReferenceToType * refType ) { 212 if ( ! refType-> get_parameters().empty() ) {212 if ( ! refType->parameters.empty() ) { 213 213 std::ostringstream os; 214 214 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 215 215 os << "("; 216 cg.pass.genCommaList( refType-> get_parameters().begin(), refType->get_parameters().end() );216 cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() ); 217 217 os << ") "; 218 218 return os.str(); -
src/Common/Indenter.h
rb96ec83 r6840e7c 18 18 19 19 struct Indenter { 20 Indenter( unsigned int amt = 2 ) : amt( amt ) {} 21 unsigned int amt = 2; // amount 1 level increases indent by (i.e. how much to increase by in operator++) 22 unsigned int indent = 0; 20 static unsigned tabsize; 21 22 Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {} 23 unsigned int amt; // amount 1 level increases indent by (i.e. how much to increase by in operator++) 24 unsigned int indent; 23 25 24 26 Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; } … … 30 32 }; 31 33 32 inline std::ostream & operator<<( std::ostream & out, Indenter & indent ) {34 inline std::ostream & operator<<( std::ostream & out, const Indenter & indent ) { 33 35 return out << std::string(indent.indent, ' '); 34 36 } -
src/Common/PassVisitor.h
rb96ec83 r6840e7c 4 4 5 5 #include <stack> 6 7 #include "Common/utility.h" 6 8 7 9 #include "SynTree/Mutator.h" … … 236 238 virtual Attribute * mutate( Attribute * attribute ) override final; 237 239 240 virtual TypeSubstitution * mutate( TypeSubstitution * sub ) final; 241 238 242 private: 239 243 template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 240 244 template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 245 template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor ); 246 template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator ); 247 template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor ); 248 template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator ); 241 249 242 250 template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); } … … 273 281 std::list< Declaration* > * get_afterDecls () { return declsToAddAfter_impl ( pass, 0); } 274 282 275 void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); } 283 bool get_visit_children () { bool_ref * ptr = visit_children_impl(pass, 0); return ptr ? *ptr : true; } 284 bool_ref * get_visit_children_ptr() { return visit_children_impl(pass, 0); } 276 285 277 286 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } -
src/Common/PassVisitor.impl.h
rb96ec83 r6840e7c 2 2 // IWYU pragma: private, include "PassVisitor.h" 3 3 4 #define VISIT_START( node ) \ 5 __attribute__((unused)) \ 4 #define VISIT_START( node ) \ 5 __attribute__((unused)) \ 6 ChildrenGuard children_guard( get_visit_children_ptr() ); \ 7 __attribute__((unused)) \ 6 8 guard_value_impl guard( at_cleanup_impl(pass, 0) ); \ 7 bool visit_children = true; \ 8 set_visit_children( visit_children ); \ 9 call_previsit( node ); \ 10 if( visit_children ) { \ 9 call_previsit( node ); \ 11 10 12 11 #define VISIT_END( node ) \ 13 } \14 12 call_postvisit( node ); \ 15 13 16 #define MUTATE_START( node ) \ 17 __attribute__((unused)) \ 14 #define MUTATE_START( node ) \ 15 __attribute__((unused)) \ 16 ChildrenGuard children_guard( get_visit_children_ptr() ); \ 17 __attribute__((unused)) \ 18 18 guard_value_impl guard( at_cleanup_impl(pass, 0) ); \ 19 bool visit_children = true; \ 20 set_visit_children( visit_children ); \ 21 call_premutate( node ); \ 22 if( visit_children ) { \ 19 call_premutate( node ); \ 23 20 24 21 #define MUTATE_END( type, node ) \ 25 } \26 22 return call_postmutate< type * >( node ); \ 27 23 28 24 29 #define VISIT_BODY( node ) \ 30 VISIT_START( node ); \ 31 Visitor::visit( node ); \ 32 VISIT_END( node ); \ 33 34 35 #define MUTATE_BODY( type, node ) \ 36 MUTATE_START( node ); \ 37 Mutator::mutate( node ); \ 38 MUTATE_END( type, node ); \ 25 #define VISIT_BODY( node ) \ 26 VISIT_START( node ); \ 27 if( children_guard ) { \ 28 Visitor::visit( node ); \ 29 } \ 30 VISIT_END( node ); \ 31 32 33 #define MUTATE_BODY( type, node ) \ 34 MUTATE_START( node ); \ 35 if( children_guard ) { \ 36 Mutator::mutate( node ); \ 37 } \ 38 MUTATE_END( type, node ); \ 39 39 40 40 … … 63 63 template< typename pass_type > 64 64 static inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) { 65 66 65 DeclList_t* beforeDecls = visitor.get_beforeDecls(); 67 66 DeclList_t* afterDecls = visitor.get_afterDecls(); … … 76 75 try { 77 76 // run visitor on declaration 78 maybeAccept ( *i, visitor );77 maybeAccept_impl( *i, visitor ); 79 78 } catch( SemanticError &e ) { 80 79 e.set_location( (*i)->location ); … … 92 91 template< typename pass_type > 93 92 static inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) { 94 95 93 DeclList_t* beforeDecls = mutator.get_beforeDecls(); 96 94 DeclList_t* afterDecls = mutator.get_afterDecls(); … … 104 102 try { 105 103 // run mutator on declaration 106 *i = maybeMutate( *i, mutator );104 maybeMutate_impl( *i, mutator ); 107 105 } catch( SemanticError &e ) { 108 106 e.set_location( (*i)->location ); … … 118 116 } 119 117 120 template< typename Container, typename VisitorType > 121 inline void maybeAccept( Container &container, VisitorType &visitor ) { 118 template< typename TreeType, typename pass_type > 119 inline void maybeAccept_impl( TreeType * tree, PassVisitor< pass_type > & visitor ) { 120 if ( ! visitor.get_visit_children() ) return; 121 if ( tree ) { 122 tree->accept( visitor ); 123 } 124 } 125 126 template< typename Container, typename pass_type > 127 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) { 128 if ( ! visitor.get_visit_children() ) return; 122 129 SemanticError errors; 123 130 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { … … 136 143 } 137 144 138 template< typename Container, typename MutatorType > 139 inline void maybeMutateRef( Container &container, MutatorType &mutator ) { 145 template< typename TreeType, typename pass_type > 146 inline void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_type > & mutator ) { 147 if ( ! mutator.get_visit_children() ) return; 148 149 if ( tree ) { 150 tree = strict_dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) ); 151 } 152 } 153 154 template< typename Container, typename pass_type > 155 inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) { 156 if ( ! mutator.get_visit_children() ) return; 140 157 SemanticError errors; 141 158 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 142 159 try { 143 160 if ( *i ) { 144 /// *i = (*i)->acceptMutator( mutator );145 161 *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) ); 146 162 assert( *i ); … … 159 175 template< typename func_t > 160 176 void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) { 177 if ( ! get_visit_children() ) return; 161 178 SemanticError errors; 162 179 … … 199 216 void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) { 200 217 handleStatementList( statements, [this]( Statement * stmt) { 201 stmt->accept(*this );218 maybeAccept_impl( stmt, *this ); 202 219 }); 203 220 } … … 206 223 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { 207 224 handleStatementList( statements, [this]( Statement *& stmt) { 208 stmt = stmt->acceptMutator(*this );225 maybeMutate_impl( stmt, *this ); 209 226 }); 210 227 } … … 214 231 template< typename func_t > 215 232 Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) { 233 if ( ! get_visit_children() ) return stmt; 234 216 235 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 217 236 ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr () ); … … 244 263 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) { 245 264 return handleStatement( stmt, [this]( Statement * stmt ) { 246 maybeAccept ( stmt, *this );265 maybeAccept_impl( stmt, *this ); 247 266 return stmt; 248 267 }); … … 252 271 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { 253 272 return handleStatement( stmt, [this]( Statement * stmt ) { 254 return maybeMutate( stmt, *this ); 273 maybeMutate_impl( stmt, *this ); 274 return stmt; 255 275 }); 256 276 } … … 259 279 template< typename func_t > 260 280 Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) { 281 if ( ! get_visit_children() ) return expr; 261 282 if( !expr ) return nullptr; 262 283 … … 266 287 } 267 288 268 // should env be cloned (or moved)onto the result of the mutate?289 // should env be moved onto the result of the mutate? 269 290 return func( expr ); 270 291 } … … 273 294 Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) { 274 295 return handleExpression(expr, [this]( Expression * expr ) { 275 expr->accept(*this );296 maybeAccept_impl( expr, *this ); 276 297 return expr; 277 298 }); … … 281 302 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { 282 303 return handleExpression(expr, [this]( Expression * expr ) { 283 return expr->acceptMutator( *this ); 304 maybeMutate_impl( expr, *this ); 305 return expr; 284 306 }); 307 } 308 309 template< typename TreeType, typename VisitorType > 310 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) { 311 if ( ! visitor.get_visit_children() ) return; 312 auto guard = makeFuncGuard( 313 [&visitor]() { visitor.indexerScopeEnter(); }, 314 [&visitor]() { visitor.indexerScopeLeave(); } 315 ); 316 maybeAccept_impl( tree, visitor ); 317 } 318 319 template< typename TreeType, typename MutatorType > 320 inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) { 321 if ( ! mutator.get_visit_children() ) return; 322 auto guard = makeFuncGuard( 323 [&mutator]() { mutator.indexerScopeEnter(); }, 324 [&mutator]() { mutator.indexerScopeLeave(); } 325 ); 326 maybeMutate_impl( tree, mutator ); 285 327 } 286 328 … … 319 361 320 362 indexerScopedAccept( node->type , *this ); 321 maybeAccept 322 maybeAccept 323 maybeAccept 363 maybeAccept_impl ( node->init , *this ); 364 maybeAccept_impl ( node->bitfieldWidth, *this ); 365 maybeAccept_impl ( node->attributes , *this ); 324 366 325 367 if ( node->name != "" ) { … … 335 377 336 378 indexerScopedMutate( node->type , *this ); 337 maybeMutate Ref( node->init , *this );338 maybeMutate Ref( node->bitfieldWidth, *this );339 maybeMutate Ref( node->attributes , *this );379 maybeMutate_impl ( node->init , *this ); 380 maybeMutate_impl ( node->bitfieldWidth, *this ); 381 maybeMutate_impl ( node->attributes , *this ); 340 382 341 383 if ( node->name != "" ) { … … 358 400 { 359 401 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 360 maybeAccept ( node->type, *this );361 maybeAccept ( node->statements, *this );362 maybeAccept ( node->attributes, *this );402 maybeAccept_impl( node->type, *this ); 403 maybeAccept_impl( node->statements, *this ); 404 maybeAccept_impl( node->attributes, *this ); 363 405 } 364 406 … … 376 418 { 377 419 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 378 maybeMutate Ref( node->type, *this );379 maybeMutate Ref( node->statements, *this );380 maybeMutate Ref( node->attributes, *this );420 maybeMutate_impl( node->type, *this ); 421 maybeMutate_impl( node->statements, *this ); 422 maybeMutate_impl( node->attributes, *this ); 381 423 } 382 424 … … 396 438 { 397 439 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 398 maybeAccept ( node->parameters, *this );399 maybeAccept ( node->members , *this );440 maybeAccept_impl( node->parameters, *this ); 441 maybeAccept_impl( node->members , *this ); 400 442 } 401 443 … … 416 458 { 417 459 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 418 maybeMutate Ref( node->parameters, *this );419 maybeMutate Ref( node->members , *this );460 maybeMutate_impl( node->parameters, *this ); 461 maybeMutate_impl( node->members , *this ); 420 462 } 421 463 … … 437 479 { 438 480 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 439 maybeAccept ( node->parameters, *this );440 maybeAccept ( node->members , *this );481 maybeAccept_impl( node->parameters, *this ); 482 maybeAccept_impl( node->members , *this ); 441 483 } 442 484 … … 455 497 { 456 498 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 457 maybeMutate Ref( node->parameters, *this );458 maybeMutate Ref( node->members , *this );499 maybeMutate_impl( node->parameters, *this ); 500 maybeMutate_impl( node->members , *this ); 459 501 } 460 502 … … 473 515 474 516 // unlike structs, traits, and unions, enums inject their members into the global scope 475 maybeAccept ( node->parameters, *this );476 maybeAccept ( node->members , *this );517 maybeAccept_impl( node->parameters, *this ); 518 maybeAccept_impl( node->members , *this ); 477 519 478 520 VISIT_END( node ); … … 486 528 487 529 // unlike structs, traits, and unions, enums inject their members into the global scope 488 maybeMutate Ref( node->parameters, *this );489 maybeMutate Ref( node->members , *this );530 maybeMutate_impl( node->parameters, *this ); 531 maybeMutate_impl( node->members , *this ); 490 532 491 533 MUTATE_END( Declaration, node ); … … 500 542 { 501 543 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 502 maybeAccept ( node->parameters, *this );503 maybeAccept ( node->members , *this );544 maybeAccept_impl( node->parameters, *this ); 545 maybeAccept_impl( node->members , *this ); 504 546 } 505 547 … … 515 557 { 516 558 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 517 maybeMutate Ref( node->parameters, *this );518 maybeMutate Ref( node->members , *this );559 maybeMutate_impl( node->parameters, *this ); 560 maybeMutate_impl( node->members , *this ); 519 561 } 520 562 … … 532 574 { 533 575 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 534 maybeAccept ( node->parameters, *this );535 maybeAccept ( node->base , *this );576 maybeAccept_impl( node->parameters, *this ); 577 maybeAccept_impl( node->base , *this ); 536 578 } 537 579 … … 541 583 indexerAddType( node ); 542 584 543 maybeAccept ( node->assertions, *this );585 maybeAccept_impl( node->assertions, *this ); 544 586 545 587 indexerScopedAccept( node->init, *this ); … … 554 596 { 555 597 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 556 maybeMutate Ref( node->parameters, *this );557 maybeMutate Ref( node->base , *this );598 maybeMutate_impl( node->parameters, *this ); 599 maybeMutate_impl( node->base , *this ); 558 600 } 559 601 … … 563 605 indexerAddType( node ); 564 606 565 maybeMutate Ref( node->assertions, *this );607 maybeMutate_impl( node->assertions, *this ); 566 608 567 609 indexerScopedMutate( node->init, *this ); … … 578 620 { 579 621 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 580 maybeAccept ( node->parameters, *this );581 maybeAccept ( node->base , *this );622 maybeAccept_impl( node->parameters, *this ); 623 maybeAccept_impl( node->base , *this ); 582 624 } 583 625 584 626 indexerAddType( node ); 585 627 586 maybeAccept ( node->assertions, *this );628 maybeAccept_impl( node->assertions, *this ); 587 629 588 630 VISIT_END( node ); … … 595 637 { 596 638 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 597 maybeMutate Ref( node->parameters, *this );598 maybeMutate Ref( node->base , *this );639 maybeMutate_impl( node->parameters, *this ); 640 maybeMutate_impl( node->base , *this ); 599 641 } 600 642 601 643 indexerAddType( node ); 602 644 603 maybeMutate Ref( node->assertions, *this );645 maybeMutate_impl( node->assertions, *this ); 604 646 605 647 MUTATE_END( Declaration, node ); … … 612 654 VISIT_START( node ); 613 655 614 maybeAccept ( node->stmt, *this );656 maybeAccept_impl( node->stmt, *this ); 615 657 616 658 VISIT_END( node ); … … 621 663 MUTATE_START( node ); 622 664 623 maybeMutate Ref( node->stmt, *this );665 maybeMutate_impl( node->stmt, *this ); 624 666 625 667 MUTATE_END( AsmDecl, node ); … … 690 732 // if statements introduce a level of scope (for the initialization) 691 733 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 692 acceptAll( node->get_initialization(), *this );693 visitExpression ( node->condition );734 maybeAccept_impl( node->get_initialization(), *this ); 735 visitExpression ( node->condition ); 694 736 node->thenPart = visitStatement( node->thenPart ); 695 737 node->elsePart = visitStatement( node->elsePart ); … … 704 746 // if statements introduce a level of scope (for the initialization) 705 747 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 706 maybeMutate Ref( node->get_initialization(), *this );748 maybeMutate_impl( node->get_initialization(), *this ); 707 749 node->condition = mutateExpression( node->condition ); 708 750 node->thenPart = mutateStatement ( node->thenPart ); … … 742 784 // for statements introduce a level of scope (for the initialization) 743 785 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 744 maybeAccept ( node->initialization, *this );786 maybeAccept_impl( node->initialization, *this ); 745 787 visitExpression( node->condition ); 746 788 visitExpression( node->increment ); … … 756 798 // for statements introduce a level of scope (for the initialization) 757 799 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 758 maybeMutate Ref( node->initialization, *this );800 maybeMutate_impl( node->initialization, *this ); 759 801 node->condition = mutateExpression( node->condition ); 760 802 node->increment = mutateExpression( node->increment ); … … 859 901 VISIT_START( node ); 860 902 861 maybeAccept ( node->block , *this );862 maybeAccept ( node->handlers , *this );863 maybeAccept ( node->finallyBlock, *this );903 maybeAccept_impl( node->block , *this ); 904 maybeAccept_impl( node->handlers , *this ); 905 maybeAccept_impl( node->finallyBlock, *this ); 864 906 865 907 VISIT_END( node ); … … 870 912 MUTATE_START( node ); 871 913 872 maybeMutate Ref( node->block , *this );873 maybeMutate Ref( node->handlers , *this );874 maybeMutate Ref( node->finallyBlock, *this );914 maybeMutate_impl( node->block , *this ); 915 maybeMutate_impl( node->handlers , *this ); 916 maybeMutate_impl( node->finallyBlock, *this ); 875 917 876 918 MUTATE_END( Statement, node ); … … 885 927 // catch statements introduce a level of scope (for the caught exception) 886 928 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 887 maybeAccept ( node->decl, *this );929 maybeAccept_impl( node->decl, *this ); 888 930 node->cond = visitExpression( node->cond ); 889 931 node->body = visitStatement ( node->body ); … … 898 940 // catch statements introduce a level of scope (for the caught exception) 899 941 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 900 maybeMutate Ref( node->decl, *this );942 maybeMutate_impl( node->decl, *this ); 901 943 node->cond = mutateExpression( node->cond ); 902 944 node->body = mutateStatement ( node->body ); … … 972 1014 973 1015 indexerScopedAccept( node->result , *this ); 974 maybeAccept ( node->function, *this );975 maybeAccept ( node->args , *this );1016 maybeAccept_impl ( node->function, *this ); 1017 maybeAccept_impl ( node->args , *this ); 976 1018 977 1019 VISIT_END( node ); … … 984 1026 indexerScopedMutate( node->env , *this ); 985 1027 indexerScopedMutate( node->result , *this ); 986 maybeMutate Ref( node->function, *this );987 maybeMutate Ref( node->args , *this );1028 maybeMutate_impl ( node->function, *this ); 1029 maybeMutate_impl ( node->args , *this ); 988 1030 989 1031 MUTATE_END( Expression, node ); … … 996 1038 VISIT_START( node ); 997 1039 998 // maybeAccept ( node->get_env(), *this );1040 // maybeAccept_impl( node->get_env(), *this ); 999 1041 indexerScopedAccept( node->result, *this ); 1000 1042 … … 1048 1090 1049 1091 indexerScopedAccept( node->result, *this ); 1050 maybeAccept ( node->arg , *this );1092 maybeAccept_impl ( node->arg , *this ); 1051 1093 1052 1094 VISIT_END( node ); … … 1059 1101 indexerScopedMutate( node->env , *this ); 1060 1102 indexerScopedMutate( node->result, *this ); 1061 maybeMutate Ref( node->arg , *this );1103 maybeMutate_impl ( node->arg , *this ); 1062 1104 1063 1105 MUTATE_END( Expression, node ); … … 1071 1113 1072 1114 indexerScopedAccept( node->result, *this ); 1073 maybeAccept ( node->arg, *this );1115 maybeAccept_impl( node->arg, *this ); 1074 1116 1075 1117 VISIT_END( node ); … … 1082 1124 indexerScopedMutate( node->env , *this ); 1083 1125 indexerScopedMutate( node->result, *this ); 1084 maybeMutate Ref( node->arg , *this );1126 maybeMutate_impl ( node->arg , *this ); 1085 1127 1086 1128 MUTATE_END( Expression, node ); … … 1094 1136 1095 1137 indexerScopedAccept( node->result, *this ); 1096 maybeAccept 1138 maybeAccept_impl ( node->arg , *this ); 1097 1139 1098 1140 VISIT_END( node ); … … 1105 1147 indexerScopedMutate( node->env , *this ); 1106 1148 indexerScopedMutate( node->result, *this ); 1107 maybeMutate Ref( node->arg , *this );1149 maybeMutate_impl ( node->arg , *this ); 1108 1150 1109 1151 MUTATE_END( Expression, node ); … … 1138 1180 1139 1181 indexerScopedAccept( node->result , *this ); 1140 maybeAccept 1141 maybeAccept 1182 maybeAccept_impl ( node->aggregate, *this ); 1183 maybeAccept_impl ( node->member , *this ); 1142 1184 1143 1185 VISIT_END( node ); … … 1150 1192 indexerScopedMutate( node->env , *this ); 1151 1193 indexerScopedMutate( node->result , *this ); 1152 maybeMutate Ref( node->aggregate, *this );1153 maybeMutate Ref( node->member , *this );1194 maybeMutate_impl ( node->aggregate, *this ); 1195 maybeMutate_impl ( node->member , *this ); 1154 1196 1155 1197 MUTATE_END( Expression, node ); … … 1163 1205 1164 1206 indexerScopedAccept( node->result , *this ); 1165 maybeAccept 1207 maybeAccept_impl ( node->aggregate, *this ); 1166 1208 1167 1209 VISIT_END( node ); … … 1174 1216 indexerScopedMutate( node->env , *this ); 1175 1217 indexerScopedMutate( node->result , *this ); 1176 maybeMutate Ref( node->aggregate, *this );1218 maybeMutate_impl ( node->aggregate, *this ); 1177 1219 1178 1220 MUTATE_END( Expression, node ); … … 1207 1249 1208 1250 indexerScopedAccept( node->result , *this ); 1209 maybeAccept 1251 maybeAccept_impl ( &node->constant, *this ); 1210 1252 1211 1253 VISIT_END( node ); … … 1218 1260 indexerScopedMutate( node->env , *this ); 1219 1261 indexerScopedMutate( node->result, *this ); 1220 node->constant = *maybeMutate( &node->constant, *this ); 1262 Constant * ptr = &node->constant; 1263 maybeMutate_impl( ptr, *this ); 1264 node->constant = *ptr; 1221 1265 1222 1266 MUTATE_END( Expression, node ); … … 1231 1275 indexerScopedAccept( node->result, *this ); 1232 1276 if ( node->get_isType() ) { 1233 maybeAccept ( node->type, *this );1277 maybeAccept_impl( node->type, *this ); 1234 1278 } else { 1235 maybeAccept ( node->expr, *this );1279 maybeAccept_impl( node->expr, *this ); 1236 1280 } 1237 1281 … … 1246 1290 indexerScopedMutate( node->result, *this ); 1247 1291 if ( node->get_isType() ) { 1248 maybeMutate Ref( node->type, *this );1292 maybeMutate_impl( node->type, *this ); 1249 1293 } else { 1250 maybeMutate Ref( node->expr, *this );1294 maybeMutate_impl( node->expr, *this ); 1251 1295 } 1252 1296 … … 1262 1306 indexerScopedAccept( node->result, *this ); 1263 1307 if ( node->get_isType() ) { 1264 maybeAccept ( node->type, *this );1308 maybeAccept_impl( node->type, *this ); 1265 1309 } else { 1266 maybeAccept ( node->expr, *this );1310 maybeAccept_impl( node->expr, *this ); 1267 1311 } 1268 1312 … … 1277 1321 indexerScopedMutate( node->result, *this ); 1278 1322 if ( node->get_isType() ) { 1279 maybeMutate Ref( node->type, *this );1323 maybeMutate_impl( node->type, *this ); 1280 1324 } else { 1281 maybeMutate Ref( node->expr, *this );1325 maybeMutate_impl( node->expr, *this ); 1282 1326 } 1283 1327 … … 1292 1336 1293 1337 indexerScopedAccept( node->result, *this ); 1294 maybeAccept 1338 maybeAccept_impl ( node->type , *this ); 1295 1339 1296 1340 VISIT_END( node ); … … 1303 1347 indexerScopedMutate( node->env , *this ); 1304 1348 indexerScopedMutate( node->result, *this ); 1305 maybeMutate Ref( node->type , *this );1349 maybeMutate_impl ( node->type , *this ); 1306 1350 1307 1351 MUTATE_END( Expression, node ); … … 1315 1359 1316 1360 indexerScopedAccept( node->result, *this ); 1317 maybeAccept 1318 maybeAccept 1361 maybeAccept_impl ( node->type , *this ); 1362 maybeAccept_impl ( node->member, *this ); 1319 1363 1320 1364 VISIT_END( node ); … … 1327 1371 indexerScopedMutate( node->env , *this ); 1328 1372 indexerScopedMutate( node->result, *this ); 1329 maybeMutate Ref( node->type , *this );1330 maybeMutate Ref( node->member, *this );1373 maybeMutate_impl ( node->type , *this ); 1374 maybeMutate_impl ( node->member, *this ); 1331 1375 1332 1376 MUTATE_END( Expression, node ); … … 1340 1384 1341 1385 indexerScopedAccept( node->result, *this ); 1342 maybeAccept 1386 maybeAccept_impl ( node->type , *this ); 1343 1387 1344 1388 VISIT_END( node ); … … 1351 1395 indexerScopedMutate( node->env , *this ); 1352 1396 indexerScopedMutate( node->result, *this ); 1353 maybeMutate Ref( node->type , *this );1397 maybeMutate_impl ( node->type , *this ); 1354 1398 1355 1399 MUTATE_END( Expression, node ); … … 1364 1408 indexerScopedAccept( node->result, *this ); 1365 1409 if ( node->get_isType() ) { 1366 maybeAccept ( node->type, *this );1410 maybeAccept_impl( node->type, *this ); 1367 1411 } else { 1368 maybeAccept ( node->expr, *this );1412 maybeAccept_impl( node->expr, *this ); 1369 1413 } 1370 1414 … … 1379 1423 indexerScopedMutate( node->result, *this ); 1380 1424 if ( node->get_isType() ) { 1381 maybeMutate Ref( node->type, *this );1425 maybeMutate_impl( node->type, *this ); 1382 1426 } else { 1383 maybeMutate Ref( node->expr, *this );1427 maybeMutate_impl( node->expr, *this ); 1384 1428 } 1385 1429 … … 1394 1438 1395 1439 indexerScopedAccept( node->result, *this ); 1396 maybeAccept 1397 maybeAccept 1440 maybeAccept_impl ( node->arg1 , *this ); 1441 maybeAccept_impl ( node->arg2 , *this ); 1398 1442 1399 1443 VISIT_END( node ); … … 1406 1450 indexerScopedMutate( node->env , *this ); 1407 1451 indexerScopedMutate( node->result, *this ); 1408 maybeMutate Ref( node->arg1 , *this );1409 maybeMutate Ref( node->arg2 , *this );1452 maybeMutate_impl ( node->arg1 , *this ); 1453 maybeMutate_impl ( node->arg2 , *this ); 1410 1454 1411 1455 MUTATE_END( Expression, node ); … … 1419 1463 1420 1464 indexerScopedAccept( node->result, *this ); 1421 maybeAccept ( node->arg1 , *this );1422 maybeAccept ( node->arg2 , *this );1423 maybeAccept ( node->arg3 , *this );1465 maybeAccept_impl ( node->arg1 , *this ); 1466 maybeAccept_impl ( node->arg2 , *this ); 1467 maybeAccept_impl ( node->arg3 , *this ); 1424 1468 1425 1469 VISIT_END( node ); … … 1432 1476 indexerScopedMutate( node->env , *this ); 1433 1477 indexerScopedMutate( node->result, *this ); 1434 maybeMutate Ref( node->arg1 , *this );1435 maybeMutate Ref( node->arg2 , *this );1436 maybeMutate Ref( node->arg3 , *this );1478 maybeMutate_impl ( node->arg1 , *this ); 1479 maybeMutate_impl ( node->arg2 , *this ); 1480 maybeMutate_impl ( node->arg3 , *this ); 1437 1481 1438 1482 MUTATE_END( Expression, node ); … … 1446 1490 1447 1491 indexerScopedAccept( node->result, *this ); 1448 maybeAccept 1449 maybeAccept 1492 maybeAccept_impl ( node->arg1 , *this ); 1493 maybeAccept_impl ( node->arg2 , *this ); 1450 1494 1451 1495 VISIT_END( node ); … … 1458 1502 indexerScopedMutate( node->env , *this ); 1459 1503 indexerScopedMutate( node->result, *this ); 1460 maybeMutate Ref( node->arg1 , *this );1461 maybeMutate Ref( node->arg2 , *this );1504 maybeMutate_impl ( node->arg1 , *this ); 1505 maybeMutate_impl ( node->arg2 , *this ); 1462 1506 1463 1507 MUTATE_END( Expression, node ); … … 1471 1515 1472 1516 indexerScopedAccept( node->result, *this ); 1473 maybeAccept 1517 maybeAccept_impl ( node->type, *this ); 1474 1518 1475 1519 VISIT_END( node ); … … 1482 1526 indexerScopedMutate( node->env , *this ); 1483 1527 indexerScopedMutate( node->result, *this ); 1484 maybeMutate Ref( node->type , *this );1528 maybeMutate_impl ( node->type , *this ); 1485 1529 1486 1530 MUTATE_END( Expression, node ); … … 1494 1538 1495 1539 indexerScopedAccept( node->result , *this ); 1496 maybeAccept 1497 maybeAccept 1498 maybeAccept 1540 maybeAccept_impl ( node->inout , *this ); 1541 maybeAccept_impl ( node->constraint, *this ); 1542 maybeAccept_impl ( node->operand , *this ); 1499 1543 1500 1544 VISIT_END( node ); … … 1507 1551 indexerScopedMutate( node->env , *this ); 1508 1552 indexerScopedMutate( node->result , *this ); 1509 maybeMutate Ref( node->inout , *this );1510 maybeMutate Ref( node->constraint, *this );1511 maybeMutate Ref( node->operand , *this );1553 maybeMutate_impl ( node->inout , *this ); 1554 maybeMutate_impl ( node->constraint, *this ); 1555 maybeMutate_impl ( node->operand , *this ); 1512 1556 1513 1557 MUTATE_END( Expression, node ); … … 1521 1565 1522 1566 indexerScopedAccept( node->result , *this ); 1523 maybeAccept 1524 maybeAccept 1525 maybeAccept 1526 maybeAccept 1567 maybeAccept_impl ( node->callExpr , *this ); 1568 maybeAccept_impl ( node->tempDecls , *this ); 1569 maybeAccept_impl ( node->returnDecls, *this ); 1570 maybeAccept_impl ( node->dtors , *this ); 1527 1571 1528 1572 VISIT_END( node ); … … 1535 1579 indexerScopedMutate( node->env , *this ); 1536 1580 indexerScopedMutate( node->result , *this ); 1537 maybeMutate Ref( node->callExpr , *this );1538 maybeMutate Ref( node->tempDecls , *this );1539 maybeMutate Ref( node->returnDecls, *this );1540 maybeMutate Ref( node->dtors , *this );1581 maybeMutate_impl ( node->callExpr , *this ); 1582 maybeMutate_impl ( node->tempDecls , *this ); 1583 maybeMutate_impl ( node->returnDecls, *this ); 1584 maybeMutate_impl ( node->dtors , *this ); 1541 1585 1542 1586 MUTATE_END( Expression, node ); … … 1550 1594 1551 1595 indexerScopedAccept( node->result , *this ); 1552 maybeAccept 1596 maybeAccept_impl ( node->callExpr, *this ); 1553 1597 1554 1598 VISIT_END( node ); … … 1561 1605 indexerScopedMutate( node->env , *this ); 1562 1606 indexerScopedMutate( node->result , *this ); 1563 maybeMutate Ref( node->callExpr, *this );1607 maybeMutate_impl ( node->callExpr, *this ); 1564 1608 1565 1609 MUTATE_END( Expression, node ); … … 1573 1617 1574 1618 indexerScopedAccept( node->result , *this ); 1575 maybeAccept 1619 maybeAccept_impl ( node->initializer, *this ); 1576 1620 1577 1621 VISIT_END( node ); … … 1584 1628 indexerScopedMutate( node->env , *this ); 1585 1629 indexerScopedMutate( node->result , *this ); 1586 maybeMutate Ref( node->initializer, *this );1630 maybeMutate_impl ( node->initializer, *this ); 1587 1631 1588 1632 MUTATE_END( Expression, node ); … … 1596 1640 1597 1641 indexerScopedAccept( node->result, *this ); 1598 maybeAccept 1599 maybeAccept 1642 maybeAccept_impl ( node->low , *this ); 1643 maybeAccept_impl ( node->high , *this ); 1600 1644 1601 1645 VISIT_END( node ); … … 1608 1652 indexerScopedMutate( node->env , *this ); 1609 1653 indexerScopedMutate( node->result, *this ); 1610 maybeMutate Ref( node->low , *this );1611 maybeMutate Ref( node->high , *this );1654 maybeMutate_impl ( node->low , *this ); 1655 maybeMutate_impl ( node->high , *this ); 1612 1656 1613 1657 MUTATE_END( Expression, node ); … … 1621 1665 1622 1666 indexerScopedAccept( node->result, *this ); 1623 maybeAccept 1667 maybeAccept_impl ( node->exprs , *this ); 1624 1668 1625 1669 VISIT_END( node ); … … 1632 1676 indexerScopedMutate( node->env , *this ); 1633 1677 indexerScopedMutate( node->result, *this ); 1634 maybeMutate Ref( node->exprs , *this );1678 maybeMutate_impl ( node->exprs , *this ); 1635 1679 1636 1680 MUTATE_END( Expression, node ); … … 1644 1688 1645 1689 indexerScopedAccept( node->result, *this ); 1646 maybeAccept 1690 maybeAccept_impl ( node->exprs , *this ); 1647 1691 1648 1692 VISIT_END( node ); … … 1655 1699 indexerScopedMutate( node->env , *this ); 1656 1700 indexerScopedMutate( node->result, *this ); 1657 maybeMutate Ref( node->exprs , *this );1701 maybeMutate_impl ( node->exprs , *this ); 1658 1702 1659 1703 MUTATE_END( Expression, node ); … … 1667 1711 1668 1712 indexerScopedAccept( node->result, *this ); 1669 maybeAccept 1713 maybeAccept_impl ( node->tuple , *this ); 1670 1714 1671 1715 VISIT_END( node ); … … 1678 1722 indexerScopedMutate( node->env , *this ); 1679 1723 indexerScopedMutate( node->result, *this ); 1680 maybeMutate Ref( node->tuple , *this );1724 maybeMutate_impl ( node->tuple , *this ); 1681 1725 1682 1726 MUTATE_END( Expression, node ); … … 1690 1734 1691 1735 indexerScopedAccept( node->result , *this ); 1692 maybeAccept 1736 maybeAccept_impl ( node->stmtExpr, *this ); 1693 1737 1694 1738 VISIT_END( node ); … … 1701 1745 indexerScopedMutate( node->env , *this ); 1702 1746 indexerScopedMutate( node->result , *this ); 1703 maybeMutate Ref( node->stmtExpr, *this );1747 maybeMutate_impl ( node->stmtExpr, *this ); 1704 1748 1705 1749 MUTATE_END( Expression, node ); … … 1718 1762 1719 1763 indexerScopedAccept( node->result , *this ); 1720 maybeAccept 1721 maybeAccept 1722 maybeAccept 1764 maybeAccept_impl ( node->statements , *this ); 1765 maybeAccept_impl ( node->returnDecls, *this ); 1766 maybeAccept_impl ( node->dtors , *this ); 1723 1767 1724 1768 VISIT_END( node ); … … 1735 1779 1736 1780 indexerScopedMutate( node->result , *this ); 1737 maybeMutate Ref( node->statements , *this );1738 maybeMutate Ref( node->returnDecls, *this );1739 maybeMutate Ref( node->dtors , *this );1781 maybeMutate_impl ( node->statements , *this ); 1782 maybeMutate_impl ( node->returnDecls, *this ); 1783 maybeMutate_impl ( node->dtors , *this ); 1740 1784 1741 1785 MUTATE_END( Expression, node ); … … 1749 1793 1750 1794 indexerScopedAccept( node->result, *this ); 1751 maybeAccept 1795 maybeAccept_impl ( node->expr , *this ); 1752 1796 1753 1797 VISIT_END( node ); … … 1760 1804 indexerScopedMutate( node->env , *this ); 1761 1805 indexerScopedMutate( node->result, *this ); 1762 maybeMutate Ref( node->expr , *this );1806 maybeMutate_impl ( node->expr , *this ); 1763 1807 1764 1808 MUTATE_END( Expression, node ); … … 1805 1849 { 1806 1850 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1807 maybeAccept ( node->forall , *this );1808 maybeAccept ( node->parameters, *this );1851 maybeAccept_impl( node->forall , *this ); 1852 maybeAccept_impl( node->parameters, *this ); 1809 1853 } 1810 1854 … … 1820 1864 { 1821 1865 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1822 maybeMutate Ref( node->forall , *this );1823 maybeMutate Ref( node->parameters, *this );1866 maybeMutate_impl( node->forall , *this ); 1867 maybeMutate_impl( node->parameters, *this ); 1824 1868 } 1825 1869 … … 1837 1881 { 1838 1882 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1839 maybeAccept ( node->forall , *this );1840 maybeAccept ( node->parameters, *this );1883 maybeAccept_impl( node->forall , *this ); 1884 maybeAccept_impl( node->parameters, *this ); 1841 1885 } 1842 1886 … … 1852 1896 { 1853 1897 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1854 maybeMutate Ref( node->forall , *this );1855 maybeMutate Ref( node->parameters, *this );1898 maybeMutate_impl( node->forall , *this ); 1899 maybeMutate_impl( node->parameters, *this ); 1856 1900 } 1857 1901 … … 1877 1921 VISIT_START( node ); 1878 1922 1879 maybeAccept ( node->forall , *this );1880 maybeAccept ( node->parameters, *this );1923 maybeAccept_impl( node->forall , *this ); 1924 maybeAccept_impl( node->parameters, *this ); 1881 1925 1882 1926 VISIT_END( node ); … … 1887 1931 MUTATE_START( node ); 1888 1932 1889 maybeMutate Ref( node->forall , *this );1890 maybeMutate Ref( node->parameters, *this );1933 maybeMutate_impl( node->forall , *this ); 1934 maybeMutate_impl( node->parameters, *this ); 1891 1935 1892 1936 MUTATE_END( Type, node ); … … 1934 1978 VISIT_START( node ); 1935 1979 1936 maybeAccept ( node->get_designators(), *this );1980 maybeAccept_impl( node->get_designators(), *this ); 1937 1981 1938 1982 VISIT_END( node ); … … 1943 1987 MUTATE_START( node ); 1944 1988 1945 maybeMutate Ref( node->get_designators(), *this );1989 maybeMutate_impl( node->get_designators(), *this ); 1946 1990 1947 1991 MUTATE_END( Designation, node ); … … 2083 2127 MUTATE_BODY( Attribute, node ); 2084 2128 } 2129 2130 template< typename pass_type > 2131 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) { 2132 MUTATE_START( node ); 2133 2134 for ( auto & p : node->typeEnv ) { 2135 indexerScopedMutate( p.second, *this ); 2136 } 2137 for ( auto & p : node->varEnv ) { 2138 indexerScopedMutate( p.second, *this ); 2139 } 2140 2141 MUTATE_END( TypeSubstitution, node ); 2142 } -
src/Common/PassVisitor.proto.h
rb96ec83 r6840e7c 46 46 ~bool_ref() = default; 47 47 48 operator bool() { return *m_ref; }48 operator bool() { return m_ref ? *m_ref : true; } 49 49 bool operator=( bool val ) { return *m_ref = val; } 50 50 51 51 private: 52 52 53 template<typename pass> 54 friend class PassVisitor; 55 56 void set( bool & val ) { m_ref = &val; }; 57 58 bool * m_ref; 53 friend class ChildrenGuard; 54 55 bool * set( bool & val ) { 56 bool * prev = m_ref; 57 m_ref = &val; 58 return prev; 59 } 60 61 bool * m_ref = nullptr; 59 62 }; 60 63 61 template< typename TreeType, typename VisitorType > 62 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) { 63 auto guard = makeFuncGuard( 64 [&visitor]() { visitor.indexerScopeEnter(); },65 [&visitor]() { visitor.indexerScopeLeave(); }66 );67 maybeAccept( tree, visitor );68 }69 70 template< typename TreeType, typename MutatorType > 71 inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator) {72 auto guard = makeFuncGuard(73 [&mutator]() { mutator.indexerScopeEnter(); },74 [&mutator]() { mutator.indexerScopeLeave();}75 ); 76 tree = maybeMutate( tree, mutator );77 } 78 79 template< typename TreeType, typename MutatorType > 80 inline void maybeMutateRef( TreeType *& tree, MutatorType & mutator ) { 81 tree = maybeMutate( tree, mutator );82 } 64 class ChildrenGuard { 65 public: 66 67 ChildrenGuard( bool_ref * ref ) 68 : m_val ( true ) 69 , m_prev( ref ? ref->set( m_val ) : nullptr ) 70 , m_ref ( ref ) 71 {} 72 73 ~ChildrenGuard() { 74 if( m_ref ) { 75 m_ref->set( *m_prev ); 76 } 77 } 78 79 operator bool() { return m_val; } 80 81 private: 82 bool m_val; 83 bool * m_prev; 84 bool_ref * m_ref; 85 }; 83 86 84 87 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -
src/Common/utility.h
rb96ec83 r6840e7c 28 28 #include <cassert> 29 29 30 #include "Common/Indenter.h" 31 30 32 template< typename T > 31 33 static inline T * maybeClone( const T *orig ) { … … 75 77 76 78 template< typename Container > 77 void printAll( const Container &container, std::ostream &os, int indent = 0) {79 void printAll( const Container &container, std::ostream &os, Indenter indent = {} ) { 78 80 for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) { 79 81 if ( *i ) { 80 os << std::string( indent, ' ' );81 (*i)->print( os, indent + 2);82 os << indent; 83 (*i)->print( os, indent ); 82 84 // need an endl after each element because it's not easy to know when each individual item should end 83 85 os << std::endl; … … 351 353 template< typename T1, typename T2 > 352 354 struct group_iterate_t { 355 private: 356 std::tuple<T1, T2> args; 357 public: 353 358 group_iterate_t( bool skipBoundsCheck, const T1 & v1, const T2 & v2 ) : args(v1, v2) { 354 359 assertf(skipBoundsCheck || v1.size() == v2.size(), "group iteration requires containers of the same size: <%zd, %zd>.", v1.size(), v2.size()); 355 360 }; 356 361 362 typedef std::tuple<decltype(*std::get<0>(args).begin()), decltype(*std::get<1>(args).begin())> value_type; 363 typedef decltype(std::get<0>(args).begin()) T1Iter; 364 typedef decltype(std::get<1>(args).begin()) T2Iter; 365 357 366 struct iterator { 358 typedef typename std::remove_reference<T1>::type T1val;359 typedef typename std::remove_reference<T2>::type T2val;360 typedef std::tuple<typename T1val::value_type &, typename T2val::value_type &> value_type;361 typedef typename T1val::iterator T1Iter;362 typedef typename T2val::iterator T2Iter;363 367 typedef std::tuple<T1Iter, T2Iter> IterTuple; 364 368 IterTuple it; … … 370 374 value_type operator*() const { return std::tie( *std::get<0>(it), *std::get<1>(it) ); } 371 375 }; 376 372 377 iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); } 373 378 iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); } 374 375 private:376 std::tuple<T1, T2> args;377 379 }; 378 380 -
src/Concurrency/Keywords.cc
rb96ec83 r6840e7c 196 196 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* ); 197 197 void validate( DeclarationWithType * ); 198 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 198 199 void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 199 200 … … 206 207 StructDecl* monitor_decl = nullptr; 207 208 StructDecl* guard_decl = nullptr; 209 StructDecl* dtor_guard_decl = nullptr; 208 210 209 211 static std::unique_ptr< Type > generic_func; … … 229 231 230 232 void postvisit( FunctionDecl * decl ); 233 void previsit ( StructDecl * decl ); 231 234 232 235 void addStartStatement( FunctionDecl * decl, DeclarationWithType * param ); … … 236 239 acceptAll( translationUnit, impl ); 237 240 } 241 242 private : 243 bool thread_ctor_seen = false; 244 StructDecl * thread_decl = nullptr; 238 245 }; 239 246 … … 403 410 if( mutexArgs.empty() ) return; 404 411 412 if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl ); 413 414 bool isDtor = CodeGen::isDestructor( decl->name ); 415 416 if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl ); 417 405 418 for(auto arg : mutexArgs) { 406 419 validate( arg ); … … 412 425 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 413 426 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 414 415 addStatments( decl, body, mutexArgs ); 427 if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 428 429 if( isDtor ) { 430 addDtorStatments( decl, body, mutexArgs ); 431 } 432 else { 433 addStatments( decl, body, mutexArgs ); 434 } 416 435 } 417 436 … … 425 444 assert( !guard_decl ); 426 445 guard_decl = decl; 446 } 447 else if( decl->name == "monitor_dtor_guard_t" ) { 448 assert( !dtor_guard_decl ); 449 dtor_guard_decl = decl; 427 450 } 428 451 } … … 457 480 //Make sure that typed isn't mutex 458 481 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg ); 482 } 483 484 void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 485 Type * arg_type = args.front()->get_type()->clone(); 486 arg_type->set_mutex( false ); 487 488 ObjectDecl * monitors = new ObjectDecl( 489 "__monitor", 490 noStorage, 491 LinkageSpec::Cforall, 492 nullptr, 493 new PointerType( 494 noQualifiers, 495 new StructInstType( 496 noQualifiers, 497 monitor_decl 498 ) 499 ), 500 new SingleInit( new UntypedExpr( 501 new NameExpr( "get_monitor" ), 502 { new CastExpr( new VariableExpr( args.front() ), arg_type ) } 503 )) 504 ); 505 506 assert(generic_func); 507 508 //in reverse order : 509 // monitor_guard_t __guard = { __monitors, #, func }; 510 body->push_front( 511 new DeclStmt( noLabels, new ObjectDecl( 512 "__guard", 513 noStorage, 514 LinkageSpec::Cforall, 515 nullptr, 516 new StructInstType( 517 noQualifiers, 518 dtor_guard_decl 519 ), 520 new ListInit( 521 { 522 new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ), 523 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) ) 524 }, 525 noDesignators, 526 true 527 ) 528 )) 529 ); 530 531 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 532 body->push_front( new DeclStmt( noLabels, monitors) ); 459 533 } 460 534 … … 523 597 // General entry routine 524 598 //============================================================================================= 599 void ThreadStarter::previsit( StructDecl * decl ) { 600 if( decl->name == "thread_desc" && decl->body ) { 601 assert( !thread_decl ); 602 thread_decl = decl; 603 } 604 } 605 525 606 void ThreadStarter::postvisit(FunctionDecl * decl) { 526 607 if( ! CodeGen::isConstructor(decl->name) ) return; 608 609 Type * typeof_this = InitTweak::getTypeofThis(decl->type); 610 StructInstType * ctored_type = dynamic_cast< StructInstType * >( typeof_this ); 611 if( ctored_type && ctored_type->baseStruct == thread_decl ) { 612 thread_ctor_seen = true; 613 } 527 614 528 615 DeclarationWithType * param = decl->get_functionType()->get_parameters().front(); 529 616 auto type = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) ); 530 617 if( type && type->get_baseStruct()->is_thread() ) { 618 if( !thread_decl || !thread_ctor_seen ) { 619 throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>"); 620 } 621 531 622 addStartStatement( decl, param ); 532 623 } -
src/Concurrency/Waitfor.cc
rb96ec83 r6840e7c 190 190 191 191 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) { 192 std::unique_ptr< Expression > expr(makeOpAssign(192 Expression * expr = makeOpAssign( 193 193 makeOpMember( 194 194 makeOpIndex( … … 199 199 ), 200 200 value 201 ) ); 202 203 return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) ); 201 ); 202 203 ResolvExpr::findVoidExpression( expr, indexer ); 204 205 return new ExprStmt( noLabels, expr ); 204 206 } 205 207 … … 313 315 stmt->push_back( new DeclStmt( noLabels, acceptables) ); 314 316 315 UntypedExpr* set = new UntypedExpr(317 Expression * set = new UntypedExpr( 316 318 new NameExpr( "__builtin_memset" ), 317 319 { … … 322 324 ); 323 325 324 Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer ); 325 delete set; 326 327 stmt->push_back( new ExprStmt( noLabels, resolved_set ) ); 326 ResolvExpr::findVoidExpression( set, indexer ); 327 328 stmt->push_back( new ExprStmt( noLabels, set ) ); 328 329 329 330 return acceptables; … … 346 347 347 348 Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) { 348 Expression * untyped= new UntypedExpr(349 Expression * expr = new UntypedExpr( 349 350 new NameExpr( "?=?" ), 350 351 { … … 354 355 ); 355 356 356 Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer ); 357 delete untyped; 357 ResolvExpr::findVoidExpression( expr, indexer ); 358 358 359 359 return new ExprStmt( noLabels, expr ); … … 379 379 new ListInit( 380 380 map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){ 381 Expression * untyped= new CastExpr(381 Expression * init = new CastExpr( 382 382 new UntypedExpr( 383 383 new NameExpr( "get_monitor" ), … … 393 393 ); 394 394 395 Expression * init = ResolvExpr::findSingleExpression( untyped, indexer ); 396 delete untyped; 395 ResolvExpr::findSingleExpression( init, indexer ); 397 396 return new SingleInit( init ); 398 397 }) -
src/GenPoly/Box.cc
rb96ec83 r6840e7c 600 600 601 601 // add size/align for generic types to parameter list 602 if ( ! appExpr->get_function()-> has_result()) return;602 if ( ! appExpr->get_function()->result ) return; 603 603 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 604 604 assert( funcType ); … … 714 714 715 715 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 716 assertf( arg->has_result(), "arg does not have result: %s", toString( arg ).c_str() ); 717 if ( isPolyType( param, exprTyVars ) ) { 718 Type * newType = arg->get_result()->clone(); 716 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 717 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 718 719 if ( arg->result->get_lvalue() ) { 720 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 721 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 722 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 723 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 724 // return; 725 // } 726 // } 727 arg = generalizedLvalue( new AddressExpr( arg ) ); 728 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 729 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 730 arg = new CastExpr( arg, param->clone() ); 731 } 732 } else { 733 // use type computed in unification to declare boxed variables 734 Type * newType = param->clone(); 719 735 if ( env ) env->apply( newType ); 720 std::unique_ptr<Type> manager( newType ); 721 if ( isPolyType( newType ) ) { 722 // if the argument's type is polymorphic, we don't need to box again! 723 return; 724 } else if ( arg->get_result()->get_lvalue() ) { 725 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 726 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 727 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 728 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 729 // return; 730 // } 731 // } 732 arg = generalizedLvalue( new AddressExpr( arg ) ); 733 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 734 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 735 arg = new CastExpr( arg, param->clone() ); 736 } 737 } else { 738 // use type computed in unification to declare boxed variables 739 Type * newType = param->clone(); 740 if ( env ) env->apply( newType ); 741 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 742 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 743 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 744 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 745 assign->get_args().push_back( new VariableExpr( newObj ) ); 746 assign->get_args().push_back( arg ); 747 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 748 arg = new AddressExpr( new VariableExpr( newObj ) ); 749 } // if 736 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 737 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 738 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 739 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 740 assign->get_args().push_back( new VariableExpr( newObj ) ); 741 assign->get_args().push_back( arg ); 742 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 743 arg = new AddressExpr( new VariableExpr( newObj ) ); 750 744 } // if 751 745 } … … 965 959 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 966 960 if ( varExpr->get_var()->get_name() == "?[?]" ) { 967 assert( appExpr-> has_result());961 assert( appExpr->result ); 968 962 assert( appExpr->get_args().size() == 2 ); 969 963 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); … … 999 993 } // if 1000 994 } else if ( varExpr->get_var()->get_name() == "*?" ) { 1001 assert( appExpr-> has_result());995 assert( appExpr->result ); 1002 996 assert( ! appExpr->get_args().empty() ); 1003 997 if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) { … … 1016 1010 } // if 1017 1011 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) { 1018 assert( appExpr-> has_result());1012 assert( appExpr->result ); 1019 1013 assert( appExpr->get_args().size() == 1 ); 1020 1014 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { … … 1036 1030 } // if 1037 1031 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) { 1038 assert( appExpr-> has_result());1032 assert( appExpr->result ); 1039 1033 assert( appExpr->get_args().size() == 1 ); 1040 1034 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { … … 1042 1036 } // if 1043 1037 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 1044 assert( appExpr-> has_result());1038 assert( appExpr->result ); 1045 1039 assert( appExpr->get_args().size() == 2 ); 1046 1040 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); … … 1068 1062 } // if 1069 1063 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) { 1070 assert( appExpr-> has_result());1064 assert( appExpr->result ); 1071 1065 assert( appExpr->get_args().size() == 2 ); 1072 1066 Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ); … … 1162 1156 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1163 1157 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1164 assert( addrExpr->get_arg()-> has_result()&& ! addrExpr->get_arg()->get_result()->isVoid() );1158 assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() ); 1165 1159 1166 1160 bool needs = false; 1167 1161 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 1168 if ( expr-> has_result()&& isPolyType( expr->get_result(), scopeTyVars, env ) ) {1162 if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1169 1163 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1170 1164 if ( name->get_name() == "*?" ) { 1171 1165 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 1172 assert( appExpr->get_function()-> has_result());1166 assert( appExpr->get_function()->result ); 1173 1167 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 1174 1168 assert( function ); -
src/GenPoly/FindFunction.cc
rb96ec83 r6840e7c 18 18 #include <utility> // for pair 19 19 20 #include "Common/PassVisitor.h" // for PassVisitor 20 21 #include "Common/SemanticError.h" // for SemanticError 21 22 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::iterator … … 27 28 28 29 namespace GenPoly { 29 class FindFunction : public Mutator{30 class FindFunction : public WithGuards, public WithVisitorRef<FindFunction>, public WithShortCircuiting { 30 31 public: 31 32 FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ); 32 33 33 virtual Type *mutate( FunctionType *functionType ); 34 virtual Type *mutate( PointerType *pointerType ); 34 void premutate( FunctionType * functionType ); 35 Type * postmutate( FunctionType * functionType ); 36 void premutate( PointerType * pointerType ); 35 37 private: 36 38 void handleForall( const Type::ForallList &forall ); … … 43 45 44 46 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 45 FindFunctionfinder( functions, tyVars, false, predicate );47 PassVisitor<FindFunction> finder( functions, tyVars, false, predicate ); 46 48 type->acceptMutator( finder ); 47 49 } 48 50 49 51 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 50 FindFunctionfinder( functions, tyVars, true, predicate );52 PassVisitor<FindFunction> finder( functions, tyVars, true, predicate ); 51 53 type = type->acceptMutator( finder ); 52 54 } … … 57 59 58 60 void FindFunction::handleForall( const Type::ForallList &forall ) { 59 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i) {60 TyVarMap::iterator var = tyVars.find( (*i)->get_name());61 for ( const Declaration * td : forall ) { 62 TyVarMap::iterator var = tyVars.find( td->name ); 61 63 if ( var != tyVars.end() ) { 62 64 tyVars.erase( var->first ); … … 65 67 } 66 68 67 Type * FindFunction::mutate( FunctionType *functionType ) { 68 tyVars.beginScope(); 69 void FindFunction::premutate( FunctionType * functionType ) { 70 visit_children = false; 71 GuardScope( tyVars ); 69 72 handleForall( functionType->get_forall() ); 70 mutateAll( functionType->get_returnVals(), *this ); 73 mutateAll( functionType->get_returnVals(), *visitor ); 74 } 75 76 Type * FindFunction::postmutate( FunctionType * functionType ) { 71 77 Type *ret = functionType; 72 78 if ( predicate( functionType, tyVars ) ) { … … 77 83 } // if 78 84 } // if 79 tyVars.endScope();80 85 return ret; 81 86 } 82 87 83 Type * FindFunction::mutate( PointerType *pointerType ) {84 tyVars.beginScope();88 void FindFunction::premutate( PointerType * pointerType ) { 89 GuardScope( tyVars ); 85 90 handleForall( pointerType->get_forall() ); 86 Type *ret = Mutator::mutate( pointerType );87 tyVars.endScope();88 return ret;89 91 } 90 92 } // namespace GenPoly -
src/GenPoly/GenPoly.cc
rb96ec83 r6840e7c 432 432 } 433 433 434 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) { 435 // is parameter is not polymorphic, don't need to box 436 if ( ! isPolyType( param, exprTyVars ) ) return false; 437 Type * newType = arg->clone(); 438 if ( env ) env->apply( newType ); 439 std::unique_ptr<Type> manager( newType ); 440 // if the argument's type is polymorphic, we don't need to box again! 441 return ! isPolyType( newType ); 442 } 443 444 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) { 445 FunctionType * function = getFunctionType( appExpr->function->result ); 446 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); 447 TyVarMap exprTyVars( TypeDecl::Data{} ); 448 makeTyVarMap( function, exprTyVars ); 449 return needsBoxing( param, arg, exprTyVars, env ); 450 } 451 434 452 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 435 453 // xxx - should this actually be insert? -
src/GenPoly/GenPoly.h
rb96ec83 r6840e7c 80 80 bool typesPolyCompatible( Type *aty, Type *bty ); 81 81 82 /// true if arg requires boxing given exprTyVars 83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ); 84 85 /// true if arg requires boxing in the call to appExpr 86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ); 87 82 88 /// Adds the type variable `tyVar` to `tyVarMap` 83 89 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); -
src/GenPoly/Specialize.cc
rb96ec83 r6840e7c 147 147 148 148 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 149 assertf( actual-> has_result(), "attempting to specialize an untyped expression" );149 assertf( actual->result, "attempting to specialize an untyped expression" ); 150 150 if ( needsSpecialization( formalType, actual->get_result(), env ) ) { 151 151 if ( FunctionType *funType = getFunctionType( formalType ) ) { -
src/GenPoly/module.mk
rb96ec83 r6840e7c 20 20 GenPoly/Lvalue.cc \ 21 21 GenPoly/Specialize.cc \ 22 GenPoly/CopyParams.cc \23 22 GenPoly/FindFunction.cc \ 24 23 GenPoly/InstantiateGeneric.cc -
src/InitTweak/FixInit.cc
rb96ec83 r6840e7c 94 94 /// true if type does not need to be copy constructed to ensure correctness 95 95 bool skipCopyConstruct( Type * type ); 96 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );96 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ); 97 97 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 98 98 … … 259 259 260 260 GenStructMemberCalls::generate( translationUnit ); 261 261 262 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a 262 263 // hack in the way untyped assignments are generated, where the first argument cannot have … … 288 289 for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 289 290 try { 290 *i =maybeMutate( *i, fixer );291 maybeMutate( *i, fixer ); 291 292 translationUnit.splice( i, fixer.pass.staticDtorDecls ); 292 293 } catch( SemanticError &e ) { … … 322 323 323 324 Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) { 324 assert( appExpr );325 326 325 if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) { 327 if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() )) {326 if ( function->var->linkage.is_builtin ) { 328 327 // optimization: don't need to copy construct in order to call intrinsic functions 329 328 return appExpr; … … 331 330 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 332 331 assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() ); 333 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype-> get_parameters().size() == 2 ) {334 Type * t1 = getPointerBase( ftype-> get_parameters().front()->get_type() );335 Type * t2 = ftype-> get_parameters().back()->get_type();332 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->parameters.size() == 2 ) { 333 Type * t1 = getPointerBase( ftype->parameters.front()->get_type() ); 334 Type * t2 = ftype->parameters.back()->get_type(); 336 335 assert( t1 ); 337 336 … … 366 365 ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg ); 367 366 ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->get_callStmt() ); 368 Expression * untyped = exprStmt->get_expr(); 367 Expression * resolved = exprStmt->expr; 368 exprStmt->expr = nullptr; // take ownership of expr 369 369 370 370 // resolve copy constructor 371 371 // should only be one alternative for copy ctor and dtor expressions, since all arguments are fixed 372 372 // (VariableExpr and already resolved expression) 373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )374 Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << resolved << std::endl; ) 374 ResolvExpr::findVoidExpression( resolved, indexer ); 375 375 assert( resolved ); 376 376 if ( resolved->get_env() ) { … … 380 380 resolved->set_env( nullptr ); 381 381 } // if 382 383 382 delete stmt; 384 383 return resolved; 385 384 } 386 385 387 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {386 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ) { 388 387 static UniqueName tempNamer("_tmp_cp"); 389 388 assert( env ); 390 389 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) 391 assert( arg-> has_result());392 Type * result = arg-> get_result();390 assert( arg->result ); 391 Type * result = arg->result; 393 392 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 394 393 395 // type may involve type variables, so apply type substitution to get temporary variable's actual type 394 // type may involve type variables, so apply type substitution to get temporary variable's actual type. 395 // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T). 396 396 result = result->clone(); 397 env->apply ( result );397 env->applyFree( result ); 398 398 ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr ); 399 399 tmp->get_type()->set_const( false ); … … 406 406 // if the chosen constructor is intrinsic, the copy is unnecessary, so 407 407 // don't create the temporary and don't call the copy constructor 408 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 409 assert( function ); 410 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 408 VariableExpr * function = strict_dynamic_cast< VariableExpr * >( appExpr->function ); 409 if ( function->var->linkage == LinkageSpec::Intrinsic ) { 410 // arguments that need to be boxed need a temporary regardless of whether the copy constructor is intrinsic, 411 // so that the object isn't changed inside of the polymorphic function 412 if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return; 413 } 411 414 } 412 415 … … 416 419 // replace argument to function call with temporary 417 420 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 418 impCpCtorExpr-> get_tempDecls().push_back( tmp );419 impCpCtorExpr-> get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );421 impCpCtorExpr->tempDecls.push_back( tmp ); 422 impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) ); 420 423 } 421 424 … … 427 430 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 428 431 429 ApplicationExpr * appExpr = impCpCtorExpr-> get_callExpr();432 ApplicationExpr * appExpr = impCpCtorExpr->callExpr; 430 433 431 434 // take each argument and attempt to copy construct it. 432 for ( Expression * & arg : appExpr->get_args() ) { 433 copyConstructArg( arg, impCpCtorExpr ); 435 FunctionType * ftype = GenPoly::getFunctionType( appExpr->function->result ); 436 assert( ftype ); 437 auto & params = ftype->parameters; 438 auto iter = params.begin(); 439 for ( Expression * & arg : appExpr->args ) { 440 Type * formal = nullptr; 441 if ( iter != params.end() ) { 442 DeclarationWithType * param = *iter++; 443 formal = param->get_type(); 444 } 445 446 copyConstructArg( arg, impCpCtorExpr, formal ); 434 447 } // for 435 448 … … 437 450 // initialized with the return value and is destructed later 438 451 // xxx - handle named return values? 439 Type * result = appExpr-> get_result();452 Type * result = appExpr->result; 440 453 if ( ! result->isVoid() ) { 441 454 static UniqueName retNamer("_tmp_cp_ret"); … … 443 456 env->apply( result ); 444 457 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr ); 445 ret-> get_type()->set_const( false );446 impCpCtorExpr-> get_returnDecls().push_back( ret );458 ret->type->set_const( false ); 459 impCpCtorExpr->returnDecls.push_back( ret ); 447 460 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 448 461 if ( ! dynamic_cast< ReferenceType * >( result ) ) { … … 551 564 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 552 565 // move env from callExpr to retExpr 553 retExpr->set_env( callExpr->get_env() ); 554 callExpr->set_env( nullptr ); 566 std::swap( retExpr->env, callExpr->env ); 555 567 return retExpr; 556 568 } else { … … 754 766 if ( ctorStmt && (ctorCall = isIntrinsicCallExpr( ctorStmt->expr )) && ctorCall->get_args().size() == 2 ) { 755 767 // clean up intrinsic copy constructor calls by making them into SingleInits 756 objDecl->init = new SingleInit( ctorCall->args.back() ); 768 Expression * ctorArg = ctorCall->args.back(); 769 std::swap( ctorArg->env, ctorCall->env ); 770 objDecl->init = new SingleInit( ctorArg ); 771 757 772 ctorCall->args.pop_back(); 758 773 } else { … … 822 837 GuardValue( labelVars ); 823 838 labelVars.clear(); 839 // LabelFinder does not recurse into FunctionDecl, so need to visit 840 // its children manually. 824 841 maybeAccept( funcDecl->type, finder ); 825 842 maybeAccept( funcDecl->statements, finder ); … … 1079 1096 } 1080 1097 1081 DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) {1098 DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) { 1082 1099 // add object to the indexer assumes that there will be no name collisions 1083 1100 // in generated code. If this changes, add mutate methods for entities with … … 1087 1104 } 1088 1105 1089 Expression* MutatingResolver::mutate( UntypedExpr *untypedExpr ) { 1090 return strict_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) ); 1106 Expression * MutatingResolver::mutate( UntypedExpr * untypedExpr ) { 1107 Expression * newExpr = untypedExpr; 1108 ResolvExpr::findVoidExpression( newExpr, indexer ); 1109 return newExpr; 1091 1110 } 1092 1111 … … 1094 1113 static UniqueName tempNamer( "_tmp_ctor_expr" ); 1095 1114 // xxx - is the size check necessary? 1096 assert( ctorExpr-> has_result()&& ctorExpr->get_result()->size() == 1 );1115 assert( ctorExpr->result && ctorExpr->get_result()->size() == 1 ); 1097 1116 1098 1117 // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary. … … 1113 1132 1114 1133 // resolve assignment and dispose of new env 1115 Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer ); 1116 delete resolvedAssign->env; 1117 resolvedAssign->env = nullptr; 1118 delete assign; 1134 ResolvExpr::findVoidExpression( assign, indexer ); 1135 delete assign->env; 1136 assign->env = nullptr; 1119 1137 1120 1138 // for constructor expr: … … 1125 1143 // T & tmp; 1126 1144 // &tmp = &x, ?{}(tmp), tmp 1127 CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );1145 CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) ); 1128 1146 commaExpr->set_env( env ); 1129 1147 return commaExpr; -
src/InitTweak/GenInit.cc
rb96ec83 r6840e7c 85 85 // should not have a ConstructorInit generated. 86 86 87 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed 88 bool isManaged( Type * type ) const; // determine if type is managed 89 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor 90 GenPoly::ScopedSet< std::string > managedTypes; 87 ManagedTypes managedTypes; 91 88 bool inFunction = false; 92 89 }; … … 129 126 // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address 130 127 // is being returned 131 if ( returnStmt-> get_expr()&& returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {128 if ( returnStmt->expr && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) { 132 129 // explicitly construct the return value using the return expression and the retVal object 133 assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() ); 134 135 stmtsToAddBefore.push_back( genCtorDtor( "?{}", dynamic_cast< ObjectDecl *>( returnVals.front() ), returnStmt->get_expr() ) ); 130 assertf( returnVals.front()->name != "", "Function %s has unnamed return value\n", funcName.c_str() ); 131 132 ObjectDecl * retVal = strict_dynamic_cast< ObjectDecl * >( returnVals.front() ); 133 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( returnStmt->expr ) ) { 134 // return statement has already been mutated - don't need to do it again 135 if ( varExpr->var == retVal ) return; 136 } 137 stmtsToAddBefore.push_back( genCtorDtor( "?{}", retVal, returnStmt->get_expr() ) ); 136 138 137 139 // return the retVal object 138 returnStmt-> set_expr( new VariableExpr( returnVals.front()) );140 returnStmt->expr = new VariableExpr( returnVals.front() ); 139 141 } // if 140 142 } … … 199 201 } 200 202 201 bool CtorDtor::isManaged( Type * type ) const {203 bool ManagedTypes::isManaged( Type * type ) const { 202 204 // references are never constructed 203 205 if ( dynamic_cast< ReferenceType * >( type ) ) return false; … … 215 217 } 216 218 217 bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {219 bool ManagedTypes::isManaged( ObjectDecl * objDecl ) const { 218 220 Type * type = objDecl->get_type(); 219 221 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { … … 223 225 } 224 226 225 void CtorDtor::handleDWT( DeclarationWithType * dwt ) {227 void ManagedTypes::handleDWT( DeclarationWithType * dwt ) { 226 228 // if this function is a user-defined constructor or destructor, mark down the type as "managed" 227 229 if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && CodeGen::isCtorDtor( dwt->get_name() ) ) { … … 233 235 } 234 236 } 237 238 void ManagedTypes::handleStruct( StructDecl * aggregateDecl ) { 239 // don't construct members, but need to take note if there is a managed member, 240 // because that means that this type is also managed 241 for ( Declaration * member : aggregateDecl->get_members() ) { 242 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) { 243 if ( isManaged( field ) ) { 244 StructInstType inst( Type::Qualifiers(), aggregateDecl ); 245 managedTypes.insert( SymTab::Mangler::mangle( &inst ) ); 246 break; 247 } 248 } 249 } 250 } 251 252 void ManagedTypes::beginScope() { managedTypes.beginScope(); } 253 void ManagedTypes::endScope() { managedTypes.endScope(); } 235 254 236 255 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) { … … 277 296 278 297 void CtorDtor::previsit( ObjectDecl * objDecl ) { 279 handleDWT( objDecl );298 managedTypes.handleDWT( objDecl ); 280 299 // hands off if @=, extern, builtin, etc. 281 300 // even if unmanaged, try to construct global or static if initializer is not constexpr, since this is not legal C 282 if ( tryConstruct( objDecl ) && ( isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {301 if ( tryConstruct( objDecl ) && ( managedTypes.isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) { 283 302 // constructed objects cannot be designated 284 303 if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n", objDecl ); … … 295 314 inFunction = true; 296 315 297 handleDWT( functionDecl );316 managedTypes.handleDWT( functionDecl ); 298 317 299 318 GuardScope( managedTypes ); … … 301 320 for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) { 302 321 for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) { 303 handleDWT( assertion );322 managedTypes.handleDWT( assertion ); 304 323 } 305 324 } … … 311 330 visit_children = false; // do not try to construct and destruct aggregate members 312 331 313 // don't construct members, but need to take note if there is a managed member, 314 // because that means that this type is also managed 315 for ( Declaration * member : aggregateDecl->get_members() ) { 316 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) { 317 if ( isManaged( field ) ) { 318 StructInstType inst( Type::Qualifiers(), aggregateDecl ); 319 managedTypes.insert( SymTab::Mangler::mangle( &inst ) ); 320 break; 321 } 322 } 323 } 332 managedTypes.handleStruct( aggregateDecl ); 324 333 } 325 334 -
src/InitTweak/GenInit.h
rb96ec83 r6840e7c 16 16 #pragma once 17 17 18 #include <list> // for list19 #include <string> // for string18 #include <list> // for list 19 #include <string> // for string 20 20 21 #include "SynTree/SynTree.h" // for Visitor Nodes 21 #include "SynTree/SynTree.h" // for Visitor Nodes 22 23 #include "GenPoly/ScopedSet.h" // for ScopedSet 22 24 23 25 namespace InitTweak { … … 33 35 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer 34 36 ConstructorInit * genCtorInit( ObjectDecl * objDecl ); 37 38 class ManagedTypes { 39 public: 40 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed 41 bool isManaged( Type * type ) const; // determine if type is managed 42 43 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor 44 void handleStruct( StructDecl * aggregateDecl ); // add type to managed if child is managed 45 46 void beginScope(); 47 void endScope(); 48 private: 49 GenPoly::ScopedSet< std::string > managedTypes; 50 }; 35 51 } // namespace 36 52 -
src/InitTweak/InitTweak.cc
rb96ec83 r6840e7c 168 168 deleteAll( indices ); 169 169 indices.clear(); 170 } 171 172 bool InitExpander::addReference() { 173 bool added = false; 174 for ( Expression *& expr : cur ) { 175 expr = new AddressExpr( expr ); 176 added = true; 177 } 178 return added; 170 179 } 171 180 … … 270 279 } 271 280 272 Type * getT hisType( FunctionType * ftype ) {273 assertf( ftype, "getT hisType: nullptr ftype" );274 ObjectDecl * thisParam = get ThisParam( ftype );281 Type * getTypeofThis( FunctionType * ftype ) { 282 assertf( ftype, "getTypeofThis: nullptr ftype" ); 283 ObjectDecl * thisParam = getParamThis( ftype ); 275 284 ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( thisParam->type ); 276 285 return refType->base; 277 286 } 278 287 279 ObjectDecl * get ThisParam( FunctionType * ftype ) {280 assertf( ftype, "get ThisParam: nullptr ftype" );288 ObjectDecl * getParamThis( FunctionType * ftype ) { 289 assertf( ftype, "getParamThis: nullptr ftype" ); 281 290 auto & params = ftype->parameters; 282 assertf( ! params.empty(), "get ThisParam: ftype with 0 parameters: %s", toString( ftype ).c_str() );291 assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( ftype ).c_str() ); 283 292 return strict_dynamic_cast< ObjectDecl * >( params.front() ); 284 293 } … … 353 362 assert( expr ); 354 363 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) { 355 return varExpr-> get_var();364 return varExpr->var; 356 365 } else if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( expr ) ) { 357 return memberExpr-> get_member();366 return memberExpr->member; 358 367 } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 359 return getCalledFunction( castExpr-> get_arg());368 return getCalledFunction( castExpr->arg ); 360 369 } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( expr ) ) { 361 370 return handleDerefCalledFunction( untypedExpr ); … … 363 372 return handleDerefCalledFunction( appExpr ); 364 373 } else if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) { 365 return getCalledFunction( addrExpr->get_arg() ); 374 return getCalledFunction( addrExpr->arg ); 375 } else if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( expr ) ) { 376 return getCalledFunction( commaExpr->arg2 ); 366 377 } 367 378 return nullptr; … … 578 589 FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) { 579 590 FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ); 580 if ( ! function ) return 0;581 if ( function-> get_name() != fname ) return 0;582 FunctionType * ftype = function-> get_functionType();583 if ( ftype-> get_parameters().size() != 2 ) return 0;591 if ( ! function ) return nullptr; 592 if ( function->name != fname ) return nullptr; 593 FunctionType * ftype = function->type; 594 if ( ftype->parameters.size() != 2 ) return nullptr; 584 595 585 596 Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() ); 586 Type * t2 = ftype-> get_parameters().back()->get_type();597 Type * t2 = ftype->parameters.back()->get_type(); 587 598 assert( t1 ); 588 599 … … 604 615 } 605 616 FunctionDecl * isDefaultConstructor( Declaration * decl ) { 606 if ( isConstructor( decl-> get_name()) ) {617 if ( isConstructor( decl->name ) ) { 607 618 if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) { 608 if ( func-> get_functionType()->get_parameters().size() == 1 ) {619 if ( func->type->parameters.size() == 1 ) { 609 620 return func; 610 621 } -
src/InitTweak/InitTweak.h
rb96ec83 r6840e7c 31 31 32 32 /// returns the base type of the first parameter to a constructor/destructor/assignment function 33 Type * getT hisType( FunctionType * ftype );33 Type * getTypeofThis( FunctionType * ftype ); 34 34 35 35 /// returns the first parameter of a constructor/destructor/assignment function 36 ObjectDecl * get ThisParam( FunctionType * ftype );36 ObjectDecl * getParamThis( FunctionType * ftype ); 37 37 38 38 /// transform Initializer into an argument list that can be passed to a call expression … … 105 105 void addArrayIndex( Expression * index, Expression * dimension ); 106 106 void clearArrayIndices(); 107 bool addReference(); 107 108 108 109 class ExpanderImpl; -
src/MakeLibCfa.cc
rb96ec83 r6840e7c 119 119 newDecls.push_back( funcDecl ); 120 120 121 Statement * stmt = nullptr; 121 122 switch ( opInfo.type ) { 122 123 case CodeGen::OT_INDEX: … … 128 129 case CodeGen::OT_POSTFIXASSIGN: 129 130 case CodeGen::OT_INFIXASSIGN: 131 // return the recursive call 132 stmt = new ReturnStmt( noLabels, newExpr ); 133 break; 130 134 case CodeGen::OT_CTOR: 131 135 case CodeGen::OT_DTOR: 132 // returnthe recursive call133 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ));136 // execute the recursive call 137 stmt = new ExprStmt( noLabels, newExpr ); 134 138 break; 135 139 case CodeGen::OT_CONSTANT: … … 138 142 assert( false ); 139 143 } // switch 144 funcDecl->get_statements()->push_back( stmt ); 140 145 } 141 146 } // namespace -
src/Makefile.in
rb96ec83 r6840e7c 175 175 GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \ 176 176 GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT) \ 177 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \178 177 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 179 178 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \ … … 495 494 ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \ 496 495 GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \ 497 GenPoly/Specialize.cc GenPoly/CopyParams.cc \ 498 GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \ 499 InitTweak/GenInit.cc InitTweak/FixInit.cc \ 500 InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \ 501 Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \ 502 Parser/ParseNode.cc Parser/DeclarationNode.cc \ 503 Parser/ExpressionNode.cc Parser/StatementNode.cc \ 504 Parser/InitializerNode.cc Parser/TypeData.cc \ 505 Parser/LinkageSpec.cc Parser/parserutility.cc \ 506 ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \ 507 ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \ 508 ResolvExpr/CommonType.cc ResolvExpr/ConversionCost.cc \ 509 ResolvExpr/CastCost.cc ResolvExpr/PtrsCastable.cc \ 510 ResolvExpr/AdjustExprType.cc ResolvExpr/AlternativePrinter.cc \ 511 ResolvExpr/Resolver.cc ResolvExpr/ResolveTypeof.cc \ 512 ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \ 513 ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \ 514 ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \ 515 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 516 SymTab/FixFunction.cc SymTab/ImplementationType.cc \ 517 SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \ 518 SynTree/VoidType.cc SynTree/BasicType.cc \ 519 SynTree/PointerType.cc SynTree/ArrayType.cc \ 520 SynTree/ReferenceType.cc SynTree/FunctionType.cc \ 521 SynTree/ReferenceToType.cc SynTree/TupleType.cc \ 522 SynTree/TypeofType.cc SynTree/AttrType.cc \ 496 GenPoly/Specialize.cc GenPoly/FindFunction.cc \ 497 GenPoly/InstantiateGeneric.cc InitTweak/GenInit.cc \ 498 InitTweak/FixInit.cc InitTweak/FixGlobalInit.cc \ 499 InitTweak/InitTweak.cc Parser/parser.yy Parser/lex.ll \ 500 Parser/TypedefTable.cc Parser/ParseNode.cc \ 501 Parser/DeclarationNode.cc Parser/ExpressionNode.cc \ 502 Parser/StatementNode.cc Parser/InitializerNode.cc \ 503 Parser/TypeData.cc Parser/LinkageSpec.cc \ 504 Parser/parserutility.cc ResolvExpr/AlternativeFinder.cc \ 505 ResolvExpr/Alternative.cc ResolvExpr/Unify.cc \ 506 ResolvExpr/PtrsAssignable.cc ResolvExpr/CommonType.cc \ 507 ResolvExpr/ConversionCost.cc ResolvExpr/CastCost.cc \ 508 ResolvExpr/PtrsCastable.cc ResolvExpr/AdjustExprType.cc \ 509 ResolvExpr/AlternativePrinter.cc ResolvExpr/Resolver.cc \ 510 ResolvExpr/ResolveTypeof.cc ResolvExpr/RenameVars.cc \ 511 ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \ 512 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \ 513 ResolvExpr/CurrentObject.cc SymTab/Indexer.cc \ 514 SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \ 515 SymTab/ImplementationType.cc SymTab/TypeEquality.cc \ 516 SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \ 517 SynTree/BasicType.cc SynTree/PointerType.cc \ 518 SynTree/ArrayType.cc SynTree/ReferenceType.cc \ 519 SynTree/FunctionType.cc SynTree/ReferenceToType.cc \ 520 SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \ 523 521 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 524 522 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 718 716 GenPoly/$(DEPDIR)/$(am__dirstamp) 719 717 GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \ 720 GenPoly/$(DEPDIR)/$(am__dirstamp)721 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT): GenPoly/$(am__dirstamp) \722 718 GenPoly/$(DEPDIR)/$(am__dirstamp) 723 719 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT): \ … … 997 993 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@ 998 994 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@ 999 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po@am__quote@1000 995 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@ 1001 996 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@ … … 1479 1474 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Specialize.obj `if test -f 'GenPoly/Specialize.cc'; then $(CYGPATH_W) 'GenPoly/Specialize.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Specialize.cc'; fi` 1480 1475 1481 GenPoly/driver_cfa_cpp-CopyParams.o: GenPoly/CopyParams.cc1482 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-CopyParams.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo -c -o GenPoly/driver_cfa_cpp-CopyParams.o `test -f 'GenPoly/CopyParams.cc' || echo '$(srcdir)/'`GenPoly/CopyParams.cc1483 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po1484 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/CopyParams.cc' object='GenPoly/driver_cfa_cpp-CopyParams.o' libtool=no @AMDEPBACKSLASH@1485 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@1486 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-CopyParams.o `test -f 'GenPoly/CopyParams.cc' || echo '$(srcdir)/'`GenPoly/CopyParams.cc1487 1488 GenPoly/driver_cfa_cpp-CopyParams.obj: GenPoly/CopyParams.cc1489 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-CopyParams.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo -c -o GenPoly/driver_cfa_cpp-CopyParams.obj `if test -f 'GenPoly/CopyParams.cc'; then $(CYGPATH_W) 'GenPoly/CopyParams.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/CopyParams.cc'; fi`1490 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po1491 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/CopyParams.cc' object='GenPoly/driver_cfa_cpp-CopyParams.obj' libtool=no @AMDEPBACKSLASH@1492 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@1493 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-CopyParams.obj `if test -f 'GenPoly/CopyParams.cc'; then $(CYGPATH_W) 'GenPoly/CopyParams.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/CopyParams.cc'; fi`1494 1495 1476 GenPoly/driver_cfa_cpp-FindFunction.o: GenPoly/FindFunction.cc 1496 1477 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-FindFunction.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo -c -o GenPoly/driver_cfa_cpp-FindFunction.o `test -f 'GenPoly/FindFunction.cc' || echo '$(srcdir)/'`GenPoly/FindFunction.cc -
src/Parser/DeclarationNode.cc
rb96ec83 r6840e7c 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Aug 10 17:02:00201713 // Update Count : 102 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Sep 23 18:16:48 2017 13 // Update Count : 1024 14 14 // 15 15 … … 40 40 using namespace std; 41 41 42 // These must remain in the same order asthe corresponding DeclarationNode enumerations.43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", " NoBasicTypeNames" };42 // These must harmonize with the corresponding DeclarationNode enumerations. 43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "int128", "float80", "float128", "NoBasicTypeNames" }; 44 44 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" }; 45 45 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; -
src/Parser/ExpressionNode.cc
rb96ec83 r6840e7c 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Sep 14 23:09:34201713 // Update Count : 69012 // Last Modified On : Wed Sep 27 22:51:55 2017 13 // Update Count : 781 14 14 // 15 15 … … 60 60 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 61 61 62 static const char * lnthsInt[2][6] = { 63 { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", }, 64 { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", } 65 }; // lnthsInt 66 67 static inline void checkLNInt( string & str, int & lnth, int & size ) { 68 string::size_type posn = str.find_first_of( "lL" ), start = posn; 69 if ( posn == string::npos ) return; 70 size = 4; // assume largest size 71 posn += 1; // advance to size 72 if ( str[posn] == '8' ) { // 8 73 lnth = 0; 74 } else if ( str[posn] == '1' ) { 75 posn += 1; 76 if ( str[posn] == '6' ) { // 16 77 lnth = 1; 78 } else { // 128 79 posn += 1; 80 lnth = 5; 81 } // if 82 } else { 83 if ( str[posn] == '3' ) { // 32 84 lnth = 2; 85 } else if ( str[posn] == '6' ) { // 64 86 lnth = 3; 87 } else { 88 assertf( false, "internal error, bad integral length %s", str.c_str() ); 89 } // if 90 posn += 1; 91 } // if 92 str.erase( start, posn - start + 1 ); // remove length suffix 93 } // checkLNInt 94 62 95 static void sepNumeric( string & str, string & units ) { 63 96 string::size_type posn = str.find_first_of( "`" ); … … 69 102 70 103 Expression * build_constantInteger( string & str ) { 71 static const BasicType::Kind kind[2][ 5] = {104 static const BasicType::Kind kind[2][6] = { 72 105 // short (h) must be before char (hh) 73 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },74 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },106 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, }, 107 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, }, 75 108 }; 76 109 77 string units; // units110 string units; 78 111 sepNumeric( str, units ); // separate constant from units 79 112 80 113 bool dec = true, Unsigned = false; // decimal, unsigned constant 81 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t 114 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 115 int lnth = -1; // literal length 116 82 117 unsigned long long int v; // converted integral value 83 118 size_t last = str.length() - 1; // last character of constant … … 140 175 } // if 141 176 str.erase( last - size - 1, size + 1 ); // remove 'h'/"hh" 177 } else { // suffix "ln" ? 178 checkLNInt( str, lnth, size ); 142 179 } // if 143 180 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ? … … 163 200 str.erase( last - size, size + 1 ); // remove 'h'/"hh" 164 201 } else if ( checkZ( str[last] ) ) { // suffix 'z' ? 165 size = 5;202 lnth = 4; 166 203 str.erase( last, 1 ); // remove 'z' 167 } // if 168 204 } else { // suffix "ln" ? 205 checkLNInt( str, lnth, size ); 206 } // if 207 208 assert( 0 <= size && size < 6 ); 209 // Constant type is correct for overload resolving. 169 210 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) ); 170 if ( Unsigned && size < 2 ) { // less than int ?171 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which eliminates warnings for large values.211 if ( Unsigned && size < 2 ) { // hh or h, less than int ? 212 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 172 213 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) ); 173 } else if ( size == 5 ) { // explicit cast to size_t 174 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), "size_t", false ) ); 214 } else if ( lnth != -1 ) { // explicit length ? 215 if ( lnth == 5 ) { // int128 ? 216 size = 5; 217 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) ); 218 } else { 219 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ) ); 220 } // if 175 221 } // if 176 222 CLEANUP: … … 182 228 return ret; 183 229 } // build_constantInteger 230 231 232 static inline void checkLNFloat( string & str, int & lnth, int & size ) { 233 string::size_type posn = str.find_first_of( "lL" ), start = posn; 234 if ( posn == string::npos ) return; 235 size = 2; // assume largest size 236 lnth = 0; 237 posn += 1; // advance to size 238 if ( str[posn] == '3' ) { // 32 239 size = 0; 240 } else if ( str[posn] == '6' ) { // 64 241 size = 1; 242 } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128 243 size = 2; 244 if ( str[posn] == '1' ) posn += 1; 245 } else { 246 assertf( false, "internal error, bad floating point length %s", str.c_str() ); 247 } // if 248 posn += 1; 249 str.erase( start, posn - start + 1 ); // remove length suffix 250 } // checkLNFloat 251 184 252 185 253 Expression * build_constantFloat( string & str ) { … … 189 257 }; 190 258 191 string units; // units259 string units; 192 260 sepNumeric( str, units ); // separate constant from units 193 261 194 262 bool complx = false; // real, complex 195 int size = 1; // 0 => float, 1 => double (default), 2 => long double 263 int size = 1; // 0 => float, 1 => double, 2 => long double 264 int lnth = -1; // literal length 196 265 // floating-point constant has minimum of 2 characters: 1. or .1 197 266 size_t last = str.length() - 1; … … 211 280 } else if ( checkL( str[last] ) ) { // long double ? 212 281 size = 2; 282 } else { 283 size = 1; // double (default) 284 checkLNFloat( str, lnth, size ); 213 285 } // if 214 286 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ? … … 216 288 } // if 217 289 290 assert( 0 <= size && size < 3 ); 218 291 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) ); 292 if ( lnth != -1 ) { // explicit length ? 293 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ) ); 294 } // if 219 295 if ( units.length() != 0 ) { 220 296 ret = new UntypedExpr( new NameExpr( units ), { ret } ); … … 321 397 322 398 NameExpr * build_varref( const string * name ) { 323 NameExpr * expr = new NameExpr( *name , nullptr);399 NameExpr * expr = new NameExpr( *name ); 324 400 delete name; 325 401 return expr; … … 412 488 list< Expression * > args; 413 489 buildMoveList( expr_node, args ); 414 return new UntypedExpr( maybeMoveBuild< Expression >(function), args , nullptr);490 return new UntypedExpr( maybeMoveBuild< Expression >(function), args ); 415 491 } // build_func 416 492 -
src/Parser/ParseNode.h
rb96ec83 r6840e7c 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Sep 14 23:09:39201713 // Update Count : 8 1512 // Last Modified On : Sat Sep 23 18:11:22 2017 13 // Update Count : 821 14 14 // 15 15 … … 47 47 #define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */ 48 48 49 extern char * yyfilename;50 extern int yylineno;51 49 extern YYLTYPE yylloc; 52 50 … … 197 195 class DeclarationNode : public ParseNode { 198 196 public: 199 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType }; 197 // These enumerations must harmonize with their names. 198 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType }; 199 static const char * basicTypeNames[]; 200 200 enum ComplexType { Complex, Imaginary, NoComplexType }; 201 static const char * complexTypeNames[]; 201 202 enum Signedness { Signed, Unsigned, NoSignedness }; 203 static const char * signednessNames[]; 202 204 enum Length { Short, Long, LongLong, NoLength }; 205 static const char * lengthNames[]; 203 206 enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate }; 207 static const char * aggregateNames[]; 204 208 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass }; 209 static const char * typeClassNames[]; 205 210 enum BuiltinType { Valist, Zero, One, NoBuiltinType }; 206 207 static const char * basicTypeNames[];208 static const char * complexTypeNames[];209 static const char * signednessNames[];210 static const char * lengthNames[];211 static const char * aggregateNames[];212 static const char * typeClassNames[];213 211 static const char * builtinTypeNames[]; 214 212 -
src/Parser/TypeData.cc
rb96ec83 r6840e7c 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 1 23:13:38201713 // Update Count : 5 6912 // Last Modified On : Mon Sep 25 18:33:41 2017 13 // Update Count : 587 14 14 // 15 15 … … 98 98 } // TypeData::TypeData 99 99 100 100 101 TypeData::~TypeData() { 101 102 delete base; … … 161 162 } // switch 162 163 } // TypeData::~TypeData 164 163 165 164 166 TypeData * TypeData::clone() const { … … 235 237 } // TypeData::clone 236 238 239 237 240 void TypeData::print( ostream &os, int indent ) const { 238 241 for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) { … … 398 401 } // switch 399 402 } // TypeData::print 403 400 404 401 405 template< typename ForallList > … … 430 434 } // if 431 435 } // for 432 } 436 } // buildForall 437 433 438 434 439 Type * typebuild( const TypeData * td ) { … … 477 482 } // typebuild 478 483 484 479 485 TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) { 480 486 TypeData * ret = nullptr; … … 504 510 } // typeextractAggregate 505 511 512 506 513 Type::Qualifiers buildQualifiers( const TypeData * td ) { 507 514 return td->qualifiers; 508 515 } // buildQualifiers 509 516 517 518 static string genTSError( string msg, DeclarationNode::BasicType basictype ) { 519 throw SemanticError( string( "invalid type specifier \"" ) + msg + "\" for type \"" + DeclarationNode::basicTypeNames[basictype] + "\"." ); 520 } // genTSError 521 510 522 Type * buildBasicType( const TypeData * td ) { 511 523 BasicType::Kind ret; … … 513 525 switch ( td->basictype ) { 514 526 case DeclarationNode::Void: 515 if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) { 516 throw SemanticError( "invalid type specifier \"void\" in type: ", td ); 517 } // if 518 527 if ( td->signedness != DeclarationNode::NoSignedness ) { 528 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); 529 } // if 530 if ( td->length != DeclarationNode::NoLength ) { 531 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 532 } // if 519 533 return new VoidType( buildQualifiers( td ) ); 520 534 break; … … 522 536 case DeclarationNode::Bool: 523 537 if ( td->signedness != DeclarationNode::NoSignedness ) { 524 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessNames[ td->signedness ] + " in type: ", td);538 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); 525 539 } // if 526 540 if ( td->length != DeclarationNode::NoLength ) { 527 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td);541 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 528 542 } // if 529 543 … … 538 552 539 553 if ( td->length != DeclarationNode::NoLength ) { 540 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td);554 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 541 555 } // if 542 556 … … 557 571 break; 558 572 573 case DeclarationNode::Int128: 574 ret = td->signedness == 1 ? BasicType::UnsignedInt128 : BasicType::SignedInt128; 575 if ( td->length != DeclarationNode::NoLength ) { 576 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 577 } // if 578 break; 579 559 580 case DeclarationNode::Float: 581 case DeclarationNode::Float80: 582 case DeclarationNode::Float128: 560 583 case DeclarationNode::Double: 561 584 case DeclarationNode::LongDouble: // not set until below … … 568 591 FloatingPoint: ; 569 592 if ( td->signedness != DeclarationNode::NoSignedness ) { 570 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessNames[ td->signedness ] + " in type: ", td);593 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); 571 594 } // if 572 595 if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) { 573 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td);596 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 574 597 } // if 575 598 if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) { 576 throw SemanticError( "invalid type specifier \"long\" in type: ", td);599 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 577 600 } // if 578 601 if ( td->length == DeclarationNode::Long ) { … … 593 616 goto Integral; 594 617 default: 595 assert (false);618 assertf( false, "unknown basic type" ); 596 619 return nullptr; 597 620 } // switch … … 601 624 return bt; 602 625 } // buildBasicType 626 603 627 604 628 PointerType * buildPointer( const TypeData * td ) { … … 612 636 return pt; 613 637 } // buildPointer 638 614 639 615 640 ArrayType * buildArray( const TypeData * td ) { … … 626 651 } // buildArray 627 652 653 628 654 ReferenceType * buildReference( const TypeData * td ) { 629 655 ReferenceType * rt; … … 637 663 } // buildReference 638 664 665 639 666 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 640 667 assert( td->kind == TypeData::Aggregate ); … … 665 692 return at; 666 693 } // buildAggregate 694 667 695 668 696 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { … … 722 750 } // buildAggInst 723 751 752 724 753 ReferenceToType * buildAggInst( const TypeData * td ) { 725 754 assert( td->kind == TypeData::AggregateInst ); … … 761 790 } // buildAggInst 762 791 792 763 793 NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) { 764 794 assert( td->kind == TypeData::Symbolic ); … … 775 805 } // buildSymbolic 776 806 807 777 808 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 778 809 assert( td->kind == TypeData::Enum ); … … 790 821 } // buildEnum 791 822 823 792 824 TypeInstType * buildSymbolicInst( const TypeData * td ) { 793 825 assert( td->kind == TypeData::SymbolicInst ); … … 797 829 return ret; 798 830 } // buildSymbolicInst 831 799 832 800 833 TupleType * buildTuple( const TypeData * td ) { … … 807 840 } // buildTuple 808 841 842 809 843 TypeofType * buildTypeof( const TypeData * td ) { 810 844 assert( td->kind == TypeData::Typeof ); … … 813 847 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() ); 814 848 } // buildTypeof 849 815 850 816 851 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) { … … 836 871 return nullptr; 837 872 } // buildDecl 873 838 874 839 875 FunctionType * buildFunction( const TypeData * td ) { … … 857 893 return ft; 858 894 } // buildFunction 895 859 896 860 897 // Transform KR routine declarations into C99 routine declarations: -
src/Parser/lex.ll
rb96ec83 r6840e7c 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : S un Sep 10 22:29:15201713 * Update Count : 6 2012 * Last Modified On : Sat Sep 23 17:29:28 2017 13 * Update Count : 632 14 14 */ 15 15 … … 93 93 // numeric constants, CFA: '_' in constant 94 94 hex_quad {hex}("_"?{hex}){3} 95 length ("ll"|"LL"|[lL])|("hh"|"HH"|[hH]) 95 size_opt (8|16|32|64|128)? 96 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH]) 96 97 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?{user_suffix_opt} 97 98 … … 109 110 // GCC: D (double) and iI (imaginary) suffixes, and DL (long double) 110 111 exponent "_"?[eE]"_"?[+-]?{decimal_digits} 111 floating_suffix ([fFdDlL]?[iI]?)|([iI][lLfFdD]) 112 floating_size 32|64|80|128 113 floating_length ([fFdDlL]|[lL]{floating_size}) 114 floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length}) 112 115 floating_suffix_opt ("_"?({floating_suffix}|"DL"))?{user_suffix_opt} 113 116 decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal}) … … 234 237 finally { KEYWORD_RETURN(FINALLY); } // CFA 235 238 float { KEYWORD_RETURN(FLOAT); } 236 __float128 { KEYWORD_RETURN(FLOAT); } // GCC 239 __float80 { KEYWORD_RETURN(FLOAT80); } // GCC 240 float80 { KEYWORD_RETURN(FLOAT80); } // GCC 241 __float128 { KEYWORD_RETURN(FLOAT128); } // GCC 242 float128 { KEYWORD_RETURN(FLOAT128); } // GCC 237 243 for { KEYWORD_RETURN(FOR); } 238 244 forall { KEYWORD_RETURN(FORALL); } // CFA … … 249 255 __inline__ { KEYWORD_RETURN(INLINE); } // GCC 250 256 int { KEYWORD_RETURN(INT); } 251 __int128 { KEYWORD_RETURN(INT ); } // GCC252 __int128_t { KEYWORD_RETURN(INT); } // GCC257 __int128 { KEYWORD_RETURN(INT128); } // GCC 258 int128 { KEYWORD_RETURN(INT128); } // GCC 253 259 __label__ { KEYWORD_RETURN(LABEL); } // GCC 254 260 long { KEYWORD_RETURN(LONG); } … … 285 291 __typeof { KEYWORD_RETURN(TYPEOF); } // GCC 286 292 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC 287 __uint128_t { KEYWORD_RETURN(INT); } // GCC288 293 union { KEYWORD_RETURN(UNION); } 289 294 unsigned { KEYWORD_RETURN(UNSIGNED); } -
src/Parser/parser.yy
rb96ec83 r6840e7c 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Sep 14 23:07:12201713 // Update Count : 28 1512 // Last Modified On : Mon Oct 16 11:07:29 2017 13 // Update Count : 2892 14 14 // 15 15 … … 43 43 #define YYDEBUG_LEXER_TEXT (yylval) // lexer loads this up each time 44 44 #define YYDEBUG 1 // get the pretty debugging code to compile 45 #define YYERROR_VERBOSE 45 #define YYERROR_VERBOSE // more information in syntax errors 46 46 47 47 #undef __GNUC_MINOR__ … … 117 117 bool forall = false; // aggregate have one or more forall qualifiers ? 118 118 119 # define YYLLOC_DEFAULT(Cur, Rhs, N) \ 120 do \ 121 if (N) { \ 122 (Cur).first_line = YYRHSLOC(Rhs, 1).first_line; \ 123 (Cur).first_column = YYRHSLOC(Rhs, 1).first_column; \ 124 (Cur).last_line = YYRHSLOC(Rhs, N).last_line; \ 125 (Cur).last_column = YYRHSLOC(Rhs, N).last_column; \ 126 (Cur).filename = YYRHSLOC(Rhs, 1).filename; \ 127 } else { \ 128 (Cur).first_line = (Cur).last_line = \ 129 YYRHSLOC(Rhs, 0).last_line; \ 130 (Cur).first_column = (Cur).last_column = \ 131 YYRHSLOC(Rhs, 0).last_column; \ 132 (Cur).filename = YYRHSLOC(Rhs, 0).filename; \ 133 } \ 134 while (0) 119 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type 120 #define YYLLOC_DEFAULT(Cur, Rhs, N) \ 121 if ( N ) { \ 122 (Cur).first_line = YYRHSLOC( Rhs, 1 ).first_line; \ 123 (Cur).first_column = YYRHSLOC( Rhs, 1 ).first_column; \ 124 (Cur).last_line = YYRHSLOC( Rhs, N ).last_line; \ 125 (Cur).last_column = YYRHSLOC( Rhs, N ).last_column; \ 126 (Cur).filename = YYRHSLOC( Rhs, 1 ).filename; \ 127 } else { \ 128 (Cur).first_line = (Cur).last_line = YYRHSLOC( Rhs, 0 ).last_line; \ 129 (Cur).first_column = (Cur).last_column = YYRHSLOC( Rhs, 0 ).last_column; \ 130 (Cur).filename = YYRHSLOC( Rhs, 0 ).filename; \ 131 } 135 132 %} 136 133 137 134 %define parse.error verbose 138 135 139 // Types declaration 136 // Types declaration for productions 140 137 %union 141 138 { … … 173 170 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 174 171 %token BOOL COMPLEX IMAGINARY // C99 172 %token INT128 FLOAT80 FLOAT128 // GCC 175 173 %token ZERO_T ONE_T // CFA 176 174 %token VALIST // GCC … … 252 250 %type<sn> exception_statement handler_clause finally_clause 253 251 %type<catch_kind> handler_key 252 %type<sn> mutex_statement 254 253 %type<en> when_clause when_clause_opt waitfor timeout 255 254 %type<sn> waitfor_statement … … 458 457 | '(' compound_statement ')' // GCC, lambda expression 459 458 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >($2) ) ) ); } 460 | primary_expression '{' argument_expression_list '}' // CFA, constructor call461 {462 Token fn;463 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'?464 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );465 }466 459 | type_name '.' no_attr_identifier // CFA, nested type 467 460 { $$ = nullptr; } // FIX ME … … 478 471 // equivalent to the old x[i,j]. 479 472 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $4 ) ); } 473 | postfix_expression '{' argument_expression_list '}' // CFA, constructor call 474 { 475 Token fn; 476 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 477 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 478 } 480 479 | postfix_expression '(' argument_expression_list ')' 481 480 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } … … 809 808 | jump_statement 810 809 | with_statement 810 | mutex_statement 811 811 | waitfor_statement 812 812 | exception_statement … … 1033 1033 ; 1034 1034 1035 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex". 1036 mutex_statement: 1037 MUTEX '(' argument_expression_list ')' statement 1038 { $$ = nullptr; } // FIX ME 1039 ; 1040 1035 1041 when_clause: 1036 1042 WHEN '(' comma_expression ')' … … 1551 1557 | VOLATILE 1552 1558 { $$ = DeclarationNode::newTypeQualifier( Type::Volatile ); } 1553 | MUTEX1554 { $$ = DeclarationNode::newTypeQualifier( Type::Mutex ); }1555 1559 | ATOMIC 1556 1560 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } … … 1606 1610 1607 1611 basic_type_name: 1608 CHAR 1612 VOID 1613 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 1614 | BOOL // C99 1615 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 1616 | CHAR 1609 1617 { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); } 1618 | INT 1619 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); } 1620 | INT128 1621 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); } 1622 | FLOAT 1623 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); } 1624 | FLOAT80 1625 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float80 ); } 1626 | FLOAT128 1627 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float128 ); } 1610 1628 | DOUBLE 1611 1629 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); } 1612 | FLOAT 1613 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); } 1614 | INT 1615 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); } 1616 | LONG 1617 { $$ = DeclarationNode::newLength( DeclarationNode::Long ); } 1618 | SHORT 1619 { $$ = DeclarationNode::newLength( DeclarationNode::Short ); } 1630 | COMPLEX // C99 1631 { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); } 1632 | IMAGINARY // C99 1633 { $$ = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); } 1620 1634 | SIGNED 1621 1635 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Signed ); } 1622 1636 | UNSIGNED 1623 1637 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); } 1624 | VOID 1625 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 1626 | BOOL // C99 1627 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 1628 | COMPLEX // C99 1629 { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); } 1630 | IMAGINARY // C99 1631 { $$ = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); } 1638 | SHORT 1639 { $$ = DeclarationNode::newLength( DeclarationNode::Short ); } 1640 | LONG 1641 { $$ = DeclarationNode::newLength( DeclarationNode::Long ); } 1632 1642 | ZERO_T 1633 1643 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); } … … 2699 2709 paren_identifier attribute_list_opt 2700 2710 { $$ = $1->addQualifiers( $2 ); } 2711 | '&' MUTEX paren_identifier attribute_list_opt 2712 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); } 2701 2713 | identifier_parameter_ptr 2702 2714 | identifier_parameter_array attribute_list_opt … … 2739 2751 // 2740 2752 // typedef int foo; 2753 // forall( otype T ) foo( T ); 2741 2754 // int f( int foo ); // redefine typedef name in new scope 2742 2755 // … … 2746 2759 typedef attribute_list_opt 2747 2760 { $$ = $1->addQualifiers( $2 ); } 2761 | '&' MUTEX typedef attribute_list_opt 2762 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); } 2748 2763 | type_parameter_ptr 2749 2764 | type_parameter_array attribute_list_opt … … 2892 2907 abstract_parameter_declarator: 2893 2908 abstract_parameter_ptr 2909 | '&' MUTEX attribute_list_opt 2910 { $$ = DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf )->addQualifiers( $3 ); } 2894 2911 | abstract_parameter_array attribute_list_opt 2895 2912 { $$ = $1->addQualifiers( $2 ); } -
src/ResolvExpr/AdjustExprType.cc
rb96ec83 r6840e7c 14 14 // 15 15 16 #include "Common/PassVisitor.h" 16 17 #include "SymTab/Indexer.h" // for Indexer 17 18 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Kind::Ftype … … 21 22 22 23 namespace ResolvExpr { 23 class AdjustExprType : public Mutator { 24 typedef Mutator Parent; 25 using Parent::mutate; 24 class AdjustExprType : public WithShortCircuiting { 26 25 public: 27 26 AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer ); 27 void premutate( VoidType * ) { visit_children = false; } 28 void premutate( BasicType * ) { visit_children = false; } 29 void premutate( PointerType * ) { visit_children = false; } 30 void premutate( FunctionType * ) { visit_children = false; } 31 void premutate( StructInstType * ) { visit_children = false; } 32 void premutate( UnionInstType * ) { visit_children = false; } 33 void premutate( EnumInstType * ) { visit_children = false; } 34 void premutate( TraitInstType * ) { visit_children = false; } 35 void premutate( TypeInstType * ) { visit_children = false; } 36 void premutate( TupleType * ) { visit_children = false; } 37 void premutate( VarArgsType * ) { visit_children = false; } 38 void premutate( ZeroType * ) { visit_children = false; } 39 void premutate( OneType * ) { visit_children = false; } 40 41 Type * postmutate( ArrayType *arrayType ); 42 Type * postmutate( FunctionType *functionType ); 43 Type * postmutate( TypeInstType *aggregateUseType ); 44 28 45 private: 29 virtual Type* mutate( VoidType *voidType );30 virtual Type* mutate( BasicType *basicType );31 virtual Type* mutate( PointerType *pointerType );32 virtual Type* mutate( ArrayType *arrayType );33 virtual Type* mutate( FunctionType *functionType );34 virtual Type* mutate( StructInstType *aggregateUseType );35 virtual Type* mutate( UnionInstType *aggregateUseType );36 virtual Type* mutate( EnumInstType *aggregateUseType );37 virtual Type* mutate( TraitInstType *aggregateUseType );38 virtual Type* mutate( TypeInstType *aggregateUseType );39 virtual Type* mutate( TupleType *tupleType );40 virtual Type* mutate( VarArgsType *varArgsType );41 virtual Type* mutate( ZeroType *zeroType );42 virtual Type* mutate( OneType *oneType );43 44 46 const TypeEnvironment &env; 45 47 const SymTab::Indexer &indexer; … … 47 49 48 50 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 49 AdjustExprTypeadjuster( env, indexer );51 PassVisitor<AdjustExprType> adjuster( env, indexer ); 50 52 Type *newType = type->acceptMutator( adjuster ); 51 53 type = newType; … … 56 58 } 57 59 58 Type *AdjustExprType::mutate( VoidType *voidType ) { 59 return voidType; 60 } 61 62 Type *AdjustExprType::mutate( BasicType *basicType ) { 63 return basicType; 64 } 65 66 Type *AdjustExprType::mutate( PointerType *pointerType ) { 67 return pointerType; 68 } 69 70 Type *AdjustExprType::mutate( ArrayType *arrayType ) { 60 Type * AdjustExprType::postmutate( ArrayType * arrayType ) { 71 61 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 72 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ) ); 62 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base ); 63 arrayType->base = nullptr; 73 64 delete arrayType; 74 65 return pointerType; 75 66 } 76 67 77 Type *AdjustExprType::mutate( FunctionType *functionType ) { 78 PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType ); 79 return pointerType; 68 Type * AdjustExprType::postmutate( FunctionType * functionType ) { 69 return new PointerType( Type::Qualifiers(), functionType ); 80 70 } 81 71 82 Type *AdjustExprType::mutate( StructInstType *aggregateUseType ) { 83 return aggregateUseType; 84 } 85 86 Type *AdjustExprType::mutate( UnionInstType *aggregateUseType ) { 87 return aggregateUseType; 88 } 89 90 Type *AdjustExprType::mutate( EnumInstType *aggregateUseType ) { 91 return aggregateUseType; 92 } 93 94 Type *AdjustExprType::mutate( TraitInstType *aggregateUseType ) { 95 return aggregateUseType; 96 } 97 98 Type *AdjustExprType::mutate( TypeInstType *typeInst ) { 72 Type * AdjustExprType::postmutate( TypeInstType * typeInst ) { 99 73 EqvClass eqvClass; 100 74 if ( env.lookup( typeInst->get_name(), eqvClass ) ) { … … 113 87 return typeInst; 114 88 } 115 116 Type *AdjustExprType::mutate( TupleType *tupleType ) {117 return tupleType;118 }119 120 Type *AdjustExprType::mutate( VarArgsType *varArgsType ) {121 return varArgsType;122 }123 124 Type *AdjustExprType::mutate( ZeroType *zeroType ) {125 return zeroType;126 }127 128 Type *AdjustExprType::mutate( OneType *oneType ) {129 return oneType;130 }131 89 } // namespace ResolvExpr 132 90 -
src/ResolvExpr/Alternative.cc
rb96ec83 r6840e7c 66 66 } 67 67 68 void Alternative::print( std::ostream &os, intindent ) const {69 os << std::string( indent, ' ' ) <<"Cost " << cost << ": ";68 void Alternative::print( std::ostream &os, Indenter indent ) const { 69 os << "Cost " << cost << ": "; 70 70 if ( expr ) { 71 expr->print( os, indent );72 os << "(types:" << std::endl;73 os << std::string( indent+4, ' ' );74 expr-> get_result()->print( os, indent + 4);75 os << std::endl << ")" << std::endl;71 expr->print( os, indent+1 ); 72 os << std::endl << indent << "(types:" << std::endl; 73 os << indent+1; 74 expr->result->print( os, indent+1 ); 75 os << std::endl << indent << ")" << std::endl; 76 76 } else { 77 77 os << "Null expression!" << std::endl; 78 78 } // if 79 os << std::string( indent, ' ' )<< "Environment: ";80 env.print( os, indent+ 2);79 os << indent << "Environment: "; 80 env.print( os, indent+1 ); 81 81 os << std::endl; 82 82 } -
src/ResolvExpr/Alternative.h
rb96ec83 r6840e7c 39 39 ~Alternative(); 40 40 41 void print( std::ostream &os, int indent = 0) const;41 void print( std::ostream &os, Indenter indent = {} ) const; 42 42 43 43 Cost cost; -
src/ResolvExpr/AlternativeFinder.cc
rb96ec83 r6840e7c 75 75 76 76 namespace { 77 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) { 77 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) { 78 Indenter indent = { Indenter::tabsize, indentAmt }; 78 79 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 79 80 i->print( os, indent ); … … 195 196 AltList winners; 196 197 findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) ); 197 stream << "Cannot choose between " << winners.size() << " alternatives for expression 198 stream << "Cannot choose between " << winners.size() << " alternatives for expression\n"; 198 199 expr->print( stream ); 199 stream << "Alternatives are: ";200 printAlts( winners, stream, 8);200 stream << "Alternatives are:\n"; 201 printAlts( winners, stream, 1 ); 201 202 throw SemanticError( stream.str() ); 202 203 } … … 604 605 Alternative newerAlt( newAlt ); 605 606 newerAlt.env = newEnv; 606 assert ( (*candidate)->get_uniqueId() );607 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() ); 607 608 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 608 609 … … 728 729 PRINT( 729 730 std::cerr << "known function ops:" << std::endl; 730 printAlts( funcOpFinder.alternatives, std::cerr, 8);731 printAlts( funcOpFinder.alternatives, std::cerr, 1 ); 731 732 ) 732 733 … … 838 839 bool isLvalue( Expression *expr ) { 839 840 // xxx - recurse into tuples? 840 return expr-> has_result()&& ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );841 return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) ); 841 842 } 842 843 … … 972 973 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 973 974 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 974 VariableExpr newExpr( *i , nameExpr->get_argName());975 VariableExpr newExpr( *i ); 975 976 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 976 977 PRINT( … … 1267 1268 // O(N^2) checks of d-types with e-types 1268 1269 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { 1269 Type * toType = resolveTypeof( initAlt.type , indexer );1270 Type * toType = resolveTypeof( initAlt.type->clone(), indexer ); 1270 1271 SymTab::validateType( toType, &indexer ); 1271 1272 adjustExprType( toType, env, indexer ); -
src/ResolvExpr/CastCost.cc
rb96ec83 r6840e7c 24 24 #include "typeops.h" // for typesCompatibleIgnoreQualifiers 25 25 26 #if 0 27 #define PRINT(x) x 28 #else 29 #define PRINT(x) 30 #endif 26 31 27 32 namespace ResolvExpr { … … 52 57 } // if 53 58 } // if 59 60 PRINT( 61 std::cerr << "castCost ::: src is "; 62 src->print( std::cerr ); 63 std::cerr << std::endl << "dest is "; 64 dest->print( std::cerr ); 65 std::cerr << std::endl << "env is" << std::endl; 66 env.print( std::cerr, 8 ); 67 ) 68 54 69 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 70 PRINT( std::cerr << "compatible!" << std::endl; ) 55 71 return Cost::zero; 56 72 } else if ( dynamic_cast< VoidType* >( dest ) ) { 57 73 return Cost::safe; 58 74 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 75 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 59 76 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer & indexer) { 60 77 return ptrsCastable( t1, t2, env, indexer ); -
src/ResolvExpr/CommonType.cc
rb96ec83 r6840e7c 10 10 // Created On : Sun May 17 06:59:27 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 16:24:31201713 // Update Count : 712 // Last Modified On : Mon Sep 25 15:18:17 2017 13 // Update Count : 9 14 14 // 15 15 … … 150 150 static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = 151 151 { 152 /* Bool Char SignedChar UnsignedChar ShortSignedInt ShortUnsignedInt SignedInt UnsignedInt LongSignedInt LongUnsignedInt LongLongSignedInt LongLongUnsignedInt Float Double LongDouble FloatComplex DoubleComplex LongDoubleComplex FloatImaginary DoubleImaginary LongDoubleImaginary */ 153 /* Bool */ { BasicType::Bool, BasicType::Char, BasicType::SignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 154 /* Char */ { BasicType::Char, BasicType::Char, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 155 /* SignedChar */ { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::SignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 156 /* UnsignedChar */ { BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 157 /* ShortSignedInt */ { BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 158 /* ShortUnsignedInt */ { BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 159 /* SignedInt */ { BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 160 /* UnsignedInt */ { BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 161 /* LongSignedInt */ { BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 162 /* LongUnsignedInt */ { BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 163 /* LongLongSignedInt */ { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 164 /* LongLongUnsignedInt */ { BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 165 /* Float */ { BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 166 /* Double */ { BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::LongDouble, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 167 /* LongDouble */ { BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex }, 168 /* FloatComplex */ { BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 169 /* DoubleComplex */ { BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 170 /* LongDoubleComplex */ { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex }, 171 /* FloatImaginary */ { BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary }, 172 /* DoubleImaginary */ { BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary }, 173 /* LongDoubleImaginary */ { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary } 152 /* Bool Char SignedChar UnsignedChar ShortSignedInt ShortUnsignedInt SignedInt UnsignedInt LongSignedInt LongUnsignedInt LongLongSignedInt LongLongUnsignedInt Float Double LongDouble FloatComplex DoubleComplex LongDoubleComplex FloatImaginary DoubleImaginary LongDoubleImaginary SignedInt128 UnsignedInt128 */ 153 /* Bool */ { BasicType::Bool, BasicType::Char, BasicType::SignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 154 /* Char */ { BasicType::Char, BasicType::Char, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 155 /* SignedChar */ { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::SignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 156 /* UnsignedChar */ { BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 157 /* ShortSignedInt */ { BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 158 /* ShortUnsignedInt */ { BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 159 /* SignedInt */ { BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 160 /* UnsignedInt */ { BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 161 /* LongSignedInt */ { BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 162 /* LongUnsignedInt */ { BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 163 /* LongLongSignedInt */ { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 164 /* LongLongUnsignedInt */ { BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 165 /* Float */ { BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::Float, BasicType::Float, }, 166 /* Double */ { BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::LongDouble, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::Double, BasicType::Double, }, 167 /* LongDouble */ { BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDouble, BasicType::LongDouble, }, 168 /* FloatComplex */ { BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::FloatComplex, }, 169 /* DoubleComplex */ { BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, }, 170 /* LongDoubleComplex */ { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, }, 171 /* FloatImaginary */ { BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::FloatImaginary, BasicType::FloatImaginary, }, 172 /* DoubleImaginary */ { BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::DoubleImaginary, BasicType::DoubleImaginary, }, 173 /* LongDoubleImaginary */ { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary }, 174 /* SignedInt128 */ { BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, }, 175 /* UnsignedInt128 */ { BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::UnsignedInt128, BasicType::UnsignedInt128, }, 174 176 }; 175 177 -
src/ResolvExpr/ConversionCost.cc
rb96ec83 r6840e7c 10 10 // Created On : Sun May 17 07:06:19 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:35:46 201613 // Update Count : 612 // Last Modified On : Mon Sep 25 15:43:34 2017 13 // Update Count : 10 14 14 // 15 15 … … 219 219 */ 220 220 221 static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = 222 { 223 /* Src \ Dest: Bool Char SChar UChar Short UShort Int UInt Long ULong LLong ULLong Float Double LDbl FCplex DCplex LDCplex FImag DImag LDImag */ 224 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 11, 12, 13, -1, -1, -1 }, 225 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 10, 11, 12, -1, -1, -1 }, 226 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 10, 11, 12, -1, -1, -1 }, 227 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 9, 10, 11, -1, -1, -1 }, 228 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 8, 9, 10, -1, -1, -1 }, 229 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 7, 8, 9, -1, -1, -1 }, 230 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 5, 6, 7, 6, 7, 8, -1, -1, -1 }, 231 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 4, 5, 6, 5, 6, 7, -1, -1, -1 }, 232 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 5, 6, 7, -1, -1, -1 }, 233 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 4, 5, 6, -1, -1, -1 }, 234 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 3, 4, 5, -1, -1, -1 }, 235 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 2, 3, 4, -1, -1, -1 }, 236 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1 }, 237 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1 }, 238 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1 }, 239 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1 }, 240 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1 }, 241 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1 }, 242 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2 }, 243 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1 }, 244 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0 } 221 static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = { 222 /* Src \ Dest: Bool Char SChar UChar Short UShort Int UInt Long ULong LLong ULLong Float Double LDbl FCplex DCplex LDCplex FImag DImag LDImag I128, U128 */ 223 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 12, 13, 14, 12, 13, 14, -1, -1, -1, 10, 11, }, 224 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, }, 225 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, }, 226 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 10, 11, 12, 10, 11, 12, -1, -1, -1, 8, 9, }, 227 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 9, 10, 11, 9, 10, 11, -1, -1, -1, 7, 8, }, 228 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 8, 9, 10, 8, 9, 10, -1, -1, -1, 6, 7, }, 229 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 7, 8, 9, 7, 8, 9, -1, -1, -1, 5, 6, }, 230 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, }, 231 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, }, 232 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 5, 6, 7, 5, 6, 7, -1, -1, -1, 3, 4, }, 233 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 6, 4, 5, 6, -1, -1, -1, 2, 3, }, 234 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 4, 5, 3, 4, 5, -1, -1, -1, 1, 2, }, 235 236 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1, -1, -1, }, 237 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1, -1, -1, }, 238 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, }, 239 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1, -1, -1, }, 240 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, }, 241 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, }, 242 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2, -1, -1, }, 243 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1, -1, -1, }, 244 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, -1, }, 245 246 /* I128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 3, 4, 5, -1, -1, -1, 0, 1, }, 247 /* U128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 2, 3, 4, -1, -1, -1, -1, 0, }, 245 248 }; 246 249 … … 303 306 // recursively compute conversion cost from T1 to T2. 304 307 // cv can be safely dropped because of 'implicit dereference' behavior. 305 refType-> get_base()->accept( *this );306 if ( refType-> get_base()->get_qualifiers() == dest->get_qualifiers() ) {308 refType->base->accept( *this ); 309 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) { 307 310 cost.incReference(); // prefer exact qualifiers 308 } else if ( refType-> get_base()->get_qualifiers() < dest->get_qualifiers() ) {311 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) { 309 312 cost.incSafe(); // then gaining qualifiers 310 313 } else { … … 318 321 void ConversionCost::visit(StructInstType *inst) { 319 322 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { 320 if ( inst-> get_name() == destAsInst->get_name()) {323 if ( inst->name == destAsInst->name ) { 321 324 cost = Cost::zero; 322 325 } // if … … 325 328 326 329 void ConversionCost::visit(UnionInstType *inst) { 327 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {328 if ( inst-> get_name() == destAsInst->get_name()) {330 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) { 331 if ( inst->name == destAsInst->name ) { 329 332 cost = Cost::zero; 330 333 } // if -
src/ResolvExpr/ResolveTypeof.cc
rb96ec83 r6840e7c 18 18 #include <cassert> // for assert 19 19 20 #include "Common/PassVisitor.h" // for PassVisitor 20 21 #include "Resolver.h" // for resolveInVoidContext 21 22 #include "SynTree/Expression.h" // for Expression … … 41 42 } 42 43 43 class ResolveTypeof : public Mutator{44 class ResolveTypeof : public WithShortCircuiting { 44 45 public: 45 46 ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {} 46 Type *mutate( TypeofType *typeofType ); 47 void premutate( TypeofType *typeofType ); 48 Type * postmutate( TypeofType *typeofType ); 47 49 48 50 private: … … 50 52 }; 51 53 52 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {53 ResolveTypeofmutator( indexer );54 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) { 55 PassVisitor<ResolveTypeof> mutator( indexer ); 54 56 return type->acceptMutator( mutator ); 55 57 } 56 58 57 Type *ResolveTypeof::mutate( TypeofType *typeofType ) { 59 void ResolveTypeof::premutate( TypeofType * ) { 60 visit_children = false; 61 } 62 63 Type * ResolveTypeof::postmutate( TypeofType *typeofType ) { 58 64 #if 0 59 std::c out<< "resolving typeof: ";60 typeofType->print( std::c out);61 std::c out<< std::endl;65 std::cerr << "resolving typeof: "; 66 typeofType->print( std::cerr ); 67 std::cerr << std::endl; 62 68 #endif 63 if ( typeofType-> get_expr()) {64 Expression * newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );65 assert( newExpr-> has_result() && ! newExpr->get_result()->isVoid() );66 Type * newType = newExpr->get_result();67 newExpr-> set_result( nullptr );69 if ( typeofType->expr ) { 70 Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer ); 71 assert( newExpr->result && ! newExpr->result->isVoid() ); 72 Type * newType = newExpr->result; 73 newExpr->result = nullptr; 68 74 delete typeofType; 69 75 delete newExpr; -
src/ResolvExpr/Resolver.cc
rb96ec83 r6840e7c 53 53 void previsit( FunctionDecl *functionDecl ); 54 54 void postvisit( FunctionDecl *functionDecl ); 55 void previsit( ObjectDecl * functionDecl );55 void previsit( ObjectDecl *objectDecll ); 56 56 void previsit( TypeDecl *typeDecl ); 57 57 void previsit( EnumDecl * enumDecl ); … … 109 109 110 110 namespace { 111 void finishExpr( Expression *expr, const TypeEnvironment &env ) {112 expr-> set_env( new TypeSubstitution );111 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) { 112 expr->env = oldenv ? oldenv->clone() : new TypeSubstitution; 113 113 env.makeSubstitution( *expr->get_env() ); 114 114 } 115 116 void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) { 117 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 118 if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) { 119 // cast is to the same type as its argument, so it's unnecessary -- remove it 120 expr = castExpr->arg; 121 castExpr->arg = nullptr; 122 std::swap( expr->env, castExpr->env ); 123 delete castExpr; 124 } 125 } 126 } 115 127 } // namespace 116 128 117 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {129 void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 118 130 global_renamer.reset(); 119 131 TypeEnvironment env; 120 132 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); 121 finishExpr( newExpr, env ); 122 return newExpr; 123 } 124 125 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 133 finishExpr( newExpr, env, untyped->env ); 134 delete untyped; 135 untyped = newExpr; 136 } 137 138 void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) { 139 if ( ! untyped ) return; 126 140 TypeEnvironment env; 127 141 AlternativeFinder finder( indexer, env ); … … 129 143 #if 0 130 144 if ( finder.get_alternatives().size() != 1 ) { 131 std::c out<< "untyped expr is ";132 untyped->print( std::c out);133 std::c out<< std::endl << "alternatives are:";134 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i) {135 i->print( std::cout);145 std::cerr << "untyped expr is "; 146 untyped->print( std::cerr ); 147 std::cerr << std::endl << "alternatives are:"; 148 for ( const Alternative & alt : finder.get_alternatives() ) { 149 alt.print( std::cerr ); 136 150 } // for 137 151 } // if … … 140 154 Alternative &choice = finder.get_alternatives().front(); 141 155 Expression *newExpr = choice.expr->clone(); 142 finishExpr( newExpr, choice.env ); 143 return newExpr; 156 finishExpr( newExpr, choice.env, untyped->env ); 157 delete untyped; 158 untyped = newExpr; 159 } 160 161 void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) { 162 assert( untyped && type ); 163 untyped = new CastExpr( untyped, type ); 164 findSingleExpression( untyped, indexer ); 165 removeExtraneousCast( untyped, indexer ); 144 166 } 145 167 … … 157 179 } 158 180 159 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {181 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 160 182 TypeEnvironment env; 161 183 AlternativeFinder finder( indexer, env ); … … 186 208 throw SemanticError( "No interpretations for case control expression", untyped ); 187 209 } // if 188 finishExpr( newExpr, *newEnv ); 189 return newExpr; 210 finishExpr( newExpr, *newEnv, untyped->env ); 211 delete untyped; 212 untyped = newExpr; 190 213 } 191 214 … … 212 235 void Resolver::handlePtrType( PtrType * type ) { 213 236 if ( type->get_dimension() ) { 214 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() ); 215 Expression *newExpr = findSingleExpression( castExpr, indexer ); 216 delete type->get_dimension(); 217 type->set_dimension( newExpr ); 237 findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer ); 218 238 } 219 239 } … … 245 265 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 246 266 } 247 248 267 249 268 void Resolver::postvisit( FunctionDecl *functionDecl ) { … … 269 288 void Resolver::previsit( ExprStmt *exprStmt ) { 270 289 visit_children = false; 271 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" ); 272 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer ); 273 delete exprStmt->get_expr(); 274 exprStmt->set_expr( newExpr ); 290 assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" ); 291 findVoidExpression( exprStmt->expr, indexer ); 275 292 } 276 293 277 294 void Resolver::previsit( AsmExpr *asmExpr ) { 278 295 visit_children = false; 279 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer ); 280 delete asmExpr->get_operand(); 281 asmExpr->set_operand( newExpr ); 296 findVoidExpression( asmExpr->operand, indexer ); 282 297 if ( asmExpr->get_inout() ) { 283 newExpr = findVoidExpression( asmExpr->get_inout(), indexer ); 284 delete asmExpr->get_inout(); 285 asmExpr->set_inout( newExpr ); 298 findVoidExpression( asmExpr->inout, indexer ); 286 299 } // if 287 300 } … … 294 307 295 308 void Resolver::previsit( IfStmt *ifStmt ) { 296 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer ); 297 delete ifStmt->get_condition(); 298 ifStmt->set_condition( newExpr ); 309 findSingleExpression( ifStmt->condition, indexer ); 299 310 } 300 311 301 312 void Resolver::previsit( WhileStmt *whileStmt ) { 302 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer ); 303 delete whileStmt->get_condition(); 304 whileStmt->set_condition( newExpr ); 313 findSingleExpression( whileStmt->condition, indexer ); 305 314 } 306 315 307 316 void Resolver::previsit( ForStmt *forStmt ) { 308 if ( forStmt->get_condition() ) { 309 Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer ); 310 delete forStmt->get_condition(); 311 forStmt->set_condition( newExpr ); 317 if ( forStmt->condition ) { 318 findSingleExpression( forStmt->condition, indexer ); 312 319 } // if 313 320 314 if ( forStmt->get_increment() ) { 315 Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer ); 316 delete forStmt->get_increment(); 317 forStmt->set_increment( newExpr ); 321 if ( forStmt->increment ) { 322 findVoidExpression( forStmt->increment, indexer ); 318 323 } // if 319 324 } … … 321 326 void Resolver::previsit( SwitchStmt *switchStmt ) { 322 327 GuardValue( currentObject ); 323 Expression *newExpr; 324 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer ); 325 delete switchStmt->get_condition(); 326 switchStmt->set_condition( newExpr ); 327 328 currentObject = CurrentObject( newExpr->get_result() ); 328 findIntegralExpression( switchStmt->condition, indexer ); 329 330 currentObject = CurrentObject( switchStmt->condition->result ); 329 331 } 330 332 … … 333 335 std::list< InitAlternative > initAlts = currentObject.getOptions(); 334 336 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 335 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 336 Expression * newExpr = findSingleExpression( castExpr, indexer ); 337 castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 338 caseStmt->set_condition( castExpr->get_arg() ); 339 castExpr->set_arg( nullptr ); 337 // must remove cast from case statement because RangeExpr cannot be cast. 338 Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() ); 339 findSingleExpression( newExpr, indexer ); 340 CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 341 caseStmt->condition = castExpr->arg; 342 castExpr->arg = nullptr; 340 343 delete castExpr; 341 344 } … … 346 349 // must resolve the argument for a computed goto 347 350 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement 348 if ( Expression * arg = branchStmt->get_computedTarget() ) { 349 VoidType v = Type::Qualifiers(); // cast to void * for the alternative finder 350 PointerType pt( Type::Qualifiers(), v.clone() ); 351 CastExpr * castExpr = new CastExpr( arg, pt.clone() ); 352 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression 353 branchStmt->set_target( newExpr ); 351 if ( branchStmt->computedTarget ) { 352 // computed goto argument is void * 353 findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer ); 354 354 } // if 355 355 } // if … … 358 358 void Resolver::previsit( ReturnStmt *returnStmt ) { 359 359 visit_children = false; 360 if ( returnStmt->get_expr() ) { 361 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 362 Expression *newExpr = findSingleExpression( castExpr, indexer ); 363 delete castExpr; 364 returnStmt->set_expr( newExpr ); 360 if ( returnStmt->expr ) { 361 findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer ); 365 362 } // if 366 363 } … … 373 370 indexer.lookupStruct( "__cfaehm__base_exception_t" ); 374 371 assert( exception_decl ); 375 Expression * wrapped = new CastExpr( 376 throwStmt->get_expr(), 377 new PointerType( 378 noQualifiers, 379 new StructInstType( 380 noQualifiers, 381 exception_decl 382 ) 383 ) 384 ); 385 Expression * newExpr = findSingleExpression( wrapped, indexer ); 386 throwStmt->set_expr( newExpr ); 372 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) ); 373 findSingleExpression( throwStmt->expr, exceptType, indexer ); 387 374 } 388 375 } 389 376 390 377 void Resolver::previsit( CatchStmt *catchStmt ) { 391 if ( catchStmt->get_cond() ) { 392 Expression * wrapped = new CastExpr( 393 catchStmt->get_cond(), 394 new BasicType( noQualifiers, BasicType::Bool ) 395 ); 396 catchStmt->set_cond( findSingleExpression( wrapped, indexer ) ); 397 } 398 } 399 400 inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) { 401 if( !expr ) return; 402 Expression * newExpr = findSingleExpression( expr, indexer ); 403 delete expr; 404 expr = newExpr; 405 } 406 407 inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) { 408 if( !expr ) return; 409 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer ); 410 delete expr; 411 expr = newExpr; 378 if ( catchStmt->cond ) { 379 findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer ); 380 } 412 381 } 413 382 … … 579 548 // Resolve the conditions as if it were an IfStmt 580 549 // Resolve the statments normally 581 resolveAsIf( clause.condition, this->indexer );550 findSingleExpression( clause.condition, this->indexer ); 582 551 clause.statement->accept( *visitor ); 583 552 } … … 588 557 // Resolve the conditions as if it were an IfStmt 589 558 // Resolve the statments normally 590 resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );591 resolveAsIf( stmt->timeout.condition, this->indexer );559 findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer ); 560 findSingleExpression( stmt->timeout.condition, this->indexer ); 592 561 stmt->timeout.statement->accept( *visitor ); 593 562 } … … 596 565 // Resolve the conditions as if it were an IfStmt 597 566 // Resolve the statments normally 598 resolveAsIf( stmt->orelse.condition, this->indexer );567 findSingleExpression( stmt->orelse.condition, this->indexer ); 599 568 stmt->orelse.statement->accept( *visitor ); 600 569 } … … 613 582 visit_children = false; 614 583 // resolve initialization using the possibilities as determined by the currentObject cursor 615 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );616 Expression * newExpr = findSingleExpression( untyped, indexer );584 Expression * newExpr = new UntypedInitExpr( singleInit->value, currentObject.getOptions() ); 585 findSingleExpression( newExpr, indexer ); 617 586 InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr ); 618 587 … … 621 590 622 591 // discard InitExpr wrapper and retain relevant pieces 623 newExpr = initExpr->get_expr(); 624 newExpr->set_env( initExpr->get_env() ); 625 initExpr->set_expr( nullptr ); 626 initExpr->set_env( nullptr ); 592 newExpr = initExpr->expr; 593 initExpr->expr = nullptr; 594 std::swap( initExpr->env, newExpr->env ); 627 595 delete initExpr; 628 596 629 597 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 630 598 Type * initContext = currentObject.getCurrentType(); 599 600 removeExtraneousCast( newExpr, indexer ); 631 601 632 602 // check if actual object's type is char[] … … 636 606 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 637 607 if ( isCharType( pt->get_base() ) ) { 638 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 639 CastExpr *ce = strict_dynamic_cast< CastExpr * >( newExpr ); 640 newExpr = ce->get_arg(); 641 ce->set_arg( nullptr ); 642 delete ce; 608 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) { 609 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 610 newExpr = ce->get_arg(); 611 ce->set_arg( nullptr ); 612 std::swap( ce->env, newExpr->env ); 613 delete ce; 614 } 643 615 } 644 616 } … … 647 619 648 620 // set initializer expr to resolved express 649 singleInit-> set_value( newExpr );621 singleInit->value = newExpr; 650 622 651 623 // move cursor to next object in preparation for next initializer -
src/ResolvExpr/Resolver.h
rb96ec83 r6840e7c 30 30 void resolve( std::list< Declaration * > translationUnit ); 31 31 void resolveDecl( Declaration *, const SymTab::Indexer &indexer ); 32 Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer &indexer );33 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );34 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );32 Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer &indexer ); 33 void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ); 34 void findSingleExpression( Expression *& untyped, const SymTab::Indexer &indexer ); 35 35 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); 36 36 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
rb96ec83 r6840e7c 68 68 } 69 69 70 void EqvClass::print( std::ostream &os, intindent ) const {71 os << std::string( indent, ' ' ) <<"( ";70 void EqvClass::print( std::ostream &os, Indenter indent ) const { 71 os << "( "; 72 72 std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) ); 73 73 os << ")"; 74 74 if ( type ) { 75 75 os << " -> "; 76 type->print( os, indent );76 type->print( os, indent+1 ); 77 77 } // if 78 78 if ( ! allowWidening ) { … … 144 144 } 145 145 146 void TypeEnvironment::print( std::ostream &os, intindent ) const {146 void TypeEnvironment::print( std::ostream &os, Indenter indent ) const { 147 147 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) { 148 148 i->print( os, indent ); -
src/ResolvExpr/TypeEnvironment.h
rb96ec83 r6840e7c 68 68 EqvClass &operator=( const EqvClass &other ); 69 69 ~EqvClass(); 70 void print( std::ostream &os, int indent = 0) const;70 void print( std::ostream &os, Indenter indent = {} ) const; 71 71 }; 72 72 … … 80 80 void makeSubstitution( TypeSubstitution &result ) const; 81 81 bool isEmpty() const { return env.empty(); } 82 void print( std::ostream &os, int indent = 0) const;82 void print( std::ostream &os, Indenter indent = {} ) const; 83 83 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ); 84 84 void simpleCombine( const TypeEnvironment &second ); -
src/ResolvExpr/Unify.cc
rb96ec83 r6840e7c 22 22 #include <utility> // for pair 23 23 24 #include "Common/PassVisitor.h" // for PassVisitor 24 25 #include "FindOpenVars.h" // for findOpenVars 25 26 #include "Parser/LinkageSpec.h" // for C … … 537 538 /// If this isn't done then argument lists can have wildly different 538 539 /// size and structure, when they should be compatible. 539 struct TtypeExpander : public Mutator { 540 TypeEnvironment & env; 541 TtypeExpander( TypeEnvironment & env ) : env( env ) {} 542 Type * mutate( TypeInstType * typeInst ) { 540 struct TtypeExpander : public WithShortCircuiting { 541 TypeEnvironment & tenv; 542 TtypeExpander( TypeEnvironment & tenv ) : tenv( tenv ) {} 543 void premutate( TypeInstType * ) { visit_children = false; } 544 Type * postmutate( TypeInstType * typeInst ) { 543 545 EqvClass eqvClass; 544 if ( env.lookup( typeInst->get_name(), eqvClass ) ) {546 if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) { 545 547 if ( eqvClass.data.kind == TypeDecl::Ttype ) { 546 548 // expand ttype parameter into its actual type … … 560 562 dst.clear(); 561 563 for ( DeclarationWithType * dcl : src ) { 562 TtypeExpanderexpander( env );564 PassVisitor<TtypeExpander> expander( env ); 563 565 dcl->acceptMutator( expander ); 564 566 std::list< Type * > types; … … 750 752 std::list<Type *> types1, types2; 751 753 752 TtypeExpanderexpander( env );754 PassVisitor<TtypeExpander> expander( env ); 753 755 flat1->acceptMutator( expander ); 754 756 flat2->acceptMutator( expander ); -
src/SymTab/Autogen.cc
rb96ec83 r6840e7c 43 43 namespace SymTab { 44 44 Type * SizeType = 0; 45 typedef ScopedMap< std::string, bool > TypeMap; 46 47 /// Data used to generate functions generically. Specifically, the name of the generated function, a function which generates the routine protoype, and a map which contains data to determine whether a function should be generated. 45 46 /// Data used to generate functions generically. Specifically, the name of the generated function and a function which generates the routine protoype 48 47 struct FuncData { 49 48 typedef FunctionType * (*TypeGen)( Type * ); 50 FuncData( const std::string & fname, const TypeGen & genType , TypeMap & map ) : fname( fname ), genType( genType ), map( map) {}49 FuncData( const std::string & fname, const TypeGen & genType ) : fname( fname ), genType( genType ) {} 51 50 std::string fname; 52 51 TypeGen genType; 53 TypeMap & map; 54 }; 55 56 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting { 52 }; 53 54 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting, public WithIndexer { 57 55 AutogenerateRoutines(); 58 56 … … 70 68 71 69 private: 70 72 71 GenPoly::ScopedSet< std::string > structsDone; 73 72 unsigned int functionNesting = 0; // current level of nested functions 74 /// Note: the following maps could be ScopedSets, but it should be easier to work 75 /// deleted functions in if they are maps, since the value false can be inserted 76 /// at the current scope without affecting outer scopes or requiring copies. 77 TypeMap copyable, assignable, constructable, destructable; 73 74 InitTweak::ManagedTypes managedTypes; 78 75 std::vector< FuncData > data; 79 76 }; … … 81 78 /// generates routines for tuple types. 82 79 struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting { 83 void previsit( FunctionDecl * functionDecl );84 85 void postvisit( TupleType * tupleType );86 87 void previsit( CompoundStmt * compoundStmt );80 void previsit( FunctionDecl * functionDecl ); 81 82 void postvisit( TupleType * tupleType ); 83 84 void previsit( CompoundStmt * compoundStmt ); 88 85 89 86 private: … … 101 98 } 102 99 100 //============================================================================================= 101 // FuncGenerator definitions 102 //============================================================================================= 103 class FuncGenerator { 104 public: 105 std::list< Declaration * > definitions, forwards; 106 107 FuncGenerator( Type * type, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : type( type ), data( data ), functionNesting( functionNesting ), indexer( indexer ) {} 108 109 virtual bool shouldAutogen() const = 0; 110 void genStandardFuncs(); 111 virtual void genFieldCtors() = 0; 112 protected: 113 Type * type; 114 const std::vector< FuncData > & data; 115 unsigned int functionNesting; 116 SymTab::Indexer & indexer; 117 118 virtual void genFuncBody( FunctionDecl * dcl ) = 0; 119 virtual bool isConcurrentType() const = 0; 120 121 void resolve( FunctionDecl * dcl ); 122 void generatePrototypes( std::list< FunctionDecl * > & newFuncs ); 123 }; 124 125 class StructFuncGenerator : public FuncGenerator { 126 StructDecl * aggregateDecl; 127 public: 128 StructFuncGenerator( StructDecl * aggregateDecl, StructInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ), aggregateDecl( aggregateDecl) {} 129 130 virtual bool shouldAutogen() const override; 131 virtual bool isConcurrentType() const override; 132 133 virtual void genFuncBody( FunctionDecl * dcl ) override; 134 virtual void genFieldCtors() override; 135 136 private: 137 /// generates a single struct member operation (constructor call, destructor call, assignment call) 138 void makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ); 139 140 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies 141 template<typename Iterator> 142 void makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ); 143 144 /// generate the body of a constructor which takes parameters that match fields, e.g. 145 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 146 template<typename Iterator> 147 void makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ); 148 }; 149 150 class UnionFuncGenerator : public FuncGenerator { 151 UnionDecl * aggregateDecl; 152 public: 153 UnionFuncGenerator( UnionDecl * aggregateDecl, UnionInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ), aggregateDecl( aggregateDecl) {} 154 155 virtual bool shouldAutogen() const override; 156 virtual bool isConcurrentType() const override; 157 158 virtual void genFuncBody( FunctionDecl * dcl ) override; 159 virtual void genFieldCtors() override; 160 161 private: 162 /// generates a single struct member operation (constructor call, destructor call, assignment call) 163 template<typename OutputIterator> 164 void makeMemberOp( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ); 165 166 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies 167 template<typename Iterator> 168 void makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ); 169 170 /// generate the body of a constructor which takes parameters that match fields, e.g. 171 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 172 template<typename Iterator> 173 void makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ); 174 }; 175 176 class EnumFuncGenerator : public FuncGenerator { 177 public: 178 EnumFuncGenerator( EnumInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ) {} 179 180 virtual bool shouldAutogen() const override; 181 virtual bool isConcurrentType() const override; 182 183 virtual void genFuncBody( FunctionDecl * dcl ) override; 184 virtual void genFieldCtors() override; 185 186 private: 187 }; 188 189 class TypeFuncGenerator : public FuncGenerator { 190 TypeDecl * typeDecl; 191 public: 192 TypeFuncGenerator( TypeDecl * typeDecl, TypeInstType * refType, const std::vector<FuncData> & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ), typeDecl( typeDecl ) {} 193 194 virtual bool shouldAutogen() const override; 195 virtual void genFuncBody( FunctionDecl * dcl ) override; 196 virtual bool isConcurrentType() const override; 197 virtual void genFieldCtors() override; 198 }; 199 200 //============================================================================================= 201 // helper functions 202 //============================================================================================= 203 void generateFunctions( FuncGenerator & gen, std::list< Declaration * > & declsToAdd ) { 204 if ( ! gen.shouldAutogen() ) return; 205 206 // generate each of the functions based on the supplied FuncData objects 207 gen.genStandardFuncs(); 208 gen.genFieldCtors(); 209 210 declsToAdd.splice( declsToAdd.end(), gen.forwards ); 211 declsToAdd.splice( declsToAdd.end(), gen.definitions ); 212 } 213 103 214 bool isUnnamedBitfield( ObjectDecl * obj ) { 104 return obj != nullptr && obj-> get_name() == "" && obj->get_bitfieldWidth()!= nullptr;215 return obj != nullptr && obj->name == "" && obj->bitfieldWidth != nullptr; 105 216 } 106 217 … … 108 219 void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) { 109 220 FunctionDecl * decl = functionDecl->clone(); 110 delete decl-> get_statements();111 decl->s et_statements( nullptr );221 delete decl->statements; 222 decl->statements = nullptr; 112 223 declsToAdd.push_back( decl ); 113 224 decl->fixUniqueId(); 114 225 } 115 226 227 const std::list< TypeDecl * > getGenericParams( Type * t ) { 228 std::list< TypeDecl * > * ret = nullptr; 229 if ( StructInstType * inst = dynamic_cast< StructInstType * > ( t ) ) { 230 ret = inst->get_baseParameters(); 231 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) { 232 ret = inst->get_baseParameters(); 233 } 234 return ret ? *ret : std::list< TypeDecl * >(); 235 } 236 116 237 /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *) 117 238 FunctionType * genDefaultType( Type * paramType ) { 239 const auto & typeParams = getGenericParams( paramType ); 118 240 FunctionType *ftype = new FunctionType( Type::Qualifiers(), false ); 241 cloneAll( typeParams, ftype->forall ); 119 242 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr ); 120 ftype-> get_parameters().push_back( dstParam );243 ftype->parameters.push_back( dstParam ); 121 244 return ftype; 122 245 } … … 126 249 FunctionType *ftype = genDefaultType( paramType ); 127 250 ObjectDecl *srcParam = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); 128 ftype-> get_parameters().push_back( srcParam );251 ftype->parameters.push_back( srcParam ); 129 252 return ftype; 130 253 } … … 134 257 FunctionType *ftype = genCopyType( paramType ); 135 258 ObjectDecl *returnVal = new ObjectDecl( "_ret", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); 136 ftype-> get_returnVals().push_back( returnVal );259 ftype->returnVals.push_back( returnVal ); 137 260 return ftype; 138 261 } … … 151 274 } 152 275 153 /// inserts base type of first argument into map if pred(funcDecl) is true 154 void insert( FunctionDecl *funcDecl, TypeMap & map, FunctionDecl * (*pred)(Declaration *) ) { 155 // insert type into constructable, etc. map if appropriate 156 if ( pred( funcDecl ) ) { 157 FunctionType * ftype = funcDecl->get_functionType(); 158 assert( ! ftype->get_parameters().empty() ); 159 Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() ); 160 assert( t ); 161 map.insert( Mangler::mangleType( t ), true ); 162 } 163 } 164 165 /// using map and t, determines if is constructable, etc. 166 bool lookup( const TypeMap & map, Type * t ) { 167 assertf( t, "Autogenerate lookup was given non-type: %s", toString( t ).c_str() ); 168 if ( dynamic_cast< PointerType * >( t ) ) { 169 // will need more complicated checking if we want this to work with pointer types, since currently 170 return true; 171 } else if ( ArrayType * at = dynamic_cast< ArrayType * >( t ) ) { 172 // an array's constructor, etc. is generated on the fly based on the base type's constructor, etc. 173 return lookup( map, at->get_base() ); 174 } 175 TypeMap::const_iterator it = map.find( Mangler::mangleType( t ) ); 176 if ( it != map.end() ) return it->second; 177 // something that does not appear in the map is by default not constructable, etc. 178 return false; 179 } 180 181 /// using map and aggr, examines each member to determine if constructor, etc. should be generated 182 template<typename Container> 183 bool shouldGenerate( const TypeMap & map, const Container & container ) { 184 for ( Type * t : container ) { 185 if ( ! lookup( map, t ) ) return false; 186 } 187 return true; 188 } 189 190 /// data structure for abstracting the generation of special functions 191 template< typename OutputIterator, typename Container > 192 struct FuncGenerator { 193 const Container & container; 194 Type *refType; 195 unsigned int functionNesting; 196 const std::list< TypeDecl* > & typeParams; 197 OutputIterator out; 198 FuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : container( container ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {} 199 200 /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map. 201 void gen( const FuncData & data, bool concurrent_type ) { 202 if ( ! shouldGenerate( data.map, container ) ) return; 203 FunctionType * ftype = data.genType( refType ); 204 276 Type * declToType( Declaration * decl ) { 277 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 278 return dwt->get_type(); 279 } 280 return nullptr; 281 } 282 283 Type * declToTypeDeclBase( Declaration * decl ) { 284 if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) { 285 return td->base; 286 } 287 return nullptr; 288 } 289 290 //============================================================================================= 291 // FuncGenerator member definitions 292 //============================================================================================= 293 void FuncGenerator::genStandardFuncs() { 294 std::list< FunctionDecl * > newFuncs; 295 generatePrototypes( newFuncs ); 296 297 for ( FunctionDecl * dcl : newFuncs ) { 298 genFuncBody( dcl ); 299 if ( CodeGen::isAssignment( dcl->name ) ) { 300 // assignment needs to return a value 301 FunctionType * assignType = dcl->type; 302 assert( assignType->parameters.size() == 2 ); 303 assert( assignType->returnVals.size() == 1 ); 304 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.front() ); 305 dcl->statements->push_back( new ReturnStmt( noLabels, new VariableExpr( dstParam ) ) ); 306 } 307 resolve( dcl ); 308 } 309 } 310 311 void FuncGenerator::generatePrototypes( std::list< FunctionDecl * > & newFuncs ) { 312 bool concurrent_type = isConcurrentType(); 313 for ( const FuncData & data : data ) { 314 // generate a function (?{}, ?=?, ^?{}) based on the current FuncData. 315 FunctionType * ftype = data.genType( type ); 316 317 // destructor for concurrent type must be mutex 205 318 if ( concurrent_type && CodeGen::isDestructor( data.fname ) ) { 206 319 ftype->parameters.front()->get_type()->set_mutex( true ); 207 320 } 208 321 209 cloneAll( typeParams, ftype->forall ); 210 *out++ = genFunc( data.fname, ftype, functionNesting ); 211 data.map.insert( Mangler::mangleType( refType ), true ); 212 } 213 }; 214 215 template< typename OutputIterator, typename Container > 216 FuncGenerator<OutputIterator, Container> makeFuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) { 217 return FuncGenerator<OutputIterator, Container>( container, refType, functionNesting, typeParams, out ); 218 } 219 220 /// generates a single enumeration assignment expression 221 ApplicationExpr * genEnumAssign( FunctionType * ftype, FunctionDecl * assignDecl ) { 222 // enum copy construct and assignment is just C-style assignment. 223 // this looks like a bad recursive call, but code gen will turn it into 224 // a C-style assignment. 225 // This happens before function pointer type conversion, so need to do it manually here 226 // NOTE: ftype is not necessarily the functionType belonging to assignDecl - ftype is the 227 // type of the function that this expression is being generated for (so that the correct 228 // parameters) are using in the variable exprs 229 assert( ftype->get_parameters().size() == 2 ); 230 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 231 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 232 233 VariableExpr * assignVarExpr = new VariableExpr( assignDecl ); 234 Type * assignVarExprType = assignVarExpr->get_result(); 235 assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType ); 236 assignVarExpr->set_result( assignVarExprType ); 237 ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr ); 238 assignExpr->get_args().push_back( new VariableExpr( dstParam ) ); 239 assignExpr->get_args().push_back( new VariableExpr( srcParam ) ); 240 return assignExpr; 241 } 242 243 // E ?=?(E volatile*, int), 244 // ?=?(E _Atomic volatile*, int); 245 void makeEnumFunctions( EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) { 246 247 // T ?=?(E *, E); 248 FunctionType *assignType = genAssignType( refType ); 249 250 // void ?{}(E *); void ^?{}(E *); 251 FunctionType * ctorType = genDefaultType( refType->clone() ); 252 FunctionType * dtorType = genDefaultType( refType->clone() ); 253 254 // void ?{}(E *, E); 255 FunctionType *copyCtorType = genCopyType( refType->clone() ); 256 257 // add unused attribute to parameters of default constructor and destructor 258 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 259 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 260 261 // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)? 262 // right now these cases work, but that might change. 263 264 // xxx - Temporary: make these functions intrinsic so they codegen as C assignment. 265 // Really they're something of a cross between instrinsic and autogen, so should 266 // probably make a new linkage type 267 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting, true ); 268 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting, true ); 269 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting, true ); 270 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting, true ); 271 272 // body is either return stmt or expr stmt 273 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, genEnumAssign( assignType, assignDecl ) ) ); 274 copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, genEnumAssign( copyCtorType, assignDecl ) ) ); 275 276 declsToAdd.push_back( ctorDecl ); 277 declsToAdd.push_back( copyCtorDecl ); 278 declsToAdd.push_back( dtorDecl ); 279 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 280 } 281 282 /// generates a single struct member operation (constructor call, destructor call, assignment call) 283 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ) { 322 newFuncs.push_back( genFunc( data.fname, ftype, functionNesting ) ); 323 } 324 } 325 326 void FuncGenerator::resolve( FunctionDecl * dcl ) { 327 try { 328 ResolvExpr::resolveDecl( dcl, indexer ); 329 if ( functionNesting == 0 ) { 330 // forward declare if top-level struct, so that 331 // type is complete as soon as its body ends 332 // Note: this is necessary if we want structs which contain 333 // generic (otype) structs as members. 334 addForwardDecl( dcl, forwards ); 335 } 336 definitions.push_back( dcl ); 337 indexer.addId( dcl ); 338 } catch ( SemanticError err ) { 339 // okay if decl does not resolve - that means the function should not be generated 340 delete dcl; 341 } 342 } 343 344 bool StructFuncGenerator::shouldAutogen() const { 345 // Builtins do not use autogeneration. 346 return ! aggregateDecl->linkage.is_builtin; 347 } 348 bool StructFuncGenerator::isConcurrentType() const { return aggregateDecl->is_thread() || aggregateDecl->is_monitor(); } 349 350 void StructFuncGenerator::genFuncBody( FunctionDecl * dcl ) { 351 // generate appropriate calls to member ctor, assignment 352 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 353 if ( ! CodeGen::isDestructor( dcl->name ) ) { 354 makeFunctionBody( aggregateDecl->members.begin(), aggregateDecl->members.end(), dcl ); 355 } else { 356 makeFunctionBody( aggregateDecl->members.rbegin(), aggregateDecl->members.rend(), dcl, false ); 357 } 358 } 359 360 void StructFuncGenerator::genFieldCtors() { 361 // field ctors are only generated if default constructor and copy constructor are both generated 362 unsigned numCtors = std::count_if( definitions.begin(), definitions.end(), [](Declaration * dcl) { return CodeGen::isConstructor( dcl->name ); } ); 363 364 // Field constructors are only generated if default and copy constructor 365 // are generated, since they need access to both 366 if ( numCtors != 2 ) return; 367 368 // create constructors which take each member type as a parameter. 369 // for example, for struct A { int x, y; }; generate 370 // void ?{}(A *, int) and void ?{}(A *, int, int) 371 FunctionType * memCtorType = genDefaultType( type ); 372 for ( Declaration * member : aggregateDecl->members ) { 373 DeclarationWithType * field = strict_dynamic_cast<DeclarationWithType *>( member ); 374 if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( field ) ) ) { 375 // don't make a function whose parameter is an unnamed bitfield 376 continue; 377 } 378 memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 ) ); 379 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 380 makeFieldCtorBody( aggregateDecl->members.begin(), aggregateDecl->members.end(), ctor ); 381 resolve( ctor ); 382 } 383 delete memCtorType; 384 } 385 386 void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) { 284 387 InitTweak::InitExpander srcParam( src ); 285 388 286 389 // assign to destination 287 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), strict_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) ); 288 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 289 } 290 291 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies 390 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), strict_dynamic_cast< ReferenceType* >( dstParam->get_type() )->base->clone() ) ); 391 genImplicitCall( srcParam, dstselect, func->name, back_inserter( func->statements->kids ), field, forward ); 392 } 393 292 394 template<typename Iterator> 293 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true) {395 void StructFuncGenerator::makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward ) { 294 396 for ( ; member != end; ++member ) { 295 397 if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate … … 301 403 } 302 404 303 if ( type->get_const() && func->get_name() == "?=?") {405 if ( type->get_const() && CodeGen::isAssignment( func->name ) ) { 304 406 // don't assign const members, but do construct/destruct 305 continue;306 }307 308 if ( field->get_name() == "" ) {309 // don't assign to anonymous members310 // xxx - this is a temporary fix. Anonymous members tie into311 // our inheritance model. I think the correct way to handle this is to312 // cast the structure to the type of the member and let the resolver313 // figure out whether it's valid and have a pass afterwards that fixes314 // the assignment to use pointer arithmetic with the offset of the315 // member, much like how generic type members are handled.316 407 continue; 317 408 } … … 323 414 srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() ); 324 415 } 416 325 417 // srcParam may be NULL, in which case we have default ctor/dtor 326 418 assert( dstParam ); 327 419 328 420 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr; 329 make StructMemberOp( dstParam, srcselect, field, func, forward );421 makeMemberOp( dstParam, srcselect, field, func, forward ); 330 422 } // if 331 423 } // for 332 } // makeStructFunctionBody 333 334 /// generate the body of a constructor which takes parameters that match fields, e.g. 335 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 424 } // makeFunctionBody 425 336 426 template<typename Iterator> 337 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) {338 FunctionType * ftype = func-> get_functionType();339 std::list<DeclarationWithType*> & params = ftype-> get_parameters();427 void StructFuncGenerator::makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) { 428 FunctionType * ftype = func->type; 429 std::list<DeclarationWithType*> & params = ftype->parameters; 340 430 assert( params.size() >= 2 ); // should not call this function for default ctor, etc. 341 431 … … 349 439 // don't make a function whose parameter is an unnamed bitfield 350 440 continue; 351 } else if ( field->get_name() == "" ) {352 // don't assign to anonymous members353 // xxx - this is a temporary fix. Anonymous members tie into354 // our inheritance model. I think the correct way to handle this is to355 // cast the structure to the type of the member and let the resolver356 // figure out whether it's valid and have a pass afterwards that fixes357 // the assignment to use pointer arithmetic with the offset of the358 // member, much like how generic type members are handled.359 continue;360 441 } else if ( parameter != params.end() ) { 361 442 // matching parameter, initialize field with copy ctor 362 443 Expression *srcselect = new VariableExpr(*parameter); 363 make StructMemberOp( dstParam, srcselect, field, func );444 makeMemberOp( dstParam, srcselect, field, func ); 364 445 ++parameter; 365 446 } else { 366 447 // no matching parameter, initialize field with default ctor 367 make StructMemberOp( dstParam, nullptr, field, func );448 makeMemberOp( dstParam, nullptr, field, func ); 368 449 } 369 450 } … … 371 452 } 372 453 373 Type * declToType( Declaration * decl ) { 374 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 375 return dwt->get_type(); 376 } 377 return nullptr; 378 } 379 380 /// generates struct constructors, destructor, and assignment functions 381 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { 454 bool UnionFuncGenerator::shouldAutogen() const { 382 455 // Builtins do not use autogeneration. 383 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) { 384 return; 385 } 386 387 // Make function polymorphic in same parameters as generic struct, if applicable 388 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 389 390 // generate each of the functions based on the supplied FuncData objects 391 std::list< FunctionDecl * > newFuncs; 392 // structure that iterates aggregate decl members, returning their types 393 auto generator = makeFuncGenerator( lazy_map( aggregateDecl->members, declToType ), refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 394 for ( const FuncData & d : data ) { 395 generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() ); 396 } 397 456 return ! aggregateDecl->linkage.is_builtin; 457 } 458 459 // xxx - is this right? 460 bool UnionFuncGenerator::isConcurrentType() const { return false; }; 461 462 /// generate a single union assignment expression (using memcpy) 463 template< typename OutputIterator > 464 void UnionFuncGenerator::makeMemberOp( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) { 465 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 466 copy->args.push_back( new AddressExpr( new VariableExpr( dstParam ) ) ); 467 copy->args.push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 468 copy->args.push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); 469 *out++ = new ExprStmt( noLabels, copy ); 470 } 471 472 /// generates the body of a union assignment/copy constructor/field constructor 473 void UnionFuncGenerator::genFuncBody( FunctionDecl * funcDecl ) { 474 FunctionType * ftype = funcDecl->type; 475 if ( InitTweak::isCopyConstructor( funcDecl ) || InitTweak::isAssignment( funcDecl ) ) { 476 assert( ftype->parameters.size() == 2 ); 477 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 478 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.back() ); 479 makeMemberOp( srcParam, dstParam, back_inserter( funcDecl->statements->kids ) ); 480 } else { 481 // default ctor/dtor body is empty - add unused attribute to parameter to silence warnings 482 assert( ftype->parameters.size() == 1 ); 483 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 484 dstParam->attributes.push_back( new Attribute( "unused" ) ); 485 } 486 } 487 488 /// generate the body of a constructor which takes parameters that match fields, e.g. 489 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 490 void UnionFuncGenerator::genFieldCtors() { 398 491 // field ctors are only generated if default constructor and copy constructor are both generated 399 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 400 401 if ( functionNesting == 0 ) { 402 // forward declare if top-level struct, so that 403 // type is complete as soon as its body ends 404 // Note: this is necessary if we want structs which contain 405 // generic (otype) structs as members. 406 for ( FunctionDecl * dcl : newFuncs ) { 407 addForwardDecl( dcl, declsToAdd ); 408 } 409 } 410 411 for ( FunctionDecl * dcl : newFuncs ) { 412 // generate appropriate calls to member ctor, assignment 413 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 414 if ( ! CodeGen::isDestructor( dcl->get_name() ) ) { 415 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl ); 416 } else { 417 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, false ); 418 } 419 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 420 // assignment needs to return a value 421 FunctionType * assignType = dcl->get_functionType(); 422 assert( assignType->get_parameters().size() == 2 ); 423 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() ); 424 dcl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 425 } 426 declsToAdd.push_back( dcl ); 427 } 428 429 // create constructors which take each member type as a parameter. 430 // for example, for struct A { int x, y; }; generate 431 // void ?{}(A *, int) and void ?{}(A *, int, int) 492 unsigned numCtors = std::count_if( definitions.begin(), definitions.end(), [](Declaration * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 493 432 494 // Field constructors are only generated if default and copy constructor 433 495 // are generated, since they need access to both 434 if ( numCtors == 2 ) { 435 FunctionType * memCtorType = genDefaultType( refType ); 436 cloneAll( typeParams, memCtorType->get_forall() ); 437 for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) { 438 DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i ); 439 assert( member ); 440 if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( member ) ) ) { 441 // don't make a function whose parameter is an unnamed bitfield 442 continue; 443 } else if ( member->get_name() == "" ) { 444 // don't assign to anonymous members 445 // xxx - this is a temporary fix. Anonymous members tie into 446 // our inheritance model. I think the correct way to handle this is to 447 // cast the structure to the type of the member and let the resolver 448 // figure out whether it's valid/choose the correct unnamed member 449 continue; 450 } 451 memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), Type::StorageClasses(), LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) ); 452 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 453 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor ); 454 declsToAdd.push_back( ctor ); 455 } 456 delete memCtorType; 457 } 458 } 459 460 /// generate a single union assignment expression (using memcpy) 461 template< typename OutputIterator > 462 void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) { 463 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 464 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) ); 465 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 466 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); 467 *out++ = new ExprStmt( noLabels, copy ); 468 } 469 470 /// generates the body of a union assignment/copy constructor/field constructor 471 void makeUnionAssignBody( FunctionDecl * funcDecl ) { 472 FunctionType * ftype = funcDecl->get_functionType(); 473 assert( ftype->get_parameters().size() == 2 ); 474 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 475 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 476 477 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) ); 478 if ( CodeGen::isAssignment( funcDecl->get_name() ) ) { 479 // also generate return statement in assignment 480 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 481 } 482 } 483 484 /// generates union constructors, destructors, and assignment operator 485 void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) { 486 // Make function polymorphic in same parameters as generic union, if applicable 487 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 488 489 // default ctor/dtor need only first parameter 490 // void ?{}(T *); void ^?{}(T *); 491 FunctionType *ctorType = genDefaultType( refType ); 492 FunctionType *dtorType = genDefaultType( refType ); 493 494 // copy ctor needs both parameters 495 // void ?{}(T *, T); 496 FunctionType *copyCtorType = genCopyType( refType ); 497 498 // assignment needs both and return value 499 // T ?=?(T *, T); 500 FunctionType *assignType = genAssignType( refType ); 501 502 cloneAll( typeParams, ctorType->get_forall() ); 503 cloneAll( typeParams, dtorType->get_forall() ); 504 cloneAll( typeParams, copyCtorType->get_forall() ); 505 cloneAll( typeParams, assignType->get_forall() ); 506 507 // add unused attribute to parameters of default constructor and destructor 508 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 509 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 510 511 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 512 // because each unit generates copies of the default routines for each aggregate. 513 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting ); 514 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting ); 515 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting ); 516 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting ); 517 518 makeUnionAssignBody( assignDecl ); 519 520 // body of assignment and copy ctor is the same 521 makeUnionAssignBody( copyCtorDecl ); 496 if ( numCtors != 2 ) return; 522 497 523 498 // create a constructor which takes the first member type as a parameter. … … 525 500 // void ?{}(A *, int) 526 501 // This is to mimic C's behaviour which initializes the first member of the union. 527 std::list<Declaration *> memCtors; 528 for ( Declaration * member : aggregateDecl->get_members() ) { 529 if ( DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ) ) { 530 ObjectDecl * srcParam = new ObjectDecl( "src", Type::StorageClasses(), LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 ); 531 532 FunctionType * memCtorType = ctorType->clone(); 533 memCtorType->get_parameters().push_back( srcParam ); 534 FunctionDecl * ctor = genFunc( "?{}", memCtorType, functionNesting ); 535 536 makeUnionAssignBody( ctor ); 537 memCtors.push_back( ctor ); 538 // only generate a ctor for the first field 502 FunctionType * memCtorType = genDefaultType( type ); 503 for ( Declaration * member : aggregateDecl->members ) { 504 DeclarationWithType * field = strict_dynamic_cast<DeclarationWithType *>( member ); 505 if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( field ) ) ) { 506 // don't make a function whose parameter is an unnamed bitfield 539 507 break; 540 508 } 541 } 542 543 declsToAdd.push_back( ctorDecl ); 544 declsToAdd.push_back( copyCtorDecl ); 545 declsToAdd.push_back( dtorDecl ); 546 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 547 declsToAdd.splice( declsToAdd.end(), memCtors ); 548 } 549 509 memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, field->get_type()->clone(), nullptr ) ); 510 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 511 ObjectDecl * srcParam = strict_dynamic_cast<ObjectDecl *>( ctor->type->parameters.back() ); 512 srcParam->fixUniqueId(); 513 ObjectDecl * dstParam = InitTweak::getParamThis( ctor->type ); 514 makeMemberOp( srcParam, dstParam, back_inserter( ctor->statements->kids ) ); 515 resolve( ctor ); 516 // only generate one field ctor for unions 517 break; 518 } 519 delete memCtorType; 520 } 521 522 void EnumFuncGenerator::genFuncBody( FunctionDecl * funcDecl ) { 523 // xxx - Temporary: make these functions intrinsic so they codegen as C assignment. 524 // Really they're something of a cross between instrinsic and autogen, so should 525 // probably make a new linkage type 526 funcDecl->linkage = LinkageSpec::Intrinsic; 527 FunctionType * ftype = funcDecl->type; 528 if ( InitTweak::isCopyConstructor( funcDecl ) || InitTweak::isAssignment( funcDecl ) ) { 529 assert( ftype->parameters.size() == 2 ); 530 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 531 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.back() ); 532 533 // enum copy construct and assignment is just C-style assignment. 534 // this looks like a bad recursive call, but code gen will turn it into 535 // a C-style assignment. 536 // This happens before function pointer type conversion, so need to do it manually here 537 ApplicationExpr * callExpr = new ApplicationExpr( VariableExpr::functionPointer( funcDecl ) ); 538 callExpr->get_args().push_back( new VariableExpr( dstParam ) ); 539 callExpr->get_args().push_back( new VariableExpr( srcParam ) ); 540 funcDecl->statements->push_back( new ExprStmt( noLabels, callExpr ) ); 541 } else { 542 // default ctor/dtor body is empty - add unused attribute to parameter to silence warnings 543 assert( ftype->parameters.size() == 1 ); 544 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 545 dstParam->attributes.push_back( new Attribute( "unused" ) ); 546 } 547 } 548 549 bool EnumFuncGenerator::shouldAutogen() const { return true; } 550 bool EnumFuncGenerator::isConcurrentType() const { return false; } 551 // enums do not have field constructors 552 void EnumFuncGenerator::genFieldCtors() {} 553 554 bool TypeFuncGenerator::shouldAutogen() const { return true; }; 555 556 void TypeFuncGenerator::genFuncBody( FunctionDecl * dcl ) { 557 FunctionType * ftype = dcl->type; 558 assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() ); 559 DeclarationWithType * dst = ftype->parameters.front(); 560 DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr; 561 // generate appropriate calls to member ctor, assignment 562 UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) ); 563 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 564 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 565 dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) ); 566 }; 567 568 // xxx - should reach in and determine if base type is concurrent? 569 bool TypeFuncGenerator::isConcurrentType() const { return false; }; 570 571 // opaque types do not have field constructors 572 void TypeFuncGenerator::genFieldCtors() {}; 573 574 //============================================================================================= 575 // Visitor definitions 576 //============================================================================================= 550 577 AutogenerateRoutines::AutogenerateRoutines() { 551 578 // the order here determines the order that these functions are generated. 552 579 // assignment should come last since it uses copy constructor in return. 553 data.emplace_back( "?{}", genDefaultType , constructable);554 data.emplace_back( "?{}", genCopyType , copyable);555 data.emplace_back( "^?{}", genDefaultType , destructable);556 data.emplace_back( "?=?", genAssignType , assignable);580 data.emplace_back( "?{}", genDefaultType ); 581 data.emplace_back( "?{}", genCopyType ); 582 data.emplace_back( "^?{}", genDefaultType ); 583 data.emplace_back( "?=?", genAssignType ); 557 584 } 558 585 559 586 void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) { 560 visit_children = false; 561 if ( ! enumDecl->get_members().empty() ) { 562 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); 563 // enumInst->set_baseEnum( enumDecl ); 564 makeEnumFunctions( enumInst, functionNesting, declsToAddAfter ); 587 // must visit children (enum constants) to add them to the indexer 588 if ( enumDecl->has_body() ) { 589 EnumInstType enumInst( Type::Qualifiers(), enumDecl->get_name() ); 590 enumInst.set_baseEnum( enumDecl ); 591 EnumFuncGenerator gen( &enumInst, data, functionNesting, indexer ); 592 generateFunctions( gen, declsToAddAfter ); 565 593 } 566 594 } … … 568 596 void AutogenerateRoutines::previsit( StructDecl * structDecl ) { 569 597 visit_children = false; 570 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end()) {598 if ( structDecl->has_body() ) { 571 599 StructInstType structInst( Type::Qualifiers(), structDecl->name ); 600 structInst.set_baseStruct( structDecl ); 572 601 for ( TypeDecl * typeDecl : structDecl->parameters ) { 573 // need to visit assertions so that they are added to the appropriate maps574 acceptAll( typeDecl->assertions, *visitor );575 602 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) ); 576 603 } 577 structInst.set_baseStruct( structDecl ); 578 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data ); 579 structsDone.insert( structDecl->name ); 604 StructFuncGenerator gen( structDecl, &structInst, data, functionNesting, indexer ); 605 generateFunctions( gen, declsToAddAfter ); 580 606 } // if 581 607 } … … 583 609 void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) { 584 610 visit_children = false; 585 if ( ! unionDecl->get_members().empty()) {611 if ( unionDecl->has_body() ) { 586 612 UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() ); 587 613 unionInst.set_baseUnion( unionDecl ); … … 589 615 unionInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) ); 590 616 } 591 makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAddAfter ); 617 UnionFuncGenerator gen( unionDecl, &unionInst, data, functionNesting, indexer ); 618 generateFunctions( gen, declsToAddAfter ); 592 619 } // if 593 }594 595 Type * declToTypeDeclBase( Declaration * decl ) {596 if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) {597 return td->base;598 }599 return nullptr;600 620 } 601 621 … … 605 625 if ( ! typeDecl->base ) return; 606 626 607 // generate each of the functions based on the supplied FuncData objects608 std::list< FunctionDecl * > newFuncs;609 std::list< Declaration * > tds { typeDecl };610 std::list< TypeDecl * > typeParams;611 627 TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl ); 612 auto generator = makeFuncGenerator( lazy_map( tds, declToTypeDeclBase ), &refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 613 for ( const FuncData & d : data ) { 614 generator.gen( d, false ); 615 } 616 617 if ( functionNesting == 0 ) { 618 // forward declare if top-level struct, so that 619 // type is complete as soon as its body ends 620 // Note: this is necessary if we want structs which contain 621 // generic (otype) structs as members. 622 for ( FunctionDecl * dcl : newFuncs ) { 623 addForwardDecl( dcl, declsToAddAfter ); 624 } 625 } 626 627 for ( FunctionDecl * dcl : newFuncs ) { 628 FunctionType * ftype = dcl->type; 629 assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() ); 630 DeclarationWithType * dst = ftype->parameters.front(); 631 DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr; 632 // generate appropriate calls to member ctor, assignment 633 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 634 UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) ); 635 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 636 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 637 dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) ); 638 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 639 // assignment needs to return a value 640 FunctionType * assignType = dcl->type; 641 assert( assignType->parameters.size() == 2 ); 642 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.back() ); 643 dcl->statements->kids.push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 644 } 645 declsToAddAfter.push_back( dcl ); 646 } 628 TypeFuncGenerator gen( typeDecl, &refType, data, functionNesting, indexer ); 629 generateFunctions( gen, declsToAddAfter ); 647 630 } 648 631 … … 665 648 visit_children = false; 666 649 // record the existence of this function as appropriate 667 insert( functionDecl, constructable, InitTweak::isDefaultConstructor ); 668 insert( functionDecl, assignable, InitTweak::isAssignment ); 669 insert( functionDecl, copyable, InitTweak::isCopyConstructor ); 670 insert( functionDecl, destructable, InitTweak::isDestructor ); 650 managedTypes.handleDWT( functionDecl ); 671 651 672 652 maybeAccept( functionDecl->type, *visitor ); … … 677 657 678 658 void AutogenerateRoutines::previsit( CompoundStmt * ) { 679 GuardScope( constructable ); 680 GuardScope( assignable ); 681 GuardScope( copyable ); 682 GuardScope( destructable ); 659 GuardScope( managedTypes ); 683 660 GuardScope( structsDone ); 684 661 } -
src/SymTab/Autogen.h
rb96ec83 r6840e7c 19 19 #include <string> // for string 20 20 21 #include "CodeGen/OperatorTable.h" 21 22 #include "Common/UniqueName.h" // for UniqueName 22 23 #include "InitTweak/InitTweak.h" // for InitExpander … … 51 52 52 53 // generate the type of a copy constructor for paramType 53 FunctionType * gen DefaultType( Type * paramType );54 FunctionType * genCopyType( Type * paramType ); 54 55 55 56 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. … … 60 61 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 61 62 template< typename OutputIterator > 62 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false ) { 64 bool isReferenceCtorDtor = false; 65 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { 66 // reference constructors are essentially application of the rebind operator. 67 // apply & to both arguments, do not need a cast 68 fname = "?=?"; 69 dstParam = new AddressExpr( dstParam ); 70 addCast = false; 71 isReferenceCtorDtor = true; 72 } 73 63 74 // want to be able to generate assignment, ctor, and dtor generically, 64 75 // so fname is either ?=?, ?{}, or ^?{} 65 UntypedExpr * fExpr = new UntypedExpr( new NameExpr( fname ) );76 UntypedExpr * fExpr = new UntypedExpr( new NameExpr( fname ) ); 66 77 67 78 if ( addCast ) { … … 78 89 dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) ); 79 90 } 80 fExpr-> get_args().push_back( dstParam );91 fExpr->args.push_back( dstParam ); 81 92 82 93 Statement * listInit = srcParam.buildListInit( fExpr ); 83 94 84 std::list< Expression * > args = *++srcParam; 85 fExpr->get_args().splice( fExpr->get_args().end(), args ); 95 // fetch next set of arguments 96 ++srcParam; 97 98 // return if adding reference fails - will happen on default constructor and destructor 99 if ( isReferenceCtorDtor && ! srcParam.addReference() ) { 100 delete fExpr; 101 return listInit; 102 } 103 104 std::list< Expression * > args = *srcParam; 105 fExpr->args.splice( fExpr->args.end(), args ); 86 106 87 107 *out++ = new ExprStmt( noLabels, fExpr ); … … 105 125 // generate: for ( int i = 0; i < N; ++i ) 106 126 begin = new ConstantExpr( Constant::from_int( 0 ) ); 107 end = array-> get_dimension()->clone();127 end = array->dimension->clone(); 108 128 cmp = new NameExpr( "?<?" ); 109 129 update = new NameExpr( "++?" ); … … 111 131 // generate: for ( int i = N-1; i >= 0; --i ) 112 132 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 113 ((UntypedExpr*)begin)-> get_args().push_back( array->get_dimension()->clone() );114 ((UntypedExpr*)begin)-> get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );133 ((UntypedExpr*)begin)->args.push_back( array->dimension->clone() ); 134 ((UntypedExpr*)begin)->args.push_back( new ConstantExpr( Constant::from_int( 1 ) ) ); 115 135 end = new ConstantExpr( Constant::from_int( 0 ) ); 116 136 cmp = new NameExpr( "?>=?" ); … … 121 141 122 142 UntypedExpr *cond = new UntypedExpr( cmp ); 123 cond-> get_args().push_back( new VariableExpr( index ) );124 cond-> get_args().push_back( end );143 cond->args.push_back( new VariableExpr( index ) ); 144 cond->args.push_back( end ); 125 145 126 146 UntypedExpr *inc = new UntypedExpr( update ); 127 inc-> get_args().push_back( new VariableExpr( index ) );147 inc->args.push_back( new VariableExpr( index ) ); 128 148 129 149 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 130 dstIndex-> get_args().push_back( dstParam );131 dstIndex-> get_args().push_back( new VariableExpr( index ) );150 dstIndex->args.push_back( dstParam ); 151 dstIndex->args.push_back( new VariableExpr( index ) ); 132 152 dstParam = dstIndex; 133 153 134 154 // srcParam must keep track of the array indices to build the 135 155 // source parameter and/or array list initializer 136 srcParam.addArrayIndex( new VariableExpr( index ), array-> get_dimension()->clone() );156 srcParam.addArrayIndex( new VariableExpr( index ), array->dimension->clone() ); 137 157 138 158 // for stmt's body, eventually containing call 139 159 CompoundStmt * body = new CompoundStmt( noLabels ); 140 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body-> get_kids() ), array->get_base(), addCast, forward );160 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->kids ), array->base, addCast, forward ); 141 161 142 162 // block containing for stmt and index variable 143 163 std::list<Statement *> initList; 144 164 CompoundStmt * block = new CompoundStmt( noLabels ); 145 block-> get_kids().push_back( new DeclStmt( noLabels, index ) );165 block->push_back( new DeclStmt( noLabels, index ) ); 146 166 if ( listInit ) block->get_kids().push_back( listInit ); 147 block-> get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );167 block->push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 148 168 149 169 *out++ = block; … … 151 171 152 172 template< typename OutputIterator > 153 Statement * genCall( InitTweak::InitExpander & 173 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 154 174 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 155 175 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 165 185 /// ImplicitCtorDtorStmt node. 166 186 template< typename OutputIterator > 167 void genImplicitCall( InitTweak::InitExpander & 187 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 168 188 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 169 189 assert( obj ); … … 173 193 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ); 174 194 std::list< Statement * > stmts; 175 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj-> get_type(), addCast, forward );195 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward ); 176 196 177 197 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call -
src/SymTab/FixFunction.cc
rb96ec83 r6840e7c 26 26 FixFunction::FixFunction() : isVoid( false ) {} 27 27 28 DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) { 28 29 DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) { 29 30 // can't delete function type because it may contain assertions, so transfer ownership to new object 30 ObjectDecl *pointer = new ObjectDecl( functionDecl-> get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes());31 functionDecl-> get_attributes().clear();31 ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes ); 32 functionDecl->attributes.clear(); 32 33 functionDecl->type = nullptr; 33 34 delete functionDecl; … … 35 36 } 36 37 37 Type * FixFunction::mutate(VoidType *voidType) { 38 isVoid = true; 39 return voidType; 40 } 41 42 Type * FixFunction::mutate(BasicType *basicType) { 43 return basicType; 44 } 45 46 Type * FixFunction::mutate(PointerType *pointerType) { 47 return pointerType; 48 } 49 50 Type * FixFunction::mutate(ArrayType *arrayType) { 38 Type * FixFunction::postmutate(ArrayType *arrayType) { 51 39 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 52 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() ); 40 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic ); 41 arrayType->base = nullptr; 42 arrayType->dimension = nullptr; 53 43 delete arrayType; 54 44 return pointerType; 55 45 } 56 46 57 Type * FixFunction::mutate(StructInstType *aggregateUseType) {58 return aggregateUseType;47 void FixFunction::premutate(VoidType *) { 48 isVoid = true; 59 49 } 60 50 61 Type * FixFunction::mutate(UnionInstType *aggregateUseType) { 62 return aggregateUseType; 63 } 64 65 Type * FixFunction::mutate(EnumInstType *aggregateUseType) { 66 return aggregateUseType; 67 } 68 69 Type * FixFunction::mutate(TraitInstType *aggregateUseType) { 70 return aggregateUseType; 71 } 72 73 Type * FixFunction::mutate(TypeInstType *aggregateUseType) { 74 return aggregateUseType; 75 } 76 77 Type * FixFunction::mutate(TupleType *tupleType) { 78 return tupleType; 79 } 80 81 Type * FixFunction::mutate(VarArgsType *varArgsType) { 82 return varArgsType; 83 } 84 85 Type * FixFunction::mutate(ZeroType *zeroType) { 86 return zeroType; 87 } 88 89 Type * FixFunction::mutate(OneType *oneType) { 90 return oneType; 91 } 51 void FixFunction::premutate(FunctionDecl *) { visit_children = false; } 52 void FixFunction::premutate(BasicType *) { visit_children = false; } 53 void FixFunction::premutate(PointerType *) { visit_children = false; } 54 void FixFunction::premutate(StructInstType *) { visit_children = false; } 55 void FixFunction::premutate(UnionInstType *) { visit_children = false; } 56 void FixFunction::premutate(EnumInstType *) { visit_children = false; } 57 void FixFunction::premutate(TraitInstType *) { visit_children = false; } 58 void FixFunction::premutate(TypeInstType *) { visit_children = false; } 59 void FixFunction::premutate(TupleType *) { visit_children = false; } 60 void FixFunction::premutate(VarArgsType *) { visit_children = false; } 61 void FixFunction::premutate(ZeroType *) { visit_children = false; } 62 void FixFunction::premutate(OneType *) { visit_children = false; } 92 63 } // namespace SymTab 93 64 -
src/SymTab/FixFunction.h
rb96ec83 r6840e7c 16 16 #pragma once 17 17 18 #include " SynTree/Mutator.h" // for Mutator19 #include "SynTree/SynTree.h" // for Types18 #include "Common/PassVisitor.h" // for PassVisitor 19 #include "SynTree/SynTree.h" // for Types 20 20 21 21 namespace SymTab { 22 22 /// Replaces function and array types by equivalent pointer types. 23 class FixFunction : public Mutator{23 class FixFunction : public WithShortCircuiting { 24 24 typedef Mutator Parent; 25 25 public: 26 26 FixFunction(); 27 27 28 bool get_isVoid() const { return isVoid; } 29 void set_isVoid( bool newValue ) { isVoid = newValue; } 30 private: 31 virtual DeclarationWithType* mutate(FunctionDecl *functionDecl); 28 void premutate(FunctionDecl *functionDecl); 29 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 32 30 33 virtual Type* mutate(VoidType *voidType); 34 virtual Type* mutate(BasicType *basicType); 35 virtual Type* mutate(PointerType *pointerType); 36 virtual Type* mutate(ArrayType *arrayType); 37 virtual Type* mutate(StructInstType *aggregateUseType); 38 virtual Type* mutate(UnionInstType *aggregateUseType); 39 virtual Type* mutate(EnumInstType *aggregateUseType); 40 virtual Type* mutate(TraitInstType *aggregateUseType); 41 virtual Type* mutate(TypeInstType *aggregateUseType); 42 virtual Type* mutate(TupleType *tupleType); 43 virtual Type* mutate(VarArgsType *varArgsType); 44 virtual Type* mutate(ZeroType *zeroType); 45 virtual Type* mutate(OneType *oneType); 31 Type * postmutate(ArrayType * arrayType); 32 33 void premutate(VoidType * voidType); 34 void premutate(BasicType * basicType); 35 void premutate(PointerType * pointerType); 36 void premutate(StructInstType * aggregateUseType); 37 void premutate(UnionInstType * aggregateUseType); 38 void premutate(EnumInstType * aggregateUseType); 39 void premutate(TraitInstType * aggregateUseType); 40 void premutate(TypeInstType * aggregateUseType); 41 void premutate(TupleType * tupleType); 42 void premutate(VarArgsType * varArgsType); 43 void premutate(ZeroType * zeroType); 44 void premutate(OneType * oneType); 46 45 47 46 bool isVoid; -
src/SymTab/Indexer.cc
rb96ec83 r6840e7c 407 407 makeWritable(); 408 408 409 const std::string &name = decl-> get_name();409 const std::string &name = decl->name; 410 410 std::string mangleName; 411 if ( LinkageSpec::isOverridable( decl-> get_linkage()) ) {411 if ( LinkageSpec::isOverridable( decl->linkage ) ) { 412 412 // mangle the name without including the appropriate suffix, so overridable routines are placed into the 413 413 // same "bucket" as their user defined versions. … … 418 418 419 419 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage 420 if ( ! LinkageSpec::isMangled( decl-> get_linkage()) ) {420 if ( ! LinkageSpec::isMangled( decl->linkage ) ) { 421 421 // NOTE this is broken in Richard's original code in such a way that it never triggers (it 422 422 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to … … 571 571 572 572 if ( doDebug ) { 573 std::c out<< "--- Entering scope " << scope << std::endl;573 std::cerr << "--- Entering scope " << scope << std::endl; 574 574 } 575 575 } 576 576 577 577 void Indexer::leaveScope() { 578 using std::c out;578 using std::cerr; 579 579 580 580 assert( scope > 0 && "cannot leave initial scope" ); 581 if ( doDebug ) { 582 cerr << "--- Leaving scope " << scope << " containing" << std::endl; 583 } 581 584 --scope; 582 585 583 586 while ( tables && tables->scope > scope ) { 584 587 if ( doDebug ) { 585 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 586 dump( tables->idTable, cout ); 587 dump( tables->typeTable, cout ); 588 dump( tables->structTable, cout ); 589 dump( tables->enumTable, cout ); 590 dump( tables->unionTable, cout ); 591 dump( tables->traitTable, cout ); 588 dump( tables->idTable, cerr ); 589 dump( tables->typeTable, cerr ); 590 dump( tables->structTable, cerr ); 591 dump( tables->enumTable, cerr ); 592 dump( tables->unionTable, cerr ); 593 dump( tables->traitTable, cerr ); 592 594 } 593 595 -
src/SymTab/Mangler.cc
rb96ec83 r6840e7c 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:40:29 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Jun 28 15:31:00201713 // Update Count : 2 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:49:26 2017 13 // Update Count : 23 14 14 // 15 15 #include "Mangler.h" … … 115 115 "Id", // DoubleImaginary 116 116 "Ir", // LongDoubleImaginary 117 "w", // SignedInt128 118 "Uw", // UnsignedInt128 117 119 }; 118 120 -
src/SymTab/Validate.cc
rb96ec83 r6840e7c 153 153 void previsit( ObjectDecl * object ); 154 154 void previsit( FunctionDecl * func ); 155 void previsit( StructDecl * aggrDecl ); 156 void previsit( UnionDecl * aggrDecl ); 155 157 }; 156 158 … … 270 272 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist 271 273 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 274 ReturnChecker::checkFunctionReturns( translationUnit ); 275 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen 272 276 Concurrency::applyKeywords( translationUnit ); 277 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution 273 278 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay 274 279 Concurrency::implementMutexFuncs( translationUnit ); 275 280 Concurrency::implementThreadStarter( translationUnit ); 276 ReturnChecker::checkFunctionReturns( translationUnit );277 281 mutateAll( translationUnit, compoundliteral ); 278 acceptAll( translationUnit, fpd );279 282 ArrayLength::computeLength( translationUnit ); 280 acceptAll( translationUnit, finder ); 283 acceptAll( translationUnit, finder ); // xxx - remove this pass soon 281 284 mutateAll( translationUnit, labelAddrFixer ); 282 285 } … … 369 372 DWTIterator begin( dwts.begin() ), end( dwts.end() ); 370 373 if ( begin == end ) return; 371 FixFunctionfixer;374 PassVisitor<FixFunction> fixer; 372 375 DWTIterator i = begin; 373 376 *i = (*i)->acceptMutator( fixer ); 374 if ( fixer. get_isVoid()) {377 if ( fixer.pass.isVoid ) { 375 378 DWTIterator j = i; 376 379 ++i; … … 383 386 ++i; 384 387 for ( ; i != end; ++i ) { 385 FixFunctionfixer;388 PassVisitor<FixFunction> fixer; 386 389 *i = (*i)->acceptMutator( fixer ); 387 if ( fixer. get_isVoid()) {390 if ( fixer.pass.isVoid ) { 388 391 throw SemanticError( "invalid type void in function type ", func ); 389 392 } // if … … 597 600 // apply FixFunction to every assertion to check for invalid void type 598 601 for ( DeclarationWithType *& assertion : type->assertions ) { 599 FixFunctionfixer;602 PassVisitor<FixFunction> fixer; 600 603 assertion = assertion->acceptMutator( fixer ); 601 if ( fixer. get_isVoid()) {604 if ( fixer.pass.isVoid ) { 602 605 throw SemanticError( "invalid type void in assertion of function ", node ); 603 606 } // if … … 618 621 forallFixer( func->type->forall, func ); 619 622 func->fixUniqueId(); 623 } 624 625 void ForallPointerDecay::previsit( StructDecl * aggrDecl ) { 626 forallFixer( aggrDecl->parameters, aggrDecl ); 627 } 628 629 void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) { 630 forallFixer( aggrDecl->parameters, aggrDecl ); 620 631 } 621 632 -
src/SynTree/AddressExpr.cc
rb96ec83 r6840e7c 33 33 Type * addrType( Type * type ) { 34 34 if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) { 35 return new ReferenceType( refType->get_qualifiers(), addrType( refType-> get_base()) );35 return new ReferenceType( refType->get_qualifiers(), addrType( refType->base ) ); 36 36 } else { 37 37 return new PointerType( Type::Qualifiers(), type->clone() ); … … 40 40 } 41 41 42 AddressExpr::AddressExpr( Expression *arg , Expression *_aname ) : Expression( _aname), arg( arg ) {43 if ( arg-> has_result()) {44 if ( arg-> get_result()->get_lvalue() ) {42 AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) { 43 if ( arg->result ) { 44 if ( arg->result->get_lvalue() ) { 45 45 // lvalue, retains all layers of reference and gains a pointer inside the references 46 set_result( addrType( arg-> get_result()) );46 set_result( addrType( arg->result ) ); 47 47 } else { 48 48 // taking address of non-lvalue -- must be a reference, loses one layer of reference 49 ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg-> get_result());50 set_result( addrType( refType-> get_base()) );49 ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg->result ); 50 set_result( addrType( refType->base ) ); 51 51 } 52 52 // result of & is never an lvalue … … 62 62 } 63 63 64 void AddressExpr::print( std::ostream &os, intindent ) const {64 void AddressExpr::print( std::ostream &os, Indenter indent ) const { 65 65 os << "Address of:" << std::endl; 66 66 if ( arg ) { 67 os << std::string( indent+2, ' ' );68 arg->print( os, indent+ 2);67 os << indent+1; 68 arg->print( os, indent+1 ); 69 69 } // if 70 70 } … … 77 77 LabelAddressExpr::~LabelAddressExpr() {} 78 78 79 void LabelAddressExpr::print( std::ostream & os, int indent) const {80 os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) <<arg;79 void LabelAddressExpr::print( std::ostream & os, Indenter ) const { 80 os << "Address of label:" << arg; 81 81 } 82 82 -
src/SynTree/AggregateDecl.cc
rb96ec83 r6840e7c 41 41 } 42 42 43 void AggregateDecl::print( std::ostream &os, intindent ) const {43 void AggregateDecl::print( std::ostream &os, Indenter indent ) const { 44 44 using std::string; 45 45 using std::endl; 46 46 47 os << typeString() << " " << get_name()<< ":";47 os << typeString() << " " << name << ":"; 48 48 if ( get_linkage() != LinkageSpec::Cforall ) { 49 os << " " << LinkageSpec::linkageName( get_linkage());49 os << " " << LinkageSpec::linkageName( linkage ); 50 50 } // if 51 os << " with body " << has_body() << endl;51 os << " with body " << has_body(); 52 52 53 53 if ( ! parameters.empty() ) { 54 os << endl << string( indent+2, ' ' ) << "with parameters" << endl;55 printAll( parameters, os, indent+ 4);54 os << endl << indent << "... with parameters" << endl; 55 printAll( parameters, os, indent+1 ); 56 56 } // if 57 57 if ( ! members.empty() ) { 58 os << endl << string( indent+2, ' ' ) << "with members" << endl;59 printAll( members, os, indent+ 4);58 os << endl << indent << "... with members" << endl; 59 printAll( members, os, indent+1 ); 60 60 } // if 61 61 if ( ! attributes.empty() ) { 62 os << endl << string( indent+2, ' ' ) << "with attributes" << endl;63 printAll( attributes, os, indent+ 4);62 os << endl << indent << "... with attributes" << endl; 63 printAll( attributes, os, indent+1 ); 64 64 } // if 65 os << endl; 65 66 } 66 67 67 void AggregateDecl::printShort( std::ostream &os, intindent ) const {68 void AggregateDecl::printShort( std::ostream &os, Indenter indent ) const { 68 69 using std::string; 69 70 using std::endl; 70 71 71 os << typeString() << " " << get_name(); 72 os << string( indent+2, ' ' ) << "with body " << has_body() << endl; 72 os << typeString() << " " << name << " with body " << has_body() << endl; 73 73 74 74 if ( ! parameters.empty() ) { 75 os << endl << string( indent+2, ' ' ) << "with parameters" << endl;76 printAll( parameters, os, indent+ 4);75 os << indent << "... with parameters" << endl; 76 printAll( parameters, os, indent+1 ); 77 77 } // if 78 78 } -
src/SynTree/ApplicationExpr.cc
rb96ec83 r6840e7c 55 55 set_result( ResolvExpr::extractResultType( function ) ); 56 56 57 assert( has_result());57 assert( result ); 58 58 } 59 59 … … 68 68 } 69 69 70 void printInferParams( const InferredParams & inferParams, std::ostream &os, intindent, int level ) {70 void printInferParams( const InferredParams & inferParams, std::ostream &os, Indenter indent, int level ) { 71 71 if ( ! inferParams.empty() ) { 72 os << std::string(indent, ' ')<< "with inferred parameters " << level << ":" << std::endl;72 os << indent << "with inferred parameters " << level << ":" << std::endl; 73 73 for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) { 74 os << std::string(indent+2, ' ');75 Declaration::declFromId( i->second.decl )->printShort( os, indent+ 2);74 os << indent+1; 75 Declaration::declFromId( i->second.decl )->printShort( os, indent+1 ); 76 76 os << std::endl; 77 printInferParams( *i->second.inferParams, os, indent+ 2, level+1 );77 printInferParams( *i->second.inferParams, os, indent+1, level+1 ); 78 78 } // for 79 79 } // if 80 80 } 81 81 82 void ApplicationExpr::print( std::ostream &os, int indent ) const { 83 os << "Application of" << std::endl << std::string(indent+2, ' '); 84 function->print( os, indent+2 ); 82 void ApplicationExpr::print( std::ostream &os, Indenter indent ) const { 83 os << "Application of" << std::endl << indent+1; 84 function->print( os, indent+1 ); 85 os << std::endl; 85 86 if ( ! args.empty() ) { 86 os << std::string( indent, ' ' ) << "to arguments" << std::endl;87 printAll( args, os, indent+ 2);87 os << indent << "... to arguments" << std::endl; 88 printAll( args, os, indent+1 ); 88 89 } // if 89 printInferParams( inferParams, os, indent+ 2, 0 );90 printInferParams( inferParams, os, indent+1, 0 ); 90 91 Expression::print( os, indent ); 91 92 } -
src/SynTree/ArrayType.cc
rb96ec83 r6840e7c 39 39 } 40 40 41 void ArrayType::print( std::ostream &os, intindent ) const {41 void ArrayType::print( std::ostream &os, Indenter indent ) const { 42 42 Type::print( os, indent ); 43 43 if ( isStatic ) { -
src/SynTree/AttrType.cc
rb96ec83 r6840e7c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AttrType.cc.cc -- 7 // AttrType.cc.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 42 42 } 43 43 44 void AttrType::print( std::ostream &os, intindent ) const {44 void AttrType::print( std::ostream &os, Indenter indent ) const { 45 45 Type::print( os, indent ); 46 46 os << "attribute " << name << " applied to "; -
src/SynTree/Attribute.cc
rb96ec83 r6840e7c 28 28 } 29 29 30 void Attribute::print( std::ostream &os, intindent ) const {30 void Attribute::print( std::ostream &os, Indenter indent ) const { 31 31 using std::endl; 32 32 using std::string; … … 36 36 if ( ! parameters.empty() ) { 37 37 os << " with parameters: " << endl; 38 printAll( parameters, os, indent );38 printAll( parameters, os, indent+1 ); 39 39 } 40 40 } -
src/SynTree/Attribute.h
rb96ec83 r6840e7c 43 43 bool empty() const { return name == ""; } 44 44 45 Attribute * clone() const { return new Attribute( *this ); }46 virtual void accept( Visitor & v ) { v.visit( this ); }47 virtual Attribute * acceptMutator( Mutator & m ) { return m.mutate( this ); }48 virtual void print( std::ostream & os, int indent = 0 ) const;45 Attribute * clone() const override { return new Attribute( *this ); } 46 virtual void accept( Visitor & v ) override { v.visit( this ); } 47 virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 48 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 49 49 }; 50 50 -
src/SynTree/BaseSyntaxNode.h
rb96ec83 r6840e7c 17 17 18 18 #include "Common/CodeLocation.h" 19 #include "Common/Indenter.h" 19 20 class Visitor; 20 21 class Mutator; … … 29 30 virtual void accept( Visitor & v ) = 0; 30 31 virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0; 31 virtual void print( std::ostream & os, int indent = 0 ) const = 0; 32 /// Notes: 33 /// * each node is responsible for indenting its children. 34 /// * Expressions should not finish with a newline, since the expression's parent has better information. 35 virtual void print( std::ostream & os, Indenter indent = {} ) const = 0; 36 void print( std::ostream & os, unsigned int indent ) { 37 print( os, Indenter{ Indenter::tabsize, indent }); 38 } 32 39 }; 33 40 -
src/SynTree/BasicType.cc
rb96ec83 r6840e7c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // BasicType.cc -- 7 // BasicType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 11 12:52:05201713 // Update Count : 912 // Last Modified On : Mon Sep 25 14:14:03 2017 13 // Update Count : 11 14 14 // 15 15 … … 24 24 BasicType::BasicType( const Type::Qualifiers &tq, Kind bt, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), kind( bt ) {} 25 25 26 void BasicType::print( std::ostream &os, intindent ) const {26 void BasicType::print( std::ostream &os, Indenter indent ) const { 27 27 Type::print( os, indent ); 28 28 os << BasicType::typeNames[ kind ]; … … 43 43 case LongLongSignedInt: 44 44 case LongLongUnsignedInt: 45 case SignedInt128: 46 case UnsignedInt128: 45 47 return true; 46 48 case Float: -
src/SynTree/CommaExpr.cc
rb96ec83 r6840e7c 21 21 #include "Type.h" // for Type 22 22 23 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 , Expression *_aname)24 : Expression( _aname), arg1( arg1 ), arg2( arg2 ) {23 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 ) 24 : Expression(), arg1( arg1 ), arg2( arg2 ) { 25 25 // xxx - result of a comma expression is never an lvalue, so should set lvalue 26 26 // to false on all result types. Actually doing this causes some strange things … … 39 39 } 40 40 41 void CommaExpr::print( std::ostream &os, intindent ) const {41 void CommaExpr::print( std::ostream &os, Indenter indent ) const { 42 42 os << "Comma Expression:" << std::endl; 43 os << std::string( indent+2, ' ');44 arg1->print( os, indent+ 2);43 os << (indent+1); 44 arg1->print( os, indent+1 ); 45 45 os << std::endl; 46 os << std::string( indent+2, ' ');47 arg2->print( os, indent+ 2);46 os << (indent+1); 47 arg2->print( os, indent+1 ); 48 48 Expression::print( os, indent ); 49 49 } -
src/SynTree/CompoundStmt.cc
rb96ec83 r6840e7c 73 73 } 74 74 75 void CompoundStmt::print( std::ostream &os, intindent ) const {76 os << "CompoundStmt" << endl 77 printAll( kids, os, indent + 2);75 void CompoundStmt::print( std::ostream &os, Indenter indent ) const { 76 os << "CompoundStmt" << endl; 77 printAll( kids, os, indent+1 ); 78 78 } 79 79 -
src/SynTree/Constant.cc
rb96ec83 r6840e7c 71 71 } 72 72 73 void Constant::print( std::ostream &os ) const {73 void Constant::print( std::ostream &os, Indenter ) const { 74 74 os << "(" << rep << " " << val.ival; 75 75 if ( type ) { -
src/SynTree/Constant.h
rb96ec83 r6840e7c 19 19 #include <string> // for string 20 20 21 #include "BaseSyntaxNode.h" 21 22 #include "Mutator.h" // for Mutator 22 23 #include "Visitor.h" // for Visitor … … 24 25 class Type; 25 26 26 class Constant {27 class Constant : public BaseSyntaxNode { 27 28 public: 28 29 Constant( Type * type, std::string rep, unsigned long long val ); … … 30 31 Constant( const Constant & other ); 31 32 virtual ~Constant(); 33 34 virtual Constant * clone() const { return new Constant( *this ); } 32 35 33 36 Type * get_type() { return type; } … … 54 57 virtual void accept( Visitor & v ) { v.visit( this ); } 55 58 virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); } 56 virtual void print( std::ostream & os ) const;59 virtual void print( std::ostream & os, Indenter indent = 0 ) const; 57 60 private: 58 61 Type * type; -
src/SynTree/DeclStmt.cc
rb96ec83 r6840e7c 33 33 } 34 34 35 void DeclStmt::print( std::ostream &os, intindent ) const {35 void DeclStmt::print( std::ostream &os, Indenter indent ) const { 36 36 assert( decl != 0 ); 37 37 os << "Declaration of "; -
src/SynTree/Declaration.cc
rb96ec83 r6840e7c 42 42 43 43 void Declaration::fixUniqueId() { 44 // don't need to set unique ID twice 45 if ( uniqueId ) return; 44 46 uniqueId = ++lastUniqueId; 45 47 idMap[ uniqueId ] = this; … … 70 72 } 71 73 72 void AsmDecl::print( std::ostream &os, intindent ) const {74 void AsmDecl::print( std::ostream &os, Indenter indent ) const { 73 75 stmt->print( os, indent ); 74 76 } 75 77 76 void AsmDecl::printShort( std::ostream &os, intindent ) const {78 void AsmDecl::printShort( std::ostream &os, Indenter indent ) const { 77 79 stmt->print( os, indent ); 78 80 } -
src/SynTree/Declaration.h
rb96ec83 r6840e7c 61 61 62 62 void fixUniqueId( void ); 63 virtual Declaration *clone() const = 0;63 virtual Declaration *clone() const override = 0; 64 64 virtual void accept( Visitor &v ) override = 0; 65 virtual Declaration *acceptMutator( Mutator &m ) = 0;66 virtual void print( std::ostream &os, int indent = 0) const override = 0;67 virtual void printShort( std::ostream &os, int indent = 0) const = 0;65 virtual Declaration *acceptMutator( Mutator &m ) override = 0; 66 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; 67 virtual void printShort( std::ostream &os, Indenter indent = {} ) const = 0; 68 68 69 69 static void dumpIds( std::ostream &os ); … … 142 142 virtual void accept( Visitor &v ) override { v.visit( this ); } 143 143 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 144 virtual void print( std::ostream &os, int indent = 0) const override;145 virtual void printShort( std::ostream &os, int indent = 0) const override;144 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 145 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 146 146 }; 147 147 … … 170 170 virtual void accept( Visitor &v ) override { v.visit( this ); } 171 171 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 172 virtual void print( std::ostream &os, int indent = 0) const override;173 virtual void printShort( std::ostream &os, int indent = 0) const override;172 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 173 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 174 174 }; 175 175 … … 193 193 194 194 virtual NamedTypeDecl *clone() const override = 0; 195 virtual void print( std::ostream &os, int indent = 0) const override;196 virtual void printShort( std::ostream &os, int indent = 0) const override;195 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 196 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 197 197 }; 198 198 … … 235 235 virtual void accept( Visitor &v ) override { v.visit( this ); } 236 236 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 237 virtual void print( std::ostream &os, int indent = 0) const override;237 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 238 238 239 239 private: … … 276 276 AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; } 277 277 278 virtual void print( std::ostream &os, int indent = 0) const override;279 virtual void printShort( std::ostream &os, int indent = 0) const override;278 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 279 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 280 280 protected: 281 281 virtual std::string typeString() const = 0; … … 355 355 virtual void accept( Visitor &v ) override { v.visit( this ); } 356 356 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 357 virtual void print( std::ostream &os, int indent = 0) const override;358 virtual void printShort( std::ostream &os, int indent = 0) const override;357 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 358 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 359 359 }; 360 360 -
src/SynTree/Expression.cc
rb96ec83 r6840e7c 33 33 #include "GenPoly/Lvalue.h" 34 34 35 Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname) {}36 37 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ),extension( other.extension ) {35 Expression::Expression() : result( 0 ), env( 0 ) {} 36 37 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ) { 38 38 } 39 39 40 40 Expression::~Expression() { 41 41 delete env; 42 delete argName; // xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix43 42 delete result; 44 43 } 45 44 46 void Expression::print( std::ostream &os, intindent ) const {45 void Expression::print( std::ostream &os, Indenter indent ) const { 47 46 if ( env ) { 48 os << std:: string( indent, ' ' ) << "with environment:" << std::endl;49 env->print( os, indent+ 2);47 os << std::endl << indent << "... with environment:" << std::endl; 48 env->print( os, indent+1 ); 50 49 } // if 51 50 52 if ( argName ) { 53 os << std::string( indent, ' ' ) << "with designator:"; 54 argName->print( os, indent+2 ); 51 if ( extension ) { 52 os << std::endl << indent << "... with extension:"; 55 53 } // if 56 57 if ( extension ) { 58 os << std::string( indent, ' ' ) << "with extension:"; 59 } // if 60 } 61 62 ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) { 54 } 55 56 ConstantExpr::ConstantExpr( Constant _c ) : Expression(), constant( _c ) { 63 57 set_result( constant.get_type()->clone() ); 64 58 } … … 69 63 ConstantExpr::~ConstantExpr() {} 70 64 71 void ConstantExpr::print( std::ostream &os, intindent ) const {65 void ConstantExpr::print( std::ostream &os, Indenter indent ) const { 72 66 os << "constant expression " ; 73 67 constant.print( os ); … … 75 69 } 76 70 77 VariableExpr::VariableExpr( DeclarationWithType *_var , Expression *_aname ) : Expression( _aname), var( _var ) {71 VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) { 78 72 assert( var ); 79 73 assert( var->get_type() ); … … 96 90 } 97 91 98 void VariableExpr::print( std::ostream &os, intindent ) const {92 void VariableExpr::print( std::ostream &os, Indenter indent ) const { 99 93 os << "Variable Expression: "; 100 101 Declaration *decl = get_var(); 102 if ( decl != 0) decl->printShort(os, indent + 2); 103 os << std::endl; 104 Expression::print( os, indent ); 105 } 106 107 SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) : 108 Expression( _aname ), expr(expr_), type(0), isType(false) { 94 var->printShort(os, indent); 95 Expression::print( os, indent ); 96 } 97 98 SizeofExpr::SizeofExpr( Expression *expr_ ) : 99 Expression(), expr(expr_), type(0), isType(false) { 109 100 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 110 101 } 111 102 112 SizeofExpr::SizeofExpr( Type *type_ , Expression *_aname) :113 Expression( _aname), expr(0), type(type_), isType(true) {103 SizeofExpr::SizeofExpr( Type *type_ ) : 104 Expression(), expr(0), type(type_), isType(true) { 114 105 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 115 106 } … … 124 115 } 125 116 126 void SizeofExpr::print( std::ostream &os, intindent) const {117 void SizeofExpr::print( std::ostream &os, Indenter indent) const { 127 118 os << "Sizeof Expression on: "; 128 129 if (isType) 130 type->print(os, indent + 2); 131 else 132 expr->print(os, indent + 2); 133 134 os << std::endl; 135 Expression::print( os, indent ); 136 } 137 138 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) : 139 Expression( _aname ), expr(expr_), type(0), isType(false) { 119 if (isType) type->print(os, indent+1); 120 else expr->print(os, indent+1); 121 Expression::print( os, indent ); 122 } 123 124 AlignofExpr::AlignofExpr( Expression *expr_ ) : 125 Expression(), expr(expr_), type(0), isType(false) { 140 126 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 141 127 } 142 128 143 AlignofExpr::AlignofExpr( Type *type_ , Expression *_aname) :144 Expression( _aname), expr(0), type(type_), isType(true) {129 AlignofExpr::AlignofExpr( Type *type_ ) : 130 Expression(), expr(0), type(type_), isType(true) { 145 131 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 146 132 } … … 155 141 } 156 142 157 void AlignofExpr::print( std::ostream &os, intindent) const {143 void AlignofExpr::print( std::ostream &os, Indenter indent) const { 158 144 os << "Alignof Expression on: "; 159 160 if (isType) 161 type->print(os, indent + 2); 162 else 163 expr->print(os, indent + 2); 164 165 os << std::endl; 166 Expression::print( os, indent ); 167 } 168 169 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) : 170 Expression( _aname ), type(type_), member(member_) { 145 if (isType) type->print(os, indent+1); 146 else expr->print(os, indent+1); 147 Expression::print( os, indent ); 148 } 149 150 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type, const std::string &member ) : 151 Expression(), type(type), member(member) { 152 assert( type ); 171 153 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 172 154 } … … 179 161 } 180 162 181 void UntypedOffsetofExpr::print( std::ostream &os, int indent) const { 182 os << std::string( indent, ' ' ) << "Untyped Offsetof Expression on member " << member << " of "; 183 184 if ( type ) { 185 type->print(os, indent + 2); 186 } else { 187 os << "<NULL>"; 188 } 189 190 os << std::endl; 191 Expression::print( os, indent ); 192 } 193 194 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) : 195 Expression( _aname ), type(type_), member(member_) { 163 void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const { 164 os << "Untyped Offsetof Expression on member " << member << " of "; 165 type->print(os, indent+1); 166 Expression::print( os, indent ); 167 } 168 169 OffsetofExpr::OffsetofExpr( Type *type, DeclarationWithType *member ) : 170 Expression(), type(type), member(member) { 171 assert( member ); 172 assert( type ); 196 173 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 197 174 } … … 204 181 } 205 182 206 void OffsetofExpr::print( std::ostream &os, int indent) const { 207 os << std::string( indent, ' ' ) << "Offsetof Expression on member "; 208 209 if ( member ) { 210 os << member->get_name(); 211 } else { 212 os << "<NULL>"; 213 } 214 215 os << " of "; 216 217 if ( type ) { 218 type->print(os, indent + 2); 219 } else { 220 os << "<NULL>"; 221 } 222 223 os << std::endl; 224 Expression::print( os, indent ); 225 } 226 227 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) { 183 void OffsetofExpr::print( std::ostream &os, Indenter indent) const { 184 os << "Offsetof Expression on member " << member->name << " of "; 185 type->print(os, indent+1); 186 Expression::print( os, indent ); 187 } 188 189 OffsetPackExpr::OffsetPackExpr( StructInstType *type ) : Expression(), type( type ) { 190 assert( type ); 228 191 set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 229 192 } … … 233 196 OffsetPackExpr::~OffsetPackExpr() { delete type; } 234 197 235 void OffsetPackExpr::print( std::ostream &os, int indent ) const { 236 os << std::string( indent, ' ' ) << "Offset pack expression on "; 237 238 if ( type ) { 239 type->print(os, indent + 2); 240 } else { 241 os << "<NULL>"; 242 } 243 244 os << std::endl; 245 Expression::print( os, indent ); 246 } 247 248 AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) : 249 Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false) { 250 } 251 252 AttrExpr::AttrExpr( Expression *attr, Type *type_, Expression *_aname ) : 253 Expression( _aname ), attr( attr ), expr(0), type(type_), isType(true) { 198 void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const { 199 os << "Offset pack expression on "; 200 type->print(os, indent+1); 201 Expression::print( os, indent ); 202 } 203 204 AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) : 205 Expression(), attr( attr ), expr(expr_), type(0), isType(false) { 206 } 207 208 AttrExpr::AttrExpr( Expression *attr, Type *type_ ) : 209 Expression(), attr( attr ), expr(0), type(type_), isType(true) { 254 210 } 255 211 … … 264 220 } 265 221 266 void AttrExpr::print( std::ostream &os, intindent) const {222 void AttrExpr::print( std::ostream &os, Indenter indent) const { 267 223 os << "Attr "; 268 attr->print( os, indent + 2);224 attr->print( os, indent+1); 269 225 if ( isType || expr ) { 270 226 os << "applied to: "; 271 272 if (isType) 273 type->print(os, indent + 2); 274 else 275 expr->print(os, indent + 2); 227 if (isType) type->print(os, indent+1); 228 else expr->print(os, indent+1); 276 229 } // if 277 278 os << std::endl; 279 Expression::print( os, indent ); 280 } 281 282 CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) { 230 Expression::print( os, indent ); 231 } 232 233 CastExpr::CastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) { 283 234 set_result(toType); 284 235 } 285 236 286 CastExpr::CastExpr( Expression *arg_ , Expression *_aname ) : Expression( _aname), arg(arg_) {237 CastExpr::CastExpr( Expression *arg_ ) : Expression(), arg(arg_) { 287 238 set_result( new VoidType( Type::Qualifiers() ) ); 288 239 } … … 295 246 } 296 247 297 void CastExpr::print( std::ostream &os, int indent ) const { 298 os << "Cast of:" << std::endl << std::string( indent+2, ' ' ); 299 arg->print(os, indent+2); 300 os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl; 301 os << std::string( indent+2, ' ' ); 248 void CastExpr::print( std::ostream &os, Indenter indent ) const { 249 os << "Cast of:" << std::endl << indent+1; 250 arg->print(os, indent+1); 251 os << std::endl << indent << "... to:"; 302 252 if ( result->isVoid() ) { 303 os << " nothing";253 os << " nothing"; 304 254 } else { 305 result->print( os, indent+2 ); 255 os << std::endl << indent+1; 256 result->print( os, indent+1 ); 306 257 } // if 307 os << std::endl;308 258 Expression::print( os, indent ); 309 259 } … … 320 270 } 321 271 322 void VirtualCastExpr::print( std::ostream &os, int indent ) const { 323 os << "Virtual Cast of:" << std::endl << std::string( indent+2, ' ' ); 324 arg->print(os, indent+2); 325 os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl; 326 os << std::string( indent+2, ' ' ); 272 void VirtualCastExpr::print( std::ostream &os, Indenter indent ) const { 273 os << "Virtual Cast of:" << std::endl << indent+1; 274 arg->print(os, indent+1); 275 os << std::endl << indent << "... to:"; 327 276 if ( ! result ) { 328 os << " unknown";277 os << " unknown"; 329 278 } else { 330 result->print( os, indent+2 ); 279 os << std::endl << indent+1; 280 result->print( os, indent+1 ); 331 281 } // if 332 os << std::endl; 333 Expression::print( os, indent ); 334 } 335 336 UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) : 337 Expression( _aname ), member(_member), aggregate(_aggregate) {} 282 Expression::print( os, indent ); 283 } 284 285 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) : 286 Expression(), member(member), aggregate(aggregate) { 287 assert( aggregate ); 288 } 338 289 339 290 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) : … … 346 297 } 347 298 348 void UntypedMemberExpr::print( std::ostream &os, int indent ) const { 349 os << "Untyped Member Expression, with field: " << std::endl; 350 os << std::string( indent+2, ' ' ); 351 get_member()->print(os, indent+4); 352 os << std::string( indent+2, ' ' ); 353 354 Expression *agg = get_aggregate(); 355 os << "from aggregate: " << std::endl; 356 if (agg != 0) { 357 os << std::string( indent + 4, ' ' ); 358 agg->print(os, indent + 4); 359 } 360 os << std::string( indent+2, ' ' ); 299 void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const { 300 os << "Untyped Member Expression, with field: " << std::endl << indent+1; 301 member->print(os, indent+1 ); 302 os << indent << "... from aggregate: " << std::endl << indent+1; 303 aggregate->print(os, indent+1); 361 304 Expression::print( os, indent ); 362 305 } … … 377 320 378 321 379 MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) : 380 Expression( _aname ), member(_member), aggregate(_aggregate) { 322 MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) : 323 Expression(), member(member), aggregate(aggregate) { 324 assert( member ); 325 assert( aggregate ); 381 326 382 327 TypeSubstitution sub( makeSub( aggregate->get_result() ) ); … … 396 341 } 397 342 398 void MemberExpr::print( std::ostream &os, intindent ) const {343 void MemberExpr::print( std::ostream &os, Indenter indent ) const { 399 344 os << "Member Expression, with field: " << std::endl; 400 401 assert( member ); 402 os << std::string( indent + 2, ' ' ); 403 member->print( os, indent + 2 ); 404 os << std::endl; 405 406 Expression *agg = get_aggregate(); 407 os << std::string( indent, ' ' ) << "from aggregate: " << std::endl; 408 if (agg != 0) { 409 os << std::string( indent + 2, ' ' ); 410 agg->print(os, indent + 2); 411 } 412 os << std::string( indent+2, ' ' ); 413 Expression::print( os, indent ); 414 } 415 416 UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) : 417 Expression( _aname ), function(_function), args(_args) {} 345 os << indent+1; 346 member->print( os, indent+1 ); 347 os << std::endl << indent << "... from aggregate: " << std::endl << indent+1; 348 aggregate->print(os, indent + 1); 349 Expression::print( os, indent ); 350 } 351 352 UntypedExpr::UntypedExpr( Expression *function, const std::list<Expression *> &args ) : 353 Expression(), function(function), args(args) {} 418 354 419 355 UntypedExpr::UntypedExpr( const UntypedExpr &other ) : … … 456 392 457 393 458 void UntypedExpr::print( std::ostream &os, intindent ) const {394 void UntypedExpr::print( std::ostream &os, Indenter indent ) const { 459 395 os << "Applying untyped: " << std::endl; 460 os << std::string( indent+2, ' ' ); 461 function->print(os, indent + 2); 462 os << std::string( indent, ' ' ) << "...to: " << std::endl; 463 printAll(args, os, indent + 2); 464 Expression::print( os, indent ); 465 } 466 467 void UntypedExpr::printArgs( std::ostream &os, int indent ) const { 468 std::list<Expression *>::const_iterator i; 469 for (i = args.begin(); i != args.end(); i++) { 470 os << std::string(indent, ' ' ); 471 (*i)->print(os, indent); 472 } 473 } 474 475 NameExpr::NameExpr( std::string _name, Expression *_aname ) : Expression( _aname ), name(_name) { 476 assertf(_name != "0", "Zero is not a valid name\n"); 477 assertf(_name != "1", "One is not a valid name\n"); 396 os << indent+1; 397 function->print(os, indent+1); 398 os << std::endl << indent << "...to: " << std::endl; 399 printAll(args, os, indent+1); 400 Expression::print( os, indent ); 401 } 402 403 NameExpr::NameExpr( std::string name ) : Expression(), name(name) { 404 assertf(name != "0", "Zero is not a valid name"); 405 assertf(name != "1", "One is not a valid name"); 478 406 } 479 407 … … 483 411 NameExpr::~NameExpr() {} 484 412 485 void NameExpr::print( std::ostream &os, intindent ) const {486 os << "Name: " << get_name() << std::endl;487 Expression::print( os, indent ); 488 } 489 490 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp , Expression *_aname) :491 Expression( _aname), arg1(arg1_), arg2(arg2_), isAnd(andp) {413 void NameExpr::print( std::ostream &os, Indenter indent ) const { 414 os << "Name: " << get_name(); 415 Expression::print( os, indent ); 416 } 417 418 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp ) : 419 Expression(), arg1(arg1_), arg2(arg2_), isAnd(andp) { 492 420 set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 493 421 } … … 502 430 } 503 431 504 void LogicalExpr::print( std::ostream &os, intindent )const {505 os << "Short-circuited operation (" << (isAnd ?"and":"or") << ") on: ";432 void LogicalExpr::print( std::ostream &os, Indenter indent )const { 433 os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: "; 506 434 arg1->print(os); 507 435 os << " and "; 508 436 arg2->print(os); 509 os << std::endl; 510 Expression::print( os, indent ); 511 } 512 513 ConditionalExpr::ConditionalExpr( Expression *arg1_, Expression *arg2_, Expression *arg3_, Expression *_aname ) : 514 Expression( _aname ), arg1(arg1_), arg2(arg2_), arg3(arg3_) {} 437 Expression::print( os, indent ); 438 } 439 440 ConditionalExpr::ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 ) : 441 Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {} 515 442 516 443 ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) : … … 524 451 } 525 452 526 void ConditionalExpr::print( std::ostream &os, int indent ) const { 527 os << "Conditional expression on: " << std::endl; 528 os << std::string( indent+2, ' ' ); 529 arg1->print( os, indent+2 ); 530 os << std::string( indent, ' ' ) << "First alternative:" << std::endl; 531 os << std::string( indent+2, ' ' ); 532 arg2->print( os, indent+2 ); 533 os << std::string( indent, ' ' ) << "Second alternative:" << std::endl; 534 os << std::string( indent+2, ' ' ); 535 arg3->print( os, indent+2 ); 536 os << std::endl; 453 void ConditionalExpr::print( std::ostream &os, Indenter indent ) const { 454 os << "Conditional expression on: " << std::endl << indent+1; 455 arg1->print( os, indent+1 ); 456 os << indent << "First alternative:" << std::endl << indent+1; 457 arg2->print( os, indent+1 ); 458 os << indent << "Second alternative:" << std::endl << indent+1; 459 arg3->print( os, indent+1 ); 537 460 Expression::print( os, indent ); 538 461 } … … 541 464 542 465 543 void AsmExpr::print( std::ostream &os, intindent ) const {466 void AsmExpr::print( std::ostream &os, Indenter indent ) const { 544 467 os << "Asm Expression: " << std::endl; 545 if ( inout ) inout->print( os, indent + 2);546 if ( constraint ) constraint->print( os, indent + 2);547 if ( operand ) operand->print( os, indent + 2);468 if ( inout ) inout->print( os, indent+1 ); 469 if ( constraint ) constraint->print( os, indent+1 ); 470 if ( operand ) operand->print( os, indent+1 ); 548 471 } 549 472 … … 551 474 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) { 552 475 assert( callExpr ); 553 assert( callExpr-> has_result());476 assert( callExpr->result ); 554 477 set_result( callExpr->get_result()->clone() ); 555 478 } … … 569 492 } 570 493 571 void ImplicitCopyCtorExpr::print( std::ostream &os, int indent ) const { 572 os << "Implicit Copy Constructor Expression: " << std::endl; 573 assert( callExpr ); 574 os << std::string( indent+2, ' ' ); 575 callExpr->print( os, indent + 2 ); 576 os << std::endl << std::string( indent, ' ' ) << "with temporaries:" << std::endl; 577 printAll(tempDecls, os, indent+2); 578 os << std::endl << std::string( indent, ' ' ) << "with return temporaries:" << std::endl; 579 printAll(returnDecls, os, indent+2); 494 void ImplicitCopyCtorExpr::print( std::ostream &os, Indenter indent ) const { 495 os << "Implicit Copy Constructor Expression: " << std::endl << indent+1; 496 callExpr->print( os, indent+1 ); 497 os << std::endl << indent << "... with temporaries:" << std::endl; 498 printAll( tempDecls, os, indent+1 ); 499 os << std::endl << indent << "... with return temporaries:" << std::endl; 500 printAll( returnDecls, os, indent+1 ); 580 501 Expression::print( os, indent ); 581 502 } … … 587 508 Expression * arg = InitTweak::getCallArg( callExpr, 0 ); 588 509 assert( arg ); 589 set_result( maybeClone( arg-> get_result()) );510 set_result( maybeClone( arg->result ) ); 590 511 } 591 512 … … 597 518 } 598 519 599 void ConstructorExpr::print( std::ostream &os, int indent ) const { 600 os << "Constructor Expression: " << std::endl; 601 assert( callExpr ); 602 os << std::string( indent+2, ' ' ); 520 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const { 521 os << "Constructor Expression: " << std::endl << indent+1; 603 522 callExpr->print( os, indent + 2 ); 604 523 Expression::print( os, indent ); … … 618 537 } 619 538 620 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const { 621 os << "Compound Literal Expression: " << std::endl; 622 os << std::string( indent+2, ' ' ); 623 get_result()->print( os, indent + 2 ); 624 os << std::string( indent+2, ' ' ); 625 initializer->print( os, indent + 2 ); 539 void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const { 540 os << "Compound Literal Expression: " << std::endl << indent+1; 541 result->print( os, indent+1 ); 542 os << indent+1; 543 initializer->print( os, indent+1 ); 626 544 Expression::print( os, indent ); 627 545 } … … 629 547 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {} 630 548 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {} 631 void RangeExpr::print( std::ostream &os, intindent ) const {549 void RangeExpr::print( std::ostream &os, Indenter indent ) const { 632 550 os << "Range Expression: "; 633 551 low->print( os, indent ); … … 659 577 deleteAll( returnDecls ); 660 578 } 661 void StmtExpr::print( std::ostream &os, intindent ) const {662 os << "Statement Expression: " << std::endl << std::string( indent, ' ' );663 statements->print( os, indent+ 2);579 void StmtExpr::print( std::ostream &os, Indenter indent ) const { 580 os << "Statement Expression: " << std::endl << indent+1; 581 statements->print( os, indent+1 ); 664 582 if ( ! returnDecls.empty() ) { 665 os << std::string( indent+2, ' ' ) << "with returnDecls: ";666 printAll( returnDecls, os, indent+ 2);583 os << indent+1 << "... with returnDecls: "; 584 printAll( returnDecls, os, indent+1 ); 667 585 } 668 586 if ( ! dtors.empty() ) { 669 os << std::string( indent+2, ' ' ) << "with dtors: ";670 printAll( dtors, os, indent+ 2);587 os << indent+1 << "... with dtors: "; 588 printAll( dtors, os, indent+1 ); 671 589 } 672 590 Expression::print( os, indent ); … … 690 608 delete var; 691 609 } 692 void UniqueExpr::print( std::ostream &os, intindent ) const {693 os << "Unique Expression with id:" << id << std::endl << std::string( indent+2, ' ' );694 get_expr()->print( os, indent+2);695 if ( get_object()) {696 os << std::string( indent+2, ' ' ) << "with decl: ";697 get_object()->printShort( os, indent+ 2);610 void UniqueExpr::print( std::ostream &os, Indenter indent ) const { 611 os << "Unique Expression with id:" << id << std::endl << indent+1; 612 expr->print( os, indent+1 ); 613 if ( object ) { 614 os << indent << "... with decl: "; 615 get_object()->printShort( os, indent+1 ); 698 616 } 699 617 Expression::print( os, indent ); … … 713 631 } 714 632 715 void UntypedInitExpr::print( std::ostream & os, intindent ) const {716 os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' );717 expr->print( os, indent+ 2);633 void UntypedInitExpr::print( std::ostream & os, Indenter indent ) const { 634 os << "Untyped Init Expression" << std::endl << indent+1; 635 expr->print( os, indent+1 ); 718 636 if ( ! initAlts.empty() ) { 719 637 for ( const InitAlternative & alt : initAlts ) { 720 os << std::string( indent+2, ' ' )<< "InitAlternative: ";721 alt.type->print( os, indent+ 2);722 alt.designation->print( os, indent+ 2);638 os << indent+1 << "InitAlternative: "; 639 alt.type->print( os, indent+1 ); 640 alt.designation->print( os, indent+1 ); 723 641 } 724 642 } … … 734 652 } 735 653 736 void InitExpr::print( std::ostream & os, intindent ) const {737 os << "Init Expression" << std::endl << std::string( indent+2, ' ' );738 expr->print( os, indent+ 2);739 os << std::string( indent+2, ' ' ) << "with designation: ";740 designation->print( os, indent+ 2);654 void InitExpr::print( std::ostream & os, Indenter indent ) const { 655 os << "Init Expression" << std::endl << indent+1; 656 expr->print( os, indent+1 ); 657 os << indent+1 << "... with designation: "; 658 designation->print( os, indent+1 ); 741 659 } 742 660 -
src/SynTree/Expression.h
rb96ec83 r6840e7c 36 36 Type * result; 37 37 TypeSubstitution * env; 38 Expression * argName; // if expression is used as an argument, it can be "designated" by this name39 38 bool extension = false; 40 39 41 Expression( Expression * _aname = nullptr);40 Expression(); 42 41 Expression( const Expression & other ); 43 42 virtual ~Expression(); … … 46 45 const Type * get_result() const { return result; } 47 46 void set_result( Type * newValue ) { result = newValue; } 48 bool has_result() const { return result != nullptr; }49 47 50 48 TypeSubstitution * get_env() const { return env; } 51 49 void set_env( TypeSubstitution * newValue ) { env = newValue; } 52 Expression * get_argName() const { return argName; }53 void set_argName( Expression * name ) { argName = name; }54 50 bool get_extension() const { return extension; } 55 51 Expression * set_extension( bool exten ) { extension = exten; return this; } 56 52 57 virtual Expression * clone() const = 0;58 virtual void accept( Visitor & v ) = 0;59 virtual Expression * acceptMutator( Mutator & m ) = 0;60 virtual void print( std::ostream & os, int indent = 0 ) const;53 virtual Expression * clone() const override = 0; 54 virtual void accept( Visitor & v ) override = 0; 55 virtual Expression * acceptMutator( Mutator & m ) override = 0; 56 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 61 57 }; 62 58 … … 101 97 virtual void accept( Visitor & v ) { v.visit( this ); } 102 98 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 103 virtual void print( std::ostream & os, int indent = 0) const;99 virtual void print( std::ostream & os, Indenter indent = {} ) const; 104 100 }; 105 101 … … 112 108 std::list<Expression*> args; 113 109 114 UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() , Expression *_aname = nullptr);110 UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() ); 115 111 UntypedExpr( const UntypedExpr & other ); 116 112 virtual ~UntypedExpr(); … … 119 115 void set_function( Expression * newValue ) { function = newValue; } 120 116 121 void set_args( std::list<Expression *> & listArgs ) { args = listArgs; }122 117 std::list<Expression*>::iterator begin_args() { return args.begin(); } 123 118 std::list<Expression*>::iterator end_args() { return args.end(); } … … 130 125 virtual void accept( Visitor & v ) { v.visit( this ); } 131 126 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 132 virtual void print( std::ostream & os, int indent = 0 ) const; 133 virtual void printArgs(std::ostream & os, int indent = 0) const; 127 virtual void print( std::ostream & os, Indenter indent = {} ) const; 134 128 }; 135 129 … … 139 133 std::string name; 140 134 141 NameExpr( std::string name , Expression *_aname = nullptr);135 NameExpr( std::string name ); 142 136 NameExpr( const NameExpr & other ); 143 137 virtual ~NameExpr(); … … 149 143 virtual void accept( Visitor & v ) { v.visit( this ); } 150 144 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 151 virtual void print( std::ostream & os, int indent = 0) const;145 virtual void print( std::ostream & os, Indenter indent = {} ) const; 152 146 }; 153 147 … … 160 154 Expression * arg; 161 155 162 AddressExpr( Expression * arg , Expression *_aname = nullptr);156 AddressExpr( Expression * arg ); 163 157 AddressExpr( const AddressExpr & other ); 164 158 virtual ~AddressExpr(); … … 170 164 virtual void accept( Visitor & v ) { v.visit( this ); } 171 165 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 172 virtual void print( std::ostream & os, int indent = 0) const;166 virtual void print( std::ostream & os, Indenter indent = {} ) const; 173 167 }; 174 168 … … 186 180 virtual void accept( Visitor & v ) { v.visit( this ); } 187 181 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 188 virtual void print( std::ostream & os, int indent = 0) const;182 virtual void print( std::ostream & os, Indenter indent = {} ) const; 189 183 }; 190 184 … … 194 188 Expression * arg; 195 189 196 CastExpr( Expression * arg , Expression *_aname = nullptr);197 CastExpr( Expression * arg, Type * toType , Expression *_aname = nullptr);190 CastExpr( Expression * arg ); 191 CastExpr( Expression * arg, Type * toType ); 198 192 CastExpr( const CastExpr & other ); 199 193 virtual ~CastExpr(); … … 205 199 virtual void accept( Visitor & v ) { v.visit( this ); } 206 200 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 207 virtual void print( std::ostream & os, int indent = 0) const;201 virtual void print( std::ostream & os, Indenter indent = {} ) const; 208 202 }; 209 203 … … 223 217 virtual void accept( Visitor & v ) { v.visit( this ); } 224 218 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 225 virtual void print( std::ostream & os, int indent = 0) const;219 virtual void print( std::ostream & os, Indenter indent = {} ) const; 226 220 }; 227 221 … … 232 226 Expression * aggregate; 233 227 234 UntypedMemberExpr( Expression * member, Expression * aggregate , Expression *_aname = nullptr);228 UntypedMemberExpr( Expression * member, Expression * aggregate ); 235 229 UntypedMemberExpr( const UntypedMemberExpr & other ); 236 230 virtual ~UntypedMemberExpr(); … … 244 238 virtual void accept( Visitor & v ) { v.visit( this ); } 245 239 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 246 virtual void print( std::ostream & os, int indent = 0) const;240 virtual void print( std::ostream & os, Indenter indent = {} ) const; 247 241 }; 248 242 … … 254 248 Expression * aggregate; 255 249 256 MemberExpr( DeclarationWithType * member, Expression * aggregate , Expression *_aname = nullptr);250 MemberExpr( DeclarationWithType * member, Expression * aggregate ); 257 251 MemberExpr( const MemberExpr & other ); 258 252 virtual ~MemberExpr(); … … 266 260 virtual void accept( Visitor & v ) { v.visit( this ); } 267 261 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 268 virtual void print( std::ostream & os, int indent = 0) const;262 virtual void print( std::ostream & os, Indenter indent = {} ) const; 269 263 }; 270 264 … … 275 269 DeclarationWithType * var; 276 270 277 VariableExpr( DeclarationWithType * var , Expression *_aname = nullptr);271 VariableExpr( DeclarationWithType * var ); 278 272 VariableExpr( const VariableExpr & other ); 279 273 virtual ~VariableExpr(); … … 287 281 virtual void accept( Visitor & v ) { v.visit( this ); } 288 282 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 289 virtual void print( std::ostream & os, int indent = 0) const;283 virtual void print( std::ostream & os, Indenter indent = {} ) const; 290 284 }; 291 285 … … 295 289 Constant constant; 296 290 297 ConstantExpr( Constant constant , Expression *_aname = nullptr);291 ConstantExpr( Constant constant ); 298 292 ConstantExpr( const ConstantExpr & other ); 299 293 virtual ~ConstantExpr(); … … 305 299 virtual void accept( Visitor & v ) { v.visit( this ); } 306 300 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 307 virtual void print( std::ostream & os, int indent = 0) const;301 virtual void print( std::ostream & os, Indenter indent = {} ) const; 308 302 }; 309 303 … … 315 309 bool isType; 316 310 317 SizeofExpr( Expression * expr , Expression *_aname = nullptr);311 SizeofExpr( Expression * expr ); 318 312 SizeofExpr( const SizeofExpr & other ); 319 SizeofExpr( Type * type , Expression *_aname = nullptr);313 SizeofExpr( Type * type ); 320 314 virtual ~SizeofExpr(); 321 315 … … 330 324 virtual void accept( Visitor & v ) { v.visit( this ); } 331 325 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 332 virtual void print( std::ostream & os, int indent = 0) const;326 virtual void print( std::ostream & os, Indenter indent = {} ) const; 333 327 }; 334 328 … … 340 334 bool isType; 341 335 342 AlignofExpr( Expression * expr , Expression *_aname = nullptr);336 AlignofExpr( Expression * expr ); 343 337 AlignofExpr( const AlignofExpr & other ); 344 AlignofExpr( Type * type , Expression *_aname = nullptr);338 AlignofExpr( Type * type ); 345 339 virtual ~AlignofExpr(); 346 340 … … 355 349 virtual void accept( Visitor & v ) { v.visit( this ); } 356 350 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 357 virtual void print( std::ostream & os, int indent = 0) const;351 virtual void print( std::ostream & os, Indenter indent = {} ) const; 358 352 }; 359 353 … … 364 358 std::string member; 365 359 366 UntypedOffsetofExpr( Type * type, const std::string & member , Expression *_aname = nullptr);360 UntypedOffsetofExpr( Type * type, const std::string & member ); 367 361 UntypedOffsetofExpr( const UntypedOffsetofExpr & other ); 368 362 virtual ~UntypedOffsetofExpr(); … … 376 370 virtual void accept( Visitor & v ) { v.visit( this ); } 377 371 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 378 virtual void print( std::ostream & os, int indent = 0) const;372 virtual void print( std::ostream & os, Indenter indent = {} ) const; 379 373 }; 380 374 … … 385 379 DeclarationWithType * member; 386 380 387 OffsetofExpr( Type * type, DeclarationWithType * member , Expression *_aname = nullptr);381 OffsetofExpr( Type * type, DeclarationWithType * member ); 388 382 OffsetofExpr( const OffsetofExpr & other ); 389 383 virtual ~OffsetofExpr(); … … 397 391 virtual void accept( Visitor & v ) { v.visit( this ); } 398 392 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 399 virtual void print( std::ostream & os, int indent = 0) const;393 virtual void print( std::ostream & os, Indenter indent = {} ) const; 400 394 }; 401 395 … … 405 399 StructInstType * type; 406 400 407 OffsetPackExpr( StructInstType * type _, Expression * aname_ = 0);401 OffsetPackExpr( StructInstType * type ); 408 402 OffsetPackExpr( const OffsetPackExpr & other ); 409 403 virtual ~OffsetPackExpr(); … … 415 409 virtual void accept( Visitor & v ) { v.visit( this ); } 416 410 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 417 virtual void print( std::ostream & os, int indent = 0) const;411 virtual void print( std::ostream & os, Indenter indent = {} ) const; 418 412 }; 419 413 … … 426 420 bool isType; 427 421 428 AttrExpr(Expression * attr, Expression * expr , Expression *_aname = nullptr);422 AttrExpr(Expression * attr, Expression * expr ); 429 423 AttrExpr( const AttrExpr & other ); 430 AttrExpr( Expression * attr, Type * type , Expression *_aname = nullptr);424 AttrExpr( Expression * attr, Type * type ); 431 425 virtual ~AttrExpr(); 432 426 … … 443 437 virtual void accept( Visitor & v ) { v.visit( this ); } 444 438 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 445 virtual void print( std::ostream & os, int indent = 0) const;439 virtual void print( std::ostream & os, Indenter indent = {} ) const; 446 440 }; 447 441 … … 452 446 Expression * arg2; 453 447 454 LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true , Expression *_aname = nullptr);448 LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true ); 455 449 LogicalExpr( const LogicalExpr & other ); 456 450 virtual ~LogicalExpr(); … … 465 459 virtual void accept( Visitor & v ) { v.visit( this ); } 466 460 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 467 virtual void print( std::ostream & os, int indent = 0) const;461 virtual void print( std::ostream & os, Indenter indent = {} ) const; 468 462 469 463 private: … … 478 472 Expression * arg3; 479 473 480 ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 , Expression *_aname = nullptr);474 ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 ); 481 475 ConditionalExpr( const ConditionalExpr & other ); 482 476 virtual ~ConditionalExpr(); … … 492 486 virtual void accept( Visitor & v ) { v.visit( this ); } 493 487 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 494 virtual void print( std::ostream & os, int indent = 0) const;488 virtual void print( std::ostream & os, Indenter indent = {} ) const; 495 489 }; 496 490 … … 501 495 Expression * arg2; 502 496 503 CommaExpr( Expression * arg1, Expression * arg2 , Expression *_aname = nullptr);497 CommaExpr( Expression * arg1, Expression * arg2 ); 504 498 CommaExpr( const CommaExpr & other ); 505 499 virtual ~CommaExpr(); … … 513 507 virtual void accept( Visitor & v ) { v.visit( this ); } 514 508 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 515 virtual void print( std::ostream & os, int indent = 0) const;509 virtual void print( std::ostream & os, Indenter indent = {} ) const; 516 510 }; 517 511 … … 531 525 virtual void accept( Visitor & v ) { v.visit( this ); } 532 526 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 533 virtual void print( std::ostream & os, int indent = 0) const;527 virtual void print( std::ostream & os, Indenter indent = {} ) const; 534 528 }; 535 529 … … 557 551 virtual void accept( Visitor & v ) { v.visit( this ); } 558 552 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 559 virtual void print( std::ostream & os, int indent = 0) const;553 virtual void print( std::ostream & os, Indenter indent = {} ) const; 560 554 561 555 // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints … … 585 579 virtual void accept( Visitor & v ) { v.visit( this ); } 586 580 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 587 virtual void print( std::ostream & os, int indent = 0) const;581 virtual void print( std::ostream & os, Indenter indent = {} ) const; 588 582 }; 589 583 … … 603 597 virtual void accept( Visitor & v ) { v.visit( this ); } 604 598 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 605 virtual void print( std::ostream & os, int indent = 0) const;599 virtual void print( std::ostream & os, Indenter indent = {} ) const; 606 600 }; 607 601 … … 621 615 virtual void accept( Visitor & v ) { v.visit( this ); } 622 616 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 623 virtual void print( std::ostream & os, int indent = 0) const;617 virtual void print( std::ostream & os, Indenter indent = {} ) const; 624 618 }; 625 619 … … 640 634 virtual void accept( Visitor & v ) { v.visit( this ); } 641 635 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 642 virtual void print( std::ostream & os, int indent = 0) const;636 virtual void print( std::ostream & os, Indenter indent = {} ) const; 643 637 }; 644 638 … … 648 642 std::list<Expression*> exprs; 649 643 650 UntypedTupleExpr( const std::list< Expression * > & exprs , Expression *_aname = nullptr);644 UntypedTupleExpr( const std::list< Expression * > & exprs ); 651 645 UntypedTupleExpr( const UntypedTupleExpr & other ); 652 646 virtual ~UntypedTupleExpr(); … … 657 651 virtual void accept( Visitor & v ) { v.visit( this ); } 658 652 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 659 virtual void print( std::ostream & os, int indent = 0) const;653 virtual void print( std::ostream & os, Indenter indent = {} ) const; 660 654 }; 661 655 … … 665 659 std::list<Expression*> exprs; 666 660 667 TupleExpr( const std::list< Expression * > & exprs , Expression *_aname = nullptr);661 TupleExpr( const std::list< Expression * > & exprs ); 668 662 TupleExpr( const TupleExpr & other ); 669 663 virtual ~TupleExpr(); … … 674 668 virtual void accept( Visitor & v ) { v.visit( this ); } 675 669 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 676 virtual void print( std::ostream & os, int indent = 0) const;670 virtual void print( std::ostream & os, Indenter indent = {} ) const; 677 671 }; 678 672 … … 695 689 virtual void accept( Visitor & v ) { v.visit( this ); } 696 690 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 697 virtual void print( std::ostream & os, int indent = 0) const;691 virtual void print( std::ostream & os, Indenter indent = {} ) const; 698 692 }; 699 693 … … 703 697 StmtExpr * stmtExpr = nullptr; 704 698 705 TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls , Expression * _aname = nullptr);699 TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls ); 706 700 TupleAssignExpr( const TupleAssignExpr & other ); 707 701 virtual ~TupleAssignExpr(); … … 713 707 virtual void accept( Visitor & v ) { v.visit( this ); } 714 708 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 715 virtual void print( std::ostream & os, int indent = 0) const;709 virtual void print( std::ostream & os, Indenter indent = {} ) const; 716 710 }; 717 711 … … 736 730 virtual void accept( Visitor & v ) { v.visit( this ); } 737 731 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 738 virtual void print( std::ostream & os, int indent = 0) const;732 virtual void print( std::ostream & os, Indenter indent = {} ) const; 739 733 }; 740 734 … … 763 757 virtual void accept( Visitor & v ) { v.visit( this ); } 764 758 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 765 virtual void print( std::ostream & os, int indent = 0) const;759 virtual void print( std::ostream & os, Indenter indent = {} ) const; 766 760 767 761 private: … … 797 791 virtual void accept( Visitor & v ) { v.visit( this ); } 798 792 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 799 virtual void print( std::ostream & os, int indent = 0) const;793 virtual void print( std::ostream & os, Indenter indent = {} ) const; 800 794 }; 801 795 … … 818 812 virtual void accept( Visitor & v ) { v.visit( this ); } 819 813 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 820 virtual void print( std::ostream & os, int indent = 0) const;814 virtual void print( std::ostream & os, Indenter indent = {} ) const; 821 815 }; 822 816 -
src/SynTree/FunctionDecl.cc
rb96ec83 r6840e7c 63 63 } 64 64 65 void FunctionDecl::print( std::ostream &os, intindent ) const {65 void FunctionDecl::print( std::ostream &os, Indenter indent ) const { 66 66 using std::endl; 67 67 using std::string; 68 68 69 if ( get_name()!= "" ) {70 os << get_name()<< ": ";69 if ( name != "" ) { 70 os << name << ": "; 71 71 } // if 72 if ( get_linkage()!= LinkageSpec::Cforall ) {73 os << LinkageSpec::linkageName( get_linkage()) << " ";72 if ( linkage != LinkageSpec::Cforall ) { 73 os << LinkageSpec::linkageName( linkage ) << " "; 74 74 } // if 75 75 76 printAll( get_attributes(), os, indent );76 printAll( attributes, os, indent ); 77 77 78 78 get_storageClasses().print( os ); 79 79 get_funcSpec().print( os ); 80 80 81 if ( get_type()) {82 get_type()->print( os, indent );81 if ( type ) { 82 type->print( os, indent ); 83 83 } else { 84 84 os << "untyped entity "; … … 86 86 87 87 if ( statements ) { 88 os << string( indent + 2, ' ' ) << "with body " << endl; 89 os << string( indent + 4, ' ' ); 90 statements->print( os, indent + 4 ); 88 os << indent << "... with body " << endl << indent+1; 89 statements->print( os, indent+1 ); 91 90 } // if 92 91 } 93 92 94 void FunctionDecl::printShort( std::ostream &os, intindent ) const {93 void FunctionDecl::printShort( std::ostream &os, Indenter indent ) const { 95 94 using std::endl; 96 95 using std::string; 97 96 98 if ( get_name()!= "" ) {99 os << get_name()<< ": ";97 if ( name != "" ) { 98 os << name << ": "; 100 99 } // if 101 102 // xxx - should printShort print attributes?103 100 104 101 get_storageClasses().print( os ); 105 102 get_funcSpec().print( os ); 106 103 107 if ( get_type()) {108 get_type()->print( os, indent );104 if ( type ) { 105 type->print( os, indent ); 109 106 } else { 110 107 os << "untyped entity "; -
src/SynTree/FunctionType.cc
rb96ec83 r6840e7c 51 51 } 52 52 53 void FunctionType::print( std::ostream &os, intindent ) const {53 void FunctionType::print( std::ostream &os, Indenter indent ) const { 54 54 using std::string; 55 55 using std::endl; … … 58 58 os << "function" << endl; 59 59 if ( ! parameters.empty() ) { 60 os << string( indent + 2, ' ' ) << "with parameters" << endl;61 printAll( parameters, os, indent + 4);60 os << indent << "... with parameters" << endl; 61 printAll( parameters, os, indent+1 ); 62 62 if ( isVarArgs ) { 63 os << string( indent + 4, ' ' )<< "and a variable number of other arguments" << endl;63 os << indent+1 << "and a variable number of other arguments" << endl; 64 64 } // if 65 65 } else if ( isVarArgs ) { 66 os << string( indent + 4, ' ' )<< "accepting unspecified arguments" << endl;66 os << indent+1 << "accepting unspecified arguments" << endl; 67 67 } // if 68 os << string( indent + 2, ' ' ) << "returning ";68 os << indent << "... returning "; 69 69 if ( returnVals.empty() ) { 70 os << endl << string( indent + 4, ' ' ) <<"nothing " << endl;70 os << "nothing " << endl; 71 71 } else { 72 72 os << endl; 73 printAll( returnVals, os, indent + 4);73 printAll( returnVals, os, indent+1 ); 74 74 } // if 75 75 } -
src/SynTree/Initializer.cc
rb96ec83 r6840e7c 38 38 } 39 39 40 void Designation::print( std::ostream &os, intindent ) const {40 void Designation::print( std::ostream &os, Indenter indent ) const { 41 41 if ( ! designators.empty() ) { 42 os << std::string(indent + 2, ' ' ) << "designated by: " << std::endl; 43 for ( std::list < Expression * >::const_iterator i = designators.begin(); i != designators.end(); i++ ) { 44 os << std::string(indent + 4, ' ' ); 45 ( *i )->print(os, indent + 4 ); 42 os << "... designated by: " << std::endl; 43 for ( const Expression * d : designators ) { 44 os << indent+1; 45 d->print(os, indent+1 ); 46 os << std::endl; 46 47 } 47 os << std::endl;48 48 } // if 49 49 } … … 64 64 } 65 65 66 void SingleInit::print( std::ostream &os, int indent ) const { 67 os << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl; 68 os << std::string(indent+4, ' ' ); 69 value->print( os, indent+4 ); 66 void SingleInit::print( std::ostream &os, Indenter indent ) const { 67 os << "Simple Initializer: "; 68 value->print( os, indent ); 70 69 } 71 70 … … 93 92 } 94 93 95 void ListInit::print( std::ostream &os, int indent ) const { 96 os << std::string(indent, ' ') << "Compound initializer: " << std::endl; 97 for ( Designation * d : designations ) { 98 d->print( os, indent + 2 ); 99 } 100 101 for ( const Initializer * init : initializers ) { 102 init->print( os, indent + 2 ); 94 void ListInit::print( std::ostream &os, Indenter indent ) const { 95 os << "Compound initializer: " << std::endl; 96 for ( auto p : group_iterate( designations, initializers ) ) { 97 const Designation * d = std::get<0>(p); 98 const Initializer * init = std::get<1>(p); 99 os << indent+1; 100 init->print( os, indent+1 ); 103 101 os << std::endl; 102 if ( ! d->designators.empty() ) { 103 os << indent+1; 104 d->print( os, indent+1 ); 105 } 104 106 } 105 107 } … … 116 118 } 117 119 118 void ConstructorInit::print( std::ostream &os, intindent ) const {119 os << std::endl << std::string(indent, ' ') <<"Constructor initializer: " << std::endl;120 void ConstructorInit::print( std::ostream &os, Indenter indent ) const { 121 os << "Constructor initializer: " << std::endl; 120 122 if ( ctor ) { 121 os << std::string(indent+2, ' '); 122 os << "initially constructed with "; 123 ctor->print( os, indent+4 ); 123 os << indent << "... initially constructed with "; 124 ctor->print( os, indent+1 ); 124 125 } // if 125 126 126 127 if ( dtor ) { 127 os << std::string(indent+2, ' '); 128 os << "destructed with "; 129 dtor->print( os, indent+4 ); 128 os << indent << "... destructed with "; 129 dtor->print( os, indent+1 ); 130 130 } 131 131 132 132 if ( init ) { 133 os << std::string(indent+2, ' '); 134 os << "with fallback C-style initializer: "; 135 init->print( os, indent+4 ); 133 os << indent << "... with fallback C-style initializer: "; 134 init->print( os, indent+1 ); 136 135 } 137 136 } -
src/SynTree/Initializer.h
rb96ec83 r6840e7c 37 37 std::list< Expression * > & get_designators() { return designators; } 38 38 39 virtual Designation * clone() const { return new Designation( *this ); };39 virtual Designation * clone() const override { return new Designation( *this ); }; 40 40 virtual void accept( Visitor &v ) override { v.visit( this ); } 41 virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }42 virtual void print( std::ostream &os, int indent = 0) const override;41 virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 42 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 43 43 }; 44 44 … … 54 54 bool get_maybeConstructed() { return maybeConstructed; } 55 55 56 virtual Initializer *clone() const = 0;56 virtual Initializer *clone() const override = 0; 57 57 virtual void accept( Visitor &v ) override = 0; 58 virtual Initializer *acceptMutator( Mutator &m ) = 0;59 virtual void print( std::ostream &os, int indent = 0) const override = 0;58 virtual Initializer *acceptMutator( Mutator &m ) override = 0; 59 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; 60 60 private: 61 61 bool maybeConstructed; … … 78 78 virtual void accept( Visitor &v ) override { v.visit( this ); } 79 79 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 80 virtual void print( std::ostream &os, int indent = 0) const override;80 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 81 81 }; 82 82 … … 106 106 virtual void accept( Visitor &v ) override { v.visit( this ); } 107 107 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 108 virtual void print( std::ostream &os, int indent = 0) const override;108 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 109 109 }; 110 110 … … 135 135 virtual void accept( Visitor &v ) override { v.visit( this ); } 136 136 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 137 virtual void print( std::ostream &os, int indent = 0) const override;137 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 138 138 139 139 private: -
src/SynTree/Mutator.cc
rb96ec83 r6840e7c 626 626 } 627 627 628 TypeSubstitution * Mutator::mutate( TypeSubstitution * sub ) { 629 for ( auto & p : sub->typeEnv ) { 630 p.second = maybeMutate( p.second, *this ); 631 } 632 for ( auto & p : sub->varEnv ) { 633 p.second = maybeMutate( p.second, *this ); 634 } 635 return sub; 636 } 637 628 638 // Local Variables: // 629 639 // tab-width: 4 // -
src/SynTree/Mutator.h
rb96ec83 r6840e7c 117 117 118 118 virtual Attribute * mutate( Attribute * attribute ); 119 120 virtual TypeSubstitution * mutate( TypeSubstitution * sub ); 121 119 122 private: 120 123 virtual Declaration * handleAggregateDecl(AggregateDecl * aggregateDecl ); -
src/SynTree/NamedTypeDecl.cc
rb96ec83 r6840e7c 38 38 } 39 39 40 void NamedTypeDecl::print( std::ostream &os, intindent ) const {40 void NamedTypeDecl::print( std::ostream &os, Indenter indent ) const { 41 41 using namespace std; 42 42 43 if ( get_name() != "" ) { 44 os << get_name() << ": "; 45 } // if 46 if ( get_linkage() != LinkageSpec::Cforall ) { 47 os << LinkageSpec::linkageName( get_linkage() ) << " "; 43 if ( name != "" ) os << name << ": "; 44 45 if ( linkage != LinkageSpec::Cforall ) { 46 os << LinkageSpec::linkageName( linkage ) << " "; 48 47 } // if 49 48 get_storageClasses().print( os ); … … 51 50 if ( base ) { 52 51 os << " for "; 53 base->print( os, indent );52 base->print( os, indent+1 ); 54 53 } // if 55 54 if ( ! parameters.empty() ) { 56 os << endl << string( indent, ' ' ) << "with parameters" << endl;57 printAll( parameters, os, indent+ 2);55 os << endl << indent << "... with parameters" << endl; 56 printAll( parameters, os, indent+1 ); 58 57 } // if 59 58 if ( ! assertions.empty() ) { 60 os << endl << string( indent, ' ' ) << "with assertions" << endl;61 printAll( assertions, os, indent+ 2);59 os << endl << indent << "... with assertions" << endl; 60 printAll( assertions, os, indent+1 ); 62 61 } // if 63 62 } 64 63 65 void NamedTypeDecl::printShort( std::ostream &os, intindent ) const {64 void NamedTypeDecl::printShort( std::ostream &os, Indenter indent ) const { 66 65 using namespace std; 67 66 68 if ( get_name() != "" ) { 69 os << get_name() << ": "; 70 } // if 67 if ( name != "" ) os << name << ": "; 71 68 get_storageClasses().print( os ); 72 69 os << typeString(); 73 70 if ( base ) { 74 71 os << " for "; 75 base->print( os, indent );72 base->print( os, indent+1 ); 76 73 } // if 77 74 if ( ! parameters.empty() ) { 78 os << endl << string( indent, ' ' ) << "with parameters" << endl;79 printAll( parameters, os, indent+ 2);75 os << endl << indent << "... with parameters" << endl; 76 printAll( parameters, os, indent+1 ); 80 77 } // if 81 78 } -
src/SynTree/ObjectDecl.cc
rb96ec83 r6840e7c 44 44 } 45 45 46 void ObjectDecl::print( std::ostream &os, int indent ) const { 47 if ( get_name() != "" ) { 48 os << get_name() << ": "; 46 void ObjectDecl::print( std::ostream &os, Indenter indent ) const { 47 if ( name != "" ) os << name << ": "; 48 49 if ( linkage != LinkageSpec::Cforall ) { 50 os << LinkageSpec::linkageName( linkage ) << " "; 49 51 } // if 50 51 if ( get_linkage() != LinkageSpec::Cforall ) {52 os << LinkageSpec::linkageName( get_linkage() ) << " ";53 } // if54 55 printAll( get_attributes(), os, indent );56 52 57 53 get_storageClasses().print( os ); 58 54 59 if ( get_type()) {60 get_type()->print( os, indent );55 if ( type ) { 56 type->print( os, indent ); 61 57 } else { 62 58 os << " untyped entity "; … … 64 60 65 61 if ( init ) { 66 os << " with initializer " << std::endl; 67 init->print( os, indent+2 ); 68 os << std::endl << std::string(indent+2, ' '); 69 os << "maybeConstructed? " << init->get_maybeConstructed(); 62 os << " with initializer (" << (init->get_maybeConstructed() ? "maybe constructed" : "not constructed") << ")" << std::endl << indent+1; 63 init->print( os, indent+1 ); 64 os << std::endl; 70 65 } // if 71 66 67 if ( ! attributes.empty() ) { 68 os << std::endl << indent << "... with attributes: " << std::endl; 69 printAll( attributes, os, indent+1 ); 70 } 71 72 72 if ( bitfieldWidth ) { 73 os << std::string(indent, ' '); 74 os << " with bitfield width "; 73 os << indent << " with bitfield width "; 75 74 bitfieldWidth->print( os ); 76 75 } // if 77 76 } 78 77 79 void ObjectDecl::printShort( std::ostream &os, intindent ) const {78 void ObjectDecl::printShort( std::ostream &os, Indenter indent ) const { 80 79 #if 0 81 80 if ( get_mangleName() != "") { … … 83 82 } else 84 83 #endif 85 if ( get_name() != "" ) { 86 os << get_name() << ": "; 87 } // if 88 89 // xxx - should printShort print attributes? 84 if ( name != "" ) os << name << ": "; 90 85 91 86 get_storageClasses().print( os ); 92 87 93 if ( get_type()) {94 get_type()->print( os, indent );88 if ( type ) { 89 type->print( os, indent ); 95 90 } else { 96 91 os << "untyped entity "; -
src/SynTree/PointerType.cc
rb96ec83 r6840e7c 41 41 } 42 42 43 void PointerType::print( std::ostream &os, intindent ) const {43 void PointerType::print( std::ostream &os, Indenter indent ) const { 44 44 Type::print( os, indent ); 45 45 if ( ! is_array() ) { -
src/SynTree/ReferenceToType.cc
rb96ec83 r6840e7c 14 14 // 15 15 16 #include <stddef.h> // for NULL17 16 #include <cassert> // for assert 18 17 #include <list> // for list, _List_const_iterator, list<>::cons... … … 38 37 } 39 38 40 void ReferenceToType::print( std::ostream &os, intindent ) const {39 void ReferenceToType::print( std::ostream &os, Indenter indent ) const { 41 40 using std::endl; 42 41 … … 44 43 os << "instance of " << typeString() << " " << name << " "; 45 44 if ( ! parameters.empty() ) { 46 os << endl << std::string( indent, ' ' ) << "with parameters" << endl;47 printAll( parameters, os, indent+ 2);45 os << endl << indent << "... with parameters" << endl; 46 printAll( parameters, os, indent+1 ); 48 47 } // if 49 48 } … … 65 64 66 65 std::list<TypeDecl*>* StructInstType::get_baseParameters() { 67 if ( ! baseStruct ) return NULL;66 if ( ! baseStruct ) return nullptr; 68 67 return &baseStruct->get_parameters(); 69 68 } … … 76 75 } 77 76 78 void StructInstType::print( std::ostream &os, intindent ) const {77 void StructInstType::print( std::ostream &os, Indenter indent ) const { 79 78 using std::endl; 80 79 81 if ( baseStruct == NULL) ReferenceToType::print( os, indent );80 if ( baseStruct == nullptr ) ReferenceToType::print( os, indent ); 82 81 else { 83 82 Type::print( os, indent ); 84 83 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body() << " "; 85 84 if ( ! parameters.empty() ) { 86 os << endl << std::string( indent, ' ' ) << "with parameters" << endl;87 printAll( parameters, os, indent+ 2);85 os << endl << indent << "... with parameters" << endl; 86 printAll( parameters, os, indent+1 ); 88 87 } // if 89 88 } // if … … 97 96 98 97 std::list< TypeDecl * > * UnionInstType::get_baseParameters() { 99 if ( ! baseUnion ) return NULL;98 if ( ! baseUnion ) return nullptr; 100 99 return &baseUnion->get_parameters(); 101 100 } … … 108 107 } 109 108 110 void UnionInstType::print( std::ostream &os, intindent ) const {109 void UnionInstType::print( std::ostream &os, Indenter indent ) const { 111 110 using std::endl; 112 111 113 if ( baseUnion == NULL) ReferenceToType::print( os, indent );112 if ( baseUnion == nullptr ) ReferenceToType::print( os, indent ); 114 113 else { 115 114 Type::print( os, indent ); 116 115 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body() << " "; 117 116 if ( ! parameters.empty() ) { 118 os << endl << std::string( indent, ' ' ) << "with parameters" << endl;119 printAll( parameters, os, indent+ 2);117 os << endl << indent << "... with parameters" << endl; 118 printAll( parameters, os, indent+1 ); 120 119 } // if 121 120 } // if … … 129 128 130 129 bool EnumInstType::isComplete() const { return baseEnum ? baseEnum->has_body() : false; } 130 131 void EnumInstType::print( std::ostream &os, Indenter indent ) const { 132 using std::endl; 133 134 if ( baseEnum == nullptr ) ReferenceToType::print( os, indent ); 135 else { 136 Type::print( os, indent ); 137 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body() << " "; 138 } // if 139 } 140 131 141 132 142 std::string TraitInstType::typeString() const { return "trait"; } … … 166 176 bool TypeInstType::isComplete() const { return baseType->isComplete(); } 167 177 168 void TypeInstType::print( std::ostream &os, intindent ) const {178 void TypeInstType::print( std::ostream &os, Indenter indent ) const { 169 179 using std::endl; 170 180 … … 172 182 os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type) "; 173 183 if ( ! parameters.empty() ) { 174 os << endl << std::string( indent, ' ' ) << "with parameters" << endl;175 printAll( parameters, os, indent+ 2);184 os << endl << indent << "... with parameters" << endl; 185 printAll( parameters, os, indent+1 ); 176 186 } // if 177 187 } -
src/SynTree/ReferenceType.cc
rb96ec83 r6840e7c 35 35 } 36 36 37 void ReferenceType::print( std::ostream &os, intindent ) const {37 void ReferenceType::print( std::ostream &os, Indenter indent ) const { 38 38 Type::print( os, indent ); 39 39 os << "reference to "; -
src/SynTree/Statement.cc
rb96ec83 r6840e7c 34 34 Statement::Statement( std::list<Label> labels ) : labels( labels ) {} 35 35 36 void Statement::print( __attribute__((unused)) std::ostream &, __attribute__((unused)) int indent ) const {} 36 void Statement::print( std::ostream & os, Indenter ) const { 37 if ( ! labels.empty() ) { 38 os << "Labels: {"; 39 for ( const Label & l : labels ) { 40 os << l << ","; 41 } 42 os << "}" << endl; 43 } 44 } 37 45 38 46 Statement::~Statement() {} … … 46 54 } 47 55 48 void ExprStmt::print( std::ostream &os, intindent ) const {49 os << "Expression Statement:" << endl << std::string( indent + 2, ' ' );50 expr->print( os, indent + 2);56 void ExprStmt::print( std::ostream &os, Indenter indent ) const { 57 os << "Expression Statement:" << endl << indent+1; 58 expr->print( os, indent+1 ); 51 59 } 52 60 … … 67 75 } 68 76 69 void AsmStmt::print( std::ostream &os, intindent ) const {77 void AsmStmt::print( std::ostream &os, Indenter indent ) const { 70 78 os << "Assembler Statement:" << endl; 71 os << std::string( indent, ' ' ) << "instruction: " << endl << std::string( indent, ' ' );72 instruction->print( os, indent + 2);79 os << indent+1 << "instruction: " << endl << indent; 80 instruction->print( os, indent+1 ); 73 81 if ( ! output.empty() ) { 74 os << endl << std::string( indent, ' ' )<< "output: " << endl;75 printAll( output, os, indent + 2);82 os << endl << indent+1 << "output: " << endl; 83 printAll( output, os, indent+1 ); 76 84 } // if 77 85 if ( ! input.empty() ) { 78 os << std::string( indent, ' ' ) << "input: " << endl << std::string( indent, ' ' );79 printAll( input, os, indent + 2);86 os << indent+1 << "input: " << endl; 87 printAll( input, os, indent+1 ); 80 88 } // if 81 89 if ( ! clobber.empty() ) { 82 os << std::string( indent, ' ' )<< "clobber: " << endl;83 printAll( clobber, os, indent + 2);90 os << indent+1 << "clobber: " << endl; 91 printAll( clobber, os, indent+1 ); 84 92 } // if 85 93 } … … 103 111 } 104 112 105 void BranchStmt::print( std::ostream &os, intindent ) const {106 os << string( indent, ' ' ) <<"Branch (" << brType[type] << ")" << endl ;107 if ( target != "" ) os << string( indent+2, ' ' )<< "with target: " << target << endl;108 if ( originalTarget != "" ) os << string( indent+2, ' ' )<< "with original target: " << originalTarget << endl;109 if ( computedTarget != nullptr ) os << string( indent+2, ' ' )<< "with computed target: " << computedTarget << endl;113 void BranchStmt::print( std::ostream &os, Indenter indent ) const { 114 os << "Branch (" << brType[type] << ")" << endl ; 115 if ( target != "" ) os << indent+1 << "with target: " << target << endl; 116 if ( originalTarget != "" ) os << indent+1 << "with original target: " << originalTarget << endl; 117 if ( computedTarget != nullptr ) os << indent+1 << "with computed target: " << computedTarget << endl; 110 118 } 111 119 … … 118 126 } 119 127 120 void ReturnStmt::print( std::ostream &os, intindent ) const {121 os << 122 if ( expr != 0) {123 os << endl << string( indent+2, ' ' );124 expr->print( os, indent + 2);128 void ReturnStmt::print( std::ostream &os, Indenter indent ) const { 129 os << "Return Statement, returning: "; 130 if ( expr != nullptr ) { 131 os << endl << indent+1; 132 expr->print( os, indent+1 ); 125 133 } 126 134 os << endl; … … 142 150 } 143 151 144 void IfStmt::print( std::ostream &os, intindent ) const {145 os << "If on condition: " << endl 146 os << string( indent+4, ' ' );147 condition->print( os, indent + 4);152 void IfStmt::print( std::ostream &os, Indenter indent ) const { 153 os << "If on condition: " << endl; 154 os << indent+1; 155 condition->print( os, indent+1 ); 148 156 149 157 if ( !initialization.empty() ) { 150 os << string( indent + 2, ' ' ) << "initialization: \n";151 for ( std::list<Statement *>::const_iterator it = initialization.begin(); it != initialization.end(); ++it) {152 os << string( indent + 4, ' ' );153 (*it)->print( os, indent + 4);158 os << indent << "... with initialization: \n"; 159 for ( const Statement * stmt : initialization ) { 160 os << indent+1; 161 stmt->print( os, indent+1 ); 154 162 } 155 163 os << endl; 156 164 } 157 165 158 os << string( indent+2, ' ' )<< "... then: " << endl;159 160 os << string( indent+4, ' ' );161 thenPart->print( os, indent + 4);166 os << indent << "... then: " << endl; 167 168 os << indent+1; 169 thenPart->print( os, indent+1 ); 162 170 163 171 if ( elsePart != 0 ) { 164 os << string( indent+2, ' ' )<< "... else: " << endl;165 os << string( indent+4, ' ' );166 elsePart->print( os, indent + 4);172 os << indent << "... else: " << endl; 173 os << indent+1; 174 elsePart->print( os, indent+1 ); 167 175 } // if 168 176 } … … 183 191 } 184 192 185 void SwitchStmt::print( std::ostream &os, intindent ) const {193 void SwitchStmt::print( std::ostream &os, Indenter indent ) const { 186 194 os << "Switch on condition: "; 187 195 condition->print( os ); 188 196 os << endl; 189 197 190 // statements 191 std::list<Statement *>::const_iterator i; 192 for ( i = statements.begin(); i != statements.end(); i++) 193 (*i)->print( os, indent + 4 ); 194 195 //for_each( statements.begin(), statements.end(), mem_fun( bind1st(&Statement::print ), os )); 198 for ( const Statement * stmt : statements ) { 199 stmt->print( os, indent+1 ); 200 } 196 201 } 197 202 198 203 CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) : 199 204 Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) { 200 if ( isDefault() && condition != 0 ) 201 throw SemanticError("default with conditions"); 205 if ( isDefault() && condition != 0 ) throw SemanticError("default case with condition: ", condition); 202 206 } 203 207 … … 216 220 } 217 221 218 void CaseStmt::print( std::ostream &os, int indent ) const { 219 os << string( indent, ' ' ); 220 221 if ( isDefault() ) 222 os << "Default "; 222 void CaseStmt::print( std::ostream &os, Indenter indent ) const { 223 if ( isDefault() ) os << "Default "; 223 224 else { 224 225 os << "Case "; 225 condition->print( os ); 226 } // if 227 228 os << endl; 229 230 std::list<Statement *>::const_iterator i; 231 for ( i = stmts.begin(); i != stmts.end(); i++) 232 (*i )->print( os, indent + 4 ); 226 condition->print( os, indent ); 227 } // if 228 os << endl; 229 230 for ( Statement * stmt : stmts ) { 231 stmt->print( os, indent+1 ); 232 } 233 233 } 234 234 … … 246 246 } 247 247 248 void WhileStmt::print( std::ostream &os, intindent ) const {248 void WhileStmt::print( std::ostream &os, Indenter indent ) const { 249 249 os << "While on condition: " << endl ; 250 condition->print( os, indent + 4);251 252 os << string( indent, ' ' ) << ".... with body: " << endl;253 254 if ( body != 0 ) body->print( os, indent + 4);250 condition->print( os, indent+1 ); 251 252 os << indent << "... with body: " << endl; 253 254 if ( body != 0 ) body->print( os, indent+1 ); 255 255 } 256 256 … … 272 272 } 273 273 274 void ForStmt::print( std::ostream &os, int indent ) const { 275 os << "Labels: {"; 276 for ( std::list<Label>::const_iterator it = get_labels().begin(); it != get_labels().end(); ++it) { 277 os << *it << ","; 278 } 279 os << "}" << endl; 280 281 os << string( indent, ' ' ) << "For Statement" << endl ; 282 283 os << string( indent + 2, ' ' ) << "initialization: \n"; 284 for ( std::list<Statement *>::const_iterator it = initialization.begin(); it != initialization.end(); ++it ) { 285 os << string( indent + 4, ' ' ); 286 (*it)->print( os, indent + 4 ); 287 } 288 289 os << "\n" << string( indent + 2, ' ' ) << "condition: \n"; 290 if ( condition != 0 ) { 291 os << string( indent + 4, ' ' ); 292 condition->print( os, indent + 4 ); 293 } 294 295 os << "\n" << string( indent + 2, ' ' ) << "increment: \n"; 296 if ( increment != 0 ) { 297 os << string( indent + 4, ' ' ); 298 increment->print( os, indent + 4 ); 299 } 300 301 os << "\n" << string( indent + 2, ' ' ) << "statement block: \n"; 274 void ForStmt::print( std::ostream &os, Indenter indent ) const { 275 Statement::print( os, indent ); // print labels 276 277 os << "For Statement" << endl; 278 279 if ( ! initialization.empty() ) { 280 os << indent << "... initialization: \n"; 281 for ( Statement * stmt : initialization ) { 282 os << indent+1; 283 stmt->print( os, indent+1 ); 284 } 285 } 286 287 if ( condition != nullptr ) { 288 os << indent << "... condition: \n" << indent+1; 289 condition->print( os, indent+1 ); 290 } 291 292 if ( increment != nullptr ) { 293 os << "\n" << indent << "... increment: \n" << indent+1; 294 increment->print( os, indent+1 ); 295 } 296 302 297 if ( body != 0 ) { 303 os << string( indent + 4, ' ' ); 304 body->print( os, indent + 4 ); 305 } 306 298 os << "\n" << indent << "... with body: \n" << indent+1; 299 body->print( os, indent+1 ); 300 } 307 301 os << endl; 308 302 } … … 322 316 } 323 317 324 void ThrowStmt::print( std::ostream &os, int indent) const { 318 void ThrowStmt::print( std::ostream &os, Indenter indent) const { 319 if ( target ) os << "Non-Local "; 320 os << "Throw Statement, raising: "; 321 expr->print(os, indent+1); 325 322 if ( target ) { 326 os << "Non-Local "; 327 } 328 os << "Throw Statement, raising: "; 329 expr->print(os, indent + 4); 330 if ( target ) { 331 os << "At: "; 332 target->print(os, indent + 4); 323 os << "... at: "; 324 target->print(os, indent+1); 333 325 } 334 326 } … … 348 340 } 349 341 350 void TryStmt::print( std::ostream &os, intindent ) const {342 void TryStmt::print( std::ostream &os, Indenter indent ) const { 351 343 os << "Try Statement" << endl; 352 os << string( indent + 2, ' ' ) << "with block:" << endl; 353 os << string( indent + 4, ' ' ); 354 block->print( os, indent + 4 ); 344 os << indent << "... with block:" << endl << indent+1; 345 block->print( os, indent+1 ); 355 346 356 347 // handlers 357 os << string( indent + 2, ' ' ) << "and handlers:" << endl;358 for ( std::list<CatchStmt *>::const_iterator i = handlers.begin(); i != handlers.end(); i++) {359 os << string( indent + 4, ' ' );360 (*i )->print( os, indent + 4);348 os << indent << "... and handlers:" << endl; 349 for ( const CatchStmt * stmt : handlers ) { 350 os << indent+1; 351 stmt->print( os, indent+1 ); 361 352 } 362 353 363 354 // finally block 364 355 if ( finallyBlock != 0 ) { 365 os << string( indent + 2, ' ' ) << "and finally:" << endl;366 finallyBlock->print( os, indent + 4);356 os << indent << "... and finally:" << endl << indent+1; 357 finallyBlock->print( os, indent+1 ); 367 358 } // if 368 359 } … … 370 361 CatchStmt::CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl, Expression *cond, Statement *body ) : 371 362 Statement( labels ), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) { 363 assertf( decl, "Catch clause must have a declaration." ); 372 364 } 373 365 … … 381 373 } 382 374 383 void CatchStmt::print( std::ostream &os, intindent ) const {375 void CatchStmt::print( std::ostream &os, Indenter indent ) const { 384 376 os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl; 385 377 386 os << string( indent + 2, ' ' ) << "... catching: "; 387 if ( decl ) { 388 decl->printShort( os, indent + 4 ); 389 os << endl; 390 } 391 else 392 os << string( indent + 4 , ' ' ) << ">>> Error: this catch clause must have a declaration <<<" << endl; 378 os << indent << "... catching: "; 379 decl->printShort( os, indent+1 ); 380 os << endl; 393 381 394 382 if ( cond ) { 395 os << string( indent + 2, ' ' ) << "with conditional:" << endl; 396 os << string( indent + 4, ' ' ); 397 cond->print( os, indent + 4 ); 398 } 399 else 400 os << string( indent + 2, ' ' ) << "with no conditional" << endl; 401 402 os << string( indent + 2, ' ' ) << "with block:" << endl; 403 os << string( indent + 4, ' ' ); 404 body->print( os, indent + 4 ); 383 os << indent << "... with conditional:" << endl << indent+1; 384 cond->print( os, indent+1 ); 385 } 386 387 os << indent << "... with block:" << endl; 388 os << indent+1; 389 body->print( os, indent+1 ); 405 390 } 406 391 … … 417 402 } 418 403 419 void FinallyStmt::print( std::ostream &os, intindent ) const {404 void FinallyStmt::print( std::ostream &os, Indenter indent ) const { 420 405 os << "Finally Statement" << endl; 421 os << string( indent + 2, ' ' ) << "with block:" << endl; 422 os << string( indent + 4, ' ' ); 423 block->print( os, indent + 4 ); 406 os << indent << "... with block:" << endl << indent+1; 407 block->print( os, indent+1 ); 424 408 } 425 409 … … 465 449 } 466 450 467 void WaitForStmt::print( std::ostream &os, intindent ) const {451 void WaitForStmt::print( std::ostream &os, Indenter indent ) const { 468 452 os << "Waitfor Statement" << endl; 469 os << string( indent + 2, ' ' ) << "with block:" << endl; 470 os << string( indent + 4, ' ' ); 453 os << indent << "... with block:" << endl << indent+1; 471 454 // block->print( os, indent + 4 ); 472 455 } … … 475 458 NullStmt::NullStmt() : Statement( std::list<Label>() ) {} 476 459 477 void NullStmt::print( std::ostream &os, __attribute__((unused)) int indent) const {478 os << "Null Statement" << endl 460 void NullStmt::print( std::ostream &os, Indenter ) const { 461 os << "Null Statement" << endl; 479 462 } 480 463 … … 490 473 } 491 474 492 void ImplicitCtorDtorStmt::print( std::ostream &os, intindent ) const {475 void ImplicitCtorDtorStmt::print( std::ostream &os, Indenter indent ) const { 493 476 os << "Implicit Ctor Dtor Statement" << endl; 494 os << string( indent + 2, ' ' ) << "with Ctor/Dtor: ";495 callStmt->print( os, indent + 2);477 os << indent << "... with Ctor/Dtor: "; 478 callStmt->print( os, indent+1); 496 479 os << endl; 497 480 } -
src/SynTree/Statement.h
rb96ec83 r6840e7c 43 43 const std::list<Label> & get_labels() const { return labels; } 44 44 45 virtual Statement *clone() const = 0;45 virtual Statement *clone() const override = 0; 46 46 virtual void accept( Visitor &v ) override = 0; 47 virtual Statement *acceptMutator( Mutator &m ) = 0;48 virtual void print( std::ostream &os, int indent = 0) const override;47 virtual Statement *acceptMutator( Mutator &m ) override = 0; 48 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 49 49 }; 50 50 … … 65 65 virtual void accept( Visitor &v ) override { v.visit( this ); } 66 66 virtual CompoundStmt *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 67 virtual void print( std::ostream &os, int indent = 0) const override;67 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 68 68 }; 69 69 … … 76 76 virtual void accept( Visitor &v ) override { v.visit( this ); } 77 77 virtual NullStmt *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 78 virtual void print( std::ostream &os, int indent = 0) const override;78 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 79 79 }; 80 80 … … 93 93 virtual void accept( Visitor &v ) override { v.visit( this ); } 94 94 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 95 virtual void print( std::ostream &os, int indent = 0) const override;95 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 96 96 }; 97 97 … … 124 124 virtual void accept( Visitor & v ) { v.visit( this ); } 125 125 virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); } 126 virtual void print( std::ostream & os, int indent = 0) const;126 virtual void print( std::ostream & os, Indenter indent = {} ) const; 127 127 }; 128 128 … … 150 150 virtual void accept( Visitor &v ) override { v.visit( this ); } 151 151 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 152 virtual void print( std::ostream &os, int indent = 0) const override;152 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 153 153 }; 154 154 … … 171 171 172 172 virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); } 173 virtual void print( std::ostream &os, int indent = 0) const override;173 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 174 174 175 175 }; … … 199 199 200 200 virtual CaseStmt *clone() const override { return new CaseStmt( *this ); } 201 virtual void print( std::ostream &os, int indent = 0) const override;201 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 202 202 private: 203 203 bool _isDefault; … … 225 225 virtual void accept( Visitor &v ) override { v.visit( this ); } 226 226 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 227 virtual void print( std::ostream &os, int indent = 0) const override;227 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 228 228 }; 229 229 … … 251 251 virtual void accept( Visitor &v ) override { v.visit( this ); } 252 252 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 253 virtual void print( std::ostream &os, int indent = 0) const override;253 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 254 254 }; 255 255 … … 280 280 virtual void accept( Visitor &v ) override { v.visit( this ); } 281 281 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 282 virtual void print( std::ostream &os, int indent = 0) const override;282 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 283 283 private: 284 284 static const char *brType[]; … … 299 299 virtual void accept( Visitor &v ) override { v.visit( this ); } 300 300 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 301 virtual void print( std::ostream &os, int indent = 0) const override;301 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 302 302 }; 303 303 … … 323 323 virtual void accept( Visitor &v ) override { v.visit( this ); } 324 324 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 325 virtual void print( std::ostream &os, int indent = 0) const override;325 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 326 326 }; 327 327 … … 346 346 virtual void accept( Visitor &v ) override { v.visit( this ); } 347 347 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 348 virtual void print( std::ostream &os, int indent = 0) const override;348 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 349 349 }; 350 350 … … 374 374 virtual void accept( Visitor &v ) override { v.visit( this ); } 375 375 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 376 virtual void print( std::ostream &os, int indent = 0) const override;376 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 377 377 }; 378 378 … … 391 391 virtual void accept( Visitor &v ) override { v.visit( this ); } 392 392 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 393 virtual void print( std::ostream &os, int indent = 0) const override;393 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 394 394 }; 395 395 … … 428 428 virtual void accept( Visitor &v ) override { v.visit( this ); } 429 429 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 430 virtual void print( std::ostream &os, int indent = 0) const override;430 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 431 431 432 432 }; … … 448 448 virtual void accept( Visitor &v ) override { v.visit( this ); } 449 449 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 450 virtual void print( std::ostream &os, int indent = 0) const override;450 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 451 451 }; 452 452 … … 470 470 virtual void accept( Visitor &v ) override { v.visit( this ); } 471 471 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 472 virtual void print( std::ostream &os, int indent = 0) const override;472 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 473 473 }; 474 474 -
src/SynTree/TupleExpr.cc
rb96ec83 r6840e7c 28 28 #include "Type.h" // for TupleType, Type 29 29 30 UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs , Expression *_aname ) : Expression( _aname), exprs( exprs ) {30 UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs ) : Expression(), exprs( exprs ) { 31 31 } 32 32 … … 39 39 } 40 40 41 void UntypedTupleExpr::print( std::ostream &os, intindent ) const {41 void UntypedTupleExpr::print( std::ostream &os, Indenter indent ) const { 42 42 os << "Untyped Tuple:" << std::endl; 43 printAll( exprs, os, indent+ 2);43 printAll( exprs, os, indent+1 ); 44 44 Expression::print( os, indent ); 45 45 } 46 46 47 TupleExpr::TupleExpr( const std::list< Expression * > & exprs , Expression *_aname ) : Expression( _aname), exprs( exprs ) {47 TupleExpr::TupleExpr( const std::list< Expression * > & exprs ) : Expression(), exprs( exprs ) { 48 48 set_result( Tuples::makeTupleType( exprs ) ); 49 49 } … … 57 57 } 58 58 59 void TupleExpr::print( std::ostream &os, intindent ) const {59 void TupleExpr::print( std::ostream &os, Indenter indent ) const { 60 60 os << "Tuple:" << std::endl; 61 printAll( exprs, os, indent+ 2);61 printAll( exprs, os, indent+1 ); 62 62 Expression::print( os, indent ); 63 63 } … … 78 78 } 79 79 80 void TupleIndexExpr::print( std::ostream &os, intindent ) const {80 void TupleIndexExpr::print( std::ostream &os, Indenter indent ) const { 81 81 os << "Tuple Index Expression, with tuple:" << std::endl; 82 os << std::string( indent+2, ' ' );83 tuple->print( os, indent+ 2);84 os << std::string( indent+2, ' ' )<< "with index: " << index << std::endl;82 os << indent+1; 83 tuple->print( os, indent+1 ); 84 os << indent+1 << "with index: " << index << std::endl; 85 85 Expression::print( os, indent ); 86 86 } 87 87 88 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls , Expression * _aname ) : Expression( _aname) {88 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls ) : Expression() { 89 89 // convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments 90 90 set_result( Tuples::makeTupleType( assigns ) ); … … 109 109 } 110 110 111 void TupleAssignExpr::print( std::ostream &os, intindent ) const {111 void TupleAssignExpr::print( std::ostream &os, Indenter indent ) const { 112 112 os << "Tuple Assignment Expression, with stmt expr:" << std::endl; 113 os << std::string( indent+2, ' ' );114 stmtExpr->print( os, indent+ 4);113 os << indent+1; 114 stmtExpr->print( os, indent+1 ); 115 115 Expression::print( os, indent ); 116 116 } -
src/SynTree/TupleType.cc
rb96ec83 r6840e7c 48 48 } 49 49 50 void TupleType::print( std::ostream &os, intindent ) const {50 void TupleType::print( std::ostream &os, Indenter indent ) const { 51 51 Type::print( os, indent ); 52 52 os << "tuple of types" << std::endl; 53 printAll( types, os, indent+ 2);53 printAll( types, os, indent+1 ); 54 54 } 55 55 -
src/SynTree/Type.cc
rb96ec83 r6840e7c 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 11 13:21:25201713 // Update Count : 3 712 // Last Modified On : Mon Sep 25 15:16:32 2017 13 // Update Count : 38 14 14 // 15 15 #include "Type.h" … … 45 45 "double _Imaginary", 46 46 "long double _Imaginary", 47 "__int128", 48 "unsigned __int128", 47 49 }; 48 50 … … 73 75 Type * type; 74 76 ReferenceType * ref; 75 for ( type = this; (ref = dynamic_cast<ReferenceType *>( type )); type = ref-> get_base());77 for ( type = this; (ref = dynamic_cast<ReferenceType *>( type )); type = ref->base ); 76 78 return type; 77 79 } … … 79 81 int Type::referenceDepth() const { return 0; } 80 82 81 void Type::print( std::ostream &os, intindent ) const {83 void Type::print( std::ostream &os, Indenter indent ) const { 82 84 if ( ! forall.empty() ) { 83 85 os << "forall" << std::endl; 84 printAll( forall, os, indent + 4);85 os << std::string( indent+2, ' ' );86 printAll( forall, os, indent+1 ); 87 os << ++indent; 86 88 } // if 87 89 88 90 if ( ! attributes.empty() ) { 89 os << endl << string( indent+2, ' ' ) <<"with attributes" << endl;90 printAll( attributes, os, indent+ 4);91 os << "with attributes" << endl; 92 printAll( attributes, os, indent+1 ); 91 93 } // if 92 94 -
src/SynTree/Type.h
rb96ec83 r6840e7c 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Aug 9 14:25:00201713 // Update Count : 15 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 14:14:01 2017 13 // Update Count : 154 14 14 // 15 15 … … 181 181 virtual void accept( Visitor & v ) = 0; 182 182 virtual Type *acceptMutator( Mutator & m ) = 0; 183 virtual void print( std::ostream & os, int indent = 0) const;183 virtual void print( std::ostream & os, Indenter indent = {} ) const; 184 184 }; 185 185 … … 198 198 virtual void accept( Visitor & v ) override { v.visit( this ); } 199 199 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 200 virtual void print( std::ostream & os, int indent = 0) const override;200 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 201 201 }; 202 202 … … 225 225 DoubleImaginary, 226 226 LongDoubleImaginary, 227 SignedInt128, 228 UnsignedInt128, 227 229 NUMBER_OF_BASIC_TYPES 228 230 } kind; … … 238 240 virtual void accept( Visitor & v ) override { v.visit( this ); } 239 241 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 240 virtual void print( std::ostream & os, int indent = 0) const override;242 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 241 243 242 244 bool isInteger() const; … … 273 275 virtual void accept( Visitor & v ) override { v.visit( this ); } 274 276 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 275 virtual void print( std::ostream & os, int indent = 0) const override;277 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 276 278 }; 277 279 … … 301 303 virtual void accept( Visitor & v ) override { v.visit( this ); } 302 304 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 303 virtual void print( std::ostream & os, int indent = 0) const override;305 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 304 306 }; 305 307 … … 325 327 virtual void accept( Visitor & v ) override { v.visit( this ); } 326 328 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 327 virtual void print( std::ostream & os, int indent = 0) const override;329 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 328 330 }; 329 331 … … 352 354 virtual void accept( Visitor & v ) override { v.visit( this ); } 353 355 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 354 virtual void print( std::ostream & os, int indent = 0) const override;356 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 355 357 }; 356 358 … … 374 376 virtual void accept( Visitor & v ) override = 0; 375 377 virtual Type *acceptMutator( Mutator & m ) override = 0; 376 virtual void print( std::ostream & os, int indent = 0) const override;378 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 377 379 378 380 virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {} … … 408 410 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 409 411 410 virtual void print( std::ostream & os, int indent = 0) const override;412 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 411 413 private: 412 414 virtual std::string typeString() const override; … … 440 442 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 441 443 442 virtual void print( std::ostream & os, int indent = 0) const override;444 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 443 445 private: 444 446 virtual std::string typeString() const override; … … 464 466 virtual void accept( Visitor & v ) override { v.visit( this ); } 465 467 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 468 469 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 466 470 private: 467 471 virtual std::string typeString() const override; … … 512 516 virtual void accept( Visitor & v ) override { v.visit( this ); } 513 517 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 514 virtual void print( std::ostream & os, int indent = 0) const override;518 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 515 519 private: 516 520 virtual std::string typeString() const override; … … 549 553 virtual void accept( Visitor & v ) override { v.visit( this ); } 550 554 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 551 virtual void print( std::ostream & os, int indent = 0) const override;555 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 552 556 }; 553 557 … … 568 572 virtual void accept( Visitor & v ) override { v.visit( this ); } 569 573 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 570 virtual void print( std::ostream & os, int indent = 0) const override;574 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 571 575 }; 572 576 … … 597 601 virtual void accept( Visitor & v ) override { v.visit( this ); } 598 602 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 599 virtual void print( std::ostream & os, int indent = 0) const override;603 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 600 604 }; 601 605 … … 611 615 virtual void accept( Visitor & v ) override { v.visit( this ); } 612 616 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 613 virtual void print( std::ostream & os, int indent = 0) const override;617 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 614 618 }; 615 619 … … 623 627 virtual void accept( Visitor & v ) override { v.visit( this ); } 624 628 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 625 virtual void print( std::ostream & os, int indent = 0) const override;629 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 626 630 }; 627 631 … … 635 639 virtual void accept( Visitor & v ) override { v.visit( this ); } 636 640 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 637 virtual void print( std::ostream & os, int indent = 0) const override;641 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 638 642 }; 639 643 -
src/SynTree/TypeDecl.cc
rb96ec83 r6840e7c 41 41 } 42 42 43 void TypeDecl::print( std::ostream &os, intindent ) const {43 void TypeDecl::print( std::ostream &os, Indenter indent ) const { 44 44 NamedTypeDecl::print( os, indent ); 45 45 if ( init ) { 46 os << std::endl << std::string( indent, ' ' )<< "with type initializer: ";47 init->print( os, indent + 2);46 os << std::endl << indent << "with type initializer: "; 47 init->print( os, indent + 1 ); 48 48 } 49 49 } -
src/SynTree/TypeExpr.cc
rb96ec83 r6840e7c 30 30 } 31 31 32 void TypeExpr::print( std::ostream &os, intindent ) const {32 void TypeExpr::print( std::ostream &os, Indenter indent ) const { 33 33 if ( type ) type->print( os, indent ); 34 34 Expression::print( os, indent ); -
src/SynTree/TypeSubstitution.cc
rb96ec83 r6840e7c 148 148 template< typename TypeClass > 149 149 Type *TypeSubstitution::handleType( TypeClass *type ) { 150 BoundVarsTypeoldBoundVars( boundVars );150 ValueGuard<BoundVarsType> oldBoundVars( boundVars ); 151 151 // bind type variables from forall-qualifiers 152 152 if ( freeOnly ) { … … 156 156 } // if 157 157 Type *ret = Mutator::mutate( type ); 158 boundVars = oldBoundVars;159 158 return ret; 160 159 } … … 162 161 template< typename TypeClass > 163 162 Type *TypeSubstitution::handleAggregateType( TypeClass *type ) { 164 BoundVarsTypeoldBoundVars( boundVars );163 ValueGuard<BoundVarsType> oldBoundVars( boundVars ); 165 164 // bind type variables from forall-qualifiers 166 165 if ( freeOnly ) { … … 177 176 } // if 178 177 Type *ret = Mutator::mutate( type ); 179 boundVars = oldBoundVars;180 178 return ret; 181 179 } … … 233 231 } 234 232 235 TypeSubstitution * TypeSubstitution::acceptMutator( Mutator & mutator ) { 236 for ( auto & p : typeEnv ) { 237 p.second = maybeMutate( p.second, mutator ); 238 } 239 for ( auto & p : varEnv ) { 240 p.second = maybeMutate( p.second, mutator ); 241 } 242 return this; 243 } 244 245 void TypeSubstitution::print( std::ostream &os, int indent ) const { 246 os << std::string( indent, ' ' ) << "Types:" << std::endl; 233 void TypeSubstitution::print( std::ostream &os, Indenter indent ) const { 234 os << indent << "Types:" << std::endl; 247 235 for ( TypeEnvType::const_iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { 248 os << std::string( indent+2, ' ' )<< i->first << " -> ";249 i->second->print( os, indent+ 4);236 os << indent+1 << i->first << " -> "; 237 i->second->print( os, indent+2 ); 250 238 os << std::endl; 251 239 } // for 252 os << std::string( indent, ' ' )<< "Non-types:" << std::endl;240 os << indent << "Non-types:" << std::endl; 253 241 for ( VarEnvType::const_iterator i = varEnv.begin(); i != varEnv.end(); ++i ) { 254 os << std::string( indent+2, ' ' )<< i->first << " -> ";255 i->second->print( os, indent+ 4);242 os << indent+1 << i->first << " -> "; 243 i->second->print( os, indent+2 ); 256 244 os << std::endl; 257 245 } // for -
src/SynTree/TypeSubstitution.h
rb96ec83 r6840e7c 59 59 void normalize(); 60 60 61 TypeSubstitution * acceptMutator( Mutator & m utator );61 TypeSubstitution * acceptMutator( Mutator & m ) { return m.mutate( this ); } 62 62 63 void print( std::ostream &os, int indent = 0) const;63 void print( std::ostream &os, Indenter indent = {} ) const; 64 64 TypeSubstitution *clone() const { return new TypeSubstitution( *this ); } 65 65 private: … … 89 89 90 90 void initialize( const TypeSubstitution &src, TypeSubstitution &dest ); 91 92 friend class Mutator; 93 94 template<typename pass_type> 95 friend class PassVisitor; 91 96 92 97 typedef std::map< std::string, Type* > TypeEnvType; -
src/SynTree/TypeofType.cc
rb96ec83 r6840e7c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeofType.cc -- 7 // TypeofType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 33 33 } 34 34 35 void TypeofType::print( std::ostream &os, intindent ) const {35 void TypeofType::print( std::ostream &os, Indenter indent ) const { 36 36 Type::print( os, indent ); 37 37 os << "type-of expression "; -
src/SynTree/VarArgsType.cc
rb96ec83 r6840e7c 25 25 VarArgsType::VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {} 26 26 27 void VarArgsType::print( std::ostream &os, intindent ) const {27 void VarArgsType::print( std::ostream &os, Indenter indent ) const { 28 28 Type::print( os, indent ); 29 29 os << "builtin var args pack"; -
src/SynTree/VoidType.cc
rb96ec83 r6840e7c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // VoidType.cc -- 7 // VoidType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 24 24 } 25 25 26 void VoidType::print( std::ostream &os, intindent ) const {26 void VoidType::print( std::ostream &os, Indenter indent ) const { 27 27 Type::print( os, indent ); 28 28 os << "void "; -
src/SynTree/ZeroOneType.cc
rb96ec83 r6840e7c 25 25 ZeroType::ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {} 26 26 27 void ZeroType::print( std::ostream &os, __attribute__((unused)) int indent) const {27 void ZeroType::print( std::ostream &os, Indenter ) const { 28 28 os << "zero_t"; 29 29 } … … 33 33 OneType::OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {} 34 34 35 void OneType::print( std::ostream &os, __attribute__((unused)) int indent) const {35 void OneType::print( std::ostream &os, Indenter ) const { 36 36 os << "one_t"; 37 37 } -
src/Tuples/Explode.h
rb96ec83 r6840e7c 30 30 Expression * distributeReference( Expression * ); 31 31 32 static inline CastExpr * isReferenceCast( Expression * expr ) { 33 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 34 if ( dynamic_cast< ReferenceType * >( castExpr->result ) ) { 35 return castExpr; 36 } 37 } 38 return nullptr; 39 } 40 32 41 /// helper function used by explode 33 42 template< typename OutputIterator > … … 35 44 if ( isTupleAssign ) { 36 45 // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components 37 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {46 if ( CastExpr * castExpr = isReferenceCast( expr ) ) { 38 47 ResolvExpr::AltList alts; 39 48 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); -
src/Tuples/TupleAssignment.cc
rb96ec83 r6840e7c 41 41 #include "SynTree/Visitor.h" // for Visitor 42 42 43 #if 0 44 #define PRINT(x) x 45 #else 46 #define PRINT(x) 47 #endif 48 43 49 namespace Tuples { 44 50 class TupleAssignSpotter { … … 84 90 bool isTuple( Expression *expr ) { 85 91 if ( ! expr ) return false; 86 assert( expr-> has_result());92 assert( expr->result ); 87 93 return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() ); 88 94 } … … 119 125 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 120 126 if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) { 121 fname = op->get_name(); 127 fname = op->get_name(); 128 PRINT( std::cerr << "TupleAssignment: " << fname << std::endl; ) 122 129 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 123 130 if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal … … 131 138 const ResolvExpr::Alternative & alt1 = ali->front(); 132 139 auto begin = std::next(ali->begin(), 1), end = ali->end(); 140 PRINT( std::cerr << "alt1 is " << alt1.expr << std::endl; ) 133 141 if ( refToTuple(alt1.expr) ) { 142 PRINT( std::cerr << "and is reference to tuple" << std::endl; ) 134 143 if ( isMultAssign( begin, end ) ) { 144 PRINT( std::cerr << "possible multiple assignment" << std::endl; ) 135 145 matcher.reset( new MultipleAssignMatcher( *this, *ali ) ); 136 146 } else { 137 147 // mass assignment 148 PRINT( std::cerr << "possible mass assignment" << std::endl; ) 138 149 matcher.reset( new MassAssignMatcher( *this, *ali ) ); 139 150 } … … 159 170 // now resolve new assignments 160 171 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 172 PRINT( 173 std::cerr << "== resolving tuple assign ==" << std::endl; 174 std::cerr << *i << std::endl; 175 ) 176 161 177 ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() ); 162 178 try { … … 238 254 239 255 ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) { 240 assert( expr-> has_result()&& ! expr->get_result()->isVoid() );256 assert( expr->result && ! expr->get_result()->isVoid() ); 241 257 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) ); 242 258 // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient. … … 248 264 ctorInit->accept( rm ); 249 265 } 266 PRINT( std::cerr << "new object: " << ret << std::endl; ) 250 267 return ret; 251 268 } -
src/benchmark/Makefile.am
rb96ec83 r6840e7c 48 48 @rm -f a.out .result.log 49 49 50 ctxswitch-pthread$(EXEEXT): 51 @BACKEND_CC@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -lrt -pthread -DN=50000000 PthrdCtxSwitch.c 52 @rm -f .result.log 53 @for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \ 54 ./a.out | tee -a .result.log ; \ 55 done 56 @./stat.py .result.log 57 @rm -f a.out .result.log 58 50 59 sched-int$(EXEEXT): 51 60 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c -
src/benchmark/Makefile.in
rb96ec83 r6840e7c 598 598 @rm -f a.out .result.log 599 599 600 ctxswitch-pthread$(EXEEXT): 601 @BACKEND_CC@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -lrt -pthread -DN=50000000 PthrdCtxSwitch.c 602 @rm -f .result.log 603 @for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \ 604 ./a.out | tee -a .result.log ; \ 605 done 606 @./stat.py .result.log 607 @rm -f a.out .result.log 608 600 609 sched-int$(EXEEXT): 601 610 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c -
src/benchmark/bench.h
rb96ec83 r6840e7c 10 10 } 11 11 #endif 12 13 12 14 13 static inline unsigned long long int Time() { -
src/benchmark/create_cfaThrd.c
rb96ec83 r6840e7c 4 4 5 5 thread MyThread {}; 6 void main(MyThread *this) {}6 void main(MyThread & this) {} 7 7 8 8 int main(int argc, char* argv[]) { -
src/driver/cfa.cc
rb96ec83 r6840e7c 9 9 // Author : Peter A. Buhr 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 // Last Modified By : Andrew Beach12 // Last Modified On : T hr Aug 17 15:24:00201713 // Update Count : 15 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Sep 26 23:12:38 2017 13 // Update Count : 159 14 14 // 15 15 … … 346 346 args[nargs] = "-fgnu89-inline"; 347 347 nargs += 1; 348 args[nargs] = "-D__int8_t_defined"; // prevent gcc type-size attributes 349 nargs += 1; 348 350 args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str(); 349 351 nargs += 1; -
src/include/cassert
rb96ec83 r6840e7c 41 41 static inline T strict_dynamic_cast( const U & src ) { 42 42 T ret = dynamic_cast<T>(src); 43 assert (ret);43 assertf(ret, "%s", toString(src).c_str()); 44 44 return ret; 45 45 } -
src/libcfa/Makefile.am
rb96ec83 r6840e7c 31 31 32 32 libcfa_a-libcfa-prelude.o : libcfa-prelude.c 33 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ - O2 -c -o $@ $<33 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -Wall -O2 -c -o $@ $< 34 34 35 35 libcfa_d_a-libcfa-prelude.o : libcfa-prelude.c 36 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ - O0 -c -o $@ $<36 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -Wall -O0 -c -o $@ $< 37 37 38 38 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@ -
src/libcfa/Makefile.in
rb96ec83 r6840e7c 1498 1498 1499 1499 libcfa_a-libcfa-prelude.o : libcfa-prelude.c 1500 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ - O2 -c -o $@ $<1500 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -Wall -O2 -c -o $@ $< 1501 1501 1502 1502 libcfa_d_a-libcfa-prelude.o : libcfa-prelude.c 1503 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ - O0 -c -o $@ $<1503 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -Wall -O0 -c -o $@ $< 1504 1504 1505 1505 # extensionless header files are overridden by -o flag in default makerule => explicitly override default rule to silently do nothing -
src/libcfa/concurrency/invoke.h
rb96ec83 r6840e7c 96 96 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 97 97 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor 99 struct __condition_node_t * dtor_node; // node used to signal the dtor in a waitfor dtor 99 100 }; 100 101 … … 110 111 struct monitor_desc self_mon; // monitor body used for mutual exclusion 111 112 struct monitor_desc * self_mon_p; // pointer to monitor with sufficient lifetime for current monitors 112 struct __monitor_group_t monitors; 113 struct __monitor_group_t monitors; // monitors currently held by this thread 113 114 114 115 // Link lists fields -
src/libcfa/concurrency/monitor
rb96ec83 r6840e7c 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:59:01201713 // Update Count : 312 // Last Modified On : Sat Oct 7 18:06:45 2017 13 // Update Count : 10 14 14 // 15 15 … … 29 29 static inline void ?{}(monitor_desc & this) { 30 30 (this.lock){}; 31 this.owner = NULL;32 31 (this.entry_queue){}; 33 32 (this.signal_stack){}; 34 this.recursion = 0; 33 this.owner = NULL; 34 this.recursion = 0; 35 35 this.mask.accepted = NULL; 36 36 this.mask.clauses = NULL; 37 37 this.mask.size = 0; 38 this.dtor_node = NULL; 38 39 } 40 41 // static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) { 42 // return ((intptr_t)lhs) < ((intptr_t)rhs); 43 // } 39 44 40 45 struct monitor_guard_t { … … 46 51 }; 47 52 48 static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {49 return ((intptr_t)lhs) < ((intptr_t)rhs);50 }51 52 53 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ); 53 54 void ^?{}( monitor_guard_t & this ); 55 56 struct monitor_dtor_guard_t { 57 monitor_desc * m; 58 monitor_desc ** prev_mntrs; 59 unsigned short prev_count; 60 fptr_t prev_func; 61 }; 62 63 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, void (*func)() ); 64 void ^?{}( monitor_dtor_guard_t & this ); 65 66 static inline forall( dtype T | sized(T) | { void ^?{}( T & mutex ); } ) 67 void delete( T * th ) { 68 ^(*th){}; 69 free( th ); 70 } 54 71 55 72 //----------------------------------------------------------------------------- … … 75 92 __condition_node_t ** tail; 76 93 }; 94 95 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ); 96 void ?{}(__condition_criterion_t & this ); 97 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ); 77 98 78 99 void ?{}( __condition_blocked_queue_t & ); -
src/libcfa/concurrency/monitor.c
rb96ec83 r6840e7c 23 23 //----------------------------------------------------------------------------- 24 24 // Forward declarations 25 static inline void set_owner( monitor_desc * this, thread_desc * owner ); 26 static inline void set_owner( monitor_desc ** storage, short count, thread_desc * owner ); 27 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 25 static inline void set_owner ( monitor_desc * this, thread_desc * owner ); 26 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner ); 27 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 28 static inline void reset_mask( monitor_desc * this ); 28 29 29 30 static inline thread_desc * next_thread( monitor_desc * this ); … … 72 73 #define monitor_restore restore( monitors, count, locks, recursions, masks ) 73 74 74 #define blockAndWake( thrd, cnt ) /* Create the necessary information to use the signaller stack */ \75 monitor_save; /* Save monitor states */ \76 BlockInternal( locks, count, thrd, cnt ); /* Everything is ready to go to sleep */ \77 monitor_restore; /* We are back, restore the owners and recursions */ \78 79 75 80 76 //----------------------------------------------------------------------------- … … 98 94 } 99 95 else if( this->owner == thrd) { 100 // We already have the monitor, just not how many times we took it96 // We already have the monitor, just note how many times we took it 101 97 verify( this->recursion > 0 ); 102 98 this->recursion += 1; … … 108 104 set_owner( this, thrd ); 109 105 106 // Reset mask 107 reset_mask( this ); 108 110 109 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts \n"); 111 110 } … … 128 127 unlock( &this->lock ); 129 128 return; 129 } 130 131 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) { 132 // Lock the monitor spinlock, lock_yield to reduce contention 133 lock_yield( &this->lock DEBUG_CTX2 ); 134 thread_desc * thrd = this_thread; 135 136 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner); 137 138 139 if( !this->owner ) { 140 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this); 141 142 // No one has the monitor, just take it 143 set_owner( this, thrd ); 144 145 unlock( &this->lock ); 146 return; 147 } 148 else if( this->owner == thrd) { 149 // We already have the monitor... but where about to destroy it so the nesting will fail 150 // Abort! 151 abortf("Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex."); 152 } 153 154 int count = 1; 155 monitor_desc ** monitors = &this; 156 __monitor_group_t group = { &this, 1, func }; 157 if( is_accepted( this, group) ) { 158 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts dtor, block and signal it \n"); 159 160 // Wake the thread that is waiting for this 161 __condition_criterion_t * urgent = pop( &this->signal_stack ); 162 verify( urgent ); 163 164 // Reset mask 165 reset_mask( this ); 166 167 // Create the node specific to this wait operation 168 wait_ctx_primed( this_thread, 0 ) 169 170 // Some one else has the monitor, wait for him to finish and then run 171 BlockInternal( &this->lock, urgent->owner->waiting_thread ); 172 173 // Some one was waiting for us, enter 174 set_owner( this, thrd ); 175 } 176 else { 177 LIB_DEBUG_PRINT_SAFE("Kernel : blocking \n"); 178 179 wait_ctx( this_thread, 0 ) 180 this->dtor_node = &waiter; 181 182 // Some one else has the monitor, wait in line for it 183 append( &this->entry_queue, thrd ); 184 BlockInternal( &this->lock ); 185 186 // BlockInternal will unlock spinlock, no need to unlock ourselves 187 return; 188 } 189 190 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this); 191 130 192 } 131 193 … … 159 221 } 160 222 223 // Leave single monitor for the last time 224 void __leave_dtor_monitor_desc( monitor_desc * this ) { 225 LIB_DEBUG_DO( 226 if( this_thread != this->owner ) { 227 abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner); 228 } 229 if( this->recursion != 1 ) { 230 abortf("Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1); 231 } 232 ) 233 } 234 161 235 // Leave the thread monitor 162 236 // last routine called by a thread. … … 211 285 // Ctor for monitor guard 212 286 // Sorts monitors before entering 213 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)()) {287 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) { 214 288 // Store current array 215 289 this.m = m; … … 229 303 this_thread->monitors.func = func; 230 304 231 LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);305 // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count); 232 306 233 307 // Enter the monitors in order … … 235 309 enter( group ); 236 310 237 LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");311 // LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n"); 238 312 } 239 313 … … 241 315 // Dtor for monitor guard 242 316 void ^?{}( monitor_guard_t & this ) { 243 LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);317 // LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count); 244 318 245 319 // Leave the monitors in order 246 320 leave( this.m, this.count ); 247 321 248 LIB_DEBUG_PRINT_SAFE("MGUARD : left\n"); 322 // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n"); 323 324 // Restore thread context 325 this_thread->monitors.list = this.prev_mntrs; 326 this_thread->monitors.size = this.prev_count; 327 this_thread->monitors.func = this.prev_func; 328 } 329 330 331 // Ctor for monitor guard 332 // Sorts monitors before entering 333 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) { 334 // Store current array 335 this.m = *m; 336 337 // Save previous thread context 338 this.prev_mntrs = this_thread->monitors.list; 339 this.prev_count = this_thread->monitors.size; 340 this.prev_func = this_thread->monitors.func; 341 342 // Update thread context (needed for conditions) 343 this_thread->monitors.list = m; 344 this_thread->monitors.size = 1; 345 this_thread->monitors.func = func; 346 347 __enter_monitor_dtor( this.m, func ); 348 } 349 350 351 // Dtor for monitor guard 352 void ^?{}( monitor_dtor_guard_t & this ) { 353 // Leave the monitors in order 354 __leave_dtor_monitor_desc( this.m ); 249 355 250 356 // Restore thread context … … 303 409 short thread_count = 0; 304 410 thread_desc * threads[ count ]; 305 for(int i = 0; i < count; i++) { 306 threads[i] = 0; 307 } 411 __builtin_memset( threads, 0, sizeof( threads ) ); 308 412 309 413 // Save monitor states … … 429 533 short max = count_max( mask ); 430 534 monitor_desc * mon_storage[max]; 535 __builtin_memset( mon_storage, 0, sizeof( mon_storage ) ); 431 536 short actual_count = aggregate( mon_storage, mask ); 432 537 538 LIB_DEBUG_PRINT_SAFE("Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (short)max); 539 433 540 if(actual_count == 0) return; 541 542 LIB_DEBUG_PRINT_SAFE("Kernel : waitfor internal proceeding\n"); 434 543 435 544 // Create storage for monitor context … … 445 554 446 555 if( next ) { 556 *mask.accepted = index; 447 557 if( mask.clauses[index].is_dtor ) { 448 #warning case not implemented 558 LIB_DEBUG_PRINT_SAFE("Kernel : dtor already there\n"); 559 verifyf( mask.clauses[index].size == 1 , "ERROR: Accepted dtor has more than 1 mutex parameter." ); 560 561 monitor_desc * mon2dtor = mask.clauses[index].list[0]; 562 verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." ); 563 564 __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria; 565 push( &mon2dtor->signal_stack, dtor_crit ); 566 567 unlock_all( locks, count ); 449 568 } 450 569 else { 451 blockAndWake( &next, 1 ); 570 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, baton-passing\n"); 571 572 // Create the node specific to this wait operation 573 wait_ctx_primed( this_thread, 0 ); 574 575 // Save monitor states 576 monitor_save; 577 578 // Set the owners to be the next thread 579 set_owner( monitors, count, next ); 580 581 // Everything is ready to go to sleep 582 BlockInternal( locks, count, &next, 1 ); 583 584 // We are back, restore the owners and recursions 585 monitor_restore; 586 587 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, returned\n"); 452 588 } 453 589 454 return index; 590 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted); 591 592 return; 455 593 } 456 594 } … … 458 596 459 597 if( duration == 0 ) { 598 LIB_DEBUG_PRINT_SAFE("Kernel : non-blocking, exiting\n"); 599 460 600 unlock_all( locks, count ); 601 602 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted); 461 603 return; 462 604 } … … 465 607 verifyf( duration < 0, "Timeout on waitfor statments not supported yet."); 466 608 609 LIB_DEBUG_PRINT_SAFE("Kernel : blocking waitfor\n"); 610 611 // Create the node specific to this wait operation 612 wait_ctx_primed( this_thread, 0 ); 467 613 468 614 monitor_save; 469 615 set_mask( monitors, count, mask ); 470 616 471 BlockInternal( locks, count ); // Everything is ready to go to sleep 472 //WE WOKE UP 473 monitor_restore; //We are back, restore the masks and recursions 617 for(int i = 0; i < count; i++) { 618 verify( monitors[i]->owner == this_thread ); 619 } 620 621 //Everything is ready to go to sleep 622 BlockInternal( locks, count ); 623 624 625 // WE WOKE UP 626 627 628 //We are back, restore the masks and recursions 629 monitor_restore; 630 631 LIB_DEBUG_PRINT_SAFE("Kernel : exiting\n"); 632 633 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted); 474 634 } 475 635 … … 478 638 479 639 static inline void set_owner( monitor_desc * this, thread_desc * owner ) { 480 LIB_DEBUG_PRINT_SAFE("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );640 // LIB_DEBUG_PRINT_SAFE("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner ); 481 641 482 642 //Pass the monitor appropriately … … 497 657 storage[i]->mask = mask; 498 658 } 659 } 660 661 static inline void reset_mask( monitor_desc * this ) { 662 this->mask.accepted = NULL; 663 this->mask.clauses = NULL; 664 this->mask.size = 0; 499 665 } 500 666 … … 584 750 } 585 751 586 static inline void save 752 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 587 753 for( int i = 0; i < count; i++ ) { 588 754 recursions[i] = ctx[i]->recursion; -
src/libcfa/iostream
rb96ec83 r6840e7c 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Sep 13 12:53:46201713 // Update Count : 1 3812 // Last Modified On : Tue Oct 10 14:51:10 2017 13 // Update Count : 140 14 14 // 15 15 … … 79 79 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char * ); 80 80 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char16_t * ); 81 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous 81 82 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char32_t * ); 83 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) 82 84 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const wchar_t * ); 83 85 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const void * ); -
src/libcfa/iostream.c
rb96ec83 r6840e7c 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 17 23:24:25201713 // Update Count : 42 212 // Last Modified On : Tue Oct 10 14:51:09 2017 13 // Update Count : 424 14 14 // 15 15 … … 191 191 } // ?|? 192 192 193 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous 193 194 forall( dtype ostype | ostream( ostype ) ) 194 195 ostype * ?|?( ostype * os, const char32_t * str ) { … … 197 198 return os; 198 199 } // ?|? 200 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) 199 201 200 202 forall( dtype ostype | ostream( ostype ) ) -
src/main.cc
rb96ec83 r6840e7c 44 44 #include "ControlStruct/Mutate.h" // for mutate 45 45 #include "GenPoly/Box.h" // for box 46 #include "GenPoly/CopyParams.h" // for copyParams47 46 #include "GenPoly/InstantiateGeneric.h" // for instantiateGeneric 48 47 #include "GenPoly/Lvalue.h" // for convertLvalue … … 321 320 OPTPRINT("instantiateGenerics") 322 321 GenPoly::instantiateGeneric( translationUnit ); 323 OPTPRINT( "copyParams" );324 GenPoly::copyParams( translationUnit );325 322 OPTPRINT( "convertLvalue" ) 326 323 GenPoly::convertLvalue( translationUnit ); -
src/prelude/extras.c
rb96ec83 r6840e7c 1 1 #include <stddef.h> // size_t, ptrdiff_t 2 #include <stdint.h> // intX_t, uintX_t, where X is 8, 16, 32, 64 2 3 #include <uchar.h> // char16_t, char32_t 3 4 #include <wchar.h> // wchar_t -
src/prelude/extras.regx
rb96ec83 r6840e7c 1 1 typedef.* size_t; 2 2 typedef.* ptrdiff_t; 3 typedef.* int8_t; 4 typedef.* int16_t; 5 typedef.* int32_t; 6 typedef.* int64_t; 7 typedef.* uint8_t; 8 typedef.* uint16_t; 9 typedef.* uint32_t; 10 typedef.* uint64_t; 3 11 typedef.* char16_t; 4 12 typedef.* char32_t; -
src/prelude/prelude.cf
rb96ec83 r6840e7c 7 7 // Created On : Sat Nov 29 07:23:41 2014 8 8 // Last Modified By : Peter A. Buhr 9 // Last Modified On : Wed Aug 30 07:56:07201710 // Update Count : 9 39 // Last Modified On : Sun Oct 8 12:21:33 2017 10 // Update Count : 97 11 11 // 12 12 … … 558 558 signed long long int ?+=?( signed long long int &, signed long long int ), ?+=?( volatile signed long long int &, signed long long int ); 559 559 unsigned long long int ?+=?( unsigned long long int &, unsigned long long int ), ?+=?( volatile unsigned long long int &, unsigned long long int ); 560 //signed int128 ?+=?( signed int128 &, signed int128 ), ?+=?( volatile signed int128 &, signed int128 ); 561 //unsigned int128 ?+=?( unsigned int128 &, unsigned int128 ), ?+=?( volatile unsigned int128 &, unsigned int128 ); 560 562 561 563 _Bool ?-=?( _Bool &, _Bool ), ?-=?( volatile _Bool &, _Bool ); -
src/tests/.expect/32/KRfunctions.txt
rb96ec83 r6840e7c 21 21 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 22 22 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 23 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1); 23 24 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 24 25 ((void)((*___dst__R2sS_1).__i__i_1) /* ?{} */); … … 33 34 struct S ___ret__2sS_1; 34 35 ((void)((*___dst__R2sS_1).__i__i_1=___src__2sS_1.__i__i_1)); 35 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));36 return ((struct S )___ret__2sS_1);36 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1))); 37 return ___ret__2sS_1; 37 38 } 38 39 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1){ … … 65 66 signed int *__x__FPi_ii__2(signed int __anonymous_object2, signed int __anonymous_object3); 66 67 ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */); 67 return ((signed int *(*)(signed int __x__i_1, signed int __y__i_1))___retval_f10__PFPi_ii__1);68 return ___retval_f10__PFPi_ii__1; 68 69 } 69 70 signed int (*__f11__FPA0i_iPiPi__1(signed int __a__i_1, signed int *__b__Pi_1, signed int *__c__Pi_1))[]{ -
src/tests/.expect/32/attributes.txt
rb96ec83 r6840e7c 23 23 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){ 24 24 struct __anonymous0 ___ret__13s__anonymous0_1; 25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1));26 return ((struct __anonymous0 )___ret__13s__anonymous0_1);25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1))); 26 return ___ret__13s__anonymous0_1; 27 27 } 28 28 __attribute__ ((unused)) struct Agn1; … … 41 41 static inline struct Agn2 ___operator_assign__F5sAgn2_R5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__R5sAgn2_1, struct Agn2 ___src__5sAgn2_1){ 42 42 struct Agn2 ___ret__5sAgn2_1; 43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), ___src__5sAgn2_1));44 return ((struct Agn2 )___ret__5sAgn2_1);43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__R5sAgn2_1))); 44 return ___ret__5sAgn2_1; 45 45 } 46 46 enum __attribute__ ((unused)) __anonymous1 { … … 69 69 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1); 70 70 static inline struct Fdl ___operator_assign__F4sFdl_R4sFdl4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1, struct Fdl ___src__4sFdl_1); 71 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1); 72 static inline void ___constructor__F_R4sFdlii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1); 73 static inline void ___constructor__F_R4sFdliii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1); 74 static inline void ___constructor__F_R4sFdliiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1); 75 static inline void ___constructor__F_R4sFdliiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1); 76 static inline void ___constructor__F_R4sFdliiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1); 77 static inline void ___constructor__F_R4sFdliiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1); 78 static inline void ___constructor__F_R4sFdliiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1); 79 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object1); 80 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object2, signed int *__f9__Pi_1); 71 81 static inline void ___constructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 72 82 ((void)((*___dst__R4sFdl_1).__f1__i_1) /* ?{} */); … … 78 88 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 79 89 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 90 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 80 91 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 81 92 } … … 89 100 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */); 90 101 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1) /* ?{} */); 102 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0) /* ?{} */); 91 103 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */); 92 104 } 93 105 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 94 106 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ^?{} */); 107 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ^?{} */); 95 108 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ^?{} */); 96 109 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ^?{} */); … … 112 125 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1)); 113 126 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1)); 127 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0)); 114 128 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1)); 115 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), ___src__4sFdl_1));116 return ((struct Fdl )___ret__4sFdl_1);129 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__R4sFdl_1))); 130 return ___ret__4sFdl_1; 117 131 } 118 132 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1){ … … 125 139 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 126 140 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 141 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 127 142 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 128 143 } … … 136 151 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 137 152 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 153 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 138 154 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 139 155 } … … 147 163 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 148 164 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 165 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 149 166 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 150 167 } … … 158 175 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 159 176 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 177 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 160 178 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 161 179 } … … 169 187 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 170 188 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 189 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 171 190 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 172 191 } … … 180 199 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 181 200 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 201 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 182 202 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 183 203 } … … 191 211 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 192 212 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 213 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 193 214 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 194 215 } … … 202 223 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 203 224 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 204 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 205 } 206 static inline void ___constructor__F_R4sFdliiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int *__f9__Pi_1){ 225 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 226 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 227 } 228 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object3){ 207 229 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */); 208 230 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */); … … 213 235 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 214 236 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 237 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object3) /* ?{} */); 238 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 239 } 240 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object4, signed int *__f9__Pi_1){ 241 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */); 242 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */); 243 ((void)((*___dst__R4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */); 244 ((void)((*___dst__R4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */); 245 ((void)((*___dst__R4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */); 246 ((void)((*___dst__R4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */); 247 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 248 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 249 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object4) /* ?{} */); 215 250 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */); 216 251 } … … 232 267 __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1; 233 268 } 234 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object 1))[];269 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object5))[]; 235 270 __attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{ 236 271 __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[]; 237 272 } 238 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 2);239 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 3){240 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object 4);273 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object6); 274 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object7){ 275 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object8); 241 276 } 242 277 signed int __vtr__Fi___1(){ … … 268 303 signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1); 269 304 signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1); 270 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 5)(__attribute__ ((unused,unused)) signed int __anonymous_object6[((unsigned int )5)]));305 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object9)(__attribute__ ((unused,unused)) signed int __anonymous_object10[((unsigned int )5)])); 271 306 signed int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 272 307 signed int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 273 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 7)(__attribute__ ((unused)) signed int (*__anonymous_object8)(__attribute__ ((unused,unused)) signed int __anonymous_object9)));308 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object11)(__attribute__ ((unused)) signed int (*__anonymous_object12)(__attribute__ ((unused,unused)) signed int __anonymous_object13))); 274 309 signed int __ad__Fi___1(){ 275 310 __attribute__ ((unused)) signed int ___retval_ad__i_1; … … 300 335 struct __anonymous4 ___ret__13s__anonymous4_2; 301 336 ((void)((*___dst__R13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2)); 302 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), ___src__13s__anonymous4_2));303 return ((struct __anonymous4 )___ret__13s__anonymous4_2);337 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), (*___dst__R13s__anonymous4_2))); 338 return ___ret__13s__anonymous4_2; 304 339 } 305 340 inline void ___constructor__F_R13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__R13s__anonymous4_2, signed int __i__i_2){ … … 313 348 } 314 349 inline void ___constructor__F_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 315 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) );350 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) /* ?{} */); 316 351 } 317 352 inline void ___destructor__F_R13e__anonymous5_intrinsic___2(__attribute__ ((unused)) enum __anonymous5 *___dst__R13e__anonymous5_2){ … … 319 354 inline enum __anonymous5 ___operator_assign__F13e__anonymous5_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 320 355 enum __anonymous5 ___ret__13e__anonymous5_2; 321 ((void)(___ret__13e__anonymous5_2=((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)) /* ?{} */); 322 return ((enum __anonymous5 )___ret__13e__anonymous5_2); 356 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)); 357 ((void)(___ret__13e__anonymous5_2=(*___dst__R13e__anonymous5_2)) /* ?{} */); 358 return ___ret__13e__anonymous5_2; 323 359 } 324 360 ((void)sizeof(enum __anonymous5 )); 325 361 } 326 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 0, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object11);327 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object1 2, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object13);328 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 4, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);329 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 16)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)());330 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 18)(__attribute__ ((unused)) signed int __anonymous_object19), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(__attribute__ ((unused)) signed int __anonymous_object21));331 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 2)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)());332 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 4)(__attribute__ ((unused)) signed int __anonymous_object25), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(__attribute__ ((unused)) signed int __anonymous_object27));362 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15); 363 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object16, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object17); 364 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object18, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object19); 365 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object21)()); 366 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(__attribute__ ((unused)) signed int __anonymous_object23), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25)); 367 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object27)()); 368 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object28)(__attribute__ ((unused)) signed int __anonymous_object29), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object30)(__attribute__ ((unused)) signed int __anonymous_object31)); 333 369 struct Vad { 334 __attribute__ ((unused)) signed int __anonymous_object 28;335 __attribute__ ((unused,unused)) signed int *__anonymous_object 29;336 __attribute__ ((unused,unused)) signed int __anonymous_object3 0[((unsigned int )10)];337 __attribute__ ((unused,unused)) signed int (*__anonymous_object3 1)();370 __attribute__ ((unused)) signed int __anonymous_object32; 371 __attribute__ ((unused,unused)) signed int *__anonymous_object33; 372 __attribute__ ((unused,unused)) signed int __anonymous_object34[((unsigned int )10)]; 373 __attribute__ ((unused,unused)) signed int (*__anonymous_object35)(); 338 374 }; 339 375 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); … … 341 377 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); 342 378 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1); 379 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object36); 380 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object37, signed int *__anonymous_object38); 381 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object39, signed int *__anonymous_object40, signed int __anonymous_object41[((unsigned int )10)]); 382 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object42, signed int *__anonymous_object43, signed int __anonymous_object44[((unsigned int )10)], signed int (*__anonymous_object45)()); 343 383 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 384 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ?{} */); 385 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */); 386 { 387 signed int _index0 = 0; 388 for (;(_index0<10);((void)(++_index0))) { 389 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index0])))) /* ?{} */); 390 } 391 392 } 393 394 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 344 395 } 345 396 static inline void ___constructor__F_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 397 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32) /* ?{} */); 398 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33) /* ?{} */); 399 { 400 signed int _index1 = 0; 401 for (;(_index1<10);((void)(++_index1))) { 402 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index1])))=___src__4sVad_1.__anonymous_object34[_index1]) /* ?{} */); 403 } 404 405 } 406 407 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35) /* ?{} */); 346 408 } 347 409 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 410 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ^?{} */); 411 { 412 signed int _index2 = (10-1); 413 for (;(_index2>=0);((void)(--_index2))) { 414 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index2])))) /* ^?{} */); 415 } 416 417 } 418 419 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ^?{} */); 420 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ^?{} */); 348 421 } 349 422 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 350 423 struct Vad ___ret__4sVad_1; 351 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), ___src__4sVad_1)); 352 return ((struct Vad )___ret__4sVad_1); 353 } 424 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32)); 425 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33)); 426 { 427 signed int _index3 = 0; 428 for (;(_index3<10);((void)(++_index3))) { 429 ((void)((*___dst__R4sVad_1).__anonymous_object34[_index3]=___src__4sVad_1.__anonymous_object34[_index3])); 430 } 431 432 } 433 434 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35)); 435 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), (*___dst__R4sVad_1))); 436 return ___ret__4sVad_1; 437 } 438 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object46){ 439 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object46) /* ?{} */); 440 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */); 441 { 442 signed int _index4 = 0; 443 for (;(_index4<10);((void)(++_index4))) { 444 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index4])))) /* ?{} */); 445 } 446 447 } 448 449 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 450 } 451 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object47, signed int *__anonymous_object48){ 452 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object47) /* ?{} */); 453 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object48) /* ?{} */); 454 { 455 signed int _index5 = 0; 456 for (;(_index5<10);((void)(++_index5))) { 457 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index5])))) /* ?{} */); 458 } 459 460 } 461 462 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 463 } 464 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object49, signed int *__anonymous_object50, signed int __anonymous_object51[((unsigned int )10)]){ 465 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object49) /* ?{} */); 466 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object50) /* ?{} */); 467 { 468 signed int _index6 = 0; 469 for (;(_index6<10);((void)(++_index6))) { 470 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index6])))=__anonymous_object51[_index6]) /* ?{} */); 471 } 472 473 } 474 475 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 476 } 477 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object52, signed int *__anonymous_object53, signed int __anonymous_object54[((unsigned int )10)], signed int (*__anonymous_object55)()){ 478 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object52) /* ?{} */); 479 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object53) /* ?{} */); 480 { 481 signed int _index7 = 0; 482 for (;(_index7<10);((void)(++_index7))) { 483 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index7])))=__anonymous_object54[_index7]) /* ?{} */); 484 } 485 486 } 487 488 ((void)((*___dst__R4sVad_1).__anonymous_object35=__anonymous_object55) /* ?{} */); 489 } -
src/tests/.expect/32/declarationSpecifier.txt
rb96ec83 r6840e7c 20 20 static inline void ___destructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1); 21 21 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 22 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1); 22 23 static inline void ___constructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1){ 23 24 ((void)((*___dst__R13s__anonymous0_1).__i__i_1) /* ?{} */); … … 32 33 struct __anonymous0 ___ret__13s__anonymous0_1; 33 34 ((void)((*___dst__R13s__anonymous0_1).__i__i_1=___src__13s__anonymous0_1.__i__i_1)); 34 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1));35 return ((struct __anonymous0 )___ret__13s__anonymous0_1);35 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1))); 36 return ___ret__13s__anonymous0_1; 36 37 } 37 38 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1){ … … 46 47 static inline void ___destructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1); 47 48 static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_R13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1); 49 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1); 48 50 static inline void ___constructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1){ 49 51 ((void)((*___dst__R13s__anonymous1_1).__i__i_1) /* ?{} */); … … 58 60 struct __anonymous1 ___ret__13s__anonymous1_1; 59 61 ((void)((*___dst__R13s__anonymous1_1).__i__i_1=___src__13s__anonymous1_1.__i__i_1)); 60 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), ___src__13s__anonymous1_1));61 return ((struct __anonymous1 )___ret__13s__anonymous1_1);62 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), (*___dst__R13s__anonymous1_1))); 63 return ___ret__13s__anonymous1_1; 62 64 } 63 65 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1){ … … 72 74 static inline void ___destructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1); 73 75 static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_R13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1); 76 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1); 74 77 static inline void ___constructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1){ 75 78 ((void)((*___dst__R13s__anonymous2_1).__i__i_1) /* ?{} */); … … 84 87 struct __anonymous2 ___ret__13s__anonymous2_1; 85 88 ((void)((*___dst__R13s__anonymous2_1).__i__i_1=___src__13s__anonymous2_1.__i__i_1)); 86 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), ___src__13s__anonymous2_1));87 return ((struct __anonymous2 )___ret__13s__anonymous2_1);89 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__R13s__anonymous2_1))); 90 return ___ret__13s__anonymous2_1; 88 91 } 89 92 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1){ … … 98 101 static inline void ___destructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1); 99 102 static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_R13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1); 103 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1); 100 104 static inline void ___constructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1){ 101 105 ((void)((*___dst__R13s__anonymous3_1).__i__i_1) /* ?{} */); … … 110 114 struct __anonymous3 ___ret__13s__anonymous3_1; 111 115 ((void)((*___dst__R13s__anonymous3_1).__i__i_1=___src__13s__anonymous3_1.__i__i_1)); 112 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), ___src__13s__anonymous3_1));113 return ((struct __anonymous3 )___ret__13s__anonymous3_1);116 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), (*___dst__R13s__anonymous3_1))); 117 return ___ret__13s__anonymous3_1; 114 118 } 115 119 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1){ … … 124 128 static inline void ___destructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1); 125 129 static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_R13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1); 130 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1); 126 131 static inline void ___constructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1){ 127 132 ((void)((*___dst__R13s__anonymous4_1).__i__i_1) /* ?{} */); … … 136 141 struct __anonymous4 ___ret__13s__anonymous4_1; 137 142 ((void)((*___dst__R13s__anonymous4_1).__i__i_1=___src__13s__anonymous4_1.__i__i_1)); 138 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), ___src__13s__anonymous4_1));139 return ((struct __anonymous4 )___ret__13s__anonymous4_1);143 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), (*___dst__R13s__anonymous4_1))); 144 return ___ret__13s__anonymous4_1; 140 145 } 141 146 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1){ … … 150 155 static inline void ___destructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1); 151 156 static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_R13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1); 157 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1); 152 158 static inline void ___constructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1){ 153 159 ((void)((*___dst__R13s__anonymous5_1).__i__i_1) /* ?{} */); … … 162 168 struct __anonymous5 ___ret__13s__anonymous5_1; 163 169 ((void)((*___dst__R13s__anonymous5_1).__i__i_1=___src__13s__anonymous5_1.__i__i_1)); 164 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), ___src__13s__anonymous5_1));165 return ((struct __anonymous5 )___ret__13s__anonymous5_1);170 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), (*___dst__R13s__anonymous5_1))); 171 return ___ret__13s__anonymous5_1; 166 172 } 167 173 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1){ … … 176 182 static inline void ___destructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1); 177 183 static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_R13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1); 184 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1); 178 185 static inline void ___constructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1){ 179 186 ((void)((*___dst__R13s__anonymous6_1).__i__i_1) /* ?{} */); … … 188 195 struct __anonymous6 ___ret__13s__anonymous6_1; 189 196 ((void)((*___dst__R13s__anonymous6_1).__i__i_1=___src__13s__anonymous6_1.__i__i_1)); 190 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), ___src__13s__anonymous6_1));191 return ((struct __anonymous6 )___ret__13s__anonymous6_1);197 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), (*___dst__R13s__anonymous6_1))); 198 return ___ret__13s__anonymous6_1; 192 199 } 193 200 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1){ … … 202 209 static inline void ___destructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1); 203 210 static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_R13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1); 211 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1); 204 212 static inline void ___constructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1){ 205 213 ((void)((*___dst__R13s__anonymous7_1).__i__i_1) /* ?{} */); … … 214 222 struct __anonymous7 ___ret__13s__anonymous7_1; 215 223 ((void)((*___dst__R13s__anonymous7_1).__i__i_1=___src__13s__anonymous7_1.__i__i_1)); 216 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), ___src__13s__anonymous7_1));217 return ((struct __anonymous7 )___ret__13s__anonymous7_1);224 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), (*___dst__R13s__anonymous7_1))); 225 return ___ret__13s__anonymous7_1; 218 226 } 219 227 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1){ … … 236 244 static inline void ___destructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1); 237 245 static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_R13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1); 246 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1); 238 247 static inline void ___constructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1){ 239 248 ((void)((*___dst__R13s__anonymous8_1).__i__s_1) /* ?{} */); … … 248 257 struct __anonymous8 ___ret__13s__anonymous8_1; 249 258 ((void)((*___dst__R13s__anonymous8_1).__i__s_1=___src__13s__anonymous8_1.__i__s_1)); 250 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), ___src__13s__anonymous8_1));251 return ((struct __anonymous8 )___ret__13s__anonymous8_1);259 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), (*___dst__R13s__anonymous8_1))); 260 return ___ret__13s__anonymous8_1; 252 261 } 253 262 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1){ … … 262 271 static inline void ___destructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1); 263 272 static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_R13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1); 273 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1); 264 274 static inline void ___constructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1){ 265 275 ((void)((*___dst__R13s__anonymous9_1).__i__s_1) /* ?{} */); … … 274 284 struct __anonymous9 ___ret__13s__anonymous9_1; 275 285 ((void)((*___dst__R13s__anonymous9_1).__i__s_1=___src__13s__anonymous9_1.__i__s_1)); 276 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), ___src__13s__anonymous9_1));277 return ((struct __anonymous9 )___ret__13s__anonymous9_1);286 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), (*___dst__R13s__anonymous9_1))); 287 return ___ret__13s__anonymous9_1; 278 288 } 279 289 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1){ … … 288 298 static inline void ___destructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1); 289 299 static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_R14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1); 300 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1); 290 301 static inline void ___constructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1){ 291 302 ((void)((*___dst__R14s__anonymous10_1).__i__s_1) /* ?{} */); … … 300 311 struct __anonymous10 ___ret__14s__anonymous10_1; 301 312 ((void)((*___dst__R14s__anonymous10_1).__i__s_1=___src__14s__anonymous10_1.__i__s_1)); 302 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), ___src__14s__anonymous10_1));303 return ((struct __anonymous10 )___ret__14s__anonymous10_1);313 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), (*___dst__R14s__anonymous10_1))); 314 return ___ret__14s__anonymous10_1; 304 315 } 305 316 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1){ … … 314 325 static inline void ___destructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1); 315 326 static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_R14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1); 327 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1); 316 328 static inline void ___constructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1){ 317 329 ((void)((*___dst__R14s__anonymous11_1).__i__s_1) /* ?{} */); … … 326 338 struct __anonymous11 ___ret__14s__anonymous11_1; 327 339 ((void)((*___dst__R14s__anonymous11_1).__i__s_1=___src__14s__anonymous11_1.__i__s_1)); 328 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), ___src__14s__anonymous11_1));329 return ((struct __anonymous11 )___ret__14s__anonymous11_1);340 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), (*___dst__R14s__anonymous11_1))); 341 return ___ret__14s__anonymous11_1; 330 342 } 331 343 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1){ … … 340 352 static inline void ___destructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1); 341 353 static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_R14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1); 354 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1); 342 355 static inline void ___constructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1){ 343 356 ((void)((*___dst__R14s__anonymous12_1).__i__s_1) /* ?{} */); … … 352 365 struct __anonymous12 ___ret__14s__anonymous12_1; 353 366 ((void)((*___dst__R14s__anonymous12_1).__i__s_1=___src__14s__anonymous12_1.__i__s_1)); 354 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), ___src__14s__anonymous12_1));355 return ((struct __anonymous12 )___ret__14s__anonymous12_1);367 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), (*___dst__R14s__anonymous12_1))); 368 return ___ret__14s__anonymous12_1; 356 369 } 357 370 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1){ … … 366 379 static inline void ___destructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1); 367 380 static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_R14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1); 381 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1); 368 382 static inline void ___constructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1){ 369 383 ((void)((*___dst__R14s__anonymous13_1).__i__s_1) /* ?{} */); … … 378 392 struct __anonymous13 ___ret__14s__anonymous13_1; 379 393 ((void)((*___dst__R14s__anonymous13_1).__i__s_1=___src__14s__anonymous13_1.__i__s_1)); 380 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), ___src__14s__anonymous13_1));381 return ((struct __anonymous13 )___ret__14s__anonymous13_1);394 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), (*___dst__R14s__anonymous13_1))); 395 return ___ret__14s__anonymous13_1; 382 396 } 383 397 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1){ … … 392 406 static inline void ___destructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1); 393 407 static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_R14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1); 408 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1); 394 409 static inline void ___constructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1){ 395 410 ((void)((*___dst__R14s__anonymous14_1).__i__s_1) /* ?{} */); … … 404 419 struct __anonymous14 ___ret__14s__anonymous14_1; 405 420 ((void)((*___dst__R14s__anonymous14_1).__i__s_1=___src__14s__anonymous14_1.__i__s_1)); 406 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), ___src__14s__anonymous14_1));407 return ((struct __anonymous14 )___ret__14s__anonymous14_1);421 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), (*___dst__R14s__anonymous14_1))); 422 return ___ret__14s__anonymous14_1; 408 423 } 409 424 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1){ … … 418 433 static inline void ___destructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1); 419 434 static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_R14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1); 435 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1); 420 436 static inline void ___constructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1){ 421 437 ((void)((*___dst__R14s__anonymous15_1).__i__s_1) /* ?{} */); … … 430 446 struct __anonymous15 ___ret__14s__anonymous15_1; 431 447 ((void)((*___dst__R14s__anonymous15_1).__i__s_1=___src__14s__anonymous15_1.__i__s_1)); 432 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), ___src__14s__anonymous15_1));433 return ((struct __anonymous15 )___ret__14s__anonymous15_1);448 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), (*___dst__R14s__anonymous15_1))); 449 return ___ret__14s__anonymous15_1; 434 450 } 435 451 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1){ … … 460 476 static inline void ___destructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1); 461 477 static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_R14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1); 478 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1); 462 479 static inline void ___constructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1){ 463 480 ((void)((*___dst__R14s__anonymous16_1).__i__i_1) /* ?{} */); … … 472 489 struct __anonymous16 ___ret__14s__anonymous16_1; 473 490 ((void)((*___dst__R14s__anonymous16_1).__i__i_1=___src__14s__anonymous16_1.__i__i_1)); 474 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), ___src__14s__anonymous16_1));475 return ((struct __anonymous16 )___ret__14s__anonymous16_1);491 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), (*___dst__R14s__anonymous16_1))); 492 return ___ret__14s__anonymous16_1; 476 493 } 477 494 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1){ … … 486 503 static inline void ___destructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1); 487 504 static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_R14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1); 505 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1); 488 506 static inline void ___constructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1){ 489 507 ((void)((*___dst__R14s__anonymous17_1).__i__i_1) /* ?{} */); … … 498 516 struct __anonymous17 ___ret__14s__anonymous17_1; 499 517 ((void)((*___dst__R14s__anonymous17_1).__i__i_1=___src__14s__anonymous17_1.__i__i_1)); 500 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), ___src__14s__anonymous17_1));501 return ((struct __anonymous17 )___ret__14s__anonymous17_1);518 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), (*___dst__R14s__anonymous17_1))); 519 return ___ret__14s__anonymous17_1; 502 520 } 503 521 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1){ … … 512 530 static inline void ___destructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1); 513 531 static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_R14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1); 532 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1); 514 533 static inline void ___constructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1){ 515 534 ((void)((*___dst__R14s__anonymous18_1).__i__i_1) /* ?{} */); … … 524 543 struct __anonymous18 ___ret__14s__anonymous18_1; 525 544 ((void)((*___dst__R14s__anonymous18_1).__i__i_1=___src__14s__anonymous18_1.__i__i_1)); 526 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), ___src__14s__anonymous18_1));527 return ((struct __anonymous18 )___ret__14s__anonymous18_1);545 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), (*___dst__R14s__anonymous18_1))); 546 return ___ret__14s__anonymous18_1; 528 547 } 529 548 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1){ … … 538 557 static inline void ___destructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1); 539 558 static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_R14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1); 559 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1); 540 560 static inline void ___constructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1){ 541 561 ((void)((*___dst__R14s__anonymous19_1).__i__i_1) /* ?{} */); … … 550 570 struct __anonymous19 ___ret__14s__anonymous19_1; 551 571 ((void)((*___dst__R14s__anonymous19_1).__i__i_1=___src__14s__anonymous19_1.__i__i_1)); 552 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), ___src__14s__anonymous19_1));553 return ((struct __anonymous19 )___ret__14s__anonymous19_1);572 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), (*___dst__R14s__anonymous19_1))); 573 return ___ret__14s__anonymous19_1; 554 574 } 555 575 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1){ … … 564 584 static inline void ___destructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1); 565 585 static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_R14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1); 586 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1); 566 587 static inline void ___constructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1){ 567 588 ((void)((*___dst__R14s__anonymous20_1).__i__i_1) /* ?{} */); … … 576 597 struct __anonymous20 ___ret__14s__anonymous20_1; 577 598 ((void)((*___dst__R14s__anonymous20_1).__i__i_1=___src__14s__anonymous20_1.__i__i_1)); 578 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), ___src__14s__anonymous20_1));579 return ((struct __anonymous20 )___ret__14s__anonymous20_1);599 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), (*___dst__R14s__anonymous20_1))); 600 return ___ret__14s__anonymous20_1; 580 601 } 581 602 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1){ … … 590 611 static inline void ___destructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1); 591 612 static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_R14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1); 613 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1); 592 614 static inline void ___constructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1){ 593 615 ((void)((*___dst__R14s__anonymous21_1).__i__i_1) /* ?{} */); … … 602 624 struct __anonymous21 ___ret__14s__anonymous21_1; 603 625 ((void)((*___dst__R14s__anonymous21_1).__i__i_1=___src__14s__anonymous21_1.__i__i_1)); 604 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), ___src__14s__anonymous21_1));605 return ((struct __anonymous21 )___ret__14s__anonymous21_1);626 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), (*___dst__R14s__anonymous21_1))); 627 return ___ret__14s__anonymous21_1; 606 628 } 607 629 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1){ … … 616 638 static inline void ___destructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1); 617 639 static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_R14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1); 640 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1); 618 641 static inline void ___constructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1){ 619 642 ((void)((*___dst__R14s__anonymous22_1).__i__i_1) /* ?{} */); … … 628 651 struct __anonymous22 ___ret__14s__anonymous22_1; 629 652 ((void)((*___dst__R14s__anonymous22_1).__i__i_1=___src__14s__anonymous22_1.__i__i_1)); 630 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), ___src__14s__anonymous22_1));631 return ((struct __anonymous22 )___ret__14s__anonymous22_1);653 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), (*___dst__R14s__anonymous22_1))); 654 return ___ret__14s__anonymous22_1; 632 655 } 633 656 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1){ … … 642 665 static inline void ___destructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1); 643 666 static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_R14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1); 667 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1); 644 668 static inline void ___constructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1){ 645 669 ((void)((*___dst__R14s__anonymous23_1).__i__i_1) /* ?{} */); … … 654 678 struct __anonymous23 ___ret__14s__anonymous23_1; 655 679 ((void)((*___dst__R14s__anonymous23_1).__i__i_1=___src__14s__anonymous23_1.__i__i_1)); 656 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), ___src__14s__anonymous23_1));657 return ((struct __anonymous23 )___ret__14s__anonymous23_1);680 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), (*___dst__R14s__anonymous23_1))); 681 return ___ret__14s__anonymous23_1; 658 682 } 659 683 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1){ … … 672 696 __attribute__ ((unused)) signed int ___retval_main__i_1; 673 697 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 674 return ((signed int )___retval_main__i_1);698 return ___retval_main__i_1; 675 699 ((void)(___retval_main__i_1=0) /* ?{} */); 676 return ((signed int )___retval_main__i_1);700 return ___retval_main__i_1; 677 701 } 678 702 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 689 713 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 690 714 ((void)(_tmp_cp_ret0) /* ^?{} */); 691 return ((signed int )___retval_main__i_1);692 } 715 return ___retval_main__i_1; 716 } -
src/tests/.expect/32/extension.txt
rb96ec83 r6840e7c 17 17 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 18 18 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 19 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1); 20 static inline void ___constructor__F_R2sSii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1); 21 static inline void ___constructor__F_R2sSiii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1, signed int __c__i_1); 19 22 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 20 23 ((void)((*___dst__R2sS_1).__a__i_1) /* ?{} */); … … 37 40 ((void)((*___dst__R2sS_1).__b__i_1=___src__2sS_1.__b__i_1)); 38 41 ((void)((*___dst__R2sS_1).__c__i_1=___src__2sS_1.__c__i_1)); 39 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));40 return ((struct S )___ret__2sS_1);42 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1))); 43 return ___ret__2sS_1; 41 44 } 42 45 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1){ … … 60 63 __extension__ signed int __c__i_1; 61 64 }; 65 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1); 66 static inline void ___constructor__F_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1); 67 static inline void ___destructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1); 68 static inline union U ___operator_assign__F2uU_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1); 69 static inline void ___constructor__F_R2uUi_autogen___1(union U *___dst__R2uU_1, signed int __a__i_1); 62 70 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1){ 63 71 } … … 70 78 union U ___ret__2uU_1; 71 79 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&___src__2uU_1)), sizeof(union U ))); 72 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), ___src__2uU_1));73 return ((union U )___ret__2uU_1);74 } 75 static inline void ___constructor__F_R2uUi_autogen___1( __attribute__ ((unused)) union U *___dst__R2uU_1, signed int __src__i_1){76 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__ src__i_1)), sizeof(signed int )));80 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), (*___dst__R2uU_1))); 81 return ___ret__2uU_1; 82 } 83 static inline void ___constructor__F_R2uUi_autogen___1(union U *___dst__R2uU_1, signed int __a__i_1){ 84 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__a__i_1)), sizeof(signed int ))); 77 85 } 78 86 __extension__ enum E { … … 94 102 __extension__ signed int *__z__Pi_2; 95 103 }; 96 signed int __i__i_2 = ((signed int )(__extension__ __a__i_1+__extension__ 3)); 104 inline void ___constructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 105 ((void)((*___dst__R2sS_2).__a__i_2) /* ?{} */); 106 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 107 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 108 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 109 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 110 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 111 } 112 inline void ___constructor__F_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 113 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2) /* ?{} */); 114 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2) /* ?{} */); 115 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2) /* ?{} */); 116 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2) /* ?{} */); 117 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2) /* ?{} */); 118 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2) /* ?{} */); 119 } 120 inline void ___destructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 121 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ^?{} */); 122 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ^?{} */); 123 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ^?{} */); 124 ((void)((*___dst__R2sS_2).__c__i_2) /* ^?{} */); 125 ((void)((*___dst__R2sS_2).__b__i_2) /* ^?{} */); 126 ((void)((*___dst__R2sS_2).__a__i_2) /* ^?{} */); 127 } 128 inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 129 struct S ___ret__2sS_2; 130 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2)); 131 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 132 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 133 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2)); 134 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2)); 135 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2)); 136 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2))); 137 return ___ret__2sS_2; 138 } 139 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ 140 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 141 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 142 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 143 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 144 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 145 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 146 } 147 inline void ___constructor__F_R2sSii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2){ 148 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 149 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 150 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 151 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 152 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 153 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 154 } 155 inline void ___constructor__F_R2sSiii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2){ 156 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 157 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 158 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 159 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 160 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 161 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 162 } 163 inline void ___constructor__F_R2sSiiiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2){ 164 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 165 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 166 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 167 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 168 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 169 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 170 } 171 inline void ___constructor__F_R2sSiiiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2){ 172 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 173 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 174 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 175 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 176 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 177 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 178 } 179 inline void ___constructor__F_R2sSiiiPiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2, signed int *__z__Pi_2){ 180 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 181 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 182 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 183 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 184 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 185 ((void)((*___dst__R2sS_2).__z__Pi_2=__z__Pi_2) /* ?{} */); 186 } 187 signed int __i__i_2 = (__extension__ __a__i_1+__extension__ 3); 97 188 ((void)__extension__ 3); 98 189 ((void)__extension__ __a__i_1); -
src/tests/.expect/32/gccExtensions.txt
rb96ec83 r6840e7c 63 63 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 64 64 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), ___src__2sS_2));66 return ((struct S )___ret__2sS_2);65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2))); 66 return ___ret__2sS_2; 67 67 } 68 68 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ … … 81 81 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 82 82 } 83 signed int __i__i_2 = ((signed int )__extension__ 3);83 signed int __i__i_2 = __extension__ 3; 84 84 __extension__ signed int __a__i_2; 85 85 __extension__ signed int __b__i_2; … … 113 113 struct s2 ___ret__3ss2_2; 114 114 ((void)((*___dst__R3ss2_2).__i__i_2=___src__3ss2_2.__i__i_2)); 115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), ___src__3ss2_2));116 return ((struct s2 )___ret__3ss2_2);115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), (*___dst__R3ss2_2))); 116 return ___ret__3ss2_2; 117 117 } 118 118 inline void ___constructor__F_R3ss2i_autogen___2(struct s2 *___dst__R3ss2_2, signed int __i__i_2){ … … 134 134 struct s3 ___ret__3ss3_2; 135 135 ((void)((*___dst__R3ss3_2).__i__i_2=___src__3ss3_2.__i__i_2)); 136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), ___src__3ss3_2));137 return ((struct s3 )___ret__3ss3_2);136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), (*___dst__R3ss3_2))); 137 return ___ret__3ss3_2; 138 138 } 139 139 inline void ___constructor__F_R3ss3i_autogen___2(struct s3 *___dst__R3ss3_2, signed int __i__i_2){ … … 157 157 struct s4 ___ret__3ss4_2; 158 158 ((void)((*___dst__R3ss4_2).__i__i_2=___src__3ss4_2.__i__i_2)); 159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), ___src__3ss4_2));160 return ((struct s4 )___ret__3ss4_2);159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), (*___dst__R3ss4_2))); 160 return ___ret__3ss4_2; 161 161 } 162 162 inline void ___constructor__F_R3ss4i_autogen___2(struct s4 *___dst__R3ss4_2, signed int __i__i_2){ … … 169 169 signed int __m3__A0A0i_2[((unsigned int )10)][((unsigned int )10)]; 170 170 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 171 return ((signed int )___retval_main__i_1);171 return ___retval_main__i_1; 172 172 ((void)(___retval_main__i_1=0) /* ?{} */); 173 return ((signed int )___retval_main__i_1);173 return ___retval_main__i_1; 174 174 } 175 175 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 186 186 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 187 187 ((void)(_tmp_cp_ret0) /* ^?{} */); 188 return ((signed int )___retval_main__i_1);188 return ___retval_main__i_1; 189 189 } -
src/tests/.expect/32/literals.txt
rb96ec83 r6840e7c 64 64 static inline void ___destructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1); 65 65 static inline struct _Istream_cstrUC ___operator_assign__F16s_Istream_cstrUC_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, struct _Istream_cstrUC ___src__16s_Istream_cstrUC_1); 66 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1); 66 67 static inline void ___constructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1){ 67 68 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1) /* ?{} */); … … 76 77 struct _Istream_cstrUC ___ret__16s_Istream_cstrUC_1; 77 78 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1=___src__16s_Istream_cstrUC_1.__s__Pc_1)); 78 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), ___src__16s_Istream_cstrUC_1));79 return ((struct _Istream_cstrUC )___ret__16s_Istream_cstrUC_1);79 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), (*___dst__R16s_Istream_cstrUC_1))); 80 return ___ret__16s_Istream_cstrUC_1; 80 81 } 81 82 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1){ … … 92 93 static inline void ___destructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1); 93 94 static inline struct _Istream_cstrC ___operator_assign__F15s_Istream_cstrC_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, struct _Istream_cstrC ___src__15s_Istream_cstrC_1); 95 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1); 96 static inline void ___constructor__F_R15s_Istream_cstrCPci_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1, signed int __size__i_1); 94 97 static inline void ___constructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1){ 95 98 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1) /* ?{} */); … … 108 111 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1=___src__15s_Istream_cstrC_1.__s__Pc_1)); 109 112 ((void)((*___dst__R15s_Istream_cstrC_1).__size__i_1=___src__15s_Istream_cstrC_1.__size__i_1)); 110 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), ___src__15s_Istream_cstrC_1));111 return ((struct _Istream_cstrC )___ret__15s_Istream_cstrC_1);113 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), (*___dst__R15s_Istream_cstrC_1))); 114 return ___ret__15s_Istream_cstrC_1; 112 115 } 113 116 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1){ … … 122 125 void *___operator_bitor__A0_1_0_0___fail__PFi_Pd0___eof__PFi_Pd0___open__PF_Pd0PCcPCc___close__PF_Pd0___read__PFPd0_Pd0PcUl___ungetc__PFPd0_Pd0c___fmt__PFi_Pd0PCc__FPd0_Pd015s_Istream_cstrC__1(__attribute__ ((unused)) signed int (*__fail__PFi_P7tistype__1)(void *__anonymous_object1284), __attribute__ ((unused)) signed int (*__eof__PFi_P7tistype__1)(void *__anonymous_object1285), __attribute__ ((unused)) void (*__open__PF_P7tistypePCcPCc__1)(void *__is__P7tistype_1, const char *__name__PCc_1, const char *__mode__PCc_1), __attribute__ ((unused)) void (*__close__PF_P7tistype__1)(void *__is__P7tistype_1), __attribute__ ((unused)) void *(*__read__PFP7tistype_P7tistypePcUl__1)(void *__anonymous_object1286, char *__anonymous_object1287, unsigned long int __anonymous_object1288), __attribute__ ((unused)) void *(*__ungetc__PFP7tistype_P7tistypec__1)(void *__anonymous_object1289, char __anonymous_object1290), __attribute__ ((unused)) signed int (*__fmt__PFi_P7tistypePCc__1)(void *__anonymous_object1291, const char *__fmt__PCc_1, ...), void *__anonymous_object1292, struct _Istream_cstrC __anonymous_object1293); 123 126 enum __anonymous0 { 124 __sepSize__C13e__anonymous0_1 = ((signed int )16),127 __sepSize__C13e__anonymous0_1 = 16, 125 128 }; 126 129 struct ofstream { … … 137 140 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1); 138 141 static inline struct ofstream ___operator_assign__F9sofstream_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1); 142 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1); 143 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1); 144 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1); 145 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1); 146 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1); 147 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]); 148 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]); 139 149 static inline void ___constructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 140 150 ((void)((*___dst__R9sofstream_1).__file__Pv_1) /* ?{} */); … … 144 154 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 145 155 { 146 signed int _index0 = ((signed int )0);156 signed int _index0 = 0; 147 157 for (;(_index0<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index0))) { 148 158 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index0])))) /* ?{} */); … … 150 160 151 161 } 152 { 153 signed int _index1 = ((signed int )0); 162 163 { 164 signed int _index1 = 0; 154 165 for (;(_index1<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index1))) { 155 166 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index1])))) /* ?{} */); … … 157 168 158 169 } 170 159 171 } 160 172 static inline void ___constructor__F_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1){ … … 165 177 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1) /* ?{} */); 166 178 { 167 signed int _index2 = ((signed int )0);179 signed int _index2 = 0; 168 180 for (;(_index2<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index2))) { 169 181 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index2])))=___src__9sofstream_1.__separator__A0c_1[_index2]) /* ?{} */); … … 171 183 172 184 } 173 { 174 signed int _index3 = ((signed int )0); 185 186 { 187 signed int _index3 = 0; 175 188 for (;(_index3<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index3))) { 176 189 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index3])))=___src__9sofstream_1.__tupleSeparator__A0c_1[_index3]) /* ?{} */); … … 178 191 179 192 } 193 180 194 } 181 195 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 182 196 { 183 signed int _index4 = (( signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1));197 signed int _index4 = (((signed int )__sepSize__C13e__anonymous0_1)-1); 184 198 for (;(_index4>=0);((void)(--_index4))) { 185 199 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index4])))) /* ^?{} */); … … 187 201 188 202 } 189 { 190 signed int _index5 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1)); 203 204 { 205 signed int _index5 = (((signed int )__sepSize__C13e__anonymous0_1)-1); 191 206 for (;(_index5>=0);((void)(--_index5))) { 192 207 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index5])))) /* ^?{} */); … … 194 209 195 210 } 211 196 212 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ^?{} */); 197 213 ((void)((*___dst__R9sofstream_1).__sawNL__b_1) /* ^?{} */); … … 208 224 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1)); 209 225 { 210 signed int _index6 = ((signed int )0);226 signed int _index6 = 0; 211 227 for (;(_index6<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index6))) { 212 228 ((void)((*___dst__R9sofstream_1).__separator__A0c_1[_index6]=___src__9sofstream_1.__separator__A0c_1[_index6])); … … 216 232 217 233 { 218 signed int _index7 = ((signed int )0);234 signed int _index7 = 0; 219 235 for (;(_index7<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index7))) { 220 236 ((void)((*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index7]=___src__9sofstream_1.__tupleSeparator__A0c_1[_index7])); … … 223 239 } 224 240 225 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), ___src__9sofstream_1));226 return ((struct ofstream )___ret__9sofstream_1);241 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), (*___dst__R9sofstream_1))); 242 return ___ret__9sofstream_1; 227 243 } 228 244 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1){ … … 233 249 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 234 250 { 235 signed int _index8 = ((signed int )0);251 signed int _index8 = 0; 236 252 for (;(_index8<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index8))) { 237 253 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index8])))) /* ?{} */); … … 239 255 240 256 } 241 { 242 signed int _index9 = ((signed int )0); 257 258 { 259 signed int _index9 = 0; 243 260 for (;(_index9<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index9))) { 244 261 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index9])))) /* ?{} */); … … 246 263 247 264 } 265 248 266 } 249 267 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1){ … … 254 272 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 255 273 { 256 signed int _index10 = ((signed int )0);274 signed int _index10 = 0; 257 275 for (;(_index10<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index10))) { 258 276 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index10])))) /* ?{} */); … … 260 278 261 279 } 262 { 263 signed int _index11 = ((signed int )0); 280 281 { 282 signed int _index11 = 0; 264 283 for (;(_index11<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index11))) { 265 284 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index11])))) /* ?{} */); … … 267 286 268 287 } 288 269 289 } 270 290 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1){ … … 275 295 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 276 296 { 277 signed int _index12 = ((signed int )0);297 signed int _index12 = 0; 278 298 for (;(_index12<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index12))) { 279 299 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index12])))) /* ?{} */); … … 281 301 282 302 } 283 { 284 signed int _index13 = ((signed int )0); 303 304 { 305 signed int _index13 = 0; 285 306 for (;(_index13<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index13))) { 286 307 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index13])))) /* ?{} */); … … 288 309 289 310 } 311 290 312 } 291 313 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1){ … … 296 318 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 297 319 { 298 signed int _index14 = ((signed int )0);320 signed int _index14 = 0; 299 321 for (;(_index14<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index14))) { 300 322 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index14])))) /* ?{} */); … … 302 324 303 325 } 304 { 305 signed int _index15 = ((signed int )0); 326 327 { 328 signed int _index15 = 0; 306 329 for (;(_index15<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index15))) { 307 330 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index15])))) /* ?{} */); … … 309 332 310 333 } 334 311 335 } 312 336 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1){ … … 317 341 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 318 342 { 319 signed int _index16 = ((signed int )0);343 signed int _index16 = 0; 320 344 for (;(_index16<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index16))) { 321 345 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index16])))) /* ?{} */); … … 323 347 324 348 } 325 { 326 signed int _index17 = ((signed int )0); 349 350 { 351 signed int _index17 = 0; 327 352 for (;(_index17<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index17))) { 328 353 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index17])))) /* ?{} */); … … 330 355 331 356 } 357 332 358 } 333 359 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]){ … … 338 364 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 339 365 { 340 signed int _index18 = ((signed int )0);366 signed int _index18 = 0; 341 367 for (;(_index18<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index18))) { 342 368 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index18])))=__separator__A0c_1[_index18]) /* ?{} */); … … 344 370 345 371 } 346 { 347 signed int _index19 = ((signed int )0); 372 373 { 374 signed int _index19 = 0; 348 375 for (;(_index19<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index19))) { 349 376 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index19])))) /* ?{} */); … … 351 378 352 379 } 380 353 381 } 354 382 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]){ … … 359 387 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 360 388 { 361 signed int _index20 = ((signed int )0);389 signed int _index20 = 0; 362 390 for (;(_index20<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index20))) { 363 391 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index20])))=__separator__A0c_1[_index20]) /* ?{} */); … … 365 393 366 394 } 367 { 368 signed int _index21 = ((signed int )0); 395 396 { 397 signed int _index21 = 0; 369 398 for (;(_index21<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index21))) { 370 399 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index21])))=__tupleSeparator__A0c_1[_index21]) /* ?{} */); … … 372 401 373 402 } 403 374 404 } 375 405 _Bool __sepPrt__Fb_P9sofstream__1(struct ofstream *__anonymous_object1294); … … 404 434 static inline void ___destructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1); 405 435 static inline struct ifstream ___operator_assign__F9sifstream_R9sifstream9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1, struct ifstream ___src__9sifstream_1); 436 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1); 406 437 static inline void ___constructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1){ 407 438 ((void)((*___dst__R9sifstream_1).__file__Pv_1) /* ?{} */); … … 416 447 struct ifstream ___ret__9sifstream_1; 417 448 ((void)((*___dst__R9sifstream_1).__file__Pv_1=___src__9sifstream_1.__file__Pv_1)); 418 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), ___src__9sifstream_1));419 return ((struct ifstream )___ret__9sifstream_1);449 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), (*___dst__R9sifstream_1))); 450 return ___ret__9sifstream_1; 420 451 } 421 452 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1){ … … 708 739 ((void)0123456789.e-09L); 709 740 ((void)0123456789.e-09DL); 710 ((void)( -0123456789.e-09));711 ((void)( -0123456789.e-09f));712 ((void)( -0123456789.e-09l));713 ((void)( -0123456789.e-09F));714 ((void)( -0123456789.e-09L));715 ((void)( -0123456789.e-09DL));741 ((void)(+0123456789.e-09)); 742 ((void)(+0123456789.e-09f)); 743 ((void)(+0123456789.e-09l)); 744 ((void)(+0123456789.e-09F)); 745 ((void)(+0123456789.e-09L)); 746 ((void)(+0123456789.e-09DL)); 716 747 ((void)(-0123456789.e-09)); 717 748 ((void)(-0123456789.e-09f)); … … 852 883 ((void)0123456789.0123456789E-09L); 853 884 ((void)0123456789.0123456789E-09DL); 854 ((void)( -0123456789.0123456789E-09));855 ((void)( -0123456789.0123456789E-09f));856 ((void)( -0123456789.0123456789E-09l));857 ((void)( -0123456789.0123456789E-09F));858 ((void)( -0123456789.0123456789E-09L));859 ((void)( -0123456789.0123456789E-09DL));885 ((void)(+0123456789.0123456789E-09)); 886 ((void)(+0123456789.0123456789E-09f)); 887 ((void)(+0123456789.0123456789E-09l)); 888 ((void)(+0123456789.0123456789E-09F)); 889 ((void)(+0123456789.0123456789E-09L)); 890 ((void)(+0123456789.0123456789E-09DL)); 860 891 ((void)(-0123456789.0123456789E-09)); 861 892 ((void)(-0123456789.0123456789E-09f)); … … 899 930 ((void)0x0123456789.p-09F); 900 931 ((void)0x0123456789.p-09L); 901 ((void)( -0x0123456789.p-09));902 ((void)( -0x0123456789.p-09f));903 ((void)( -0x0123456789.p-09l));904 ((void)( -0x0123456789.p-09F));905 ((void)( -0x0123456789.p-09L));932 ((void)(+0x0123456789.p-09)); 933 ((void)(+0x0123456789.p-09f)); 934 ((void)(+0x0123456789.p-09l)); 935 ((void)(+0x0123456789.p-09F)); 936 ((void)(+0x0123456789.p-09L)); 906 937 ((void)(-0x0123456789.p-09)); 907 938 ((void)(-0x0123456789.p-09f)); … … 944 975 ((void)0x.0123456789P-09F); 945 976 ((void)0x.0123456789P-09L); 946 ((void)( -0x.0123456789P-09));947 ((void)( -0x.0123456789P-09f));948 ((void)( -0x.0123456789P-09l));949 ((void)( -0x.0123456789P-09F));950 ((void)( -0x.0123456789P-09L));977 ((void)(+0x.0123456789P-09)); 978 ((void)(+0x.0123456789P-09f)); 979 ((void)(+0x.0123456789P-09l)); 980 ((void)(+0x.0123456789P-09F)); 981 ((void)(+0x.0123456789P-09L)); 951 982 ((void)(-0x.0123456789P-09)); 952 983 ((void)(-0x.0123456789P-09f)); … … 989 1020 ((void)0X0123456789.0123456789P-09F); 990 1021 ((void)0X0123456789.0123456789P-09L); 1022 ((void)(+0X0123456789.0123456789P-09)); 1023 ((void)(+0X0123456789.0123456789P-09f)); 1024 ((void)(+0X0123456789.0123456789P-09l)); 1025 ((void)(+0X0123456789.0123456789P-09F)); 1026 ((void)(+0X0123456789.0123456789P-09L)); 991 1027 ((void)(-0X0123456789.0123456789P-09)); 992 1028 ((void)(-0X0123456789.0123456789P-09f)); … … 994 1030 ((void)(-0X0123456789.0123456789P-09F)); 995 1031 ((void)(-0X0123456789.0123456789P-09L)); 996 ((void)(-0X0123456789.0123456789P-09)); 997 ((void)(-0X0123456789.0123456789P-09f)); 998 ((void)(-0X0123456789.0123456789P-09l)); 999 ((void)(-0X0123456789.0123456789P-09F)); 1000 ((void)(-0X0123456789.0123456789P-09L)); 1032 ((void)((signed char )01234567)); 1033 ((void)((signed short int )01234567)); 1034 ((void)((signed int )01234567)); 1035 ((void)((signed long long int )01234567)); 1036 ((void)((__int128 )01234567)); 1037 ((void)((unsigned char )01234567u)); 1038 ((void)((signed short int )01234567u)); 1039 ((void)((unsigned int )01234567u)); 1040 ((void)((signed long long int )01234567u)); 1041 ((void)((__int128 )01234567u)); 1042 ((void)(+((signed int )((signed char )01234567)))); 1043 ((void)(+((signed int )((signed short int )01234567)))); 1044 ((void)(+((signed int )01234567))); 1045 ((void)(+((signed long long int )01234567))); 1046 ((void)(+((float )((__int128 )01234567)))); 1047 ((void)(+((signed int )((unsigned char )01234567u)))); 1048 ((void)(+((signed int )((signed short int )01234567u)))); 1049 ((void)(+((unsigned int )01234567u))); 1050 ((void)(+((signed long long int )01234567u))); 1051 ((void)(+((float )((__int128 )01234567u)))); 1052 ((void)(-((signed int )((signed char )01234567)))); 1053 ((void)(-((signed int )((signed short int )01234567)))); 1054 ((void)(-((signed int )01234567))); 1055 ((void)(-((signed long long int )01234567))); 1056 ((void)(-((float )((__int128 )01234567)))); 1057 ((void)(-((signed int )((unsigned char )01234567u)))); 1058 ((void)(-((signed int )((signed short int )01234567u)))); 1059 ((void)(-((unsigned int )01234567u))); 1060 ((void)(-((signed long long int )01234567u))); 1061 ((void)(-((float )((__int128 )01234567u)))); 1062 ((void)((signed char )1234567890)); 1063 ((void)((signed short int )1234567890)); 1064 ((void)((signed int )1234567890)); 1065 ((void)((signed long long int )1234567890)); 1066 ((void)((__int128 )1234567890)); 1067 ((void)((signed char )1234567890U)); 1068 ((void)((unsigned short int )1234567890U)); 1069 ((void)((signed int )1234567890U)); 1070 ((void)((unsigned long long int )1234567890u)); 1071 ((void)((unsigned __int128 )1234567890u)); 1072 ((void)(+((signed int )((signed char )1234567890)))); 1073 ((void)(+((signed int )((signed short int )1234567890)))); 1074 ((void)(+((signed int )1234567890))); 1075 ((void)(+((signed long long int )1234567890))); 1076 ((void)(+((float )((__int128 )1234567890)))); 1077 ((void)(+((signed int )((signed char )1234567890U)))); 1078 ((void)(+((signed int )((unsigned short int )1234567890U)))); 1079 ((void)(+((signed int )1234567890U))); 1080 ((void)(+((unsigned long long int )1234567890u))); 1081 ((void)(+((float )((unsigned __int128 )1234567890u)))); 1082 ((void)(-((signed int )((signed char )1234567890)))); 1083 ((void)(-((signed int )((signed short int )1234567890)))); 1084 ((void)(-((signed int )1234567890))); 1085 ((void)(-((signed long long int )1234567890))); 1086 ((void)(-((float )((__int128 )1234567890)))); 1087 ((void)(-((signed int )((signed char )1234567890U)))); 1088 ((void)(-((signed int )((unsigned short int )1234567890U)))); 1089 ((void)(-((signed int )1234567890U))); 1090 ((void)(-((unsigned long long int )1234567890u))); 1091 ((void)(-((float )((unsigned __int128 )1234567890u)))); 1092 ((void)((signed char )0x0123456789abcdef)); 1093 ((void)((signed short int )0x0123456789abcdef)); 1094 ((void)((signed int )0x0123456789abcdef)); 1095 ((void)((signed long long int )0x0123456789abcdef)); 1096 ((void)((signed char )0x0123456789abcdefu)); 1097 ((void)((unsigned short int )0x0123456789abcdefu)); 1098 ((void)((signed int )0x0123456789abcdefu)); 1099 ((void)((unsigned long long int )0x0123456789abcdefu)); 1100 ((void)(+((signed int )((signed char )0x0123456789abcdef)))); 1101 ((void)(+((signed int )((signed short int )0x0123456789abcdef)))); 1102 ((void)(+((signed int )0x0123456789abcdef))); 1103 ((void)(+((signed long long int )0x0123456789abcdef))); 1104 ((void)(+((signed int )((signed char )0x0123456789abcdefu)))); 1105 ((void)(+((signed int )((unsigned short int )0x0123456789abcdefu)))); 1106 ((void)(+((signed int )0x0123456789abcdefu))); 1107 ((void)(+((unsigned long long int )0x0123456789abcdefu))); 1108 ((void)(-((signed int )((signed char )0x0123456789abcdef)))); 1109 ((void)(-((signed int )((signed short int )0x0123456789abcdef)))); 1110 ((void)(-((signed int )0x0123456789abcdef))); 1111 ((void)(-((signed long long int )0x0123456789abcdef))); 1112 ((void)(-((signed int )((signed char )0x0123456789abcdefu)))); 1113 ((void)(-((signed int )((unsigned short int )0x0123456789abcdefu)))); 1114 ((void)(-((signed int )0x0123456789abcdefu))); 1115 ((void)(-((unsigned long long int )0x0123456789abcdefu))); 1116 ((void)((signed char )0x0123456789ABCDEF)); 1117 ((void)((signed short int )0x0123456789ABCDEF)); 1118 ((void)((signed int )0x0123456789ABCDEF)); 1119 ((void)((signed long long int )0x0123456789ABCDEF)); 1120 ((void)((signed char )0x0123456789ABCDEFu)); 1121 ((void)((unsigned short int )0x0123456789ABCDEFu)); 1122 ((void)((signed int )0x0123456789ABCDEFu)); 1123 ((void)((unsigned long long int )0x0123456789ABCDEFu)); 1124 ((void)(+((signed int )((signed char )0x0123456789ABCDEF)))); 1125 ((void)(+((signed int )((signed short int )0x0123456789ABCDEF)))); 1126 ((void)(+((signed int )0x0123456789ABCDEF))); 1127 ((void)(+((signed long long int )0x0123456789ABCDEF))); 1128 ((void)(+((signed int )((signed char )0x0123456789ABCDEFu)))); 1129 ((void)(+((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1130 ((void)(+((signed int )0x0123456789ABCDEFu))); 1131 ((void)(+((unsigned long long int )0x0123456789ABCDEFu))); 1132 ((void)(-((signed int )((signed char )0x0123456789ABCDEF)))); 1133 ((void)(-((signed int )((signed short int )0x0123456789ABCDEF)))); 1134 ((void)(-((signed int )0x0123456789ABCDEF))); 1135 ((void)(-((signed long long int )0x0123456789ABCDEF))); 1136 ((void)(-((signed int )((signed char )0x0123456789ABCDEFu)))); 1137 ((void)(-((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1138 ((void)(-((signed int )0x0123456789ABCDEFu))); 1139 ((void)(-((unsigned long long int )0x0123456789ABCDEFu))); 1140 ((void)((signed char )0X0123456789abcdef)); 1141 ((void)((signed short int )0X0123456789abcdef)); 1142 ((void)((signed int )0X0123456789abcdef)); 1143 ((void)((signed long long int )0X0123456789abcdef)); 1144 ((void)((signed char )0X0123456789abcdefu)); 1145 ((void)((unsigned short int )0X0123456789abcdefu)); 1146 ((void)((signed int )0X0123456789abcdefu)); 1147 ((void)((unsigned long long int )0X0123456789abcdefu)); 1148 ((void)(+((signed int )((signed char )0X0123456789abcdef)))); 1149 ((void)(+((signed int )((signed short int )0X0123456789abcdef)))); 1150 ((void)(+((signed int )0X0123456789abcdef))); 1151 ((void)(+((signed long long int )0X0123456789abcdef))); 1152 ((void)(+((signed int )((signed char )0X0123456789abcdefu)))); 1153 ((void)(+((signed int )((unsigned short int )0X0123456789abcdefu)))); 1154 ((void)(+((signed int )0X0123456789abcdefu))); 1155 ((void)(+((unsigned long long int )0X0123456789abcdefu))); 1156 ((void)(-((signed int )((signed char )0X0123456789abcdef)))); 1157 ((void)(-((signed int )((signed short int )0X0123456789abcdef)))); 1158 ((void)(-((signed int )0X0123456789abcdef))); 1159 ((void)(-((signed long long int )0X0123456789abcdef))); 1160 ((void)(-((signed int )((signed char )0X0123456789abcdefu)))); 1161 ((void)(-((signed int )((unsigned short int )0X0123456789abcdefu)))); 1162 ((void)(-((signed int )0X0123456789abcdefu))); 1163 ((void)(-((unsigned long long int )0X0123456789abcdefu))); 1164 ((void)((signed char )0X0123456789ABCDEF)); 1165 ((void)((signed short int )0X0123456789ABCDEF)); 1166 ((void)((signed int )0X0123456789ABCDEF)); 1167 ((void)((signed long long int )0X0123456789ABCDEF)); 1168 ((void)((signed char )0X0123456789ABCDEFu)); 1169 ((void)((unsigned short int )0X0123456789ABCDEFu)); 1170 ((void)((signed int )0X0123456789ABCDEFu)); 1171 ((void)((unsigned long long int )0X0123456789ABCDEFu)); 1172 ((void)(+((signed int )((signed char )0X0123456789ABCDEF)))); 1173 ((void)(+((signed int )((signed short int )0X0123456789ABCDEF)))); 1174 ((void)(+((signed int )0X0123456789ABCDEF))); 1175 ((void)(+((signed long long int )0X0123456789ABCDEF))); 1176 ((void)(+((signed int )((signed char )0X0123456789ABCDEFu)))); 1177 ((void)(+((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1178 ((void)(+((signed int )0X0123456789ABCDEFu))); 1179 ((void)(+((unsigned long long int )0X0123456789ABCDEFu))); 1180 ((void)(-((signed int )((signed char )0X0123456789ABCDEF)))); 1181 ((void)(-((signed int )((signed short int )0X0123456789ABCDEF)))); 1182 ((void)(-((signed int )0X0123456789ABCDEF))); 1183 ((void)(-((signed long long int )0X0123456789ABCDEF))); 1184 ((void)(-((signed int )((signed char )0X0123456789ABCDEFu)))); 1185 ((void)(-((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1186 ((void)(-((signed int )0X0123456789ABCDEFu))); 1187 ((void)(-((unsigned long long int )0X0123456789ABCDEFu))); 1188 ((void)((float )0123456789.)); 1189 ((void)((double )0123456789.)); 1190 ((void)((long double )0123456789.)); 1191 ((void)((long double )0123456789.)); 1192 ((void)(+((float )0123456789.))); 1193 ((void)(+((double )0123456789.))); 1194 ((void)(+((long double )0123456789.))); 1195 ((void)(+((long double )0123456789.))); 1196 ((void)(-((float )0123456789.))); 1197 ((void)(-((double )0123456789.))); 1198 ((void)(-((long double )0123456789.))); 1199 ((void)(-((long double )0123456789.))); 1200 ((void)((float )0123456789.e09)); 1201 ((void)((double )0123456789.e09)); 1202 ((void)((long double )0123456789.e09)); 1203 ((void)((long double )0123456789.e09)); 1204 ((void)(+((float )0123456789.e+09))); 1205 ((void)(+((double )0123456789.e+09))); 1206 ((void)(+((long double )0123456789.e+09))); 1207 ((void)(+((long double )0123456789.e+09))); 1208 ((void)(-((float )0123456789.e-09))); 1209 ((void)(-((double )0123456789.e-09))); 1210 ((void)(-((long double )0123456789.e-09))); 1211 ((void)(-((long double )0123456789.e-09))); 1212 ((void)((float ).0123456789e09)); 1213 ((void)((double ).0123456789e09)); 1214 ((void)((long double ).0123456789e09)); 1215 ((void)((long double ).0123456789e09)); 1216 ((void)(+((float ).0123456789E+09))); 1217 ((void)(+((double ).0123456789E+09))); 1218 ((void)(+((long double ).0123456789E+09))); 1219 ((void)(+((long double ).0123456789E+09))); 1220 ((void)(-((float ).0123456789E-09))); 1221 ((void)(-((double ).0123456789E-09))); 1222 ((void)(-((long double ).0123456789E-09))); 1223 ((void)(-((long double ).0123456789E-09))); 1224 ((void)((float )0123456789.0123456789)); 1225 ((void)((double )0123456789.0123456789)); 1226 ((void)((long double )0123456789.0123456789)); 1227 ((void)((long double )0123456789.0123456789)); 1228 ((void)(+((float )0123456789.0123456789E09))); 1229 ((void)(+((double )0123456789.0123456789E09))); 1230 ((void)(+((long double )0123456789.0123456789E09))); 1231 ((void)(+((long double )0123456789.0123456789E09))); 1232 ((void)(-((float )0123456789.0123456789E+09))); 1233 ((void)(-((double )0123456789.0123456789E+09))); 1234 ((void)(-((long double )0123456789.0123456789E+09))); 1235 ((void)(-((long double )0123456789.0123456789E+09))); 1236 ((void)((float )0123456789.0123456789E-09)); 1237 ((void)((double )0123456789.0123456789E-09)); 1238 ((void)((long double )0123456789.0123456789E-09)); 1239 ((void)((long double )0123456789.0123456789E-09)); 1240 ((void)((float )0x0123456789.p09)); 1241 ((void)((double )0x0123456789.p09)); 1242 ((void)((long double )0x0123456789.p09)); 1243 ((void)((long double )0x0123456789.p09)); 1244 ((void)(+((float )0x0123456789.p09))); 1245 ((void)(+((double )0x0123456789.p09))); 1246 ((void)(+((long double )0x0123456789.p09))); 1247 ((void)(+((long double )0x0123456789.p09))); 1248 ((void)(-((float )0x0123456789.p09))); 1249 ((void)(-((double )0x0123456789.p09))); 1250 ((void)(-((long double )0x0123456789.p09))); 1251 ((void)(-((long double )0x0123456789.p09))); 1252 ((void)((float )0x0123456789.p+09)); 1253 ((void)((double )0x0123456789.p+09)); 1254 ((void)((long double )0x0123456789.p+09)); 1255 ((void)((long double )0x0123456789.p+09)); 1256 ((void)(+((float )0x0123456789.p-09))); 1257 ((void)(+((double )0x0123456789.p-09))); 1258 ((void)(+((long double )0x0123456789.p-09))); 1259 ((void)(+((long double )0x0123456789.p-09))); 1260 ((void)(-((float )0x.0123456789p09))); 1261 ((void)(-((double )0x.0123456789p09))); 1262 ((void)(-((long double )0x.0123456789p09))); 1263 ((void)(-((long double )0x.0123456789p09))); 1001 1264 ((void)__f__F_c__1('a')); 1002 1265 ((void)__f__F_Sc__1(20)); … … 1111 1374 ((void)L"a" "b" "c"); 1112 1375 ((void)(___retval_main__i_1=0) /* ?{} */); 1113 return ((signed int )___retval_main__i_1);1376 return ___retval_main__i_1; 1114 1377 } 1115 1378 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } … … 1126 1389 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 1127 1390 ((void)(_tmp_cp_ret0) /* ^?{} */); 1128 return ((signed int )___retval_main__i_1);1129 } 1391 return ___retval_main__i_1; 1392 } -
src/tests/.expect/64/KRfunctions.txt
rb96ec83 r6840e7c 21 21 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 22 22 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 23 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1); 23 24 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 24 25 ((void)((*___dst__R2sS_1).__i__i_1) /* ?{} */); … … 33 34 struct S ___ret__2sS_1; 34 35 ((void)((*___dst__R2sS_1).__i__i_1=___src__2sS_1.__i__i_1)); 35 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));36 return ((struct S )___ret__2sS_1);36 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1))); 37 return ___ret__2sS_1; 37 38 } 38 39 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1){ … … 65 66 signed int *__x__FPi_ii__2(signed int __anonymous_object2, signed int __anonymous_object3); 66 67 ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */); 67 return ((signed int *(*)(signed int __x__i_1, signed int __y__i_1))___retval_f10__PFPi_ii__1);68 return ___retval_f10__PFPi_ii__1; 68 69 } 69 70 signed int (*__f11__FPA0i_iPiPi__1(signed int __a__i_1, signed int *__b__Pi_1, signed int *__c__Pi_1))[]{ -
src/tests/.expect/64/attributes.txt
rb96ec83 r6840e7c 23 23 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){ 24 24 struct __anonymous0 ___ret__13s__anonymous0_1; 25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1));26 return ((struct __anonymous0 )___ret__13s__anonymous0_1);25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1))); 26 return ___ret__13s__anonymous0_1; 27 27 } 28 28 __attribute__ ((unused)) struct Agn1; … … 41 41 static inline struct Agn2 ___operator_assign__F5sAgn2_R5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__R5sAgn2_1, struct Agn2 ___src__5sAgn2_1){ 42 42 struct Agn2 ___ret__5sAgn2_1; 43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), ___src__5sAgn2_1));44 return ((struct Agn2 )___ret__5sAgn2_1);43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__R5sAgn2_1))); 44 return ___ret__5sAgn2_1; 45 45 } 46 46 enum __attribute__ ((unused)) __anonymous1 { … … 69 69 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1); 70 70 static inline struct Fdl ___operator_assign__F4sFdl_R4sFdl4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1, struct Fdl ___src__4sFdl_1); 71 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1); 72 static inline void ___constructor__F_R4sFdlii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1); 73 static inline void ___constructor__F_R4sFdliii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1); 74 static inline void ___constructor__F_R4sFdliiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1); 75 static inline void ___constructor__F_R4sFdliiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1); 76 static inline void ___constructor__F_R4sFdliiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1); 77 static inline void ___constructor__F_R4sFdliiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1); 78 static inline void ___constructor__F_R4sFdliiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1); 79 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object1); 80 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object2, signed int *__f9__Pi_1); 71 81 static inline void ___constructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 72 82 ((void)((*___dst__R4sFdl_1).__f1__i_1) /* ?{} */); … … 78 88 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 79 89 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 90 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 80 91 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 81 92 } … … 89 100 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */); 90 101 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1) /* ?{} */); 102 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0) /* ?{} */); 91 103 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */); 92 104 } 93 105 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 94 106 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ^?{} */); 107 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ^?{} */); 95 108 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ^?{} */); 96 109 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ^?{} */); … … 112 125 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1)); 113 126 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1)); 127 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0)); 114 128 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1)); 115 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), ___src__4sFdl_1));116 return ((struct Fdl )___ret__4sFdl_1);129 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__R4sFdl_1))); 130 return ___ret__4sFdl_1; 117 131 } 118 132 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1){ … … 125 139 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 126 140 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 141 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 127 142 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 128 143 } … … 136 151 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 137 152 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 153 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 138 154 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 139 155 } … … 147 163 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 148 164 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 165 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 149 166 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 150 167 } … … 158 175 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 159 176 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 177 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 160 178 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 161 179 } … … 169 187 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 170 188 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 189 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 171 190 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 172 191 } … … 180 199 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 181 200 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 201 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 182 202 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 183 203 } … … 191 211 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 192 212 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 213 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 193 214 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 194 215 } … … 202 223 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 203 224 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 204 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 205 } 206 static inline void ___constructor__F_R4sFdliiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int *__f9__Pi_1){ 225 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 226 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 227 } 228 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object3){ 207 229 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */); 208 230 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */); … … 213 235 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 214 236 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 237 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object3) /* ?{} */); 238 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 239 } 240 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object4, signed int *__f9__Pi_1){ 241 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */); 242 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */); 243 ((void)((*___dst__R4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */); 244 ((void)((*___dst__R4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */); 245 ((void)((*___dst__R4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */); 246 ((void)((*___dst__R4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */); 247 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 248 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 249 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object4) /* ?{} */); 215 250 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */); 216 251 } … … 232 267 __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1; 233 268 } 234 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object 1))[];269 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object5))[]; 235 270 __attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{ 236 271 __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[]; 237 272 } 238 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 2);239 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 3){240 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object 4);273 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object6); 274 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object7){ 275 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object8); 241 276 } 242 277 signed int __vtr__Fi___1(){ … … 268 303 signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1); 269 304 signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1); 270 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 5)(__attribute__ ((unused,unused)) signed int __anonymous_object6[((unsigned long int )5)]));305 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object9)(__attribute__ ((unused,unused)) signed int __anonymous_object10[((unsigned long int )5)])); 271 306 signed int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 272 307 signed int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 273 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 7)(__attribute__ ((unused)) signed int (*__anonymous_object8)(__attribute__ ((unused,unused)) signed int __anonymous_object9)));308 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object11)(__attribute__ ((unused)) signed int (*__anonymous_object12)(__attribute__ ((unused,unused)) signed int __anonymous_object13))); 274 309 signed int __ad__Fi___1(){ 275 310 __attribute__ ((unused)) signed int ___retval_ad__i_1; … … 300 335 struct __anonymous4 ___ret__13s__anonymous4_2; 301 336 ((void)((*___dst__R13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2)); 302 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), ___src__13s__anonymous4_2));303 return ((struct __anonymous4 )___ret__13s__anonymous4_2);337 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), (*___dst__R13s__anonymous4_2))); 338 return ___ret__13s__anonymous4_2; 304 339 } 305 340 inline void ___constructor__F_R13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__R13s__anonymous4_2, signed int __i__i_2){ … … 313 348 } 314 349 inline void ___constructor__F_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 315 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) );350 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) /* ?{} */); 316 351 } 317 352 inline void ___destructor__F_R13e__anonymous5_intrinsic___2(__attribute__ ((unused)) enum __anonymous5 *___dst__R13e__anonymous5_2){ … … 319 354 inline enum __anonymous5 ___operator_assign__F13e__anonymous5_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 320 355 enum __anonymous5 ___ret__13e__anonymous5_2; 321 ((void)(___ret__13e__anonymous5_2=((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)) /* ?{} */); 322 return ((enum __anonymous5 )___ret__13e__anonymous5_2); 356 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)); 357 ((void)(___ret__13e__anonymous5_2=(*___dst__R13e__anonymous5_2)) /* ?{} */); 358 return ___ret__13e__anonymous5_2; 323 359 } 324 360 ((void)sizeof(enum __anonymous5 )); 325 361 } 326 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 0, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object11);327 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object1 2, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object13);328 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 4, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);329 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 16)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)());330 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 18)(__attribute__ ((unused)) signed int __anonymous_object19), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(__attribute__ ((unused)) signed int __anonymous_object21));331 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 2)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)());332 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 4)(__attribute__ ((unused)) signed int __anonymous_object25), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(__attribute__ ((unused)) signed int __anonymous_object27));362 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15); 363 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object16, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object17); 364 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object18, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object19); 365 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object21)()); 366 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(__attribute__ ((unused)) signed int __anonymous_object23), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25)); 367 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object27)()); 368 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object28)(__attribute__ ((unused)) signed int __anonymous_object29), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object30)(__attribute__ ((unused)) signed int __anonymous_object31)); 333 369 struct Vad { 334 __attribute__ ((unused)) signed int __anonymous_object 28;335 __attribute__ ((unused,unused)) signed int *__anonymous_object 29;336 __attribute__ ((unused,unused)) signed int __anonymous_object3 0[((unsigned long int )10)];337 __attribute__ ((unused,unused)) signed int (*__anonymous_object3 1)();370 __attribute__ ((unused)) signed int __anonymous_object32; 371 __attribute__ ((unused,unused)) signed int *__anonymous_object33; 372 __attribute__ ((unused,unused)) signed int __anonymous_object34[((unsigned long int )10)]; 373 __attribute__ ((unused,unused)) signed int (*__anonymous_object35)(); 338 374 }; 339 375 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); … … 341 377 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); 342 378 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1); 379 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object36); 380 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object37, signed int *__anonymous_object38); 381 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object39, signed int *__anonymous_object40, signed int __anonymous_object41[((unsigned long int )10)]); 382 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object42, signed int *__anonymous_object43, signed int __anonymous_object44[((unsigned long int )10)], signed int (*__anonymous_object45)()); 343 383 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 384 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ?{} */); 385 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */); 386 { 387 signed int _index0 = 0; 388 for (;(_index0<10);((void)(++_index0))) { 389 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index0)])))) /* ?{} */); 390 } 391 392 } 393 394 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 344 395 } 345 396 static inline void ___constructor__F_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 397 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32) /* ?{} */); 398 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33) /* ?{} */); 399 { 400 signed int _index1 = 0; 401 for (;(_index1<10);((void)(++_index1))) { 402 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index1)])))=___src__4sVad_1.__anonymous_object34[((signed long int )_index1)]) /* ?{} */); 403 } 404 405 } 406 407 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35) /* ?{} */); 346 408 } 347 409 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 410 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ^?{} */); 411 { 412 signed int _index2 = (10-1); 413 for (;(_index2>=0);((void)(--_index2))) { 414 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index2)])))) /* ^?{} */); 415 } 416 417 } 418 419 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ^?{} */); 420 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ^?{} */); 348 421 } 349 422 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 350 423 struct Vad ___ret__4sVad_1; 351 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), ___src__4sVad_1)); 352 return ((struct Vad )___ret__4sVad_1); 353 } 424 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32)); 425 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33)); 426 { 427 signed int _index3 = 0; 428 for (;(_index3<10);((void)(++_index3))) { 429 ((void)((*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index3)]=___src__4sVad_1.__anonymous_object34[((signed long int )_index3)])); 430 } 431 432 } 433 434 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35)); 435 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), (*___dst__R4sVad_1))); 436 return ___ret__4sVad_1; 437 } 438 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object46){ 439 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object46) /* ?{} */); 440 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */); 441 { 442 signed int _index4 = 0; 443 for (;(_index4<10);((void)(++_index4))) { 444 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index4)])))) /* ?{} */); 445 } 446 447 } 448 449 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 450 } 451 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object47, signed int *__anonymous_object48){ 452 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object47) /* ?{} */); 453 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object48) /* ?{} */); 454 { 455 signed int _index5 = 0; 456 for (;(_index5<10);((void)(++_index5))) { 457 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index5)])))) /* ?{} */); 458 } 459 460 } 461 462 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 463 } 464 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object49, signed int *__anonymous_object50, signed int __anonymous_object51[((unsigned long int )10)]){ 465 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object49) /* ?{} */); 466 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object50) /* ?{} */); 467 { 468 signed int _index6 = 0; 469 for (;(_index6<10);((void)(++_index6))) { 470 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index6)])))=__anonymous_object51[((signed long int )_index6)]) /* ?{} */); 471 } 472 473 } 474 475 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 476 } 477 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object52, signed int *__anonymous_object53, signed int __anonymous_object54[((unsigned long int )10)], signed int (*__anonymous_object55)()){ 478 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object52) /* ?{} */); 479 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object53) /* ?{} */); 480 { 481 signed int _index7 = 0; 482 for (;(_index7<10);((void)(++_index7))) { 483 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index7)])))=__anonymous_object54[((signed long int )_index7)]) /* ?{} */); 484 } 485 486 } 487 488 ((void)((*___dst__R4sVad_1).__anonymous_object35=__anonymous_object55) /* ?{} */); 489 } -
src/tests/.expect/64/declarationSpecifier.txt
rb96ec83 r6840e7c 20 20 static inline void ___destructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1); 21 21 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 22 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1); 22 23 static inline void ___constructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1){ 23 24 ((void)((*___dst__R13s__anonymous0_1).__i__i_1) /* ?{} */); … … 32 33 struct __anonymous0 ___ret__13s__anonymous0_1; 33 34 ((void)((*___dst__R13s__anonymous0_1).__i__i_1=___src__13s__anonymous0_1.__i__i_1)); 34 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1));35 return ((struct __anonymous0 )___ret__13s__anonymous0_1);35 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1))); 36 return ___ret__13s__anonymous0_1; 36 37 } 37 38 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1){ … … 46 47 static inline void ___destructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1); 47 48 static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_R13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1); 49 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1); 48 50 static inline void ___constructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1){ 49 51 ((void)((*___dst__R13s__anonymous1_1).__i__i_1) /* ?{} */); … … 58 60 struct __anonymous1 ___ret__13s__anonymous1_1; 59 61 ((void)((*___dst__R13s__anonymous1_1).__i__i_1=___src__13s__anonymous1_1.__i__i_1)); 60 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), ___src__13s__anonymous1_1));61 return ((struct __anonymous1 )___ret__13s__anonymous1_1);62 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), (*___dst__R13s__anonymous1_1))); 63 return ___ret__13s__anonymous1_1; 62 64 } 63 65 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1){ … … 72 74 static inline void ___destructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1); 73 75 static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_R13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1); 76 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1); 74 77 static inline void ___constructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1){ 75 78 ((void)((*___dst__R13s__anonymous2_1).__i__i_1) /* ?{} */); … … 84 87 struct __anonymous2 ___ret__13s__anonymous2_1; 85 88 ((void)((*___dst__R13s__anonymous2_1).__i__i_1=___src__13s__anonymous2_1.__i__i_1)); 86 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), ___src__13s__anonymous2_1));87 return ((struct __anonymous2 )___ret__13s__anonymous2_1);89 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__R13s__anonymous2_1))); 90 return ___ret__13s__anonymous2_1; 88 91 } 89 92 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1){ … … 98 101 static inline void ___destructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1); 99 102 static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_R13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1); 103 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1); 100 104 static inline void ___constructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1){ 101 105 ((void)((*___dst__R13s__anonymous3_1).__i__i_1) /* ?{} */); … … 110 114 struct __anonymous3 ___ret__13s__anonymous3_1; 111 115 ((void)((*___dst__R13s__anonymous3_1).__i__i_1=___src__13s__anonymous3_1.__i__i_1)); 112 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), ___src__13s__anonymous3_1));113 return ((struct __anonymous3 )___ret__13s__anonymous3_1);116 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), (*___dst__R13s__anonymous3_1))); 117 return ___ret__13s__anonymous3_1; 114 118 } 115 119 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1){ … … 124 128 static inline void ___destructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1); 125 129 static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_R13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1); 130 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1); 126 131 static inline void ___constructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1){ 127 132 ((void)((*___dst__R13s__anonymous4_1).__i__i_1) /* ?{} */); … … 136 141 struct __anonymous4 ___ret__13s__anonymous4_1; 137 142 ((void)((*___dst__R13s__anonymous4_1).__i__i_1=___src__13s__anonymous4_1.__i__i_1)); 138 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), ___src__13s__anonymous4_1));139 return ((struct __anonymous4 )___ret__13s__anonymous4_1);143 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), (*___dst__R13s__anonymous4_1))); 144 return ___ret__13s__anonymous4_1; 140 145 } 141 146 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1){ … … 150 155 static inline void ___destructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1); 151 156 static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_R13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1); 157 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1); 152 158 static inline void ___constructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1){ 153 159 ((void)((*___dst__R13s__anonymous5_1).__i__i_1) /* ?{} */); … … 162 168 struct __anonymous5 ___ret__13s__anonymous5_1; 163 169 ((void)((*___dst__R13s__anonymous5_1).__i__i_1=___src__13s__anonymous5_1.__i__i_1)); 164 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), ___src__13s__anonymous5_1));165 return ((struct __anonymous5 )___ret__13s__anonymous5_1);170 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), (*___dst__R13s__anonymous5_1))); 171 return ___ret__13s__anonymous5_1; 166 172 } 167 173 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1){ … … 176 182 static inline void ___destructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1); 177 183 static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_R13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1); 184 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1); 178 185 static inline void ___constructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1){ 179 186 ((void)((*___dst__R13s__anonymous6_1).__i__i_1) /* ?{} */); … … 188 195 struct __anonymous6 ___ret__13s__anonymous6_1; 189 196 ((void)((*___dst__R13s__anonymous6_1).__i__i_1=___src__13s__anonymous6_1.__i__i_1)); 190 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), ___src__13s__anonymous6_1));191 return ((struct __anonymous6 )___ret__13s__anonymous6_1);197 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), (*___dst__R13s__anonymous6_1))); 198 return ___ret__13s__anonymous6_1; 192 199 } 193 200 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1){ … … 202 209 static inline void ___destructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1); 203 210 static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_R13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1); 211 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1); 204 212 static inline void ___constructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1){ 205 213 ((void)((*___dst__R13s__anonymous7_1).__i__i_1) /* ?{} */); … … 214 222 struct __anonymous7 ___ret__13s__anonymous7_1; 215 223 ((void)((*___dst__R13s__anonymous7_1).__i__i_1=___src__13s__anonymous7_1.__i__i_1)); 216 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), ___src__13s__anonymous7_1));217 return ((struct __anonymous7 )___ret__13s__anonymous7_1);224 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), (*___dst__R13s__anonymous7_1))); 225 return ___ret__13s__anonymous7_1; 218 226 } 219 227 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1){ … … 236 244 static inline void ___destructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1); 237 245 static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_R13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1); 246 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1); 238 247 static inline void ___constructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1){ 239 248 ((void)((*___dst__R13s__anonymous8_1).__i__s_1) /* ?{} */); … … 248 257 struct __anonymous8 ___ret__13s__anonymous8_1; 249 258 ((void)((*___dst__R13s__anonymous8_1).__i__s_1=___src__13s__anonymous8_1.__i__s_1)); 250 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), ___src__13s__anonymous8_1));251 return ((struct __anonymous8 )___ret__13s__anonymous8_1);259 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), (*___dst__R13s__anonymous8_1))); 260 return ___ret__13s__anonymous8_1; 252 261 } 253 262 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1){ … … 262 271 static inline void ___destructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1); 263 272 static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_R13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1); 273 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1); 264 274 static inline void ___constructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1){ 265 275 ((void)((*___dst__R13s__anonymous9_1).__i__s_1) /* ?{} */); … … 274 284 struct __anonymous9 ___ret__13s__anonymous9_1; 275 285 ((void)((*___dst__R13s__anonymous9_1).__i__s_1=___src__13s__anonymous9_1.__i__s_1)); 276 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), ___src__13s__anonymous9_1));277 return ((struct __anonymous9 )___ret__13s__anonymous9_1);286 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), (*___dst__R13s__anonymous9_1))); 287 return ___ret__13s__anonymous9_1; 278 288 } 279 289 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1){ … … 288 298 static inline void ___destructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1); 289 299 static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_R14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1); 300 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1); 290 301 static inline void ___constructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1){ 291 302 ((void)((*___dst__R14s__anonymous10_1).__i__s_1) /* ?{} */); … … 300 311 struct __anonymous10 ___ret__14s__anonymous10_1; 301 312 ((void)((*___dst__R14s__anonymous10_1).__i__s_1=___src__14s__anonymous10_1.__i__s_1)); 302 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), ___src__14s__anonymous10_1));303 return ((struct __anonymous10 )___ret__14s__anonymous10_1);313 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), (*___dst__R14s__anonymous10_1))); 314 return ___ret__14s__anonymous10_1; 304 315 } 305 316 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1){ … … 314 325 static inline void ___destructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1); 315 326 static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_R14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1); 327 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1); 316 328 static inline void ___constructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1){ 317 329 ((void)((*___dst__R14s__anonymous11_1).__i__s_1) /* ?{} */); … … 326 338 struct __anonymous11 ___ret__14s__anonymous11_1; 327 339 ((void)((*___dst__R14s__anonymous11_1).__i__s_1=___src__14s__anonymous11_1.__i__s_1)); 328 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), ___src__14s__anonymous11_1));329 return ((struct __anonymous11 )___ret__14s__anonymous11_1);340 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), (*___dst__R14s__anonymous11_1))); 341 return ___ret__14s__anonymous11_1; 330 342 } 331 343 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1){ … … 340 352 static inline void ___destructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1); 341 353 static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_R14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1); 354 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1); 342 355 static inline void ___constructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1){ 343 356 ((void)((*___dst__R14s__anonymous12_1).__i__s_1) /* ?{} */); … … 352 365 struct __anonymous12 ___ret__14s__anonymous12_1; 353 366 ((void)((*___dst__R14s__anonymous12_1).__i__s_1=___src__14s__anonymous12_1.__i__s_1)); 354 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), ___src__14s__anonymous12_1));355 return ((struct __anonymous12 )___ret__14s__anonymous12_1);367 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), (*___dst__R14s__anonymous12_1))); 368 return ___ret__14s__anonymous12_1; 356 369 } 357 370 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1){ … … 366 379 static inline void ___destructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1); 367 380 static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_R14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1); 381 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1); 368 382 static inline void ___constructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1){ 369 383 ((void)((*___dst__R14s__anonymous13_1).__i__s_1) /* ?{} */); … … 378 392 struct __anonymous13 ___ret__14s__anonymous13_1; 379 393 ((void)((*___dst__R14s__anonymous13_1).__i__s_1=___src__14s__anonymous13_1.__i__s_1)); 380 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), ___src__14s__anonymous13_1));381 return ((struct __anonymous13 )___ret__14s__anonymous13_1);394 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), (*___dst__R14s__anonymous13_1))); 395 return ___ret__14s__anonymous13_1; 382 396 } 383 397 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1){ … … 392 406 static inline void ___destructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1); 393 407 static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_R14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1); 408 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1); 394 409 static inline void ___constructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1){ 395 410 ((void)((*___dst__R14s__anonymous14_1).__i__s_1) /* ?{} */); … … 404 419 struct __anonymous14 ___ret__14s__anonymous14_1; 405 420 ((void)((*___dst__R14s__anonymous14_1).__i__s_1=___src__14s__anonymous14_1.__i__s_1)); 406 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), ___src__14s__anonymous14_1));407 return ((struct __anonymous14 )___ret__14s__anonymous14_1);421 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), (*___dst__R14s__anonymous14_1))); 422 return ___ret__14s__anonymous14_1; 408 423 } 409 424 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1){ … … 418 433 static inline void ___destructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1); 419 434 static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_R14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1); 435 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1); 420 436 static inline void ___constructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1){ 421 437 ((void)((*___dst__R14s__anonymous15_1).__i__s_1) /* ?{} */); … … 430 446 struct __anonymous15 ___ret__14s__anonymous15_1; 431 447 ((void)((*___dst__R14s__anonymous15_1).__i__s_1=___src__14s__anonymous15_1.__i__s_1)); 432 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), ___src__14s__anonymous15_1));433 return ((struct __anonymous15 )___ret__14s__anonymous15_1);448 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), (*___dst__R14s__anonymous15_1))); 449 return ___ret__14s__anonymous15_1; 434 450 } 435 451 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1){ … … 460 476 static inline void ___destructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1); 461 477 static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_R14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1); 478 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1); 462 479 static inline void ___constructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1){ 463 480 ((void)((*___dst__R14s__anonymous16_1).__i__i_1) /* ?{} */); … … 472 489 struct __anonymous16 ___ret__14s__anonymous16_1; 473 490 ((void)((*___dst__R14s__anonymous16_1).__i__i_1=___src__14s__anonymous16_1.__i__i_1)); 474 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), ___src__14s__anonymous16_1));475 return ((struct __anonymous16 )___ret__14s__anonymous16_1);491 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), (*___dst__R14s__anonymous16_1))); 492 return ___ret__14s__anonymous16_1; 476 493 } 477 494 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1){ … … 486 503 static inline void ___destructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1); 487 504 static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_R14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1); 505 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1); 488 506 static inline void ___constructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1){ 489 507 ((void)((*___dst__R14s__anonymous17_1).__i__i_1) /* ?{} */); … … 498 516 struct __anonymous17 ___ret__14s__anonymous17_1; 499 517 ((void)((*___dst__R14s__anonymous17_1).__i__i_1=___src__14s__anonymous17_1.__i__i_1)); 500 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), ___src__14s__anonymous17_1));501 return ((struct __anonymous17 )___ret__14s__anonymous17_1);518 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), (*___dst__R14s__anonymous17_1))); 519 return ___ret__14s__anonymous17_1; 502 520 } 503 521 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1){ … … 512 530 static inline void ___destructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1); 513 531 static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_R14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1); 532 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1); 514 533 static inline void ___constructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1){ 515 534 ((void)((*___dst__R14s__anonymous18_1).__i__i_1) /* ?{} */); … … 524 543 struct __anonymous18 ___ret__14s__anonymous18_1; 525 544 ((void)((*___dst__R14s__anonymous18_1).__i__i_1=___src__14s__anonymous18_1.__i__i_1)); 526 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), ___src__14s__anonymous18_1));527 return ((struct __anonymous18 )___ret__14s__anonymous18_1);545 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), (*___dst__R14s__anonymous18_1))); 546 return ___ret__14s__anonymous18_1; 528 547 } 529 548 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1){ … … 538 557 static inline void ___destructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1); 539 558 static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_R14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1); 559 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1); 540 560 static inline void ___constructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1){ 541 561 ((void)((*___dst__R14s__anonymous19_1).__i__i_1) /* ?{} */); … … 550 570 struct __anonymous19 ___ret__14s__anonymous19_1; 551 571 ((void)((*___dst__R14s__anonymous19_1).__i__i_1=___src__14s__anonymous19_1.__i__i_1)); 552 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), ___src__14s__anonymous19_1));553 return ((struct __anonymous19 )___ret__14s__anonymous19_1);572 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), (*___dst__R14s__anonymous19_1))); 573 return ___ret__14s__anonymous19_1; 554 574 } 555 575 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1){ … … 564 584 static inline void ___destructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1); 565 585 static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_R14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1); 586 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1); 566 587 static inline void ___constructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1){ 567 588 ((void)((*___dst__R14s__anonymous20_1).__i__i_1) /* ?{} */); … … 576 597 struct __anonymous20 ___ret__14s__anonymous20_1; 577 598 ((void)((*___dst__R14s__anonymous20_1).__i__i_1=___src__14s__anonymous20_1.__i__i_1)); 578 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), ___src__14s__anonymous20_1));579 return ((struct __anonymous20 )___ret__14s__anonymous20_1);599 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), (*___dst__R14s__anonymous20_1))); 600 return ___ret__14s__anonymous20_1; 580 601 } 581 602 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1){ … … 590 611 static inline void ___destructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1); 591 612 static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_R14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1); 613 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1); 592 614 static inline void ___constructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1){ 593 615 ((void)((*___dst__R14s__anonymous21_1).__i__i_1) /* ?{} */); … … 602 624 struct __anonymous21 ___ret__14s__anonymous21_1; 603 625 ((void)((*___dst__R14s__anonymous21_1).__i__i_1=___src__14s__anonymous21_1.__i__i_1)); 604 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), ___src__14s__anonymous21_1));605 return ((struct __anonymous21 )___ret__14s__anonymous21_1);626 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), (*___dst__R14s__anonymous21_1))); 627 return ___ret__14s__anonymous21_1; 606 628 } 607 629 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1){ … … 616 638 static inline void ___destructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1); 617 639 static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_R14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1); 640 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1); 618 641 static inline void ___constructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1){ 619 642 ((void)((*___dst__R14s__anonymous22_1).__i__i_1) /* ?{} */); … … 628 651 struct __anonymous22 ___ret__14s__anonymous22_1; 629 652 ((void)((*___dst__R14s__anonymous22_1).__i__i_1=___src__14s__anonymous22_1.__i__i_1)); 630 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), ___src__14s__anonymous22_1));631 return ((struct __anonymous22 )___ret__14s__anonymous22_1);653 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), (*___dst__R14s__anonymous22_1))); 654 return ___ret__14s__anonymous22_1; 632 655 } 633 656 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1){ … … 642 665 static inline void ___destructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1); 643 666 static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_R14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1); 667 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1); 644 668 static inline void ___constructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1){ 645 669 ((void)((*___dst__R14s__anonymous23_1).__i__i_1) /* ?{} */); … … 654 678 struct __anonymous23 ___ret__14s__anonymous23_1; 655 679 ((void)((*___dst__R14s__anonymous23_1).__i__i_1=___src__14s__anonymous23_1.__i__i_1)); 656 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), ___src__14s__anonymous23_1));657 return ((struct __anonymous23 )___ret__14s__anonymous23_1);680 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), (*___dst__R14s__anonymous23_1))); 681 return ___ret__14s__anonymous23_1; 658 682 } 659 683 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1){ … … 672 696 __attribute__ ((unused)) signed int ___retval_main__i_1; 673 697 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 674 return ((signed int )___retval_main__i_1);698 return ___retval_main__i_1; 675 699 ((void)(___retval_main__i_1=0) /* ?{} */); 676 return ((signed int )___retval_main__i_1);700 return ___retval_main__i_1; 677 701 } 678 702 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 689 713 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 690 714 ((void)(_tmp_cp_ret0) /* ^?{} */); 691 return ((signed int )___retval_main__i_1);692 } 715 return ___retval_main__i_1; 716 } -
src/tests/.expect/64/extension.txt
rb96ec83 r6840e7c 17 17 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 18 18 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 19 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1); 20 static inline void ___constructor__F_R2sSii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1); 21 static inline void ___constructor__F_R2sSiii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1, signed int __c__i_1); 19 22 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 20 23 ((void)((*___dst__R2sS_1).__a__i_1) /* ?{} */); … … 37 40 ((void)((*___dst__R2sS_1).__b__i_1=___src__2sS_1.__b__i_1)); 38 41 ((void)((*___dst__R2sS_1).__c__i_1=___src__2sS_1.__c__i_1)); 39 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));40 return ((struct S )___ret__2sS_1);42 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1))); 43 return ___ret__2sS_1; 41 44 } 42 45 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1){ … … 60 63 __extension__ signed int __c__i_1; 61 64 }; 65 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1); 66 static inline void ___constructor__F_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1); 67 static inline void ___destructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1); 68 static inline union U ___operator_assign__F2uU_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1); 69 static inline void ___constructor__F_R2uUi_autogen___1(union U *___dst__R2uU_1, signed int __a__i_1); 62 70 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1){ 63 71 } … … 70 78 union U ___ret__2uU_1; 71 79 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&___src__2uU_1)), sizeof(union U ))); 72 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), ___src__2uU_1));73 return ((union U )___ret__2uU_1);74 } 75 static inline void ___constructor__F_R2uUi_autogen___1( __attribute__ ((unused)) union U *___dst__R2uU_1, signed int __src__i_1){76 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__ src__i_1)), sizeof(signed int )));80 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), (*___dst__R2uU_1))); 81 return ___ret__2uU_1; 82 } 83 static inline void ___constructor__F_R2uUi_autogen___1(union U *___dst__R2uU_1, signed int __a__i_1){ 84 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__a__i_1)), sizeof(signed int ))); 77 85 } 78 86 __extension__ enum E { … … 94 102 __extension__ signed int *__z__Pi_2; 95 103 }; 96 signed int __i__i_2 = ((signed int )(__extension__ __a__i_1+__extension__ 3)); 104 inline void ___constructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 105 ((void)((*___dst__R2sS_2).__a__i_2) /* ?{} */); 106 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 107 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 108 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 109 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 110 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 111 } 112 inline void ___constructor__F_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 113 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2) /* ?{} */); 114 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2) /* ?{} */); 115 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2) /* ?{} */); 116 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2) /* ?{} */); 117 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2) /* ?{} */); 118 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2) /* ?{} */); 119 } 120 inline void ___destructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 121 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ^?{} */); 122 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ^?{} */); 123 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ^?{} */); 124 ((void)((*___dst__R2sS_2).__c__i_2) /* ^?{} */); 125 ((void)((*___dst__R2sS_2).__b__i_2) /* ^?{} */); 126 ((void)((*___dst__R2sS_2).__a__i_2) /* ^?{} */); 127 } 128 inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 129 struct S ___ret__2sS_2; 130 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2)); 131 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 132 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 133 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2)); 134 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2)); 135 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2)); 136 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2))); 137 return ___ret__2sS_2; 138 } 139 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ 140 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 141 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 142 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 143 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 144 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 145 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 146 } 147 inline void ___constructor__F_R2sSii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2){ 148 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 149 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 150 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 151 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 152 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 153 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 154 } 155 inline void ___constructor__F_R2sSiii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2){ 156 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 157 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 158 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 159 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 160 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 161 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 162 } 163 inline void ___constructor__F_R2sSiiiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2){ 164 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 165 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 166 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 167 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 168 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 169 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 170 } 171 inline void ___constructor__F_R2sSiiiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2){ 172 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 173 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 174 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 175 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 176 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 177 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 178 } 179 inline void ___constructor__F_R2sSiiiPiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2, signed int *__z__Pi_2){ 180 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 181 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 182 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 183 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 184 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 185 ((void)((*___dst__R2sS_2).__z__Pi_2=__z__Pi_2) /* ?{} */); 186 } 187 signed int __i__i_2 = (__extension__ __a__i_1+__extension__ 3); 97 188 ((void)__extension__ 3); 98 189 ((void)__extension__ __a__i_1); -
src/tests/.expect/64/gccExtensions.txt
rb96ec83 r6840e7c 63 63 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 64 64 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), ___src__2sS_2));66 return ((struct S )___ret__2sS_2);65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2))); 66 return ___ret__2sS_2; 67 67 } 68 68 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ … … 81 81 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 82 82 } 83 signed int __i__i_2 = ((signed int )__extension__ 3);83 signed int __i__i_2 = __extension__ 3; 84 84 __extension__ signed int __a__i_2; 85 85 __extension__ signed int __b__i_2; … … 113 113 struct s2 ___ret__3ss2_2; 114 114 ((void)((*___dst__R3ss2_2).__i__i_2=___src__3ss2_2.__i__i_2)); 115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), ___src__3ss2_2));116 return ((struct s2 )___ret__3ss2_2);115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), (*___dst__R3ss2_2))); 116 return ___ret__3ss2_2; 117 117 } 118 118 inline void ___constructor__F_R3ss2i_autogen___2(struct s2 *___dst__R3ss2_2, signed int __i__i_2){ … … 134 134 struct s3 ___ret__3ss3_2; 135 135 ((void)((*___dst__R3ss3_2).__i__i_2=___src__3ss3_2.__i__i_2)); 136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), ___src__3ss3_2));137 return ((struct s3 )___ret__3ss3_2);136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), (*___dst__R3ss3_2))); 137 return ___ret__3ss3_2; 138 138 } 139 139 inline void ___constructor__F_R3ss3i_autogen___2(struct s3 *___dst__R3ss3_2, signed int __i__i_2){ … … 157 157 struct s4 ___ret__3ss4_2; 158 158 ((void)((*___dst__R3ss4_2).__i__i_2=___src__3ss4_2.__i__i_2)); 159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), ___src__3ss4_2));160 return ((struct s4 )___ret__3ss4_2);159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), (*___dst__R3ss4_2))); 160 return ___ret__3ss4_2; 161 161 } 162 162 inline void ___constructor__F_R3ss4i_autogen___2(struct s4 *___dst__R3ss4_2, signed int __i__i_2){ … … 169 169 signed int __m3__A0A0i_2[((unsigned long int )10)][((unsigned long int )10)]; 170 170 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 171 return ((signed int )___retval_main__i_1);171 return ___retval_main__i_1; 172 172 ((void)(___retval_main__i_1=0) /* ?{} */); 173 return ((signed int )___retval_main__i_1);173 return ___retval_main__i_1; 174 174 } 175 175 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 186 186 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 187 187 ((void)(_tmp_cp_ret0) /* ^?{} */); 188 return ((signed int )___retval_main__i_1);188 return ___retval_main__i_1; 189 189 } -
src/tests/.expect/64/literals.txt
rb96ec83 r6840e7c 64 64 static inline void ___destructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1); 65 65 static inline struct _Istream_cstrUC ___operator_assign__F16s_Istream_cstrUC_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, struct _Istream_cstrUC ___src__16s_Istream_cstrUC_1); 66 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1); 66 67 static inline void ___constructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1){ 67 68 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1) /* ?{} */); … … 76 77 struct _Istream_cstrUC ___ret__16s_Istream_cstrUC_1; 77 78 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1=___src__16s_Istream_cstrUC_1.__s__Pc_1)); 78 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), ___src__16s_Istream_cstrUC_1));79 return ((struct _Istream_cstrUC )___ret__16s_Istream_cstrUC_1);79 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), (*___dst__R16s_Istream_cstrUC_1))); 80 return ___ret__16s_Istream_cstrUC_1; 80 81 } 81 82 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1){ … … 92 93 static inline void ___destructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1); 93 94 static inline struct _Istream_cstrC ___operator_assign__F15s_Istream_cstrC_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, struct _Istream_cstrC ___src__15s_Istream_cstrC_1); 95 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1); 96 static inline void ___constructor__F_R15s_Istream_cstrCPci_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1, signed int __size__i_1); 94 97 static inline void ___constructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1){ 95 98 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1) /* ?{} */); … … 108 111 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1=___src__15s_Istream_cstrC_1.__s__Pc_1)); 109 112 ((void)((*___dst__R15s_Istream_cstrC_1).__size__i_1=___src__15s_Istream_cstrC_1.__size__i_1)); 110 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), ___src__15s_Istream_cstrC_1));111 return ((struct _Istream_cstrC )___ret__15s_Istream_cstrC_1);113 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), (*___dst__R15s_Istream_cstrC_1))); 114 return ___ret__15s_Istream_cstrC_1; 112 115 } 113 116 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1){ … … 122 125 void *___operator_bitor__A0_1_0_0___fail__PFi_Pd0___eof__PFi_Pd0___open__PF_Pd0PCcPCc___close__PF_Pd0___read__PFPd0_Pd0PcUl___ungetc__PFPd0_Pd0c___fmt__PFi_Pd0PCc__FPd0_Pd015s_Istream_cstrC__1(__attribute__ ((unused)) signed int (*__fail__PFi_P7tistype__1)(void *__anonymous_object1284), __attribute__ ((unused)) signed int (*__eof__PFi_P7tistype__1)(void *__anonymous_object1285), __attribute__ ((unused)) void (*__open__PF_P7tistypePCcPCc__1)(void *__is__P7tistype_1, const char *__name__PCc_1, const char *__mode__PCc_1), __attribute__ ((unused)) void (*__close__PF_P7tistype__1)(void *__is__P7tistype_1), __attribute__ ((unused)) void *(*__read__PFP7tistype_P7tistypePcUl__1)(void *__anonymous_object1286, char *__anonymous_object1287, unsigned long int __anonymous_object1288), __attribute__ ((unused)) void *(*__ungetc__PFP7tistype_P7tistypec__1)(void *__anonymous_object1289, char __anonymous_object1290), __attribute__ ((unused)) signed int (*__fmt__PFi_P7tistypePCc__1)(void *__anonymous_object1291, const char *__fmt__PCc_1, ...), void *__anonymous_object1292, struct _Istream_cstrC __anonymous_object1293); 123 126 enum __anonymous0 { 124 __sepSize__C13e__anonymous0_1 = ((signed int )16),127 __sepSize__C13e__anonymous0_1 = 16, 125 128 }; 126 129 struct ofstream { … … 137 140 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1); 138 141 static inline struct ofstream ___operator_assign__F9sofstream_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1); 142 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1); 143 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1); 144 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1); 145 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1); 146 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1); 147 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]); 148 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]); 139 149 static inline void ___constructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 140 150 ((void)((*___dst__R9sofstream_1).__file__Pv_1) /* ?{} */); … … 144 154 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 145 155 { 146 signed int _index0 = ((signed int )0);156 signed int _index0 = 0; 147 157 for (;(_index0<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index0))) { 148 158 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index0)])))) /* ?{} */); … … 150 160 151 161 } 152 { 153 signed int _index1 = ((signed int )0); 162 163 { 164 signed int _index1 = 0; 154 165 for (;(_index1<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index1))) { 155 166 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index1)])))) /* ?{} */); … … 157 168 158 169 } 170 159 171 } 160 172 static inline void ___constructor__F_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1){ … … 165 177 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1) /* ?{} */); 166 178 { 167 signed int _index2 = ((signed int )0);179 signed int _index2 = 0; 168 180 for (;(_index2<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index2))) { 169 181 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index2)])))=___src__9sofstream_1.__separator__A0c_1[((signed long int )_index2)]) /* ?{} */); … … 171 183 172 184 } 173 { 174 signed int _index3 = ((signed int )0); 185 186 { 187 signed int _index3 = 0; 175 188 for (;(_index3<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index3))) { 176 189 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index3)])))=___src__9sofstream_1.__tupleSeparator__A0c_1[((signed long int )_index3)]) /* ?{} */); … … 178 191 179 192 } 193 180 194 } 181 195 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 182 196 { 183 signed int _index4 = (( signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1));197 signed int _index4 = (((signed int )__sepSize__C13e__anonymous0_1)-1); 184 198 for (;(_index4>=0);((void)(--_index4))) { 185 199 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index4)])))) /* ^?{} */); … … 187 201 188 202 } 189 { 190 signed int _index5 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1)); 203 204 { 205 signed int _index5 = (((signed int )__sepSize__C13e__anonymous0_1)-1); 191 206 for (;(_index5>=0);((void)(--_index5))) { 192 207 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index5)])))) /* ^?{} */); … … 194 209 195 210 } 211 196 212 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ^?{} */); 197 213 ((void)((*___dst__R9sofstream_1).__sawNL__b_1) /* ^?{} */); … … 208 224 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1)); 209 225 { 210 signed int _index6 = ((signed int )0);226 signed int _index6 = 0; 211 227 for (;(_index6<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index6))) { 212 228 ((void)((*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index6)]=___src__9sofstream_1.__separator__A0c_1[((signed long int )_index6)])); … … 216 232 217 233 { 218 signed int _index7 = ((signed int )0);234 signed int _index7 = 0; 219 235 for (;(_index7<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index7))) { 220 236 ((void)((*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index7)]=___src__9sofstream_1.__tupleSeparator__A0c_1[((signed long int )_index7)])); … … 223 239 } 224 240 225 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), ___src__9sofstream_1));226 return ((struct ofstream )___ret__9sofstream_1);241 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), (*___dst__R9sofstream_1))); 242 return ___ret__9sofstream_1; 227 243 } 228 244 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1){ … … 233 249 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 234 250 { 235 signed int _index8 = ((signed int )0);251 signed int _index8 = 0; 236 252 for (;(_index8<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index8))) { 237 253 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index8)])))) /* ?{} */); … … 239 255 240 256 } 241 { 242 signed int _index9 = ((signed int )0); 257 258 { 259 signed int _index9 = 0; 243 260 for (;(_index9<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index9))) { 244 261 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index9)])))) /* ?{} */); … … 246 263 247 264 } 265 248 266 } 249 267 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1){ … … 254 272 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 255 273 { 256 signed int _index10 = ((signed int )0);274 signed int _index10 = 0; 257 275 for (;(_index10<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index10))) { 258 276 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index10)])))) /* ?{} */); … … 260 278 261 279 } 262 { 263 signed int _index11 = ((signed int )0); 280 281 { 282 signed int _index11 = 0; 264 283 for (;(_index11<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index11))) { 265 284 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index11)])))) /* ?{} */); … … 267 286 268 287 } 288 269 289 } 270 290 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1){ … … 275 295 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 276 296 { 277 signed int _index12 = ((signed int )0);297 signed int _index12 = 0; 278 298 for (;(_index12<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index12))) { 279 299 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index12)])))) /* ?{} */); … … 281 301 282 302 } 283 { 284 signed int _index13 = ((signed int )0); 303 304 { 305 signed int _index13 = 0; 285 306 for (;(_index13<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index13))) { 286 307 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index13)])))) /* ?{} */); … … 288 309 289 310 } 311 290 312 } 291 313 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1){ … … 296 318 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 297 319 { 298 signed int _index14 = ((signed int )0);320 signed int _index14 = 0; 299 321 for (;(_index14<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index14))) { 300 322 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index14)])))) /* ?{} */); … … 302 324 303 325 } 304 { 305 signed int _index15 = ((signed int )0); 326 327 { 328 signed int _index15 = 0; 306 329 for (;(_index15<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index15))) { 307 330 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index15)])))) /* ?{} */); … … 309 332 310 333 } 334 311 335 } 312 336 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1){ … … 317 341 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 318 342 { 319 signed int _index16 = ((signed int )0);343 signed int _index16 = 0; 320 344 for (;(_index16<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index16))) { 321 345 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index16)])))) /* ?{} */); … … 323 347 324 348 } 325 { 326 signed int _index17 = ((signed int )0); 349 350 { 351 signed int _index17 = 0; 327 352 for (;(_index17<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index17))) { 328 353 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index17)])))) /* ?{} */); … … 330 355 331 356 } 357 332 358 } 333 359 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]){ … … 338 364 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 339 365 { 340 signed int _index18 = ((signed int )0);366 signed int _index18 = 0; 341 367 for (;(_index18<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index18))) { 342 368 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index18)])))=__separator__A0c_1[((signed long int )_index18)]) /* ?{} */); … … 344 370 345 371 } 346 { 347 signed int _index19 = ((signed int )0); 372 373 { 374 signed int _index19 = 0; 348 375 for (;(_index19<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index19))) { 349 376 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index19)])))) /* ?{} */); … … 351 378 352 379 } 380 353 381 } 354 382 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]){ … … 359 387 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 360 388 { 361 signed int _index20 = ((signed int )0);389 signed int _index20 = 0; 362 390 for (;(_index20<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index20))) { 363 391 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index20)])))=__separator__A0c_1[((signed long int )_index20)]) /* ?{} */); … … 365 393 366 394 } 367 { 368 signed int _index21 = ((signed int )0); 395 396 { 397 signed int _index21 = 0; 369 398 for (;(_index21<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index21))) { 370 399 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index21)])))=__tupleSeparator__A0c_1[((signed long int )_index21)]) /* ?{} */); … … 372 401 373 402 } 403 374 404 } 375 405 _Bool __sepPrt__Fb_P9sofstream__1(struct ofstream *__anonymous_object1294); … … 404 434 static inline void ___destructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1); 405 435 static inline struct ifstream ___operator_assign__F9sifstream_R9sifstream9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1, struct ifstream ___src__9sifstream_1); 436 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1); 406 437 static inline void ___constructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1){ 407 438 ((void)((*___dst__R9sifstream_1).__file__Pv_1) /* ?{} */); … … 416 447 struct ifstream ___ret__9sifstream_1; 417 448 ((void)((*___dst__R9sifstream_1).__file__Pv_1=___src__9sifstream_1.__file__Pv_1)); 418 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), ___src__9sifstream_1));419 return ((struct ifstream )___ret__9sifstream_1);449 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), (*___dst__R9sifstream_1))); 450 return ___ret__9sifstream_1; 420 451 } 421 452 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1){ … … 708 739 ((void)0123456789.e-09L); 709 740 ((void)0123456789.e-09DL); 710 ((void)( -0123456789.e-09));711 ((void)( -0123456789.e-09f));712 ((void)( -0123456789.e-09l));713 ((void)( -0123456789.e-09F));714 ((void)( -0123456789.e-09L));715 ((void)( -0123456789.e-09DL));741 ((void)(+0123456789.e-09)); 742 ((void)(+0123456789.e-09f)); 743 ((void)(+0123456789.e-09l)); 744 ((void)(+0123456789.e-09F)); 745 ((void)(+0123456789.e-09L)); 746 ((void)(+0123456789.e-09DL)); 716 747 ((void)(-0123456789.e-09)); 717 748 ((void)(-0123456789.e-09f)); … … 852 883 ((void)0123456789.0123456789E-09L); 853 884 ((void)0123456789.0123456789E-09DL); 854 ((void)( -0123456789.0123456789E-09));855 ((void)( -0123456789.0123456789E-09f));856 ((void)( -0123456789.0123456789E-09l));857 ((void)( -0123456789.0123456789E-09F));858 ((void)( -0123456789.0123456789E-09L));859 ((void)( -0123456789.0123456789E-09DL));885 ((void)(+0123456789.0123456789E-09)); 886 ((void)(+0123456789.0123456789E-09f)); 887 ((void)(+0123456789.0123456789E-09l)); 888 ((void)(+0123456789.0123456789E-09F)); 889 ((void)(+0123456789.0123456789E-09L)); 890 ((void)(+0123456789.0123456789E-09DL)); 860 891 ((void)(-0123456789.0123456789E-09)); 861 892 ((void)(-0123456789.0123456789E-09f)); … … 899 930 ((void)0x0123456789.p-09F); 900 931 ((void)0x0123456789.p-09L); 901 ((void)( -0x0123456789.p-09));902 ((void)( -0x0123456789.p-09f));903 ((void)( -0x0123456789.p-09l));904 ((void)( -0x0123456789.p-09F));905 ((void)( -0x0123456789.p-09L));932 ((void)(+0x0123456789.p-09)); 933 ((void)(+0x0123456789.p-09f)); 934 ((void)(+0x0123456789.p-09l)); 935 ((void)(+0x0123456789.p-09F)); 936 ((void)(+0x0123456789.p-09L)); 906 937 ((void)(-0x0123456789.p-09)); 907 938 ((void)(-0x0123456789.p-09f)); … … 944 975 ((void)0x.0123456789P-09F); 945 976 ((void)0x.0123456789P-09L); 946 ((void)( -0x.0123456789P-09));947 ((void)( -0x.0123456789P-09f));948 ((void)( -0x.0123456789P-09l));949 ((void)( -0x.0123456789P-09F));950 ((void)( -0x.0123456789P-09L));977 ((void)(+0x.0123456789P-09)); 978 ((void)(+0x.0123456789P-09f)); 979 ((void)(+0x.0123456789P-09l)); 980 ((void)(+0x.0123456789P-09F)); 981 ((void)(+0x.0123456789P-09L)); 951 982 ((void)(-0x.0123456789P-09)); 952 983 ((void)(-0x.0123456789P-09f)); … … 989 1020 ((void)0X0123456789.0123456789P-09F); 990 1021 ((void)0X0123456789.0123456789P-09L); 1022 ((void)(+0X0123456789.0123456789P-09)); 1023 ((void)(+0X0123456789.0123456789P-09f)); 1024 ((void)(+0X0123456789.0123456789P-09l)); 1025 ((void)(+0X0123456789.0123456789P-09F)); 1026 ((void)(+0X0123456789.0123456789P-09L)); 991 1027 ((void)(-0X0123456789.0123456789P-09)); 992 1028 ((void)(-0X0123456789.0123456789P-09f)); … … 994 1030 ((void)(-0X0123456789.0123456789P-09F)); 995 1031 ((void)(-0X0123456789.0123456789P-09L)); 996 ((void)(-0X0123456789.0123456789P-09)); 997 ((void)(-0X0123456789.0123456789P-09f)); 998 ((void)(-0X0123456789.0123456789P-09l)); 999 ((void)(-0X0123456789.0123456789P-09F)); 1000 ((void)(-0X0123456789.0123456789P-09L)); 1032 ((void)((signed char )01234567)); 1033 ((void)((signed short int )01234567)); 1034 ((void)((signed int )01234567)); 1035 ((void)((signed long int )01234567)); 1036 ((void)((__int128 )01234567)); 1037 ((void)((unsigned char )01234567u)); 1038 ((void)((signed short int )01234567u)); 1039 ((void)((unsigned int )01234567u)); 1040 ((void)((signed long int )01234567u)); 1041 ((void)((__int128 )01234567u)); 1042 ((void)(+((signed int )((signed char )01234567)))); 1043 ((void)(+((signed int )((signed short int )01234567)))); 1044 ((void)(+((signed int )01234567))); 1045 ((void)(+((signed long int )01234567))); 1046 ((void)(+((float )((__int128 )01234567)))); 1047 ((void)(+((signed int )((unsigned char )01234567u)))); 1048 ((void)(+((signed int )((signed short int )01234567u)))); 1049 ((void)(+((unsigned int )01234567u))); 1050 ((void)(+((signed long int )01234567u))); 1051 ((void)(+((float )((__int128 )01234567u)))); 1052 ((void)(-((signed int )((signed char )01234567)))); 1053 ((void)(-((signed int )((signed short int )01234567)))); 1054 ((void)(-((signed int )01234567))); 1055 ((void)(-((signed long int )01234567))); 1056 ((void)(-((float )((__int128 )01234567)))); 1057 ((void)(-((signed int )((unsigned char )01234567u)))); 1058 ((void)(-((signed int )((signed short int )01234567u)))); 1059 ((void)(-((unsigned int )01234567u))); 1060 ((void)(-((signed long int )01234567u))); 1061 ((void)(-((float )((__int128 )01234567u)))); 1062 ((void)((signed char )1234567890)); 1063 ((void)((signed short int )1234567890)); 1064 ((void)((signed int )1234567890)); 1065 ((void)((signed long int )1234567890)); 1066 ((void)((__int128 )1234567890)); 1067 ((void)((signed char )1234567890U)); 1068 ((void)((unsigned short int )1234567890U)); 1069 ((void)((signed int )1234567890U)); 1070 ((void)((unsigned long int )1234567890u)); 1071 ((void)((unsigned __int128 )1234567890u)); 1072 ((void)(+((signed int )((signed char )1234567890)))); 1073 ((void)(+((signed int )((signed short int )1234567890)))); 1074 ((void)(+((signed int )1234567890))); 1075 ((void)(+((signed long int )1234567890))); 1076 ((void)(+((float )((__int128 )1234567890)))); 1077 ((void)(+((signed int )((signed char )1234567890U)))); 1078 ((void)(+((signed int )((unsigned short int )1234567890U)))); 1079 ((void)(+((signed int )1234567890U))); 1080 ((void)(+((unsigned long int )1234567890u))); 1081 ((void)(+((float )((unsigned __int128 )1234567890u)))); 1082 ((void)(-((signed int )((signed char )1234567890)))); 1083 ((void)(-((signed int )((signed short int )1234567890)))); 1084 ((void)(-((signed int )1234567890))); 1085 ((void)(-((signed long int )1234567890))); 1086 ((void)(-((float )((__int128 )1234567890)))); 1087 ((void)(-((signed int )((signed char )1234567890U)))); 1088 ((void)(-((signed int )((unsigned short int )1234567890U)))); 1089 ((void)(-((signed int )1234567890U))); 1090 ((void)(-((unsigned long int )1234567890u))); 1091 ((void)(-((float )((unsigned __int128 )1234567890u)))); 1092 ((void)((signed char )0x0123456789abcdef)); 1093 ((void)((signed short int )0x0123456789abcdef)); 1094 ((void)((signed int )0x0123456789abcdef)); 1095 ((void)((signed long int )0x0123456789abcdef)); 1096 ((void)((signed char )0x0123456789abcdefu)); 1097 ((void)((unsigned short int )0x0123456789abcdefu)); 1098 ((void)((signed int )0x0123456789abcdefu)); 1099 ((void)((unsigned long int )0x0123456789abcdefu)); 1100 ((void)(+((signed int )((signed char )0x0123456789abcdef)))); 1101 ((void)(+((signed int )((signed short int )0x0123456789abcdef)))); 1102 ((void)(+((signed int )0x0123456789abcdef))); 1103 ((void)(+((signed long int )0x0123456789abcdef))); 1104 ((void)(+((signed int )((signed char )0x0123456789abcdefu)))); 1105 ((void)(+((signed int )((unsigned short int )0x0123456789abcdefu)))); 1106 ((void)(+((signed int )0x0123456789abcdefu))); 1107 ((void)(+((unsigned long int )0x0123456789abcdefu))); 1108 ((void)(-((signed int )((signed char )0x0123456789abcdef)))); 1109 ((void)(-((signed int )((signed short int )0x0123456789abcdef)))); 1110 ((void)(-((signed int )0x0123456789abcdef))); 1111 ((void)(-((signed long int )0x0123456789abcdef))); 1112 ((void)(-((signed int )((signed char )0x0123456789abcdefu)))); 1113 ((void)(-((signed int )((unsigned short int )0x0123456789abcdefu)))); 1114 ((void)(-((signed int )0x0123456789abcdefu))); 1115 ((void)(-((unsigned long int )0x0123456789abcdefu))); 1116 ((void)((signed char )0x0123456789ABCDEF)); 1117 ((void)((signed short int )0x0123456789ABCDEF)); 1118 ((void)((signed int )0x0123456789ABCDEF)); 1119 ((void)((signed long int )0x0123456789ABCDEF)); 1120 ((void)((signed char )0x0123456789ABCDEFu)); 1121 ((void)((unsigned short int )0x0123456789ABCDEFu)); 1122 ((void)((signed int )0x0123456789ABCDEFu)); 1123 ((void)((unsigned long int )0x0123456789ABCDEFu)); 1124 ((void)(+((signed int )((signed char )0x0123456789ABCDEF)))); 1125 ((void)(+((signed int )((signed short int )0x0123456789ABCDEF)))); 1126 ((void)(+((signed int )0x0123456789ABCDEF))); 1127 ((void)(+((signed long int )0x0123456789ABCDEF))); 1128 ((void)(+((signed int )((signed char )0x0123456789ABCDEFu)))); 1129 ((void)(+((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1130 ((void)(+((signed int )0x0123456789ABCDEFu))); 1131 ((void)(+((unsigned long int )0x0123456789ABCDEFu))); 1132 ((void)(-((signed int )((signed char )0x0123456789ABCDEF)))); 1133 ((void)(-((signed int )((signed short int )0x0123456789ABCDEF)))); 1134 ((void)(-((signed int )0x0123456789ABCDEF))); 1135 ((void)(-((signed long int )0x0123456789ABCDEF))); 1136 ((void)(-((signed int )((signed char )0x0123456789ABCDEFu)))); 1137 ((void)(-((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1138 ((void)(-((signed int )0x0123456789ABCDEFu))); 1139 ((void)(-((unsigned long int )0x0123456789ABCDEFu))); 1140 ((void)((signed char )0X0123456789abcdef)); 1141 ((void)((signed short int )0X0123456789abcdef)); 1142 ((void)((signed int )0X0123456789abcdef)); 1143 ((void)((signed long int )0X0123456789abcdef)); 1144 ((void)((signed char )0X0123456789abcdefu)); 1145 ((void)((unsigned short int )0X0123456789abcdefu)); 1146 ((void)((signed int )0X0123456789abcdefu)); 1147 ((void)((unsigned long int )0X0123456789abcdefu)); 1148 ((void)(+((signed int )((signed char )0X0123456789abcdef)))); 1149 ((void)(+((signed int )((signed short int )0X0123456789abcdef)))); 1150 ((void)(+((signed int )0X0123456789abcdef))); 1151 ((void)(+((signed long int )0X0123456789abcdef))); 1152 ((void)(+((signed int )((signed char )0X0123456789abcdefu)))); 1153 ((void)(+((signed int )((unsigned short int )0X0123456789abcdefu)))); 1154 ((void)(+((signed int )0X0123456789abcdefu))); 1155 ((void)(+((unsigned long int )0X0123456789abcdefu))); 1156 ((void)(-((signed int )((signed char )0X0123456789abcdef)))); 1157 ((void)(-((signed int )((signed short int )0X0123456789abcdef)))); 1158 ((void)(-((signed int )0X0123456789abcdef))); 1159 ((void)(-((signed long int )0X0123456789abcdef))); 1160 ((void)(-((signed int )((signed char )0X0123456789abcdefu)))); 1161 ((void)(-((signed int )((unsigned short int )0X0123456789abcdefu)))); 1162 ((void)(-((signed int )0X0123456789abcdefu))); 1163 ((void)(-((unsigned long int )0X0123456789abcdefu))); 1164 ((void)((signed char )0X0123456789ABCDEF)); 1165 ((void)((signed short int )0X0123456789ABCDEF)); 1166 ((void)((signed int )0X0123456789ABCDEF)); 1167 ((void)((signed long int )0X0123456789ABCDEF)); 1168 ((void)((signed char )0X0123456789ABCDEFu)); 1169 ((void)((unsigned short int )0X0123456789ABCDEFu)); 1170 ((void)((signed int )0X0123456789ABCDEFu)); 1171 ((void)((unsigned long int )0X0123456789ABCDEFu)); 1172 ((void)(+((signed int )((signed char )0X0123456789ABCDEF)))); 1173 ((void)(+((signed int )((signed short int )0X0123456789ABCDEF)))); 1174 ((void)(+((signed int )0X0123456789ABCDEF))); 1175 ((void)(+((signed long int )0X0123456789ABCDEF))); 1176 ((void)(+((signed int )((signed char )0X0123456789ABCDEFu)))); 1177 ((void)(+((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1178 ((void)(+((signed int )0X0123456789ABCDEFu))); 1179 ((void)(+((unsigned long int )0X0123456789ABCDEFu))); 1180 ((void)(-((signed int )((signed char )0X0123456789ABCDEF)))); 1181 ((void)(-((signed int )((signed short int )0X0123456789ABCDEF)))); 1182 ((void)(-((signed int )0X0123456789ABCDEF))); 1183 ((void)(-((signed long int )0X0123456789ABCDEF))); 1184 ((void)(-((signed int )((signed char )0X0123456789ABCDEFu)))); 1185 ((void)(-((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1186 ((void)(-((signed int )0X0123456789ABCDEFu))); 1187 ((void)(-((unsigned long int )0X0123456789ABCDEFu))); 1188 ((void)((float )0123456789.)); 1189 ((void)((double )0123456789.)); 1190 ((void)((long double )0123456789.)); 1191 ((void)((long double )0123456789.)); 1192 ((void)(+((float )0123456789.))); 1193 ((void)(+((double )0123456789.))); 1194 ((void)(+((long double )0123456789.))); 1195 ((void)(+((long double )0123456789.))); 1196 ((void)(-((float )0123456789.))); 1197 ((void)(-((double )0123456789.))); 1198 ((void)(-((long double )0123456789.))); 1199 ((void)(-((long double )0123456789.))); 1200 ((void)((float )0123456789.e09)); 1201 ((void)((double )0123456789.e09)); 1202 ((void)((long double )0123456789.e09)); 1203 ((void)((long double )0123456789.e09)); 1204 ((void)(+((float )0123456789.e+09))); 1205 ((void)(+((double )0123456789.e+09))); 1206 ((void)(+((long double )0123456789.e+09))); 1207 ((void)(+((long double )0123456789.e+09))); 1208 ((void)(-((float )0123456789.e-09))); 1209 ((void)(-((double )0123456789.e-09))); 1210 ((void)(-((long double )0123456789.e-09))); 1211 ((void)(-((long double )0123456789.e-09))); 1212 ((void)((float ).0123456789e09)); 1213 ((void)((double ).0123456789e09)); 1214 ((void)((long double ).0123456789e09)); 1215 ((void)((long double ).0123456789e09)); 1216 ((void)(+((float ).0123456789E+09))); 1217 ((void)(+((double ).0123456789E+09))); 1218 ((void)(+((long double ).0123456789E+09))); 1219 ((void)(+((long double ).0123456789E+09))); 1220 ((void)(-((float ).0123456789E-09))); 1221 ((void)(-((double ).0123456789E-09))); 1222 ((void)(-((long double ).0123456789E-09))); 1223 ((void)(-((long double ).0123456789E-09))); 1224 ((void)((float )0123456789.0123456789)); 1225 ((void)((double )0123456789.0123456789)); 1226 ((void)((long double )0123456789.0123456789)); 1227 ((void)((long double )0123456789.0123456789)); 1228 ((void)(+((float )0123456789.0123456789E09))); 1229 ((void)(+((double )0123456789.0123456789E09))); 1230 ((void)(+((long double )0123456789.0123456789E09))); 1231 ((void)(+((long double )0123456789.0123456789E09))); 1232 ((void)(-((float )0123456789.0123456789E+09))); 1233 ((void)(-((double )0123456789.0123456789E+09))); 1234 ((void)(-((long double )0123456789.0123456789E+09))); 1235 ((void)(-((long double )0123456789.0123456789E+09))); 1236 ((void)((float )0123456789.0123456789E-09)); 1237 ((void)((double )0123456789.0123456789E-09)); 1238 ((void)((long double )0123456789.0123456789E-09)); 1239 ((void)((long double )0123456789.0123456789E-09)); 1240 ((void)((float )0x0123456789.p09)); 1241 ((void)((double )0x0123456789.p09)); 1242 ((void)((long double )0x0123456789.p09)); 1243 ((void)((long double )0x0123456789.p09)); 1244 ((void)(+((float )0x0123456789.p09))); 1245 ((void)(+((double )0x0123456789.p09))); 1246 ((void)(+((long double )0x0123456789.p09))); 1247 ((void)(+((long double )0x0123456789.p09))); 1248 ((void)(-((float )0x0123456789.p09))); 1249 ((void)(-((double )0x0123456789.p09))); 1250 ((void)(-((long double )0x0123456789.p09))); 1251 ((void)(-((long double )0x0123456789.p09))); 1252 ((void)((float )0x0123456789.p+09)); 1253 ((void)((double )0x0123456789.p+09)); 1254 ((void)((long double )0x0123456789.p+09)); 1255 ((void)((long double )0x0123456789.p+09)); 1256 ((void)(+((float )0x0123456789.p-09))); 1257 ((void)(+((double )0x0123456789.p-09))); 1258 ((void)(+((long double )0x0123456789.p-09))); 1259 ((void)(+((long double )0x0123456789.p-09))); 1260 ((void)(-((float )0x.0123456789p09))); 1261 ((void)(-((double )0x.0123456789p09))); 1262 ((void)(-((long double )0x.0123456789p09))); 1263 ((void)(-((long double )0x.0123456789p09))); 1001 1264 ((void)__f__F_c__1('a')); 1002 1265 ((void)__f__F_Sc__1(20)); … … 1111 1374 ((void)L"a" "b" "c"); 1112 1375 ((void)(___retval_main__i_1=0) /* ?{} */); 1113 return ((signed int )___retval_main__i_1);1376 return ___retval_main__i_1; 1114 1377 } 1115 1378 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } … … 1126 1389 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 1127 1390 ((void)(_tmp_cp_ret0) /* ^?{} */); 1128 return ((signed int )___retval_main__i_1);1129 } 1391 return ___retval_main__i_1; 1392 } -
src/tests/.expect/castError.txt
rb96ec83 r6840e7c 1 castError.c:7:1 error: Cannot choose between 3 alternatives for expression Cast of: 1 castError.c:7:1 error: Cannot choose between 3 alternatives for expression 2 Cast of: 2 3 Name: f 4 ... to: 5 charAlternatives are: 6 Cost ( 1, 0, 0, 0 ): Cast of: 7 Variable Expression: f: function 8 accepting unspecified arguments 9 ... returning nothing 3 10 4 to: 5 char 6 Alternatives are: Cost ( 1, 0, 0, 0 ): Cast of: 7 Variable Expression: f: function 8 accepting unspecified arguments 9 returning 10 nothing 11 ... to: 12 char 13 (types: 14 char 15 ) 16 Environment: 17 18 Cost ( 1, 0, 0, 0 ): Cast of: 19 Variable Expression: f: signed int 20 ... to: 21 char 22 (types: 23 char 24 ) 25 Environment: 26 27 Cost ( 1, 0, 0, 0 ): Cast of: 28 Variable Expression: f: double 29 ... to: 30 char 31 (types: 32 char 33 ) 34 Environment: 11 35 12 36 13 to:14 char15 (types:16 char17 )18 Environment:19 20 Cost ( 1, 0, 0, 0 ): Cast of:21 Variable Expression: f: signed int22 23 to:24 char25 (types:26 char27 )28 Environment:29 30 Cost ( 1, 0, 0, 0 ): Cast of:31 Variable Expression: f: double32 33 to:34 char35 (types:36 char37 )38 Environment:39 40 -
src/tests/.expect/scopeErrors.txt
rb96ec83 r6840e7c 1 1 scopeErrors.c:2:1 error: duplicate object definition for thisIsAnError: signed int 2 2 scopeErrors.c:20:1 error: duplicate function definition for butThisIsAnError: function 3 with parameters 4 double 5 returning 6 _retval_butThisIsAnError: Attribute with name: unused 7 double 8 with body 9 CompoundStmt 3 ... with parameters 4 double 5 ... returning 6 _retval_butThisIsAnError: double 7 ... with attributes: 8 Attribute with name: unused 10 9 10 ... with body 11 CompoundStmt 12 -
src/tests/Makefile.am
rb96ec83 r6840e7c 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Sep 11 16:17:16201714 ## Update Count : 4 513 ## Last Modified On : Tue Oct 10 14:04:40 2017 14 ## Update Count : 47 15 15 ############################################################################### 16 16 … … 22 22 concurrent = yes 23 23 quick_test += coroutine thread monitor 24 concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt 24 concurrent_test = \ 25 coroutine \ 26 fmtLines \ 27 pingpong \ 28 prodcons \ 29 thread \ 30 matrixSum \ 31 monitor \ 32 multi-monitor \ 33 boundedBuffer \ 34 preempt \ 35 sched-int-block \ 36 sched-int-disjoint \ 37 sched-int-wait \ 38 sched-ext-barge \ 39 sched-ext-dtor \ 40 sched-ext-else \ 41 sched-ext-parse \ 42 sched-ext-recurse \ 43 sched-ext-statment \ 44 sched-ext-when 25 45 else 26 46 concurrent=no … … 113 133 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 114 134 135 ctor-autogen-ERR1: ctor-autogen.c @CFA_BINDIR@/@CFA_NAME@ 136 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 137 115 138 completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@ 116 139 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} -
src/tests/Makefile.in
rb96ec83 r6840e7c 320 320 @BUILD_CONCURRENCY_TRUE@concurrent = yes 321 321 @BUILD_CONCURRENCY_FALSE@concurrent_test = 322 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt 322 @BUILD_CONCURRENCY_TRUE@concurrent_test = \ 323 @BUILD_CONCURRENCY_TRUE@ coroutine \ 324 @BUILD_CONCURRENCY_TRUE@ fmtLines \ 325 @BUILD_CONCURRENCY_TRUE@ pingpong \ 326 @BUILD_CONCURRENCY_TRUE@ prodcons \ 327 @BUILD_CONCURRENCY_TRUE@ thread \ 328 @BUILD_CONCURRENCY_TRUE@ matrixSum \ 329 @BUILD_CONCURRENCY_TRUE@ monitor \ 330 @BUILD_CONCURRENCY_TRUE@ multi-monitor \ 331 @BUILD_CONCURRENCY_TRUE@ boundedBuffer \ 332 @BUILD_CONCURRENCY_TRUE@ preempt \ 333 @BUILD_CONCURRENCY_TRUE@ sched-int-block \ 334 @BUILD_CONCURRENCY_TRUE@ sched-int-disjoint \ 335 @BUILD_CONCURRENCY_TRUE@ sched-int-wait \ 336 @BUILD_CONCURRENCY_TRUE@ sched-ext-barge \ 337 @BUILD_CONCURRENCY_TRUE@ sched-ext-dtor \ 338 @BUILD_CONCURRENCY_TRUE@ sched-ext-else \ 339 @BUILD_CONCURRENCY_TRUE@ sched-ext-parse \ 340 @BUILD_CONCURRENCY_TRUE@ sched-ext-recurse \ 341 @BUILD_CONCURRENCY_TRUE@ sched-ext-statment \ 342 @BUILD_CONCURRENCY_TRUE@ sched-ext-when 343 323 344 324 345 # applies to both programs … … 865 886 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 866 887 888 ctor-autogen-ERR1: ctor-autogen.c @CFA_BINDIR@/@CFA_NAME@ 889 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 890 867 891 completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@ 868 892 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} -
src/tests/coroutine.c
rb96ec83 r6840e7c 10 10 // Created On : Thu Jun 8 07:29:37 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 8 07:37:12201713 // Update Count : 512 // Last Modified On : Sun Sep 17 21:38:15 2017 13 // Update Count : 7 14 14 // 15 15 … … 18 18 19 19 coroutine Fibonacci { 20 int fn; // used for communication20 int fn; // used for communication 21 21 }; 22 22 … … 26 26 27 27 void main( Fibonacci & this ) { 28 int fn1, fn2; // retained between resumes29 this.fn = 0; // case 028 int fn1, fn2; // retained between resumes 29 this.fn = 0; // case 0 30 30 fn1 = this.fn; 31 suspend(); // return tolast resume31 suspend(); // restart last resume 32 32 33 this.fn = 1; // case 1 34 fn2 = fn1; 35 fn1 = this.fn; 36 suspend(); // return to last resume 33 this.fn = 1; // case 1 34 fn2 = fn1; fn1 = this.fn; 35 suspend(); // restart last resume 37 36 38 for ( ;; ) { // general case37 for ( ;; ) { // general case 39 38 this.fn = fn1 + fn2; 40 fn2 = fn1; 41 fn1 = this.fn; 42 suspend(); // return to last resume 39 fn2 = fn1; fn1 = this.fn; 40 suspend(); // restart last resume 43 41 } // for 44 42 } 45 43 46 44 int next( Fibonacci & this ) { 47 resume( this ); // transfer tolast suspend45 resume( this ); // restart last suspend 48 46 return this.fn; 49 47 } … … 52 50 Fibonacci f1, f2; 53 51 for ( int i = 1; i <= 10; i += 1 ) { 54 sout | next( f1 ) | ' ' |next( f2 ) | endl;52 sout | next( f1 ) | next( f2 ) | endl; 55 53 } // for 56 54 } -
src/tests/fmtLines.c
rb96ec83 r6840e7c 10 10 // Created On : Sun Sep 17 21:56:15 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 18 11:35:57201713 // Update Count : 3 112 // Last Modified On : Sun Oct 1 11:57:19 2017 13 // Update Count : 34 14 14 // 15 15 … … 23 23 24 24 void ?{}( Format & fmt ) { 25 resume( fmt ); // startcoroutine25 resume( fmt ); // prime (start) coroutine 26 26 } 27 27 28 28 void ^?{}( Format & fmt ) { 29 29 if ( fmt.g != 0 || fmt.b != 0 ) sout | endl; 30 30 } 31 31 … … 47 47 48 48 void prt( Format & fmt, char ch ) { 49 50 49 fmt.ch = ch; 50 resume( fmt ); 51 51 } // prt 52 52 53 53 int main() { 54 Format fmt; 54 Format fmt; // format characters into blocks of 4 and groups of 5 blocks per line 55 55 char ch; 56 56 57 for ( ;; ) {57 Eof: for ( ;; ) { // read until end of file 58 58 sin | ch; // read one character 59 if ( eof( sin ) ) break ;// eof ?60 prt( fmt, ch ); 59 if ( eof( sin ) ) break Eof; // eof ? 60 prt( fmt, ch ); // push character for formatting 61 61 } // for 62 62 } // main -
src/tests/gmp.c
rb96ec83 r6840e7c 10 10 // Created On : Tue Apr 19 08:55:51 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 4 09:51:18201713 // Update Count : 55 012 // Last Modified On : Thu Sep 28 18:33:51 2017 13 // Update Count : 555 14 14 // 15 15 … … 97 97 98 98 sout | "Factorial Numbers" | endl; 99 Int fact; 100 fact = 1; // 1st case 99 Int fact = 1; // 1st case 101 100 sout | (int)0 | fact | endl; 102 101 for ( unsigned int i = 1; i <= 40; i += 1 ) { -
src/tests/literals.c
rb96ec83 r6840e7c 10 10 // Created On : Sat Sep 9 16:34:38 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Sep 12 07:45:46201713 // Update Count : 8812 // Last Modified On : Mon Sep 25 20:26:00 2017 13 // Update Count : 132 14 14 // 15 15 16 16 #ifdef __CFA__ 17 #include <stdint.h> 17 18 #include <fstream> 18 19 … … 72 73 73 74 0123456789.e-09; 0123456789.e-09f; 0123456789.e-09l; 0123456789.e-09F; 0123456789.e-09L; 0123456789.e-09DL; 74 -0123456789.e-09; -0123456789.e-09f; -0123456789.e-09l; -0123456789.e-09F; -0123456789.e-09L; -0123456789.e-09DL;75 +0123456789.e-09; +0123456789.e-09f; +0123456789.e-09l; +0123456789.e-09F; +0123456789.e-09L; +0123456789.e-09DL; 75 76 -0123456789.e-09; -0123456789.e-09f; -0123456789.e-09l; -0123456789.e-09F; -0123456789.e-09L; -0123456789.e-09DL; 76 77 … … 104 105 105 106 0123456789.0123456789E-09; 0123456789.0123456789E-09f; 0123456789.0123456789E-09l; 0123456789.0123456789E-09F; 0123456789.0123456789E-09L; 0123456789.0123456789E-09DL; 106 -0123456789.0123456789E-09; -0123456789.0123456789E-09f; -0123456789.0123456789E-09l; -0123456789.0123456789E-09F; -0123456789.0123456789E-09L; -0123456789.0123456789E-09DL;107 +0123456789.0123456789E-09; +0123456789.0123456789E-09f; +0123456789.0123456789E-09l; +0123456789.0123456789E-09F; +0123456789.0123456789E-09L; +0123456789.0123456789E-09DL; 107 108 -0123456789.0123456789E-09; -0123456789.0123456789E-09f; -0123456789.0123456789E-09l; -0123456789.0123456789E-09F; -0123456789.0123456789E-09L; -0123456789.0123456789E-09DL; 108 109 … … 118 119 119 120 0x0123456789.p-09; 0x0123456789.p-09f; 0x0123456789.p-09l; 0x0123456789.p-09F; 0x0123456789.p-09L; 120 -0x0123456789.p-09; -0x0123456789.p-09f; -0x0123456789.p-09l; -0x0123456789.p-09F; -0x0123456789.p-09L;121 +0x0123456789.p-09; +0x0123456789.p-09f; +0x0123456789.p-09l; +0x0123456789.p-09F; +0x0123456789.p-09L; 121 122 -0x0123456789.p-09; -0x0123456789.p-09f; -0x0123456789.p-09l; -0x0123456789.p-09F; -0x0123456789.p-09L; 122 123 … … 130 131 131 132 0x.0123456789P-09; 0x.0123456789P-09f; 0x.0123456789P-09l; 0x.0123456789P-09F; 0x.0123456789P-09L; 132 -0x.0123456789P-09; -0x.0123456789P-09f; -0x.0123456789P-09l; -0x.0123456789P-09F; -0x.0123456789P-09L;133 +0x.0123456789P-09; +0x.0123456789P-09f; +0x.0123456789P-09l; +0x.0123456789P-09F; +0x.0123456789P-09L; 133 134 -0x.0123456789P-09; -0x.0123456789P-09f; -0x.0123456789P-09l; -0x.0123456789P-09F; -0x.0123456789P-09L; 134 135 … … 142 143 143 144 0X0123456789.0123456789P-09; 0X0123456789.0123456789P-09f; 0X0123456789.0123456789P-09l; 0X0123456789.0123456789P-09F; 0X0123456789.0123456789P-09L; 145 +0X0123456789.0123456789P-09; +0X0123456789.0123456789P-09f; +0X0123456789.0123456789P-09l; +0X0123456789.0123456789P-09F; +0X0123456789.0123456789P-09L; 144 146 -0X0123456789.0123456789P-09; -0X0123456789.0123456789P-09f; -0X0123456789.0123456789P-09l; -0X0123456789.0123456789P-09F; -0X0123456789.0123456789P-09L; 145 -0X0123456789.0123456789P-09; -0X0123456789.0123456789P-09f; -0X0123456789.0123456789P-09l; -0X0123456789.0123456789P-09F; -0X0123456789.0123456789P-09L; 147 148 #ifdef __CFA__ 149 // fixed-size length 150 151 // octal 152 01234567_l8; 01234567_l16; 01234567_l32; 01234567_l64; 01234567_l128; 01234567_l8u; 01234567_ul16; 01234567_l32u; 01234567_ul64; 01234567_ul128; 153 +01234567_l8; +01234567_l16; +01234567_l32; +01234567_l64; +01234567_l128; +01234567_l8u; +01234567_ul16; +01234567_l32u; +01234567_ul64; +01234567_ul128; 154 -01234567_l8; -01234567_l16; -01234567_l32; -01234567_l64; -01234567_l128; -01234567_l8u; -01234567_ul16; -01234567_l32u; -01234567_ul64; -01234567_ul128; 155 156 // decimal 157 1234567890L8; 1234567890L16; 1234567890l32; 1234567890l64; 1234567890l128; 1234567890UL8; 1234567890L16U; 1234567890Ul32; 1234567890l64u; 1234567890l128u; 158 +1234567890L8; +1234567890L16; +1234567890l32; +1234567890l64; +1234567890l128; +1234567890UL8; +1234567890L16U; +1234567890Ul32; +1234567890l64u; +1234567890l128u; 159 -1234567890L8; -1234567890L16; -1234567890l32; -1234567890l64; -1234567890l128; -1234567890UL8; -1234567890L16U; -1234567890Ul32; -1234567890l64u; -1234567890l128u; 160 161 // hexadecimal 162 0x0123456789abcdef_l8; 0x0123456789abcdef_l16; 0x0123456789abcdefl32; 0x0123456789abcdefl64; 0x0123456789abcdef_ul8; 0x0123456789abcdef_l16u; 0x0123456789abcdeful32; 0x0123456789abcdefl64u; 163 +0x0123456789abcdef_l8; +0x0123456789abcdef_l16; +0x0123456789abcdefl32; +0x0123456789abcdefl64; +0x0123456789abcdef_ul8; +0x0123456789abcdef_l16u; +0x0123456789abcdeful32; +0x0123456789abcdefl64u; 164 -0x0123456789abcdef_l8; -0x0123456789abcdef_l16; -0x0123456789abcdefl32; -0x0123456789abcdefl64; -0x0123456789abcdef_ul8; -0x0123456789abcdef_l16u; -0x0123456789abcdeful32; -0x0123456789abcdefl64u; 165 166 0x0123456789ABCDEF_l8; 0x0123456789ABCDEF_l16; 0x0123456789ABCDEFl32; 0x0123456789ABCDEFl64; 0x0123456789ABCDEF_ul8; 0x0123456789ABCDEF_l16u; 0x0123456789ABCDEFul32; 0x0123456789ABCDEFl64u; 167 +0x0123456789ABCDEF_l8; +0x0123456789ABCDEF_l16; +0x0123456789ABCDEFl32; +0x0123456789ABCDEFl64; +0x0123456789ABCDEF_ul8; +0x0123456789ABCDEF_l16u; +0x0123456789ABCDEFul32; +0x0123456789ABCDEFl64u; 168 -0x0123456789ABCDEF_l8; -0x0123456789ABCDEF_l16; -0x0123456789ABCDEFl32; -0x0123456789ABCDEFl64; -0x0123456789ABCDEF_ul8; -0x0123456789ABCDEF_l16u; -0x0123456789ABCDEFul32; -0x0123456789ABCDEFl64u; 169 170 0X0123456789abcdef_l8; 0X0123456789abcdef_l16; 0X0123456789abcdefl32; 0X0123456789abcdefl64; 0X0123456789abcdef_ul8; 0X0123456789abcdef_l16u; 0X0123456789abcdeful32; 0X0123456789abcdefl64u; 171 +0X0123456789abcdef_l8; +0X0123456789abcdef_l16; +0X0123456789abcdefl32; +0X0123456789abcdefl64; +0X0123456789abcdef_ul8; +0X0123456789abcdef_l16u; +0X0123456789abcdeful32; +0X0123456789abcdefl64u; 172 -0X0123456789abcdef_l8; -0X0123456789abcdef_l16; -0X0123456789abcdefl32; -0X0123456789abcdefl64; -0X0123456789abcdef_ul8; -0X0123456789abcdef_l16u; -0X0123456789abcdeful32; -0X0123456789abcdefl64u; 173 174 0X0123456789ABCDEF_l8; 0X0123456789ABCDEF_l16; 0X0123456789ABCDEFl32; 0X0123456789ABCDEFl64; 0X0123456789ABCDEF_ul8; 0X0123456789ABCDEF_l16u; 0X0123456789ABCDEFul32; 0X0123456789ABCDEFl64u; 175 +0X0123456789ABCDEF_l8; +0X0123456789ABCDEF_l16; +0X0123456789ABCDEFl32; +0X0123456789ABCDEFl64; +0X0123456789ABCDEF_ul8; +0X0123456789ABCDEF_l16u; +0X0123456789ABCDEFul32; +0X0123456789ABCDEFl64u; 176 -0X0123456789ABCDEF_l8; -0X0123456789ABCDEF_l16; -0X0123456789ABCDEFl32; -0X0123456789ABCDEFl64; -0X0123456789ABCDEF_ul8; -0X0123456789ABCDEF_l16u; -0X0123456789ABCDEFul32; -0X0123456789ABCDEFl64u; 177 178 // floating 179 0123456789.l32; 0123456789.l64; 0123456789.l80; 0123456789.l128; 180 +0123456789.l32; +0123456789.l64; +0123456789.l80; +0123456789.l128; 181 -0123456789.l32; -0123456789.l64; -0123456789.l80; -0123456789.l128; 182 183 0123456789.e09L32; 0123456789.e09L64; 0123456789.e09L80; 0123456789.e09L128; 184 +0123456789.e+09L32; +0123456789.e+09L64; +0123456789.e+09L80; +0123456789.e+09L128; 185 -0123456789.e-09L32; -0123456789.e-09L64; -0123456789.e-09L80; -0123456789.e-09L128; 186 187 .0123456789e09L32; .0123456789e09L64; .0123456789e09L80; .0123456789e09L128; 188 +.0123456789E+09L32; +.0123456789E+09L64; +.0123456789E+09L80; +.0123456789E+09L128; 189 -.0123456789E-09L32; -.0123456789E-09L64; -.0123456789E-09L80; -.0123456789E-09L128; 190 191 0123456789.0123456789L32; 0123456789.0123456789L64; 0123456789.0123456789L80; 0123456789.0123456789L128; 192 +0123456789.0123456789E09L32; +0123456789.0123456789E09L64; +0123456789.0123456789E09L80; +0123456789.0123456789E09L128; 193 -0123456789.0123456789E+09L32; -0123456789.0123456789E+09L64; -0123456789.0123456789E+09L80; -0123456789.0123456789E+09L128; 194 0123456789.0123456789E-09L32; 0123456789.0123456789E-09L64; 0123456789.0123456789E-09L80; 0123456789.0123456789E-09L128; 195 196 0x0123456789.p09l32; 0x0123456789.p09l64; 0x0123456789.p09l80; 0x0123456789.p09l128; 197 +0x0123456789.p09l32; +0x0123456789.p09l64; +0x0123456789.p09l80; +0x0123456789.p09l128; 198 -0x0123456789.p09l32; -0x0123456789.p09l64; -0x0123456789.p09l80; -0x0123456789.p09l128; 199 200 0x0123456789.p+09l32; 0x0123456789.p+09L64; 0x0123456789.p+09L80; 0x0123456789.p+09L128; 201 +0x0123456789.p-09l32; +0x0123456789.p-09L64; +0x0123456789.p-09L80; +0x0123456789.p-09L128; 202 -0x.0123456789p09l32; -0x.0123456789p09L64; -0x.0123456789p09L80; -0x.0123456789p09L128; 146 203 147 204 // char, short, int suffix overloading 148 205 149 #ifdef __CFA__150 206 f( 'a' ); 151 207 f( 20_hh ); -
src/tests/sched-ext-parse.c
rb96ec83 r6840e7c 1 //---------------------------------------------------------------------------------------- 2 //---------------------------------------------------------------------------------------- 3 // 4 // DEPRECATED TEST 5 // DIFFERS BETWEEN DEBUG AND RELEASE 6 // 7 //---------------------------------------------------------------------------------------- 8 //---------------------------------------------------------------------------------------- 9 1 10 #include <monitor> 2 11 -
src/tests/sched-int-barge.c
rb96ec83 r6840e7c 1 //---------------------------------------------------------------------------------------- 2 //---------------------------------------------------------------------------------------- 3 // 4 // DEPRECATED TEST 5 // 6 //---------------------------------------------------------------------------------------- 7 //---------------------------------------------------------------------------------------- 8 1 9 #include <fstream> 2 10 #include <kernel> -
src/tests/sched-int-block.c
rb96ec83 r6840e7c 1 //--------------------------------------------------------- 2 // Barging test 3 // Ensures that no barging can occur between : 4 // - the frontend of the signal_block and the signaled thread 5 // - the signaled threadand the backend of the signal_block 6 //--------------------------------------------------------- 7 8 1 9 #include <fstream> 2 10 #include <kernel> -
src/tests/sched-int-wait.c
rb96ec83 r6840e7c 1 //--------------------------------------------------------- 2 // Multi wait test 3 // Ensures that no deadlock from waiting/signalling conditions 4 //--------------------------------------------------------- 5 6 1 7 #include <fstream> 2 8 #include <kernel>
Note:
See TracChangeset
for help on using the changeset viewer.