Changes in / [6840e7c:b96ec83]


Ignore:
Files:
8 added
30 deleted
148 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/lstlang.sty

    r6840e7c rb96ec83  
    22%%
    33%% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    4 %%
    5 %% lstlang.sty --
    6 %%
     4%% 
     5%% lstlang.sty -- 
     6%% 
    77%% Author           : Peter A. Buhr
    88%% Created On       : Sat May 13 16:34:42 2017
     
    110110                __attribute__, auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__,
    111111                __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, 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, waitfor, when, with, zero_t},
    115115        morekeywords=[2]{
    116                 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, or,
    117                 resume, suspend, thread, _Thread_local, waitfor, when, yield},
     116                _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex,
     117                resume, suspend, thread, _Thread_local, yield},
    118118        moredirectives={defined,include_next}%
    119119}
  • doc/proposals/concurrency/Makefile

    r6840e7c rb96ec83  
    1616text/basics \
    1717text/concurrency \
    18 text/internals \
    1918text/parallelism \
    20 text/together \
    21 text/future \
    2219}
    2320
     
    2623        ext_monitor \
    2724        int_monitor \
    28         dependency \
    2925}}
    3026
  • doc/proposals/concurrency/annex/glossary.tex

    r6840e7c rb96ec83  
    1313}
    1414
    15 \longnewglossaryentry{bulk-acq}
    16 {name={bulk-acquiring}}
     15\longnewglossaryentry{group-acquire}
     16{name={bulk acquiring}}
    1717{
    1818Implicitly 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.
    2519}
    2620
     
    107101\newacronym{api}{API}{Application Program Interface}
    108102\newacronym{raii}{RAII}{Ressource Acquisition Is Initialization}
    109 \newacronym{numa}{NUMA}{Non-Uniform Memory Access}
  • doc/proposals/concurrency/figures/ext_monitor.fig

    r6840e7c rb96ec83  
    14144 1 -1 0 0 0 10 0.0000 2 105 90 6000 2160 d\001
    1515-6
    16 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
     166 5850 1650 6150 1950
     171 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 1905
     184 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\001
    1919-6
    20206 5100 1800 5400 2100
     
    22224 1 -1 0 0 0 10 0.0000 2 105 120 5250 2010 Y\001
    2323-6
    24 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
     246 5100 2100 5400 2400
     251 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 2250 105 105 5250 2250 5355 2250
     264 1 -1 0 0 0 10 0.0000 2 105 120 5250 2295 X\001
    2727-6
    28 6 3070 5445 7275 5655
     286 3000 5400 7200 5700
    29291 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3150 5550 80 80 3150 5550 3230 5630
    30301 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4500 5550 105 105 4500 5550 4605 5655
     
    32324 0 -1 0 0 0 12 0.0000 2 135 1035 4725 5625 blocked task\001
    33334 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 135 1050 6225 5625 routine mask\001
     344 0 -1 0 0 0 12 0.0000 2 180 930 6225 5625 routine ptrs\001
    3535-6
    36361 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3300 3600 105 105 3300 3600 3405 3705
     
    43432 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
    4444         4050 2925 5475 2925 5475 3225 4050 3225 4050 2925
     452 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
     46         5850 2850 6075 3000
    45472 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
    4648         3150 3750 3750 3750 3750 4050 3150 4050
     
    64662 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5
    6567         5850 4200 5850 3300 4350 3300 4350 4200 5850 4200
     682 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3
     69         5250 2850 5850 2850 5850 1650
     702 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
     71         3150 3150 3750 3150 3750 2850 5325 2850
    66722 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2
    6773        1 1 1.00 60.00 120.00
    6874        7 1 1.00 60.00 120.00
    6975         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
    74762 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
    7577         5100 1800 5400 1800 5400 2400 5100 2400 5100 1800
  • doc/proposals/concurrency/style/cfa-format.tex

    r6840e7c rb96ec83  
    108108  belowskip=3pt,
    109109  keepspaces=true,
    110   tabsize=4,
    111110  % frame=lines,
    112111  literate=,
     
    134133  belowskip=3pt,
    135134  keepspaces=true,
    136   tabsize=4,
    137135  % frame=lines,
    138136  literate=,
     
    152150  keywordstyle=\bfseries\color{blue},
    153151  keywordstyle=[2]\bfseries\color{Plum},
    154   commentstyle=\sf\itshape\color{OliveGreen},             % green and italic comments
     152  commentstyle=\itshape\color{OliveGreen},                  % green and italic comments
    155153  identifierstyle=\color{identifierCol},
    156154  stringstyle=\sf\color{Mahogany},                                % use sanserif font
     
    160158  belowskip=3pt,
    161159  keepspaces=true,
    162   tabsize=4,
    163160  % frame=lines,
    164161  literate=,
  • doc/proposals/concurrency/text/basics.tex

    r6840e7c rb96ec83  
    11% ======================================================================
    22% ======================================================================
    3 \chapter{Concurrency Basics}\label{basics}
     3\chapter{Basics}\label{basics}
    44% ======================================================================
    55% ======================================================================
    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.
     6Before 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.
    77
    88\section{Basics of concurrency}
    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.
     9At 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.
    1410
    1511\section{\protect\CFA 's Thread Building Blocks}
    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.
     12One 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 to 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.
    1713
    1814\section{Coroutines: A stepping stone}\label{coroutine}
    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;
     15While 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
     17Here 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;
    12335                fn2 = fn1;
    12436                fn1 = this.fn;
    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}
     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}
    14359
    14460\subsection{Construction}
    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.
     61One 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
     63The 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 still leak coroutines before they are ready. There are several solutions to this problem but the chosen options effectively forces the design of the coroutine.
    14864
    14965Furthermore, \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:
     
    16278}
    16379\end{cfacode}
    164 
    16580The generated C code\footnote{Code trimmed down for brevity} creates a local thunk to hold type information:
    16681
     
    18095}
    18196\end{ccode}
    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.
     97The 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 in 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.
    18398
    18499\subsection{Alternative: Composition}
    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 
     100One 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}
     113There 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.
    248114
    249115\subsection{Alternative: Reserved keyword}
     
    251117
    252118\begin{cfacode}
    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.
     119        coroutine Fibonacci {
     120              int fn; // used for communication
     121        };
     122\end{cfacode}
     123This 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.
     124While 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.
    258125
    259126\subsection{Alternative: Lamda Objects}
     
    292159      coroutine_desc * get_coroutine(T & this);
    293160};
    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.
     161\end{cfacode}
     162This 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.
    299163
    300164\begin{center}
     
    322186\end{center}
    323187
    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.
     188The combination of these two approaches allows users new to concurrency to have a easy and concise method while more advanced users can expose themselves to otherwise hidden pitfalls at the benefit of tighter control on memory layout and initialization.
    325189
    326190\section{Thread Interface}\label{threads}
     
    328192
    329193\begin{cfacode}
    330 thread foo {};
     194        thread foo {};
    331195\end{cfacode}
    332196
     
    341205\end{cfacode}
    342206
    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.
     207Obviously, 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
     216In 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
     235An 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
     237Of 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.
    373238\begin{cfacode}
    374239thread World;
     
    389254\end{cfacode}
    390255
    391 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
     256This 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 scale to multiple threads meaning basic synchronisation is very simple
    392257
    393258\begin{cfacode}
     
    411276\end{cfacode}
    412277
    413 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
     278However, 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 created much like dynamically allocating memory lets objects outlive the scope in which they are created
    414279
    415280\begin{cfacode}
     
    418283};
    419284
     285//main
    420286void main(MyThread & this) {
    421287        //...
     
    425291        MyThread * long_lived;
    426292        {
     293                MyThread short_lived;
    427294                //Start a thread at the beginning of the scope
    428                 MyThread short_lived;
     295
     296                DoStuff();
    429297
    430298                //create another thread that will outlive the thread in this scope
    431299                long_lived = new MyThread;
    432300
    433                 DoStuff();
    434 
    435301                //Wait for the thread short_lived to finish
    436302        }
    437303        DoMoreStuff();
    438304
    439         //Now wait for the long_lived to finish
     305        //Now wait for the short_lived to finish
    440306        delete long_lived;
    441307}
  • doc/proposals/concurrency/text/cforall.tex

    r6840e7c rb96ec83  
    55% ======================================================================
    66
    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.
     7As 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 language specifically tailored to the features needed to support concurrency.
    88
    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}
     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}
    1010
    1111\section{References}
    1212
    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 :
     13Like \CC, \CFA introduces references as an alternative to pointers. In regards to concurrency, the semantics difference between pointers and references aren't particularly relevant but since this document uses mostly references here is a quick overview of the semantics :
    1414\begin{cfacode}
    1515int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
    1616&r1 = x,    &&r2 = r1,   &&&r3 = r2;
    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
     17***p3 = 3;                                      // change x
     18r3 = 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
     24int y, z, & ar[3] = { x, y, z };                // initialize array of references
     25&ar[1] = &z;                                    // change reference array element
     26typeof( ar[1] ) p;                              // is int, i.e., the type of referenced object
     27typeof( &ar[1] ) q;                             // is int &, i.e., the type of reference
     28sizeof( ar[1] ) == sizeof( int );               // is true, i.e., the size of referenced object
     29sizeof( &ar[1] ) == sizeof( int *);             // is true, i.e., the size of a reference
    2630\end{cfacode}
    2731The 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.
     
    2933\section{Overloading}
    3034
    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.
     35Another important feature \CFA has in common with \CC is function overloading :
    3236\begin{cfacode}
    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)
     37// selection based on type and number of parameters
     38void f( void );                                 // (1)
     39void f( char );                                 // (2)
     40void f( int, double );                          // (3)
     41f();                                            // select (1)
     42f( 'a' );                                       // select (2)
     43f( 3, 5.2 );                                    // select (3)
    4044
    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)
     45// selection based on  type and number of returns
     46char f( int );                                  // (1)
     47double f( int );                                // (2)
     48[ int, double ] f( int );                       // (3)
     49char c = f( 3 );                                // select (1)
     50double d = f( 4 );                              // select (2)
     51[ int, double ] t = f( 5 );                     // select (3)
    4652\end{cfacode}
    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.
     53This 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.
    4854
    4955\section{Operators}
    5056Overloading 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 :
    5157\begin{cfacode}
    52 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
     58int ++?( int op );                              // unary prefix increment
     59int ?++( int op );                              // unary postfix increment
     60int ?+?( int op1, int op2 );                    // binary plus
     61int ?<=?( int op1, int op2 );                   // binary less than
     62int ?=?( int & op1, int op2 );                  // binary assignment
     63int ?+=?( int & op1, int op2 );                 // binary plus-assignment
    5864
    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};
     65struct S { int i, j; };
     66S ?+?( S op1, S op2 ) {                         // add two structures
     67        return (S){ op1.i + op2.i, op1.j + op2.j };
    6268}
    63 S s1 = {1, 2}, s2 = {2, 3}, s3;
    64 s3 = s1 + s2;                                           //compute sum: s3 == {2, 5}
     69S s1 = { 1, 2 }, s2 = { 2, 3 }, s3;
     70s3 = s1 + s2;                                   // compute sum: s3 == { 2, 5 }
    6571\end{cfacode}
    66 While concurrency does not use operator overloading directly, this feature is more important as an introduction for the syntax of constructors.
     72
     73Since concurrency does not use operator overloading, this feature is more important as an introduction for the syntax of constructors.
    6774
    6875\section{Constructors/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 :
     76\CFA uses the following syntax for constructors and destructors :
    7077\begin{cfacode}
    7178struct S {
     
    7380        int * ia;
    7481};
    75 void ?{}(S & s, int asize) {    //constructor operator
    76         s.size = asize;                         //initialize fields
    77         s.ia = calloc(size, sizeof(S));
     82void ?{}( S & s, int asize ) with s {           // constructor operator
     83        size = asize;                           // initialize fields
     84        ia = calloc( size, sizeof( S ) );
    7885}
    79 void ^?{}(S & s) {                              //destructor operator
    80         free(ia);                                       //de-initialization fields
     86void ^?{}( S & s ) with s {                     // destructor operator
     87        free( ia );                             // de-initialization fields
    8188}
    8289int main() {
    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)
     90        S x = { 10 }, y = { 100 };              // implict calls: ?{}( x, 10 ), ?{}( y, 100 )
     91        ...                                     // use x and y
     92        ^x{};  ^y{};                            // explicit calls to de-initialize
     93        x{ 20 };  y{ 200 };                     // explicit calls to reinitialize
     94        ...                                     // reuse x and y
     95}                                               // implict calls: ^?{}( y ), ^?{}( x )
    8996\end{cfacode}
    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.
     97The 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.
    10198
    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}.
     99For more information see \cite{cforall-ug,rob-thesis,www-cfa}.
  • doc/proposals/concurrency/text/concurrency.tex

    r6840e7c rb96ec83  
    44% ======================================================================
    55% ======================================================================
    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.
     6Several 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 that 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.
    77
    88Approaches 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}.
    99
    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.
     10An 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 purpose language, which is why it was rejected as the core paradigm for concurrency in \CFA.
     11
     12One 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.
    1313
    1414\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 provide numerous mechanisms to establish timing relationships among threads.
     15Non-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.
    1616
    1717\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 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.
     18As 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 composable 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.
    1919
    2020\subsection{Synchronization}
    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.
     21As 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.
    2222
    2323% ======================================================================
     
    2828A 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 :
    2929\begin{cfacode}
    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 }
     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        }
    3737\end{cfacode}
    3838
     
    4747
    4848\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}
     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
     58Here, 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
     60Having 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
     63The next semantic decision is to establish when \code{mutex} may be used as a type qualifier. Consider the following declarations:
     64\begin{cfacode}
     65int f1(monitor & mutex m);
     66int f2(const monitor & mutex m);
     67int f3(monitor ** mutex m);
     68int f4(monitor * mutex m []);
     69int f5(graph(monitor*) & mutex m);
     70\end{cfacode}
     71The 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}
     74int f1(monitor & mutex m);   //Okay : recommanded case
     75int f2(monitor * mutex m);   //Okay : could be an array but probably not
     76int f3(monitor mutex m []);  //Not Okay : Array of unkown length
     77int f4(monitor ** mutex m);  //Not Okay : Could be an array
     78int f5(monitor * mutex m []); //Not Okay : Array of unkown length
     79\end{cfacode}
     80
     81Unlike 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}
     83int f(MonitorA & mutex a, MonitorB & mutex b);
     84
     85MonitorA a;
     86MonitorB b;
     87f(a,b);
     88\end{cfacode}
     89The 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}
     103The 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
     105However, 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}
     110While 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
     112Finally, 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}
     114monitor bank {
     115        int money;
     116        log_t usr_log;
     117};
     118
     119void deposit( bank & mutex b, int deposit ) {
     120        b.money += deposit;
     121        b.usr_log | "Adding" | deposit | endl;
     122}
     123
     124void 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% ======================================================================
     135Once 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}
     137monitor counter_t {
     138        int value;
     139};
     140
     141void ?{}(counter_t & this) {
     142        this.cnt = 0;
     143}
     144
     145int ?++(counter_t & mutex this) {
     146        return ++this.value;
     147}
     148
     149//need for mutex is platform dependent here
     150void ?{}(int * this, counter_t & mutex cnt) {
     151        *this = (int)cnt;
     152}
     153\end{cfacode}
     154
    57155This counter is used as follows:
    58156\begin{center}
     
    73171Notice how the counter is used without any explicit synchronisation and yet supports thread-safe semantics for both reading and writting.
    74172
    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}
    166 \begin{center}
    167 \begin{tabular}{|c|c|}
    168 function call & \code{mutex} statement \\
     173% ======================================================================
     174% ======================================================================
     175\subsection{Implementation Details: Interaction with polymorphism}
     176% ======================================================================
     177% ======================================================================
     178Depending 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
     180First 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
     182Before 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:
     183\begin{center}
     184\setlength\tabcolsep{1.5pt}
     185\begin{tabular}{|c|c|c|}
     186Code & \gls{callsite-locking} & \gls{entry-point-locking} \\
     187\CFA & pseudo-code & pseudo-code \\
    169188\hline
    170189\begin{cfacode}[tabsize=3]
    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}
     190void foo(monitor& mutex a){
     191
     192
     193
     194        //Do Work
     195        //...
     196
     197}
     198
     199void main() {
     200        monitor a;
     201
     202
     203
     204        foo(a);
     205
     206}
     207\end{cfacode} & \begin{pseudo}[tabsize=3]
     208foo(& a) {
     209
     210
     211
     212        //Do Work
     213        //...
     214
     215}
     216
     217main() {
     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]
     226foo(& a) {
     227        //called routine
     228        //handles concurrency
     229        acquire(a);
     230        //Do Work
     231        //...
     232        release(a);
     233}
     234
     235main() {
     236        monitor a;
     237
     238
     239
     240        foo(a);
     241
     242}
     243\end{pseudo}
    189244\end{tabular}
    190245\end{center}
    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 }
     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
     249Note 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
     253forall(dtype T)
     254void foo(T * mutex t);
     255
     256//Correct
     257//this function only works on monitors
     258//(any monitor)
     259forall(dtype T | is_monitor(T))
     260void bar(T * mutex t));
    218261\end{cfacode}
    219262
     
    224267% ======================================================================
    225268% ======================================================================
    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.
     269In 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 once in a way that is natural to the user but requires additional complexity on the implementation side.
    227270
    228271First, here is a simple example of such a technique:
    229272
    230273\begin{cfacode}
    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.
     274        monitor A {
     275                condition e;
     276        }
     277
     278        void foo(A & mutex a) {
     279                ...
     280                // Wait for cooperation from bar()
     281                wait(a.e);
     282                ...
     283        }
     284
     285        void bar(A & mutex a) {
     286                // Provide cooperation for foo()
     287                ...
     288                // Unblock foo at scope exit
     289                signal(a.e);
     290        }
     291\end{cfacode}
     292
     293There are two details to note here. First, there \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
     295An important aspect to take into account here 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.
    253296
    254297% ======================================================================
     
    257300% ======================================================================
    258301% ======================================================================
    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.
     302It 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.
    260303
    261304\begin{multicols}{2}
     
    276319\end{pseudo}
    277320\end{multicols}
    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:
     321The 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 it is a logical requirement for barging prevention.
     322
     323A direct extension of the previous example is the \gls{group-acquire} version:
    281324
    282325\begin{multicols}{2}
     
    295338\end{pseudo}
    296339\end{multicols}
    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 :
     340This 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
     342While 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
    300344\begin{multicols}{2}
    301345\begin{pseudo}
     
    310354
    311355\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}
    333356
    334357acquire B
     
    339362\end{multicols}
    340363
    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]
     364The next example is where \gls{group-acquire} adds a significant layer of complexity to the internal signalling semantics.
     365
    344366\begin{multicols}{2}
    345367Waiting thread
    346368\begin{pseudo}[numbers=left]
    347369acquire A
    348         //Code Section 1
     370        // Code Section 1
    349371        acquire A & B
    350                 //Code Section 2
     372                // Code Section 2
    351373                wait A & B
    352                 //Code Section 3
     374                // Code Section 3
    353375        release A & B
    354         //Code Section 4
     376        // Code Section 4
    355377release A
    356378\end{pseudo}
     
    361383\begin{pseudo}[numbers=left, firstnumber=10]
    362384acquire A
    363         //Code Section 5
     385        // Code Section 5
    364386        acquire A & B
    365                 //Code Section 6
     387                // Code Section 6
    366388                signal A & B
    367                 //Code Section 7
     389                // Code Section 7
    368390        release A & B
    369         //Code Section 8
     391        // Code Section 8
    370392release A
    371393\end{pseudo}
    372394\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.
     395\begin{center}
     396Listing 1
     397\end{center}
     398
     399It 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:
    418400
    419401\subsubsection{Delaying signals}
    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.
     402The 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.
    421403\begin{multicols}{2}
    422404Waiter
     
    442424\end{pseudo}
    443425\end{multicols}
    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:
     426However, 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
    445428\begin{multicols}{2}
    446429Thread 1
     
    463446
    464447Thread 3
    465 \begin{pseudo}[numbers=left, firstnumber=9]
     448\begin{pseudo}[numbers=left, firstnumber=10]
    466449acquire A
    467450        acquire A & B
     
    484467Note 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.
    485468
    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.
     469In 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.
    487470
    488471\subsubsection{Dependency graphs}
    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:
     472In 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:
    490473
    491474\begin{multicols}{2}
     
    512495\end{pseudo}
    513496\end{multicols}
    514 
    515 \begin{figure}
    516 \begin{multicols}{3}
    517 Thread $\alpha$
    518 \begin{pseudo}[numbers=left, firstnumber=1]
     497Resolving dependency graph being a complex and expensive endeavour, this solution is not the preffered one.
     498
     499\subsubsection{Partial signalling} \label{partial-sig}
     500Finally, 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]
    519504acquire A
    520505        acquire A & B
     
    526511\columnbreak
    527512
    528 Thread $\gamma$
    529 \begin{pseudo}[numbers=left, firstnumber=1]
     513\begin{pseudo}[numbers=left, firstnumber=6]
    530514acquire A
    531515        acquire A & B
    532516                signal A & B
    533517        release A & B
    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 
     518        // ... More code
     519release A
     520\end{pseudo}
    547521\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.
     522The 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.
    586523
    587524% ======================================================================
     
    592529An 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}.
    593530
    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}
     531For example here is an example highlighting the difference in behaviour:
     532\begin{center}
    596533\begin{tabular}{|c|c|}
    597534\code{signal} & \code{signal_block} \\
    598535\hline
    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
     536\begin{cfacode}
     537monitor M { int val; };
     538
     539void 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
     549void 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}
     559monitor M { int val; };
     560
     561void 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
     571void 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;
    692579}
    693580\end{cfacode}
    694581\end{tabular}
    695 \caption{Dating service example using \code{signal} and \code{signal_block}. }
    696 \label{lst:datingservice}
    697 \end{figure}
     582\end{center}
     583Assuming 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}
     590Foo: 0
     591Bar: 1
     592Bar: 2
     593Foo: 3
     594\end{pseudo}&\begin{pseudo}
     595Foo: 0
     596Bar: 1
     597Foo: 2
     598Bar: 3
     599\end{pseudo}
     600\end{tabular}
     601\end{center}
     602
     603As 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% ======================================================================
     610There 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
     612The 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
     614Since 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
     616The following figure is the traditionnal illustration of a monitor :
     617
     618\begin{center}
     619{\resizebox{0.4\textwidth}{!}{\input{monitor}}}
     620\end{center}
     621
     622For \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
     630This picture and the proper entry and leave algorithms is the fundamental implementation of internal scheduling.
     631
     632\begin{multicols}{2}
     633Entry
     634\begin{pseudo}[numbers=left]
     635if monitor is free
     636        enter
     637elif I already own the monitor
     638        continue
     639else
     640        block
     641increment recursion
     642
     643\end{pseudo}
     644\columnbreak
     645Exit
     646\begin{pseudo}[numbers=left, firstnumber=8]
     647decrement recursion
     648if 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
     659Some 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.
    698660
    699661% ======================================================================
     
    738700\end{tabular}
    739701\end{center}
    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.
     702This 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
     704In 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.
    743705
    744706% ======================================================================
     
    750712
    751713\begin{cfacode}
    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 }
     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        }
    763721\end{cfacode}
    764722
     
    770728        if monitor is free
    771729                enter
    772         elif already own the monitor
     730        elif I already own the monitor
    773731                continue
    774732        elif monitor accepts me
     
    780738\end{center}
    781739
    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:
     740For the fist 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:
    783741
    784742\begin{center}
     
    786744\end{center}
    787745
    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:
     746There 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.
     747The alternative would be to have a picture more like this one:
    790748
    791749\begin{center}
     
    793751\end{center}
    794752
    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.
     753Not 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
     755At 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
     757Another 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.
    800758
    801759% ======================================================================
     
    805763% ======================================================================
    806764
    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 }
     765External scheduling, like internal scheduling, becomes orders of magnitude more complex when we start introducing multi-monitor syntax. Even in the simplest possible case some 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 monitor
     773        }
    816774\end{cfacode}
    817775
     
    819777
    820778\begin{cfacode}
    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}
     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
     788This 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
     800Note 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
     802An 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
     825While 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% ======================================================================
     832To 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
  • doc/proposals/concurrency/text/intro.tex

    r6840e7c rb96ec83  
    33% ======================================================================
    44
    5 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?]
     5This 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 \CFA
    66
    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.
     7There 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 require 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

    r6840e7c rb96ec83  
    1111\section{Paradigm}
    1212\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 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.
     13A 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 expensives 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.
    1414
    1515Examples of languages that support \glspl{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
    1616
    1717\subsection{Fibers : user-level threads without preemption}
    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.
     18A popular varient of \glspl{uthread} is what is often reffered 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.
    1919
    2020An example of a language that uses fibers is Go~\cite{Go}
    2121
    2222\subsection{Jobs and thread pools}
    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.
     23The 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 limits 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.
    2424
    2525The gold standard of this implementation is Intel's TBB library~\cite{TBB}.
    2626
    2727\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 (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.
     28While 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.
    2929
     30\newpage
    3031\TODO
    31 
    32 \section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel}
     32\subsection{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel}
    3333
    3434
    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.
     35\subsection{Paradigms}\label{cfaparadigms}
     36Given 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.
    3737
    38 \subsection{Paradigms}\label{cfaparadigms}
    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}.
     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?
  • doc/proposals/concurrency/thesis.tex

    r6840e7c rb96ec83  
    11% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    22
    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-^
    99% math escape $...$ (dollar symbol)
    1010
     
    2727\usepackage{multicol}
    2828\usepackage[acronym]{glossaries}
    29 \usepackage{varioref}
     29\usepackage{varioref}   
    3030\usepackage{listings}                                           % format program code
    3131\usepackage[flushmargin]{footmisc}                              % support label/reference in footnote
     
    7070%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    7171
    72 \setcounter{secnumdepth}{2}                           % number subsubsections
    73 \setcounter{tocdepth}{2}                              % subsubsections in table of contents
     72\setcounter{secnumdepth}{3}                           % number subsubsections
     73\setcounter{tocdepth}{3}                              % subsubsections in table of contents
    7474% \linenumbers                                          % comment out to turn off line numbering
    7575\makeindex
     
    103103\input{parallelism}
    104104
    105 \input{internals}
    106 
    107 \input{together}
    108 
    109 \input{future}
     105\chapter{Putting it all together}
    110106
    111107\chapter{Conclusion}
     108
     109\chapter{Future work}
     110Concurrency 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}
    112112
    113113\section*{Acknowledgements}
  • doc/proposals/concurrency/version

    r6840e7c rb96ec83  
    1 0.10.212
     10.9.180
  • src/CodeGen/CodeGenerator.cc

    r6840e7c rb96ec83  
    287287        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    288288                assertf( ! genC, "TypeDecls should not reach code generation." );
    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() ) {
     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() ) {
    294294                        output << " | { ";
    295                         for ( DeclarationWithType * assert :  typeDecl->assertions ) {
    296                                 assert->accept( *visitor );
    297                                 output << "; ";
    298                         }
     295                        genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() );
    299296                        output << " }";
    300297                }
     
    949946                output << ";";
    950947        }
    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 
    1014948
    1015949        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
     
    10901024        }
    10911025} // namespace CodeGen
    1092 
    1093 
    1094 unsigned Indenter::tabsize = 2;
    10951026
    10961027std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) {
  • src/CodeGen/CodeGenerator.h

    r6840e7c rb96ec83  
    100100                void postvisit( ReturnStmt * );
    101101                void postvisit( ThrowStmt * );
    102                 void postvisit( CatchStmt * );
    103                 void postvisit( WaitForStmt * );
    104102                void postvisit( WhileStmt * );
    105103                void postvisit( ForStmt * );
  • src/CodeGen/FixNames.cc

    r6840e7c rb96ec83  
    6666                );
    6767
    68                 main_type->get_parameters().push_back(
     68                mainDecl->get_functionType()->get_parameters().push_back(
    6969                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    7070                );
    7171
    72                 main_type->get_parameters().push_back(
     72                mainDecl->get_functionType()->get_parameters().push_back(
    7373                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0,
    7474                        new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ),
  • src/CodeGen/GenType.cc

    r6840e7c rb96ec83  
    210210
    211211        std::string GenType::handleGeneric( ReferenceToType * refType ) {
    212                 if ( ! refType->parameters.empty() ) {
     212                if ( ! refType->get_parameters().empty() ) {
    213213                        std::ostringstream os;
    214214                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    215215                        os << "(";
    216                         cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );
     216                        cg.pass.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
    217217                        os << ") ";
    218218                        return os.str();
  • src/Common/Indenter.h

    r6840e7c rb96ec83  
    1818
    1919struct Indenter {
    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;
     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;
    2523
    2624        Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; }
     
    3230};
    3331
    34 inline std::ostream & operator<<( std::ostream & out, const Indenter & indent ) {
     32inline std::ostream & operator<<( std::ostream & out, Indenter & indent ) {
    3533        return out << std::string(indent.indent, ' ');
    3634}
  • src/Common/PassVisitor.h

    r6840e7c rb96ec83  
    44
    55#include <stack>
    6 
    7 #include "Common/utility.h"
    86
    97#include "SynTree/Mutator.h"
     
    238236        virtual Attribute * mutate( Attribute * attribute ) override final;
    239237
    240         virtual TypeSubstitution * mutate( TypeSubstitution * sub ) final;
    241 
    242238private:
    243239        template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
    244240        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 );
    249241
    250242        template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
     
    281273        std::list< Declaration* > *     get_afterDecls () { return declsToAddAfter_impl ( pass, 0); }
    282274
    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); }
     275        void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); }
    285276
    286277        void indexerScopeEnter  ()                             { indexer_impl_enterScope  ( pass, 0       ); }
  • src/Common/PassVisitor.impl.h

    r6840e7c rb96ec83  
    22// IWYU pragma: private, include "PassVisitor.h"
    33
    4 #define VISIT_START( node )                                     \
    5         __attribute__((unused))                                   \
    6         ChildrenGuard children_guard( get_visit_children_ptr() ); \
    7         __attribute__((unused))                                   \
     4#define VISIT_START( node )                     \
     5        __attribute__((unused))                   \
    86        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
    9         call_previsit( node );                                    \
     7        bool visit_children = true;               \
     8        set_visit_children( visit_children );   \
     9        call_previsit( node );                    \
     10        if( visit_children ) {                    \
    1011
    1112#define VISIT_END( node )                       \
     13        }                                         \
    1214        call_postvisit( node );                   \
    1315
    14 #define MUTATE_START( node )                                    \
    15         __attribute__((unused))                                   \
    16         ChildrenGuard children_guard( get_visit_children_ptr() ); \
    17         __attribute__((unused))                                   \
     16#define MUTATE_START( node )                    \
     17        __attribute__((unused))                   \
    1818        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
    19         call_premutate( node );                                   \
     19        bool visit_children = true;               \
     20        set_visit_children( visit_children );   \
     21        call_premutate( node );                   \
     22        if( visit_children ) {                    \
    2023
    2124#define MUTATE_END( type, node )                \
     25        }                                         \
    2226        return call_postmutate< type * >( node ); \
    2327
    2428
    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 );      \
     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 );   \
    3939
    4040
     
    6363template< typename pass_type >
    6464static inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
     65
    6566        DeclList_t* beforeDecls = visitor.get_beforeDecls();
    6667        DeclList_t* afterDecls  = visitor.get_afterDecls();
     
    7576                try {
    7677                        // run visitor on declaration
    77                         maybeAccept_impl( *i, visitor );
     78                        maybeAccept( *i, visitor );
    7879                } catch( SemanticError &e ) {
    7980                        e.set_location( (*i)->location );
     
    9192template< typename pass_type >
    9293static inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
     94
    9395        DeclList_t* beforeDecls = mutator.get_beforeDecls();
    9496        DeclList_t* afterDecls  = mutator.get_afterDecls();
     
    102104                try {
    103105                        // run mutator on declaration
    104                         maybeMutate_impl( *i, mutator );
     106                        *i = maybeMutate( *i, mutator );
    105107                } catch( SemanticError &e ) {
    106108                        e.set_location( (*i)->location );
     
    116118}
    117119
    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;
     120template< typename Container, typename VisitorType >
     121inline void maybeAccept( Container &container, VisitorType &visitor ) {
    129122        SemanticError errors;
    130123        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
     
    143136}
    144137
    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;
     138template< typename Container, typename MutatorType >
     139inline void maybeMutateRef( Container &container, MutatorType &mutator ) {
    157140        SemanticError errors;
    158141        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    159142                try {
    160143                        if ( *i ) {
     144///                 *i = (*i)->acceptMutator( mutator );
    161145                                *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
    162146                                assert( *i );
     
    175159template< typename func_t >
    176160void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
    177         if ( ! get_visit_children() ) return;
    178161        SemanticError errors;
    179162
     
    216199void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
    217200        handleStatementList( statements, [this]( Statement * stmt) {
    218                 maybeAccept_impl( stmt, *this );
     201                stmt->accept( *this );
    219202        });
    220203}
     
    223206void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    224207        handleStatementList( statements, [this]( Statement *& stmt) {
    225                 maybeMutate_impl( stmt, *this );
     208                stmt = stmt->acceptMutator( *this );
    226209        });
    227210}
     
    231214template< typename func_t >
    232215Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
    233         if ( ! get_visit_children() ) return stmt;
    234 
    235216        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    236217        ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
     
    263244Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
    264245        return handleStatement( stmt, [this]( Statement * stmt ) {
    265                 maybeAccept_impl( stmt, *this );
     246                maybeAccept( stmt, *this );
    266247                return stmt;
    267248        });
     
    271252Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    272253        return handleStatement( stmt, [this]( Statement * stmt ) {
    273                 maybeMutate_impl( stmt, *this );
    274                 return stmt;
     254                return maybeMutate( stmt, *this );
    275255        });
    276256}
     
    279259template< typename func_t >
    280260Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
    281         if ( ! get_visit_children() ) return expr;
    282261        if( !expr ) return nullptr;
    283262
     
    287266        }
    288267
    289         // should env be moved onto the result of the mutate?
     268        // should env be cloned (or moved) onto the result of the mutate?
    290269        return func( expr );
    291270}
     
    294273Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
    295274        return handleExpression(expr, [this]( Expression * expr ) {
    296                 maybeAccept_impl( expr, *this );
     275                expr->accept( *this );
    297276                return expr;
    298277        });
     
    302281Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
    303282        return handleExpression(expr, [this]( Expression * expr ) {
    304                 maybeMutate_impl( expr, *this );
    305                 return expr;
     283                return expr->acceptMutator( *this );
    306284        });
    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 );
    327285}
    328286
     
    361319
    362320        indexerScopedAccept( node->type         , *this );
    363         maybeAccept_impl   ( node->init         , *this );
    364         maybeAccept_impl   ( node->bitfieldWidth, *this );
    365         maybeAccept_impl   ( node->attributes   , *this );
     321        maybeAccept        ( node->init         , *this );
     322        maybeAccept        ( node->bitfieldWidth, *this );
     323        maybeAccept        ( node->attributes   , *this );
    366324
    367325        if ( node->name != "" ) {
     
    377335
    378336        indexerScopedMutate( node->type         , *this );
    379         maybeMutate_impl   ( node->init         , *this );
    380         maybeMutate_impl   ( node->bitfieldWidth, *this );
    381         maybeMutate_impl   ( node->attributes   , *this );
     337        maybeMutateRef     ( node->init         , *this );
     338        maybeMutateRef     ( node->bitfieldWidth, *this );
     339        maybeMutateRef     ( node->attributes   , *this );
    382340
    383341        if ( node->name != "" ) {
     
    400358        {
    401359                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    402                 maybeAccept_impl( node->type, *this );
    403                 maybeAccept_impl( node->statements, *this );
    404                 maybeAccept_impl( node->attributes, *this );
     360                maybeAccept( node->type, *this );
     361                maybeAccept( node->statements, *this );
     362                maybeAccept( node->attributes, *this );
    405363        }
    406364
     
    418376        {
    419377                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    420                 maybeMutate_impl( node->type, *this );
    421                 maybeMutate_impl( node->statements, *this );
    422                 maybeMutate_impl( node->attributes, *this );
     378                maybeMutateRef( node->type, *this );
     379                maybeMutateRef( node->statements, *this );
     380                maybeMutateRef( node->attributes, *this );
    423381        }
    424382
     
    438396        {
    439397                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    440                 maybeAccept_impl( node->parameters, *this );
    441                 maybeAccept_impl( node->members   , *this );
     398                maybeAccept( node->parameters, *this );
     399                maybeAccept( node->members   , *this );
    442400        }
    443401
     
    458416        {
    459417                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    460                 maybeMutate_impl( node->parameters, *this );
    461                 maybeMutate_impl( node->members   , *this );
     418                maybeMutateRef( node->parameters, *this );
     419                maybeMutateRef( node->members   , *this );
    462420        }
    463421
     
    479437        {
    480438                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    481                 maybeAccept_impl( node->parameters, *this );
    482                 maybeAccept_impl( node->members   , *this );
     439                maybeAccept( node->parameters, *this );
     440                maybeAccept( node->members   , *this );
    483441        }
    484442
     
    497455        {
    498456                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    499                 maybeMutate_impl( node->parameters, *this );
    500                 maybeMutate_impl( node->members   , *this );
     457                maybeMutateRef( node->parameters, *this );
     458                maybeMutateRef( node->members   , *this );
    501459        }
    502460
     
    515473
    516474        // unlike structs, traits, and unions, enums inject their members into the global scope
    517         maybeAccept_impl( node->parameters, *this );
    518         maybeAccept_impl( node->members   , *this );
     475        maybeAccept( node->parameters, *this );
     476        maybeAccept( node->members   , *this );
    519477
    520478        VISIT_END( node );
     
    528486
    529487        // unlike structs, traits, and unions, enums inject their members into the global scope
    530         maybeMutate_impl( node->parameters, *this );
    531         maybeMutate_impl( node->members   , *this );
     488        maybeMutateRef( node->parameters, *this );
     489        maybeMutateRef( node->members   , *this );
    532490
    533491        MUTATE_END( Declaration, node );
     
    542500        {
    543501                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    544                 maybeAccept_impl( node->parameters, *this );
    545                 maybeAccept_impl( node->members   , *this );
     502                maybeAccept( node->parameters, *this );
     503                maybeAccept( node->members   , *this );
    546504        }
    547505
     
    557515        {
    558516                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    559                 maybeMutate_impl( node->parameters, *this );
    560                 maybeMutate_impl( node->members   , *this );
     517                maybeMutateRef( node->parameters, *this );
     518                maybeMutateRef( node->members   , *this );
    561519        }
    562520
     
    574532        {
    575533                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    576                 maybeAccept_impl( node->parameters, *this );
    577                 maybeAccept_impl( node->base      , *this );
     534                maybeAccept( node->parameters, *this );
     535                maybeAccept( node->base      , *this );
    578536        }
    579537
     
    583541        indexerAddType( node );
    584542
    585         maybeAccept_impl( node->assertions, *this );
     543        maybeAccept( node->assertions, *this );
    586544
    587545        indexerScopedAccept( node->init, *this );
     
    596554        {
    597555                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    598                 maybeMutate_impl( node->parameters, *this );
    599                 maybeMutate_impl( node->base      , *this );
     556                maybeMutateRef( node->parameters, *this );
     557                maybeMutateRef( node->base      , *this );
    600558        }
    601559
     
    605563        indexerAddType( node );
    606564
    607         maybeMutate_impl( node->assertions, *this );
     565        maybeMutateRef( node->assertions, *this );
    608566
    609567        indexerScopedMutate( node->init, *this );
     
    620578        {
    621579                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    622                 maybeAccept_impl( node->parameters, *this );
    623                 maybeAccept_impl( node->base      , *this );
     580                maybeAccept( node->parameters, *this );
     581                maybeAccept( node->base      , *this );
    624582        }
    625583
    626584        indexerAddType( node );
    627585
    628         maybeAccept_impl( node->assertions, *this );
     586        maybeAccept( node->assertions, *this );
    629587
    630588        VISIT_END( node );
     
    637595        {
    638596                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    639                 maybeMutate_impl( node->parameters, *this );
    640                 maybeMutate_impl( node->base      , *this );
     597                maybeMutateRef     ( node->parameters, *this );
     598                maybeMutateRef( node->base      , *this );
    641599        }
    642600
    643601        indexerAddType( node );
    644602
    645         maybeMutate_impl( node->assertions, *this );
     603        maybeMutateRef( node->assertions, *this );
    646604
    647605        MUTATE_END( Declaration, node );
     
    654612        VISIT_START( node );
    655613
    656         maybeAccept_impl( node->stmt, *this );
     614        maybeAccept( node->stmt, *this );
    657615
    658616        VISIT_END( node );
     
    663621        MUTATE_START( node );
    664622
    665         maybeMutate_impl( node->stmt, *this );
     623        maybeMutateRef( node->stmt, *this );
    666624
    667625        MUTATE_END( AsmDecl, node );
     
    732690                // if statements introduce a level of scope (for the initialization)
    733691                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    734                 maybeAccept_impl( node->get_initialization(), *this );
    735                 visitExpression ( node->condition );
     692                acceptAll( node->get_initialization(), *this );
     693                visitExpression( node->condition );
    736694                node->thenPart = visitStatement( node->thenPart );
    737695                node->elsePart = visitStatement( node->elsePart );
     
    746704                // if statements introduce a level of scope (for the initialization)
    747705                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    748                 maybeMutate_impl( node->get_initialization(), *this );
     706                maybeMutateRef( node->get_initialization(), *this );
    749707                node->condition = mutateExpression( node->condition );
    750708                node->thenPart  = mutateStatement ( node->thenPart  );
     
    784742                // for statements introduce a level of scope (for the initialization)
    785743                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    786                 maybeAccept_impl( node->initialization, *this );
     744                maybeAccept( node->initialization, *this );
    787745                visitExpression( node->condition );
    788746                visitExpression( node->increment );
     
    798756                // for statements introduce a level of scope (for the initialization)
    799757                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    800                 maybeMutate_impl( node->initialization, *this );
     758                maybeMutateRef( node->initialization, *this );
    801759                node->condition = mutateExpression( node->condition );
    802760                node->increment = mutateExpression( node->increment );
     
    901859        VISIT_START( node );
    902860
    903         maybeAccept_impl( node->block       , *this );
    904         maybeAccept_impl( node->handlers    , *this );
    905         maybeAccept_impl( node->finallyBlock, *this );
     861        maybeAccept( node->block       , *this );
     862        maybeAccept( node->handlers    , *this );
     863        maybeAccept( node->finallyBlock, *this );
    906864
    907865        VISIT_END( node );
     
    912870        MUTATE_START( node );
    913871
    914         maybeMutate_impl( node->block       , *this );
    915         maybeMutate_impl( node->handlers    , *this );
    916         maybeMutate_impl( node->finallyBlock, *this );
     872        maybeMutateRef( node->block       , *this );
     873        maybeMutateRef( node->handlers    , *this );
     874        maybeMutateRef( node->finallyBlock, *this );
    917875
    918876        MUTATE_END( Statement, node );
     
    927885                // catch statements introduce a level of scope (for the caught exception)
    928886                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    929                 maybeAccept_impl( node->decl, *this );
     887                maybeAccept( node->decl, *this );
    930888                node->cond = visitExpression( node->cond );
    931889                node->body = visitStatement ( node->body );
     
    940898                // catch statements introduce a level of scope (for the caught exception)
    941899                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    942                 maybeMutate_impl( node->decl, *this );
     900                maybeMutateRef( node->decl, *this );
    943901                node->cond = mutateExpression( node->cond );
    944902                node->body = mutateStatement ( node->body );
     
    1014972
    1015973        indexerScopedAccept( node->result  , *this );
    1016         maybeAccept_impl        ( node->function, *this );
    1017         maybeAccept_impl        ( node->args    , *this );
     974        maybeAccept        ( node->function, *this );
     975        maybeAccept        ( node->args    , *this );
    1018976
    1019977        VISIT_END( node );
     
    1026984        indexerScopedMutate( node->env     , *this );
    1027985        indexerScopedMutate( node->result  , *this );
    1028         maybeMutate_impl   ( node->function, *this );
    1029         maybeMutate_impl   ( node->args    , *this );
     986        maybeMutateRef     ( node->function, *this );
     987        maybeMutateRef     ( node->args    , *this );
    1030988
    1031989        MUTATE_END( Expression, node );
     
    1038996        VISIT_START( node );
    1039997
    1040         // maybeAccept_impl( node->get_env(), *this );
     998        // maybeAccept( node->get_env(), *this );
    1041999        indexerScopedAccept( node->result, *this );
    10421000
     
    10901048
    10911049        indexerScopedAccept( node->result, *this );
    1092         maybeAccept_impl        ( node->arg   , *this );
     1050        maybeAccept        ( node->arg   , *this );
    10931051
    10941052        VISIT_END( node );
     
    11011059        indexerScopedMutate( node->env   , *this );
    11021060        indexerScopedMutate( node->result, *this );
    1103         maybeMutate_impl   ( node->arg   , *this );
     1061        maybeMutateRef     ( node->arg   , *this );
    11041062
    11051063        MUTATE_END( Expression, node );
     
    11131071
    11141072        indexerScopedAccept( node->result, *this );
    1115         maybeAccept_impl( node->arg, *this );
     1073        maybeAccept( node->arg, *this );
    11161074
    11171075        VISIT_END( node );
     
    11241082        indexerScopedMutate( node->env   , *this );
    11251083        indexerScopedMutate( node->result, *this );
    1126         maybeMutate_impl   ( node->arg   , *this );
     1084        maybeMutateRef     ( node->arg   , *this );
    11271085
    11281086        MUTATE_END( Expression, node );
     
    11361094
    11371095        indexerScopedAccept( node->result, *this );
    1138         maybeAccept_impl   ( node->arg   , *this );
     1096        maybeAccept        ( node->arg   , *this );
    11391097
    11401098        VISIT_END( node );
     
    11471105        indexerScopedMutate( node->env   , *this );
    11481106        indexerScopedMutate( node->result, *this );
    1149         maybeMutate_impl   ( node->arg   , *this );
     1107        maybeMutateRef     ( node->arg   , *this );
    11501108
    11511109        MUTATE_END( Expression, node );
     
    11801138
    11811139        indexerScopedAccept( node->result   , *this );
    1182         maybeAccept_impl   ( node->aggregate, *this );
    1183         maybeAccept_impl   ( node->member   , *this );
     1140        maybeAccept        ( node->aggregate, *this );
     1141        maybeAccept        ( node->member   , *this );
    11841142
    11851143        VISIT_END( node );
     
    11921150        indexerScopedMutate( node->env      , *this );
    11931151        indexerScopedMutate( node->result   , *this );
    1194         maybeMutate_impl   ( node->aggregate, *this );
    1195         maybeMutate_impl   ( node->member   , *this );
     1152        maybeMutateRef     ( node->aggregate, *this );
     1153        maybeMutateRef     ( node->member   , *this );
    11961154
    11971155        MUTATE_END( Expression, node );
     
    12051163
    12061164        indexerScopedAccept( node->result   , *this );
    1207         maybeAccept_impl   ( node->aggregate, *this );
     1165        maybeAccept        ( node->aggregate, *this );
    12081166
    12091167        VISIT_END( node );
     
    12161174        indexerScopedMutate( node->env      , *this );
    12171175        indexerScopedMutate( node->result   , *this );
    1218         maybeMutate_impl   ( node->aggregate, *this );
     1176        maybeMutateRef     ( node->aggregate, *this );
    12191177
    12201178        MUTATE_END( Expression, node );
     
    12491207
    12501208        indexerScopedAccept( node->result   , *this );
    1251         maybeAccept_impl   ( &node->constant, *this );
     1209        maybeAccept        ( &node->constant, *this );
    12521210
    12531211        VISIT_END( node );
     
    12601218        indexerScopedMutate( node->env   , *this );
    12611219        indexerScopedMutate( node->result, *this );
    1262         Constant * ptr = &node->constant;
    1263         maybeMutate_impl( ptr, *this );
    1264         node->constant = *ptr;
     1220        node->constant = *maybeMutate( &node->constant, *this );
    12651221
    12661222        MUTATE_END( Expression, node );
     
    12751231        indexerScopedAccept( node->result, *this );
    12761232        if ( node->get_isType() ) {
    1277                 maybeAccept_impl( node->type, *this );
     1233                maybeAccept( node->type, *this );
    12781234        } else {
    1279                 maybeAccept_impl( node->expr, *this );
     1235                maybeAccept( node->expr, *this );
    12801236        }
    12811237
     
    12901246        indexerScopedMutate( node->result, *this );
    12911247        if ( node->get_isType() ) {
    1292                 maybeMutate_impl( node->type, *this );
     1248                maybeMutateRef( node->type, *this );
    12931249        } else {
    1294                 maybeMutate_impl( node->expr, *this );
     1250                maybeMutateRef( node->expr, *this );
    12951251        }
    12961252
     
    13061262        indexerScopedAccept( node->result, *this );
    13071263        if ( node->get_isType() ) {
    1308                 maybeAccept_impl( node->type, *this );
     1264                maybeAccept( node->type, *this );
    13091265        } else {
    1310                 maybeAccept_impl( node->expr, *this );
     1266                maybeAccept( node->expr, *this );
    13111267        }
    13121268
     
    13211277        indexerScopedMutate( node->result, *this );
    13221278        if ( node->get_isType() ) {
    1323                 maybeMutate_impl( node->type, *this );
     1279                maybeMutateRef( node->type, *this );
    13241280        } else {
    1325                 maybeMutate_impl( node->expr, *this );
     1281                maybeMutateRef( node->expr, *this );
    13261282        }
    13271283
     
    13361292
    13371293        indexerScopedAccept( node->result, *this );
    1338         maybeAccept_impl   ( node->type  , *this );
     1294        maybeAccept        ( node->type  , *this );
    13391295
    13401296        VISIT_END( node );
     
    13471303        indexerScopedMutate( node->env   , *this );
    13481304        indexerScopedMutate( node->result, *this );
    1349         maybeMutate_impl   ( node->type  , *this );
     1305        maybeMutateRef     ( node->type  , *this );
    13501306
    13511307        MUTATE_END( Expression, node );
     
    13591315
    13601316        indexerScopedAccept( node->result, *this );
    1361         maybeAccept_impl   ( node->type  , *this );
    1362         maybeAccept_impl   ( node->member, *this );
     1317        maybeAccept        ( node->type  , *this );
     1318        maybeAccept        ( node->member, *this );
    13631319
    13641320        VISIT_END( node );
     
    13711327        indexerScopedMutate( node->env   , *this );
    13721328        indexerScopedMutate( node->result, *this );
    1373         maybeMutate_impl   ( node->type  , *this );
    1374         maybeMutate_impl   ( node->member, *this );
     1329        maybeMutateRef     ( node->type  , *this );
     1330        maybeMutateRef     ( node->member, *this );
    13751331
    13761332        MUTATE_END( Expression, node );
     
    13841340
    13851341        indexerScopedAccept( node->result, *this );
    1386         maybeAccept_impl   ( node->type  , *this );
     1342        maybeAccept        ( node->type  , *this );
    13871343
    13881344        VISIT_END( node );
     
    13951351        indexerScopedMutate( node->env   , *this );
    13961352        indexerScopedMutate( node->result, *this );
    1397         maybeMutate_impl   ( node->type  , *this );
     1353        maybeMutateRef     ( node->type  , *this );
    13981354
    13991355        MUTATE_END( Expression, node );
     
    14081364        indexerScopedAccept( node->result, *this );
    14091365        if ( node->get_isType() ) {
    1410                 maybeAccept_impl( node->type, *this );
     1366                maybeAccept( node->type, *this );
    14111367        } else {
    1412                 maybeAccept_impl( node->expr, *this );
     1368                maybeAccept( node->expr, *this );
    14131369        }
    14141370
     
    14231379        indexerScopedMutate( node->result, *this );
    14241380        if ( node->get_isType() ) {
    1425                 maybeMutate_impl( node->type, *this );
     1381                maybeMutateRef( node->type, *this );
    14261382        } else {
    1427                 maybeMutate_impl( node->expr, *this );
     1383                maybeMutateRef( node->expr, *this );
    14281384        }
    14291385
     
    14381394
    14391395        indexerScopedAccept( node->result, *this );
    1440         maybeAccept_impl   ( node->arg1  , *this );
    1441         maybeAccept_impl   ( node->arg2  , *this );
     1396        maybeAccept        ( node->arg1  , *this );
     1397        maybeAccept        ( node->arg2  , *this );
    14421398
    14431399        VISIT_END( node );
     
    14501406        indexerScopedMutate( node->env   , *this );
    14511407        indexerScopedMutate( node->result, *this );
    1452         maybeMutate_impl   ( node->arg1  , *this );
    1453         maybeMutate_impl   ( node->arg2  , *this );
     1408        maybeMutateRef     ( node->arg1  , *this );
     1409        maybeMutateRef     ( node->arg2  , *this );
    14541410
    14551411        MUTATE_END( Expression, node );
     
    14631419
    14641420        indexerScopedAccept( node->result, *this );
    1465         maybeAccept_impl        ( node->arg1  , *this );
    1466         maybeAccept_impl        ( node->arg2  , *this );
    1467         maybeAccept_impl        ( node->arg3  , *this );
     1421        maybeAccept        ( node->arg1  , *this );
     1422        maybeAccept        ( node->arg2  , *this );
     1423        maybeAccept        ( node->arg3  , *this );
    14681424
    14691425        VISIT_END( node );
     
    14761432        indexerScopedMutate( node->env   , *this );
    14771433        indexerScopedMutate( node->result, *this );
    1478         maybeMutate_impl   ( node->arg1  , *this );
    1479         maybeMutate_impl   ( node->arg2  , *this );
    1480         maybeMutate_impl   ( node->arg3  , *this );
     1434        maybeMutateRef     ( node->arg1  , *this );
     1435        maybeMutateRef     ( node->arg2  , *this );
     1436        maybeMutateRef     ( node->arg3  , *this );
    14811437
    14821438        MUTATE_END( Expression, node );
     
    14901446
    14911447        indexerScopedAccept( node->result, *this );
    1492         maybeAccept_impl   ( node->arg1  , *this );
    1493         maybeAccept_impl   ( node->arg2  , *this );
     1448        maybeAccept        ( node->arg1  , *this );
     1449        maybeAccept        ( node->arg2  , *this );
    14941450
    14951451        VISIT_END( node );
     
    15021458        indexerScopedMutate( node->env   , *this );
    15031459        indexerScopedMutate( node->result, *this );
    1504         maybeMutate_impl   ( node->arg1  , *this );
    1505         maybeMutate_impl   ( node->arg2  , *this );
     1460        maybeMutateRef     ( node->arg1  , *this );
     1461        maybeMutateRef     ( node->arg2  , *this );
    15061462
    15071463        MUTATE_END( Expression, node );
     
    15151471
    15161472        indexerScopedAccept( node->result, *this );
    1517         maybeAccept_impl   ( node->type, *this );
     1473        maybeAccept        ( node->type, *this );
    15181474
    15191475        VISIT_END( node );
     
    15261482        indexerScopedMutate( node->env   , *this );
    15271483        indexerScopedMutate( node->result, *this );
    1528         maybeMutate_impl   ( node->type  , *this );
     1484        maybeMutateRef     ( node->type  , *this );
    15291485
    15301486        MUTATE_END( Expression, node );
     
    15381494
    15391495        indexerScopedAccept( node->result    , *this );
    1540         maybeAccept_impl   ( node->inout     , *this );
    1541         maybeAccept_impl   ( node->constraint, *this );
    1542         maybeAccept_impl   ( node->operand   , *this );
     1496        maybeAccept        ( node->inout     , *this );
     1497        maybeAccept        ( node->constraint, *this );
     1498        maybeAccept        ( node->operand   , *this );
    15431499
    15441500        VISIT_END( node );
     
    15511507        indexerScopedMutate( node->env       , *this );
    15521508        indexerScopedMutate( node->result    , *this );
    1553         maybeMutate_impl   ( node->inout     , *this );
    1554         maybeMutate_impl   ( node->constraint, *this );
    1555         maybeMutate_impl   ( node->operand   , *this );
     1509        maybeMutateRef     ( node->inout     , *this );
     1510        maybeMutateRef     ( node->constraint, *this );
     1511        maybeMutateRef     ( node->operand   , *this );
    15561512
    15571513        MUTATE_END( Expression, node );
     
    15651521
    15661522        indexerScopedAccept( node->result     , *this );
    1567         maybeAccept_impl   ( node->callExpr   , *this );
    1568         maybeAccept_impl   ( node->tempDecls  , *this );
    1569         maybeAccept_impl   ( node->returnDecls, *this );
    1570         maybeAccept_impl   ( node->dtors      , *this );
     1523        maybeAccept        ( node->callExpr   , *this );
     1524        maybeAccept        ( node->tempDecls  , *this );
     1525        maybeAccept        ( node->returnDecls, *this );
     1526        maybeAccept        ( node->dtors      , *this );
    15711527
    15721528        VISIT_END( node );
     
    15791535        indexerScopedMutate( node->env        , *this );
    15801536        indexerScopedMutate( node->result     , *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 );
     1537        maybeMutateRef     ( node->callExpr   , *this );
     1538        maybeMutateRef     ( node->tempDecls  , *this );
     1539        maybeMutateRef     ( node->returnDecls, *this );
     1540        maybeMutateRef     ( node->dtors      , *this );
    15851541
    15861542        MUTATE_END( Expression, node );
     
    15941550
    15951551        indexerScopedAccept( node->result  , *this );
    1596         maybeAccept_impl   ( node->callExpr, *this );
     1552        maybeAccept        ( node->callExpr, *this );
    15971553
    15981554        VISIT_END( node );
     
    16051561        indexerScopedMutate( node->env     , *this );
    16061562        indexerScopedMutate( node->result  , *this );
    1607         maybeMutate_impl   ( node->callExpr, *this );
     1563        maybeMutateRef     ( node->callExpr, *this );
    16081564
    16091565        MUTATE_END( Expression, node );
     
    16171573
    16181574        indexerScopedAccept( node->result     , *this );
    1619         maybeAccept_impl   ( node->initializer, *this );
     1575        maybeAccept        ( node->initializer, *this );
    16201576
    16211577        VISIT_END( node );
     
    16281584        indexerScopedMutate( node->env        , *this );
    16291585        indexerScopedMutate( node->result     , *this );
    1630         maybeMutate_impl     ( node->initializer, *this );
     1586        maybeMutateRef     ( node->initializer, *this );
    16311587
    16321588        MUTATE_END( Expression, node );
     
    16401596
    16411597        indexerScopedAccept( node->result, *this );
    1642         maybeAccept_impl   ( node->low   , *this );
    1643         maybeAccept_impl   ( node->high  , *this );
     1598        maybeAccept        ( node->low   , *this );
     1599        maybeAccept        ( node->high  , *this );
    16441600
    16451601        VISIT_END( node );
     
    16521608        indexerScopedMutate( node->env   , *this );
    16531609        indexerScopedMutate( node->result, *this );
    1654         maybeMutate_impl   ( node->low   , *this );
    1655         maybeMutate_impl   ( node->high  , *this );
     1610        maybeMutateRef     ( node->low   , *this );
     1611        maybeMutateRef     ( node->high  , *this );
    16561612
    16571613        MUTATE_END( Expression, node );
     
    16651621
    16661622        indexerScopedAccept( node->result, *this );
    1667         maybeAccept_impl   ( node->exprs , *this );
     1623        maybeAccept        ( node->exprs , *this );
    16681624
    16691625        VISIT_END( node );
     
    16761632        indexerScopedMutate( node->env   , *this );
    16771633        indexerScopedMutate( node->result, *this );
    1678         maybeMutate_impl   ( node->exprs , *this );
     1634        maybeMutateRef     ( node->exprs , *this );
    16791635
    16801636        MUTATE_END( Expression, node );
     
    16881644
    16891645        indexerScopedAccept( node->result, *this );
    1690         maybeAccept_impl   ( node->exprs , *this );
     1646        maybeAccept          ( node->exprs , *this );
    16911647
    16921648        VISIT_END( node );
     
    16991655        indexerScopedMutate( node->env   , *this );
    17001656        indexerScopedMutate( node->result, *this );
    1701         maybeMutate_impl   ( node->exprs , *this );
     1657        maybeMutateRef     ( node->exprs , *this );
    17021658
    17031659        MUTATE_END( Expression, node );
     
    17111667
    17121668        indexerScopedAccept( node->result, *this );
    1713         maybeAccept_impl   ( node->tuple , *this );
     1669        maybeAccept        ( node->tuple , *this );
    17141670
    17151671        VISIT_END( node );
     
    17221678        indexerScopedMutate( node->env   , *this );
    17231679        indexerScopedMutate( node->result, *this );
    1724         maybeMutate_impl   ( node->tuple , *this );
     1680        maybeMutateRef     ( node->tuple , *this );
    17251681
    17261682        MUTATE_END( Expression, node );
     
    17341690
    17351691        indexerScopedAccept( node->result  , *this );
    1736         maybeAccept_impl   ( node->stmtExpr, *this );
     1692        maybeAccept        ( node->stmtExpr, *this );
    17371693
    17381694        VISIT_END( node );
     
    17451701        indexerScopedMutate( node->env     , *this );
    17461702        indexerScopedMutate( node->result  , *this );
    1747         maybeMutate_impl   ( node->stmtExpr, *this );
     1703        maybeMutateRef     ( node->stmtExpr, *this );
    17481704
    17491705        MUTATE_END( Expression, node );
     
    17621718
    17631719        indexerScopedAccept( node->result     , *this );
    1764         maybeAccept_impl   ( node->statements , *this );
    1765         maybeAccept_impl   ( node->returnDecls, *this );
    1766         maybeAccept_impl   ( node->dtors      , *this );
     1720        maybeAccept        ( node->statements , *this );
     1721        maybeAccept        ( node->returnDecls, *this );
     1722        maybeAccept        ( node->dtors      , *this );
    17671723
    17681724        VISIT_END( node );
     
    17791735
    17801736        indexerScopedMutate( node->result     , *this );
    1781         maybeMutate_impl   ( node->statements , *this );
    1782         maybeMutate_impl   ( node->returnDecls, *this );
    1783         maybeMutate_impl   ( node->dtors      , *this );
     1737        maybeMutateRef     ( node->statements , *this );
     1738        maybeMutateRef     ( node->returnDecls, *this );
     1739        maybeMutateRef     ( node->dtors      , *this );
    17841740
    17851741        MUTATE_END( Expression, node );
     
    17931749
    17941750        indexerScopedAccept( node->result, *this );
    1795         maybeAccept_impl   ( node->expr  , *this );
     1751        maybeAccept        ( node->expr  , *this );
    17961752
    17971753        VISIT_END( node );
     
    18041760        indexerScopedMutate( node->env   , *this );
    18051761        indexerScopedMutate( node->result, *this );
    1806         maybeMutate_impl   ( node->expr  , *this );
     1762        maybeMutateRef     ( node->expr  , *this );
    18071763
    18081764        MUTATE_END( Expression, node );
     
    18491805        {
    18501806                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1851                 maybeAccept_impl( node->forall    , *this );
    1852                 maybeAccept_impl( node->parameters, *this );
     1807                maybeAccept( node->forall    , *this );
     1808                maybeAccept( node->parameters, *this );
    18531809        }
    18541810
     
    18641820        {
    18651821                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1866                 maybeMutate_impl( node->forall    , *this );
    1867                 maybeMutate_impl( node->parameters, *this );
     1822                maybeMutateRef( node->forall    , *this );
     1823                maybeMutateRef( node->parameters, *this );
    18681824        }
    18691825
     
    18811837        {
    18821838                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1883                 maybeAccept_impl( node->forall    , *this );
    1884                 maybeAccept_impl( node->parameters, *this );
     1839                maybeAccept( node->forall    , *this );
     1840                maybeAccept( node->parameters, *this );
    18851841        }
    18861842
     
    18961852        {
    18971853                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1898                 maybeMutate_impl( node->forall    , *this );
    1899                 maybeMutate_impl( node->parameters, *this );
     1854                maybeMutateRef( node->forall    , *this );
     1855                maybeMutateRef( node->parameters, *this );
    19001856        }
    19011857
     
    19211877        VISIT_START( node );
    19221878
    1923         maybeAccept_impl( node->forall    , *this );
    1924         maybeAccept_impl( node->parameters, *this );
     1879        maybeAccept( node->forall    , *this );
     1880        maybeAccept( node->parameters, *this );
    19251881
    19261882        VISIT_END( node );
     
    19311887        MUTATE_START( node );
    19321888
    1933         maybeMutate_impl( node->forall    , *this );
    1934         maybeMutate_impl( node->parameters, *this );
     1889        maybeMutateRef( node->forall    , *this );
     1890        maybeMutateRef( node->parameters, *this );
    19351891
    19361892        MUTATE_END( Type, node );
     
    19781934        VISIT_START( node );
    19791935
    1980         maybeAccept_impl( node->get_designators(), *this );
     1936        maybeAccept( node->get_designators(), *this );
    19811937
    19821938        VISIT_END( node );
     
    19871943        MUTATE_START( node );
    19881944
    1989         maybeMutate_impl( node->get_designators(), *this );
     1945        maybeMutateRef( node->get_designators(), *this );
    19901946
    19911947        MUTATE_END( Designation, node );
     
    21272083        MUTATE_BODY( Attribute, node );
    21282084}
    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

    r6840e7c rb96ec83  
    4646        ~bool_ref() = default;
    4747
    48         operator bool() { return m_ref ? *m_ref : true; }
     48        operator bool() { return *m_ref; }
    4949        bool operator=( bool val ) { return *m_ref = val; }
    5050
    5151private:
    5252
    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;
     53        template<typename pass>
     54        friend class PassVisitor;
     55
     56        void set( bool & val ) { m_ref = &val; };
     57
     58        bool * m_ref;
    6259};
    6360
    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 };
     61template< typename TreeType, typename VisitorType >
     62inline 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
     70template< typename TreeType, typename MutatorType >
     71inline 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
     79template< typename TreeType, typename MutatorType >
     80inline void maybeMutateRef( TreeType *& tree, MutatorType & mutator ) {
     81        tree = maybeMutate( tree, mutator );
     82}
    8683
    8784//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  • src/Common/utility.h

    r6840e7c rb96ec83  
    2828#include <cassert>
    2929
    30 #include "Common/Indenter.h"
    31 
    3230template< typename T >
    3331static inline T * maybeClone( const T *orig ) {
     
    7775
    7876template< typename Container >
    79 void printAll( const Container &container, std::ostream &os, Indenter indent = {} ) {
     77void printAll( const Container &container, std::ostream &os, int indent = 0 ) {
    8078        for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) {
    8179                if ( *i ) {
    82                         os << indent;
    83                         (*i)->print( os, indent );
     80                        os << std::string( indent,  ' ' );
     81                        (*i)->print( os, indent + 2 );
    8482                        // need an endl after each element because it's not easy to know when each individual item should end
    8583                        os << std::endl;
     
    353351template< typename T1, typename T2 >
    354352struct group_iterate_t {
    355 private:
    356         std::tuple<T1, T2> args;
    357 public:
    358353        group_iterate_t( bool skipBoundsCheck, const T1 & v1, const T2 & v2 ) : args(v1, v2) {
    359354                assertf(skipBoundsCheck || v1.size() == v2.size(), "group iteration requires containers of the same size: <%zd, %zd>.", v1.size(), v2.size());
    360355        };
    361356
    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 
    366357        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;
    367363                typedef std::tuple<T1Iter, T2Iter> IterTuple;
    368364                IterTuple it;
     
    374370                value_type operator*() const { return std::tie( *std::get<0>(it), *std::get<1>(it) ); }
    375371        };
    376 
    377372        iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); }
    378373        iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); }
     374
     375private:
     376        std::tuple<T1, T2> args;
    379377};
    380378
  • src/Concurrency/Keywords.cc

    r6840e7c rb96ec83  
    196196                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
    197197                void validate( DeclarationWithType * );
    198                 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    199198                void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    200199
     
    207206                StructDecl* monitor_decl = nullptr;
    208207                StructDecl* guard_decl = nullptr;
    209                 StructDecl* dtor_guard_decl = nullptr;
    210208
    211209                static std::unique_ptr< Type > generic_func;
     
    231229
    232230                void postvisit( FunctionDecl * decl );
    233                 void previsit ( StructDecl   * decl );
    234231
    235232                void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
     
    239236                        acceptAll( translationUnit, impl );
    240237                }
    241 
    242           private :
    243                 bool thread_ctor_seen = false;
    244                 StructDecl * thread_decl = nullptr;
    245238        };
    246239
     
    410403                if( mutexArgs.empty() ) return;
    411404
    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 
    418405                for(auto arg : mutexArgs) {
    419406                        validate( arg );
     
    425412                if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    426413                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    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                 }
     414
     415                addStatments( decl, body, mutexArgs );
    435416        }
    436417
     
    444425                        assert( !guard_decl );
    445426                        guard_decl = decl;
    446                 }
    447                 else if( decl->name == "monitor_dtor_guard_t" ) {
    448                         assert( !dtor_guard_decl );
    449                         dtor_guard_decl = decl;
    450427                }
    451428        }
     
    480457                //Make sure that typed isn't mutex
    481458                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) );
    533459        }
    534460
     
    597523        // General entry routine
    598524        //=============================================================================================
    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 
    606525        void ThreadStarter::postvisit(FunctionDecl * decl) {
    607526                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                 }
    614527
    615528                DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
    616529                auto type  = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) );
    617530                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 
    622531                        addStartStatement( decl, param );
    623532                }
  • src/Concurrency/Waitfor.cc

    r6840e7c rb96ec83  
    190190
    191191                Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
    192                         Expression * expr = makeOpAssign(
     192                        std::unique_ptr< Expression > expr( makeOpAssign(
    193193                                makeOpMember(
    194194                                        makeOpIndex(
     
    199199                                ),
    200200                                value
    201                         );
    202 
    203                         ResolvExpr::findVoidExpression( expr, indexer );
    204 
    205                         return new ExprStmt( noLabels, expr );
     201                        ) );
     202
     203                        return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
    206204                }
    207205
     
    315313                stmt->push_back( new DeclStmt( noLabels, acceptables) );
    316314
    317                 Expression * set = new UntypedExpr(
     315                UntypedExpr * set = new UntypedExpr(
    318316                        new NameExpr( "__builtin_memset" ),
    319317                        {
     
    324322                );
    325323
    326                 ResolvExpr::findVoidExpression( set, indexer );
    327 
    328                 stmt->push_back( new ExprStmt( noLabels, set ) );
     324                Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer );
     325                delete set;
     326
     327                stmt->push_back( new ExprStmt( noLabels, resolved_set ) );
    329328
    330329                return acceptables;
     
    347346
    348347        Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) {
    349                 Expression * expr = new UntypedExpr(
     348                Expression * untyped = new UntypedExpr(
    350349                        new NameExpr( "?=?" ),
    351350                        {
     
    355354                );
    356355
    357                 ResolvExpr::findVoidExpression( expr, indexer );
     356                Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer );
     357                delete untyped;
    358358
    359359                return new ExprStmt( noLabels, expr );
     
    379379                        new ListInit(
    380380                                map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
    381                                         Expression * init = new CastExpr(
     381                                        Expression * untyped = new CastExpr(
    382382                                                new UntypedExpr(
    383383                                                        new NameExpr( "get_monitor" ),
     
    393393                                        );
    394394
    395                                         ResolvExpr::findSingleExpression( init, indexer );
     395                                        Expression * init = ResolvExpr::findSingleExpression( untyped, indexer );
     396                                        delete untyped;
    396397                                        return new SingleInit( init );
    397398                                })
  • src/GenPoly/Box.cc

    r6840e7c rb96ec83  
    600600
    601601                        // add size/align for generic types to parameter list
    602                         if ( ! appExpr->get_function()->result ) return;
     602                        if ( ! appExpr->get_function()->has_result() ) return;
    603603                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
    604604                        assert( funcType );
     
    714714
    715715                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    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();
     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();
    735719                                if ( env ) env->apply( newType );
    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 ) );
     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
    744750                        } // if
    745751                }
     
    959965                                if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    960966                                        if ( varExpr->get_var()->get_name() == "?[?]" ) {
    961                                                 assert( appExpr->result );
     967                                                assert( appExpr->has_result() );
    962968                                                assert( appExpr->get_args().size() == 2 );
    963969                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
     
    993999                                                } // if
    9941000                                        } else if ( varExpr->get_var()->get_name() == "*?" ) {
    995                                                 assert( appExpr->result );
     1001                                                assert( appExpr->has_result() );
    9961002                                                assert( ! appExpr->get_args().empty() );
    9971003                                                if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10101016                                                } // if
    10111017                                        } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
    1012                                                 assert( appExpr->result );
     1018                                                assert( appExpr->has_result() );
    10131019                                                assert( appExpr->get_args().size() == 1 );
    10141020                                                if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10301036                                                } // if
    10311037                                        } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
    1032                                                 assert( appExpr->result );
     1038                                                assert( appExpr->has_result() );
    10331039                                                assert( appExpr->get_args().size() == 1 );
    10341040                                                if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     
    10361042                                                } // if
    10371043                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    1038                                                 assert( appExpr->result );
     1044                                                assert( appExpr->has_result() );
    10391045                                                assert( appExpr->get_args().size() == 2 );
    10401046                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
     
    10621068                                                } // if
    10631069                                        } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
    1064                                                 assert( appExpr->result );
     1070                                                assert( appExpr->has_result() );
    10651071                                                assert( appExpr->get_args().size() == 2 );
    10661072                                                Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env );
     
    11561162                void Pass1::premutate( AddressExpr * ) { visit_children = false; }
    11571163                Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
    1158                         assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() );
     1164                        assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
    11591165
    11601166                        bool needs = false;
    11611167                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    1162                                 if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
     1168                                if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    11631169                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    11641170                                                if ( name->get_name() == "*?" ) {
    11651171                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    1166                                                                 assert( appExpr->get_function()->result );
     1172                                                                assert( appExpr->get_function()->has_result() );
    11671173                                                                FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    11681174                                                                assert( function );
  • src/GenPoly/FindFunction.cc

    r6840e7c rb96ec83  
    1818#include <utility>                      // for pair
    1919
    20 #include "Common/PassVisitor.h"         // for PassVisitor
    2120#include "Common/SemanticError.h"       // for SemanticError
    2221#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::iterator
     
    2827
    2928namespace GenPoly {
    30         class FindFunction : public WithGuards, public WithVisitorRef<FindFunction>, public WithShortCircuiting {
     29        class FindFunction : public Mutator {
    3130          public:
    3231                FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate );
    3332
    34                 void premutate( FunctionType * functionType );
    35                 Type * postmutate( FunctionType * functionType );
    36                 void premutate( PointerType * pointerType );
     33                virtual Type *mutate( FunctionType *functionType );
     34                virtual Type *mutate( PointerType *pointerType );
    3735          private:
    3836                void handleForall( const Type::ForallList &forall );
     
    4543
    4644        void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {
    47                 PassVisitor<FindFunction> finder( functions, tyVars, false, predicate );
     45                FindFunction finder( functions, tyVars, false, predicate );
    4846                type->acceptMutator( finder );
    4947        }
    5048
    5149        void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {
    52                 PassVisitor<FindFunction> finder( functions, tyVars, true, predicate );
     50                FindFunction finder( functions, tyVars, true, predicate );
    5351                type = type->acceptMutator( finder );
    5452        }
     
    5957
    6058        void FindFunction::handleForall( const Type::ForallList &forall ) {
    61                 for ( const Declaration * td : forall ) {
    62                         TyVarMap::iterator var = tyVars.find( td->name );
     59                for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
     60                        TyVarMap::iterator var = tyVars.find( (*i)->get_name() );
    6361                        if ( var != tyVars.end() ) {
    6462                                tyVars.erase( var->first );
     
    6765        }
    6866
    69         void FindFunction::premutate( FunctionType * functionType ) {
    70                 visit_children = false;
    71                 GuardScope( tyVars );
     67        Type * FindFunction::mutate( FunctionType *functionType ) {
     68                tyVars.beginScope();
    7269                handleForall( functionType->get_forall() );
    73                 mutateAll( functionType->get_returnVals(), *visitor );
    74         }
    75 
    76         Type * FindFunction::postmutate( FunctionType * functionType ) {
     70                mutateAll( functionType->get_returnVals(), *this );
    7771                Type *ret = functionType;
    7872                if ( predicate( functionType, tyVars ) ) {
     
    8377                        } // if
    8478                } // if
     79                tyVars.endScope();
    8580                return ret;
    8681        }
    8782
    88         void FindFunction::premutate( PointerType * pointerType ) {
    89                 GuardScope( tyVars );
     83        Type * FindFunction::mutate( PointerType *pointerType ) {
     84                tyVars.beginScope();
    9085                handleForall( pointerType->get_forall() );
     86                Type *ret = Mutator::mutate( pointerType );
     87                tyVars.endScope();
     88                return ret;
    9189        }
    9290} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    r6840e7c rb96ec83  
    432432        }
    433433
    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 
    452434        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    453435                // xxx - should this actually be insert?
  • src/GenPoly/GenPoly.h

    r6840e7c rb96ec83  
    8080        bool typesPolyCompatible( Type *aty, Type *bty );
    8181
    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 
    8882        /// Adds the type variable `tyVar` to `tyVarMap`
    8983        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
  • src/GenPoly/Specialize.cc

    r6840e7c rb96ec83  
    147147
    148148        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    149                 assertf( actual->result, "attempting to specialize an untyped expression" );
     149                assertf( actual->has_result(), "attempting to specialize an untyped expression" );
    150150                if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
    151151                        if ( FunctionType *funType = getFunctionType( formalType ) ) {
  • src/GenPoly/module.mk

    r6840e7c rb96ec83  
    2020       GenPoly/Lvalue.cc \
    2121       GenPoly/Specialize.cc \
     22       GenPoly/CopyParams.cc \
    2223       GenPoly/FindFunction.cc \
    2324       GenPoly/InstantiateGeneric.cc
  • src/InitTweak/FixInit.cc

    r6840e7c rb96ec83  
    9494                        /// true if type does not need to be copy constructed to ensure correctness
    9595                        bool skipCopyConstruct( Type * type );
    96                         void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal );
     96                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    9797                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    9898
     
    259259
    260260                GenStructMemberCalls::generate( translationUnit );
    261 
    262261                // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
    263262                // hack in the way untyped assignments are generated, where the first argument cannot have
     
    289288                        for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    290289                                try {
    291                                         maybeMutate( *i, fixer );
     290                                        *i = maybeMutate( *i, fixer );
    292291                                        translationUnit.splice( i, fixer.pass.staticDtorDecls );
    293292                                } catch( SemanticError &e ) {
     
    323322
    324323                Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
     324                        assert( appExpr );
     325
    325326                        if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
    326                                 if ( function->var->linkage.is_builtin ) {
     327                                if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() ) ) {
    327328                                        // optimization: don't need to copy construct in order to call intrinsic functions
    328329                                        return appExpr;
     
    330331                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    331332                                        assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() );
    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();
     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();
    335336                                                assert( t1 );
    336337
     
    365366                        ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg );
    366367                        ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->get_callStmt() );
    367                         Expression * resolved = exprStmt->expr;
    368                         exprStmt->expr = nullptr; // take ownership of expr
     368                        Expression * untyped = exprStmt->get_expr();
    369369
    370370                        // resolve copy constructor
    371371                        // should only be one alternative for copy ctor and dtor expressions, since all arguments are fixed
    372372                        // (VariableExpr and already resolved expression)
    373                         CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << resolved << std::endl; )
    374                         ResolvExpr::findVoidExpression( resolved, indexer );
     373                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
     374                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );
    375375                        assert( resolved );
    376376                        if ( resolved->get_env() ) {
     
    380380                                resolved->set_env( nullptr );
    381381                        } // if
     382
    382383                        delete stmt;
    383384                        return resolved;
    384385                }
    385386
    386                 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ) {
     387                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    387388                        static UniqueName tempNamer("_tmp_cp");
    388389                        assert( env );
    389390                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; )
    390                         assert( arg->result );
    391                         Type * result = arg->result;
     391                        assert( arg->has_result() );
     392                        Type * result = arg->get_result();
    392393                        if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
    393394
    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).
     395                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
    396396                        result = result->clone();
    397                         env->applyFree( result );
     397                        env->apply( result );
    398398                        ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
    399399                        tmp->get_type()->set_const( false );
     
    406406                                // if the chosen constructor is intrinsic, the copy is unnecessary, so
    407407                                // don't create the temporary and don't call the copy constructor
    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                                 }
     408                                VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     409                                assert( function );
     410                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
    414411                        }
    415412
     
    419416                        // replace argument to function call with temporary
    420417                        arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
    421                         impCpCtorExpr->tempDecls.push_back( tmp );
    422                         impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) );
     418                        impCpCtorExpr->get_tempDecls().push_back( tmp );
     419                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
    423420                }
    424421
     
    430427                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    431428
    432                         ApplicationExpr * appExpr = impCpCtorExpr->callExpr;
     429                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
    433430
    434431                        // take each argument and attempt to copy construct it.
    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 );
     432                        for ( Expression * & arg : appExpr->get_args() ) {
     433                                copyConstructArg( arg, impCpCtorExpr );
    447434                        } // for
    448435
     
    450437                        // initialized with the return value and is destructed later
    451438                        // xxx - handle named return values?
    452                         Type * result = appExpr->result;
     439                        Type * result = appExpr->get_result();
    453440                        if ( ! result->isVoid() ) {
    454441                                static UniqueName retNamer("_tmp_cp_ret");
     
    456443                                env->apply( result );
    457444                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    458                                 ret->type->set_const( false );
    459                                 impCpCtorExpr->returnDecls.push_back( ret );
     445                                ret->get_type()->set_const( false );
     446                                impCpCtorExpr->get_returnDecls().push_back( ret );
    460447                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    461448                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
     
    564551                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    565552                                // move env from callExpr to retExpr
    566                                 std::swap( retExpr->env, callExpr->env );
     553                                retExpr->set_env( callExpr->get_env() );
     554                                callExpr->set_env( nullptr );
    567555                                return retExpr;
    568556                        } else {
     
    766754                                                if ( ctorStmt && (ctorCall = isIntrinsicCallExpr( ctorStmt->expr )) && ctorCall->get_args().size() == 2 ) {
    767755                                                        // clean up intrinsic copy constructor calls by making them into SingleInits
    768                                                         Expression * ctorArg = ctorCall->args.back();
    769                                                         std::swap( ctorArg->env, ctorCall->env );
    770                                                         objDecl->init = new SingleInit( ctorArg );
    771 
     756                                                        objDecl->init = new SingleInit( ctorCall->args.back() );
    772757                                                        ctorCall->args.pop_back();
    773758                                                } else {
     
    837822                        GuardValue( labelVars );
    838823                        labelVars.clear();
    839                         // LabelFinder does not recurse into FunctionDecl, so need to visit
    840                         // its children manually.
    841824                        maybeAccept( funcDecl->type, finder );
    842825                        maybeAccept( funcDecl->statements, finder );
     
    10961079                }
    10971080
    1098                 DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) {
     1081                DeclarationWithType * MutatingResolver::mutate( ObjectDecl *objectDecl ) {
    10991082                        // add object to the indexer assumes that there will be no name collisions
    11001083                        // in generated code. If this changes, add mutate methods for entities with
     
    11041087                }
    11051088
    1106                 Expression * MutatingResolver::mutate( UntypedExpr * untypedExpr ) {
    1107                         Expression * newExpr = untypedExpr;
    1108                         ResolvExpr::findVoidExpression( newExpr, indexer );
    1109                         return newExpr;
     1089                Expression* MutatingResolver::mutate( UntypedExpr *untypedExpr ) {
     1090                        return strict_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) );
    11101091                }
    11111092
     
    11131094                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    11141095                        // xxx - is the size check necessary?
    1115                         assert( ctorExpr->result && ctorExpr->get_result()->size() == 1 );
     1096                        assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
    11161097
    11171098                        // 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.
     
    11321113
    11331114                        // resolve assignment and dispose of new env
    1134                         ResolvExpr::findVoidExpression( assign, indexer );
    1135                         delete assign->env;
    1136                         assign->env = nullptr;
     1115                        Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );
     1116                        delete resolvedAssign->env;
     1117                        resolvedAssign->env = nullptr;
     1118                        delete assign;
    11371119
    11381120                        // for constructor expr:
     
    11431125                        //   T & tmp;
    11441126                        //   &tmp = &x, ?{}(tmp), tmp
    1145                         CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
     1127                        CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11461128                        commaExpr->set_env( env );
    11471129                        return commaExpr;
  • src/InitTweak/GenInit.cc

    r6840e7c rb96ec83  
    8585                // should not have a ConstructorInit generated.
    8686
    87                 ManagedTypes managedTypes;
     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;
    8891                bool inFunction = false;
    8992        };
     
    126129                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    127130                // is being returned
    128                 if ( returnStmt->expr && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
     131                if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
    129132                        // explicitly construct the return value using the return expression and the retVal object
    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() ) );
     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() ) );
    138136
    139137                        // return the retVal object
    140                         returnStmt->expr = new VariableExpr( returnVals.front() );
     138                        returnStmt->set_expr( new VariableExpr( returnVals.front() ) );
    141139                } // if
    142140        }
     
    201199        }
    202200
    203         bool ManagedTypes::isManaged( Type * type ) const {
     201        bool CtorDtor::isManaged( Type * type ) const {
    204202                // references are never constructed
    205203                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
     
    217215        }
    218216
    219         bool ManagedTypes::isManaged( ObjectDecl * objDecl ) const {
     217        bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {
    220218                Type * type = objDecl->get_type();
    221219                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     
    225223        }
    226224
    227         void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {
     225        void CtorDtor::handleDWT( DeclarationWithType * dwt ) {
    228226                // if this function is a user-defined constructor or destructor, mark down the type as "managed"
    229227                if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && CodeGen::isCtorDtor( dwt->get_name() ) ) {
     
    235233                }
    236234        }
    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(); }
    254235
    255236        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
     
    296277
    297278        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    298                 managedTypes.handleDWT( objDecl );
     279                handleDWT( objDecl );
    299280                // hands off if @=, extern, builtin, etc.
    300281                // even if unmanaged, try to construct global or static if initializer is not constexpr, since this is not legal C
    301                 if ( tryConstruct( objDecl ) && ( managedTypes.isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
     282                if ( tryConstruct( objDecl ) && ( isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
    302283                        // constructed objects cannot be designated
    303284                        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 );
     
    314295                inFunction = true;
    315296
    316                 managedTypes.handleDWT( functionDecl );
     297                handleDWT( functionDecl );
    317298
    318299                GuardScope( managedTypes );
     
    320301                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
    321302                        for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
    322                                 managedTypes.handleDWT( assertion );
     303                                handleDWT( assertion );
    323304                        }
    324305                }
     
    330311                visit_children = false; // do not try to construct and destruct aggregate members
    331312
    332                 managedTypes.handleStruct( aggregateDecl );
     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                }
    333324        }
    334325
  • src/InitTweak/GenInit.h

    r6840e7c rb96ec83  
    1616#pragma once
    1717
    18 #include <list>                // for list
    19 #include <string>              // for string
     18#include <list>               // for list
     19#include <string>             // for string
    2020
    21 #include "SynTree/SynTree.h"   // for Visitor Nodes
    22 
    23 #include "GenPoly/ScopedSet.h" // for ScopedSet
     21#include "SynTree/SynTree.h"  // for Visitor Nodes
    2422
    2523namespace InitTweak {
     
    3533        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
    3634        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         };
    5135} // namespace
    5236
  • src/InitTweak/InitTweak.cc

    r6840e7c rb96ec83  
    168168                deleteAll( indices );
    169169                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;
    179170        }
    180171
     
    279270        }
    280271
    281         Type * getTypeofThis( FunctionType * ftype ) {
    282                 assertf( ftype, "getTypeofThis: nullptr ftype" );
    283                 ObjectDecl * thisParam = getParamThis( ftype );
     272        Type * getThisType( FunctionType * ftype ) {
     273                assertf( ftype, "getThisType: nullptr ftype" );
     274                ObjectDecl * thisParam = getThisParam( ftype );
    284275                ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( thisParam->type );
    285276                return refType->base;
    286277        }
    287278
    288         ObjectDecl * getParamThis( FunctionType * ftype ) {
    289                 assertf( ftype, "getParamThis: nullptr ftype" );
     279        ObjectDecl * getThisParam( FunctionType * ftype ) {
     280                assertf( ftype, "getThisParam: nullptr ftype" );
    290281                auto & params = ftype->parameters;
    291                 assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( ftype ).c_str() );
     282                assertf( ! params.empty(), "getThisParam: ftype with 0 parameters: %s", toString( ftype ).c_str() );
    292283                return strict_dynamic_cast< ObjectDecl * >( params.front() );
    293284        }
     
    362353                        assert( expr );
    363354                        if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
    364                                 return varExpr->var;
     355                                return varExpr->get_var();
    365356                        } else if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( expr ) ) {
    366                                 return memberExpr->member;
     357                                return memberExpr->get_member();
    367358                        } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    368                                 return getCalledFunction( castExpr->arg );
     359                                return getCalledFunction( castExpr->get_arg() );
    369360                        } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( expr ) ) {
    370361                                return handleDerefCalledFunction( untypedExpr );
     
    372363                                return handleDerefCalledFunction( appExpr );
    373364                        } else if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
    374                                 return getCalledFunction( addrExpr->arg );
    375                         } else if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( expr ) ) {
    376                                 return getCalledFunction( commaExpr->arg2 );
     365                                return getCalledFunction( addrExpr->get_arg() );
    377366                        }
    378367                        return nullptr;
     
    589578        FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) {
    590579                FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl );
    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;
     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;
    595584
    596585                Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
    597                 Type * t2 = ftype->parameters.back()->get_type();
     586                Type * t2 = ftype->get_parameters().back()->get_type();
    598587                assert( t1 );
    599588
     
    615604        }
    616605        FunctionDecl * isDefaultConstructor( Declaration * decl ) {
    617                 if ( isConstructor( decl->name ) ) {
     606                if ( isConstructor( decl->get_name() ) ) {
    618607                        if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
    619                                 if ( func->type->parameters.size() == 1 ) {
     608                                if ( func->get_functionType()->get_parameters().size() == 1 ) {
    620609                                        return func;
    621610                                }
  • src/InitTweak/InitTweak.h

    r6840e7c rb96ec83  
    3131
    3232        /// returns the base type of the first parameter to a constructor/destructor/assignment function
    33         Type * getTypeofThis( FunctionType * ftype );
     33        Type * getThisType( FunctionType * ftype );
    3434
    3535        /// returns the first parameter of a constructor/destructor/assignment function
    36         ObjectDecl * getParamThis( FunctionType * ftype );
     36        ObjectDecl * getThisParam( FunctionType * ftype );
    3737
    3838        /// transform Initializer into an argument list that can be passed to a call expression
     
    105105                void addArrayIndex( Expression * index, Expression * dimension );
    106106                void clearArrayIndices();
    107                 bool addReference();
    108107
    109108                class ExpanderImpl;
  • src/MakeLibCfa.cc

    r6840e7c rb96ec83  
    119119                        newDecls.push_back( funcDecl );
    120120
    121                         Statement * stmt = nullptr;
    122121                        switch ( opInfo.type ) {
    123122                          case CodeGen::OT_INDEX:
     
    129128                          case CodeGen::OT_POSTFIXASSIGN:
    130129                          case CodeGen::OT_INFIXASSIGN:
    131                                         // return the recursive call
    132                                         stmt = new ReturnStmt( noLabels, newExpr );
    133                                         break;
    134130                          case CodeGen::OT_CTOR:
    135131                          case CodeGen::OT_DTOR:
    136                                         // execute the recursive call
    137                                         stmt = new ExprStmt( noLabels, newExpr );
     132                                // return the recursive call
     133                                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    138134                                        break;
    139135                          case CodeGen::OT_CONSTANT:
     
    142138                                assert( false );
    143139                        } // switch
    144                         funcDecl->get_statements()->push_back( stmt );
    145140                }
    146141        } // namespace
  • src/Makefile.in

    r6840e7c rb96ec83  
    175175        GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \
    176176        GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT) \
     177        GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \
    177178        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
    178179        GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
     
    494495        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    495496        GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.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 \
     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 \
    521523        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    522524        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    716718        GenPoly/$(DEPDIR)/$(am__dirstamp)
    717719GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \
     720        GenPoly/$(DEPDIR)/$(am__dirstamp)
     721GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT): GenPoly/$(am__dirstamp) \
    718722        GenPoly/$(DEPDIR)/$(am__dirstamp)
    719723GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
     
    993997@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@
    994998@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@
    9951000@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    9961001@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
     
    14741479@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`
    14751480
     1481GenPoly/driver_cfa_cpp-CopyParams.o: GenPoly/CopyParams.cc
     1482@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.cc
     1483@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po
     1484@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.cc
     1487
     1488GenPoly/driver_cfa_cpp-CopyParams.obj: GenPoly/CopyParams.cc
     1489@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.Po
     1491@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
    14761495GenPoly/driver_cfa_cpp-FindFunction.o: GenPoly/FindFunction.cc
    14771496@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

    r6840e7c rb96ec83  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 12:34:05 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep 23 18:16:48 2017
    13 // Update Count     : 1024
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 10 17:02:00 2017
     13// Update Count     : 1021
    1414//
    1515
     
    4040using namespace std;
    4141
    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" };
     42// These must remain in the same order as the corresponding DeclarationNode enumerations.
     43const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "NoBasicTypeNames" };
    4444const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" };
    4545const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
  • src/Parser/ExpressionNode.cc

    r6840e7c rb96ec83  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Sep 27 22:51:55 2017
    13 // Update Count     : 781
     12// Last Modified On : Thu Sep 14 23:09:34 2017
     13// Update Count     : 690
    1414//
    1515
     
    6060static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    6161
    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 
    9562static void sepNumeric( string & str, string & units ) {
    9663        string::size_type posn = str.find_first_of( "`" );
     
    10269
    10370Expression * build_constantInteger( string & str ) {
    104         static const BasicType::Kind kind[2][6] = {
     71        static const BasicType::Kind kind[2][5] = {
    10572                // short (h) must be before char (hh)
    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, },
     73                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     74                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    10875        };
    10976
    110         string units;
     77        string units;                                                                           // units
    11178        sepNumeric( str, units );                                                       // separate constant from units
    11279
    11380        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    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 
     81        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t
    11782        unsigned long long int v;                                                       // converted integral value
    11883        size_t last = str.length() - 1;                                         // last character of constant
     
    175140                        } // if
    176141                        str.erase( last - size - 1, size + 1 );         // remove 'h'/"hh"
    177                 } else {                                                                                // suffix "ln" ?
    178                         checkLNInt( str, lnth, size );
    179142                } // if
    180143        } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
     
    200163                str.erase( last - size, size + 1 );                             // remove 'h'/"hh"
    201164        } else if ( checkZ( str[last] ) ) {                                     // suffix 'z' ?
    202                 lnth = 4;
     165                size = 5;
    203166                str.erase( last, 1 );                                                   // remove 'z'
    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.
     167        } // if
     168
    210169        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    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.
     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.
    213172                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
    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
     173        } else if ( size == 5 ) {                                                       // explicit cast to size_t
     174                ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), "size_t", false ) );
    221175        } // if
    222176  CLEANUP:
     
    228182        return ret;
    229183} // 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 
    252184
    253185Expression * build_constantFloat( string & str ) {
     
    257189        };
    258190
    259         string units;
     191        string units;                                                                           // units
    260192        sepNumeric( str, units );                                                       // separate constant from units
    261193
    262194        bool complx = false;                                                            // real, complex
    263         int size = 1;                                                                           // 0 => float, 1 => double, 2 => long double
    264         int lnth = -1;                                                                          // literal length
     195        int size = 1;                                                                           // 0 => float, 1 => double (default), 2 => long double
    265196        // floating-point constant has minimum of 2 characters: 1. or .1
    266197        size_t last = str.length() - 1;
     
    280211        } else if ( checkL( str[last] ) ) {                                     // long double ?
    281212                size = 2;
    282         } else {
    283                 size = 1;                                                                               // double (default)
    284                 checkLNFloat( str, lnth, size );
    285213        } // if
    286214        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
     
    288216        } // if
    289217
    290         assert( 0 <= size && size < 3 );
    291218        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
    295219        if ( units.length() != 0 ) {
    296220                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     
    397321
    398322NameExpr * build_varref( const string * name ) {
    399         NameExpr * expr = new NameExpr( *name );
     323        NameExpr * expr = new NameExpr( *name, nullptr );
    400324        delete name;
    401325        return expr;
     
    488412        list< Expression * > args;
    489413        buildMoveList( expr_node, args );
    490         return new UntypedExpr( maybeMoveBuild< Expression >(function), args );
     414        return new UntypedExpr( maybeMoveBuild< Expression >(function), args, nullptr );
    491415} // build_func
    492416
  • src/Parser/ParseNode.h

    r6840e7c rb96ec83  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep 23 18:11:22 2017
    13 // Update Count     : 821
     12// Last Modified On : Thu Sep 14 23:09:39 2017
     13// Update Count     : 815
    1414//
    1515
     
    4747#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
    4848
     49extern char * yyfilename;
     50extern int yylineno;
    4951extern YYLTYPE yylloc;
    5052
     
    195197class DeclarationNode : public ParseNode {
    196198  public:
    197         // These enumerations must harmonize with their names.
    198         enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
     199        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
     200        enum ComplexType { Complex, Imaginary, NoComplexType };
     201        enum Signedness { Signed, Unsigned, NoSignedness };
     202        enum Length { Short, Long, LongLong, NoLength };
     203        enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
     204        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
     205        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
     206
    199207        static const char * basicTypeNames[];
    200         enum ComplexType { Complex, Imaginary, NoComplexType };
    201208        static const char * complexTypeNames[];
    202         enum Signedness { Signed, Unsigned, NoSignedness };
    203209        static const char * signednessNames[];
    204         enum Length { Short, Long, LongLong, NoLength };
    205210        static const char * lengthNames[];
    206         enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
    207211        static const char * aggregateNames[];
    208         enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
    209212        static const char * typeClassNames[];
    210         enum BuiltinType { Valist, Zero, One, NoBuiltinType };
    211213        static const char * builtinTypeNames[];
    212214
  • src/Parser/TypeData.cc

    r6840e7c rb96ec83  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 18:33:41 2017
    13 // Update Count     : 587
     12// Last Modified On : Fri Sep  1 23:13:38 2017
     13// Update Count     : 569
    1414//
    1515
     
    9898} // TypeData::TypeData
    9999
    100 
    101100TypeData::~TypeData() {
    102101        delete base;
     
    162161        } // switch
    163162} // TypeData::~TypeData
    164 
    165163
    166164TypeData * TypeData::clone() const {
     
    237235} // TypeData::clone
    238236
    239 
    240237void TypeData::print( ostream &os, int indent ) const {
    241238        for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
     
    401398        } // switch
    402399} // TypeData::print
    403 
    404400
    405401template< typename ForallList >
     
    434430                } // if
    435431        } // for
    436 } // buildForall
    437 
     432}
    438433
    439434Type * typebuild( const TypeData * td ) {
     
    482477} // typebuild
    483478
    484 
    485479TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
    486480        TypeData * ret = nullptr;
     
    510504} // typeextractAggregate
    511505
    512 
    513506Type::Qualifiers buildQualifiers( const TypeData * td ) {
    514507        return td->qualifiers;
    515508} // buildQualifiers
    516509
    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 
    522510Type * buildBasicType( const TypeData * td ) {
    523511        BasicType::Kind ret;
     
    525513        switch ( td->basictype ) {
    526514          case DeclarationNode::Void:
    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
     515                if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) {
     516                        throw SemanticError( "invalid type specifier \"void\" in type: ", td );
     517                } // if
     518
    533519                return new VoidType( buildQualifiers( td ) );
    534520                break;
     
    536522          case DeclarationNode::Bool:
    537523                if ( td->signedness != DeclarationNode::NoSignedness ) {
    538                         genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
     524                        throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessNames[ td->signedness ] + " in type: ", td );
    539525                } // if
    540526                if ( td->length != DeclarationNode::NoLength ) {
    541                         genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     527                        throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td );
    542528                } // if
    543529
     
    552538
    553539                if ( td->length != DeclarationNode::NoLength ) {
    554                         genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     540                        throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td );
    555541                } // if
    556542
     
    571557                break;
    572558
    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 
    580559          case DeclarationNode::Float:
    581           case DeclarationNode::Float80:
    582           case DeclarationNode::Float128:
    583560          case DeclarationNode::Double:
    584561          case DeclarationNode::LongDouble:                                     // not set until below
     
    591568          FloatingPoint: ;
    592569                if ( td->signedness != DeclarationNode::NoSignedness ) {
    593                         genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
     570                        throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessNames[ td->signedness ] + " in type: ", td );
    594571                } // if
    595572                if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
    596                         genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     573                        throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td );
    597574                } // if
    598575                if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) {
    599                         genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     576                        throw SemanticError( "invalid type specifier \"long\" in type: ", td );
    600577                } // if
    601578                if ( td->length == DeclarationNode::Long ) {
     
    616593                goto Integral;
    617594          default:
    618                 assertf( false, "unknown basic type" );
     595                assert(false);
    619596                return nullptr;
    620597        } // switch
     
    624601        return bt;
    625602} // buildBasicType
    626 
    627603
    628604PointerType * buildPointer( const TypeData * td ) {
     
    636612        return pt;
    637613} // buildPointer
    638 
    639614
    640615ArrayType * buildArray( const TypeData * td ) {
     
    651626} // buildArray
    652627
    653 
    654628ReferenceType * buildReference( const TypeData * td ) {
    655629        ReferenceType * rt;
     
    663637} // buildReference
    664638
    665 
    666639AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
    667640        assert( td->kind == TypeData::Aggregate );
     
    692665        return at;
    693666} // buildAggregate
    694 
    695667
    696668ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     
    750722} // buildAggInst
    751723
    752 
    753724ReferenceToType * buildAggInst( const TypeData * td ) {
    754725        assert( td->kind == TypeData::AggregateInst );
     
    790761} // buildAggInst
    791762
    792 
    793763NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
    794764        assert( td->kind == TypeData::Symbolic );
     
    805775} // buildSymbolic
    806776
    807 
    808777EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
    809778        assert( td->kind == TypeData::Enum );
     
    821790} // buildEnum
    822791
    823 
    824792TypeInstType * buildSymbolicInst( const TypeData * td ) {
    825793        assert( td->kind == TypeData::SymbolicInst );
     
    829797        return ret;
    830798} // buildSymbolicInst
    831 
    832799
    833800TupleType * buildTuple( const TypeData * td ) {
     
    840807} // buildTuple
    841808
    842 
    843809TypeofType * buildTypeof( const TypeData * td ) {
    844810        assert( td->kind == TypeData::Typeof );
     
    847813        return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
    848814} // buildTypeof
    849 
    850815
    851816Declaration * 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 ) {
     
    871836        return nullptr;
    872837} // buildDecl
    873 
    874838
    875839FunctionType * buildFunction( const TypeData * td ) {
     
    893857        return ft;
    894858} // buildFunction
    895 
    896859
    897860// Transform KR routine declarations into C99 routine declarations:
  • src/Parser/lex.ll

    r6840e7c rb96ec83  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Sat Sep 23 17:29:28 2017
    13  * Update Count     : 632
     12 * Last Modified On : Sun Sep 10 22:29:15 2017
     13 * Update Count     : 620
    1414 */
    1515
     
    9393                                // numeric constants, CFA: '_' in constant
    9494hex_quad {hex}("_"?{hex}){3}
    95 size_opt (8|16|32|64|128)?
    96 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH])
     95length ("ll"|"LL"|[lL])|("hh"|"HH"|[hH])
    9796integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?{user_suffix_opt}
    9897
     
    110109                                // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
    111110exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    112 floating_size 32|64|80|128
    113 floating_length ([fFdDlL]|[lL]{floating_size})
    114 floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length})
     111floating_suffix ([fFdDlL]?[iI]?)|([iI][lLfFdD])
    115112floating_suffix_opt ("_"?({floating_suffix}|"DL"))?{user_suffix_opt}
    116113decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
     
    237234finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
    238235float                   { KEYWORD_RETURN(FLOAT); }
    239 __float80               { KEYWORD_RETURN(FLOAT80); }                    // GCC
    240 float80                 { KEYWORD_RETURN(FLOAT80); }                    // GCC
    241 __float128              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    242 float128                { KEYWORD_RETURN(FLOAT128); }                   // GCC
     236__float128              { KEYWORD_RETURN(FLOAT); }                              // GCC
    243237for                             { KEYWORD_RETURN(FOR); }
    244238forall                  { KEYWORD_RETURN(FORALL); }                             // CFA
     
    255249__inline__              { KEYWORD_RETURN(INLINE); }                             // GCC
    256250int                             { KEYWORD_RETURN(INT); }
    257 __int128                { KEYWORD_RETURN(INT128); }                             // GCC
    258 int128                  { KEYWORD_RETURN(INT128); }                             // GCC
     251__int128                { KEYWORD_RETURN(INT); }                                // GCC
     252__int128_t              { KEYWORD_RETURN(INT); }                                // GCC
    259253__label__               { KEYWORD_RETURN(LABEL); }                              // GCC
    260254long                    { KEYWORD_RETURN(LONG); }
     
    291285__typeof                { KEYWORD_RETURN(TYPEOF); }                             // GCC
    292286__typeof__              { KEYWORD_RETURN(TYPEOF); }                             // GCC
     287__uint128_t             { KEYWORD_RETURN(INT); }                                // GCC
    293288union                   { KEYWORD_RETURN(UNION); }
    294289unsigned                { KEYWORD_RETURN(UNSIGNED); }
  • src/Parser/parser.yy

    r6840e7c rb96ec83  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Oct 16 11:07:29 2017
    13 // Update Count     : 2892
     12// Last Modified On : Thu Sep 14 23:07:12 2017
     13// Update Count     : 2815
    1414//
    1515
     
    4343#define YYDEBUG_LEXER_TEXT (yylval)                                             // lexer loads this up each time
    4444#define YYDEBUG 1                                                                               // get the pretty debugging code to compile
    45 #define YYERROR_VERBOSE                                                                 // more information in syntax errors
     45#define YYERROR_VERBOSE
    4646
    4747#undef __GNUC_MINOR__
     
    117117bool forall = false;                                                                    // aggregate have one or more forall qualifiers ?
    118118
    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 }
     119# define YYLLOC_DEFAULT(Cur, Rhs, N)                            \
     120do                                                              \
     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        }                                                             \
     134while (0)
    132135%}
    133136
    134137%define parse.error verbose
    135138
    136 // Types declaration for productions
     139// Types declaration
    137140%union
    138141{
     
    170173%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    171174%token BOOL COMPLEX IMAGINARY                                                   // C99
    172 %token INT128 FLOAT80 FLOAT128                                                  // GCC
    173175%token ZERO_T ONE_T                                                                             // CFA
    174176%token VALIST                                                                                   // GCC
     
    250252%type<sn> exception_statement                   handler_clause                          finally_clause
    251253%type<catch_kind> handler_key
    252 %type<sn> mutex_statement
    253254%type<en> when_clause                                   when_clause_opt                         waitfor                                         timeout
    254255%type<sn> waitfor_statement
     
    457458        | '(' compound_statement ')'                                            // GCC, lambda expression
    458459                { $$ = new ExpressionNode( new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >($2) ) ) ); }
     460        | primary_expression '{' argument_expression_list '}' // CFA, constructor call
     461                {
     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                }
    459466        | type_name '.' no_attr_identifier                                      // CFA, nested type
    460467                { $$ = nullptr; }                                                               // FIX ME
     
    471478                // equivalent to the old x[i,j].
    472479                { $$ = 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                 }
    479480        | postfix_expression '(' argument_expression_list ')'
    480481                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     
    808809        | jump_statement
    809810        | with_statement
    810         | mutex_statement
    811811        | waitfor_statement
    812812        | exception_statement
     
    10331033        ;
    10341034
    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 
    10411035when_clause:
    10421036        WHEN '(' comma_expression ')'
     
    15571551        | VOLATILE
    15581552                { $$ = DeclarationNode::newTypeQualifier( Type::Volatile ); }
     1553        | MUTEX
     1554                { $$ = DeclarationNode::newTypeQualifier( Type::Mutex ); }
    15591555        | ATOMIC
    15601556                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
     
    16101606
    16111607basic_type_name:
    1612         VOID
     1608        CHAR
     1609                { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }
     1610        | DOUBLE
     1611                { $$ = 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 ); }
     1620        | SIGNED
     1621                { $$ = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }
     1622        | UNSIGNED
     1623                { $$ = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }
     1624        | VOID
    16131625                { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
    16141626        | BOOL                                                                                          // C99
    16151627                { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
    1616         | CHAR
    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 ); }
    1628         | DOUBLE
    1629                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
    16301628        | COMPLEX                                                                                       // C99
    16311629                { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
    16321630        | IMAGINARY                                                                                     // C99
    16331631                { $$ = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); }
    1634         | SIGNED
    1635                 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }
    1636         | UNSIGNED
    1637                 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }
    1638         | SHORT
    1639                 { $$ = DeclarationNode::newLength( DeclarationNode::Short ); }
    1640         | LONG
    1641                 { $$ = DeclarationNode::newLength( DeclarationNode::Long ); }
    16421632        | ZERO_T
    16431633                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); }
     
    27092699        paren_identifier attribute_list_opt
    27102700                { $$ = $1->addQualifiers( $2 ); }
    2711         | '&' MUTEX paren_identifier attribute_list_opt
    2712                 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); }
    27132701        | identifier_parameter_ptr
    27142702        | identifier_parameter_array attribute_list_opt
     
    27512739//
    27522740//              typedef int foo;
    2753 //              forall( otype T ) foo( T );
    27542741//              int f( int foo ); // redefine typedef name in new scope
    27552742//
     
    27592746        typedef attribute_list_opt
    27602747                { $$ = $1->addQualifiers( $2 ); }
    2761         | '&' MUTEX typedef attribute_list_opt
    2762                 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); }
    27632748        | type_parameter_ptr
    27642749        | type_parameter_array attribute_list_opt
     
    29072892abstract_parameter_declarator:
    29082893        abstract_parameter_ptr
    2909         | '&' MUTEX attribute_list_opt
    2910                 { $$ = DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf )->addQualifiers( $3 ); }
    29112894        | abstract_parameter_array attribute_list_opt
    29122895                { $$ = $1->addQualifiers( $2 ); }
  • src/ResolvExpr/AdjustExprType.cc

    r6840e7c rb96ec83  
    1414//
    1515
    16 #include "Common/PassVisitor.h"
    1716#include "SymTab/Indexer.h"       // for Indexer
    1817#include "SynTree/Declaration.h"  // for TypeDecl, TypeDecl::Kind::Ftype
     
    2221
    2322namespace ResolvExpr {
    24         class AdjustExprType : public WithShortCircuiting {
     23        class AdjustExprType : public Mutator {
     24                typedef Mutator Parent;
     25                using Parent::mutate;
    2526          public:
    2627                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; }
     28          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 );
    4043
    41                 Type * postmutate( ArrayType *arrayType );
    42                 Type * postmutate( FunctionType *functionType );
    43                 Type * postmutate( TypeInstType *aggregateUseType );
    44 
    45           private:
    4644                const TypeEnvironment &env;
    4745                const SymTab::Indexer &indexer;
     
    4947
    5048        void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    51                 PassVisitor<AdjustExprType> adjuster( env, indexer );
     49                AdjustExprType adjuster( env, indexer );
    5250                Type *newType = type->acceptMutator( adjuster );
    5351                type = newType;
     
    5856        }
    5957
    60         Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
     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 ) {
    6171                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    62                 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base );
    63                 arrayType->base = nullptr;
     72                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ) );
    6473                delete arrayType;
    6574                return pointerType;
    6675        }
    6776
    68         Type * AdjustExprType::postmutate( FunctionType * functionType ) {
    69                 return new PointerType( Type::Qualifiers(), functionType );
     77        Type *AdjustExprType::mutate( FunctionType *functionType ) {
     78                PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
     79                return pointerType;
    7080        }
    7181
    72         Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
     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 ) {
    7399                EqvClass eqvClass;
    74100                if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     
    87113                return typeInst;
    88114        }
     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        }
    89131} // namespace ResolvExpr
    90132
  • src/ResolvExpr/Alternative.cc

    r6840e7c rb96ec83  
    6666        }
    6767
    68         void Alternative::print( std::ostream &os, Indenter indent ) const {
    69                 os << "Cost " << cost << ": ";
     68        void Alternative::print( std::ostream &os, int indent ) const {
     69                os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
    7070                if ( expr ) {
    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;
     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;
    7676                } else {
    7777                        os << "Null expression!" << std::endl;
    7878                } // if
    79                 os << indent << "Environment: ";
    80                 env.print( os, indent+1 );
     79                os << std::string( indent, ' ' ) << "Environment: ";
     80                env.print( os, indent+2 );
    8181                os << std::endl;
    8282        }
  • src/ResolvExpr/Alternative.h

    r6840e7c rb96ec83  
    3939                ~Alternative();
    4040
    41                 void print( std::ostream &os, Indenter indent = {} ) const;
     41                void print( std::ostream &os, int indent = 0 ) const;
    4242
    4343                Cost cost;
  • src/ResolvExpr/AlternativeFinder.cc

    r6840e7c rb96ec83  
    7575
    7676        namespace {
    77                 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {
    78                         Indenter indent = { Indenter::tabsize, indentAmt };
     77                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
    7978                        for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    8079                                i->print( os, indent );
     
    196195                                AltList winners;
    197196                                findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    198                                 stream << "Cannot choose between " << winners.size() << " alternatives for expression\n";
     197                                stream << "Cannot choose between " << winners.size() << " alternatives for expression ";
    199198                                expr->print( stream );
    200                                 stream << "Alternatives are:\n";
    201                                 printAlts( winners, stream, 1 );
     199                                stream << "Alternatives are:";
     200                                printAlts( winners, stream, 8 );
    202201                                throw SemanticError( stream.str() );
    203202                        }
     
    605604                                Alternative newerAlt( newAlt );
    606605                                newerAlt.env = newEnv;
    607                                 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() );
     606                                assert( (*candidate)->get_uniqueId() );
    608607                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
    609608
     
    729728                PRINT(
    730729                        std::cerr << "known function ops:" << std::endl;
    731                         printAlts( funcOpFinder.alternatives, std::cerr, 1 );
     730                        printAlts( funcOpFinder.alternatives, std::cerr, 8 );
    732731                )
    733732
     
    839838        bool isLvalue( Expression *expr ) {
    840839                // xxx - recurse into tuples?
    841                 return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
     840                return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
    842841        }
    843842
     
    973972                PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; )
    974973                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    975                         VariableExpr newExpr( *i );
     974                        VariableExpr newExpr( *i, nameExpr->get_argName() );
    976975                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
    977976                        PRINT(
     
    12681267                // O(N^2) checks of d-types with e-types
    12691268                for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
    1270                         Type * toType = resolveTypeof( initAlt.type->clone(), indexer );
     1269                        Type * toType = resolveTypeof( initAlt.type, indexer );
    12711270                        SymTab::validateType( toType, &indexer );
    12721271                        adjustExprType( toType, env, indexer );
  • src/ResolvExpr/CastCost.cc

    r6840e7c rb96ec83  
    2424#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
    2525
    26 #if 0
    27 #define PRINT(x) x
    28 #else
    29 #define PRINT(x)
    30 #endif
    3126
    3227namespace ResolvExpr {
     
    5752                        } // if
    5853                } // 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 
    6954                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
    70                         PRINT( std::cerr << "compatible!" << std::endl; )
    7155                        return Cost::zero;
    7256                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    7357                        return Cost::safe;
    7458                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    75                         PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    7659                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer & indexer) {
    7760                                return ptrsCastable( t1, t2, env, indexer );
  • src/ResolvExpr/CommonType.cc

    r6840e7c rb96ec83  
    1010// Created On       : Sun May 17 06:59:27 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:18:17 2017
    13 // Update Count     : 9
     12// Last Modified On : Thu Mar 16 16:24:31 2017
     13// Update Count     : 7
    1414//
    1515
     
    150150        static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    151151        {
    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, },
     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 }
    176174        };
    177175
  • src/ResolvExpr/ConversionCost.cc

    r6840e7c rb96ec83  
    1010// Created On       : Sun May 17 07:06:19 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:43:34 2017
    13 // Update Count     : 10
     12// Last Modified On : Wed Mar  2 17:35:46 2016
     13// Update Count     : 6
    1414//
    1515
     
    219219*/
    220220
    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,      },
     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 }
    248245        };
    249246
     
    306303                // recursively compute conversion cost from T1 to T2.
    307304                // cv can be safely dropped because of 'implicit dereference' behavior.
    308                 refType->base->accept( *this );
    309                 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
     305                refType->get_base()->accept( *this );
     306                if ( refType->get_base()->get_qualifiers() == dest->get_qualifiers() ) {
    310307                        cost.incReference();  // prefer exact qualifiers
    311                 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
     308                } else if ( refType->get_base()->get_qualifiers() < dest->get_qualifiers() ) {
    312309                        cost.incSafe(); // then gaining qualifiers
    313310                } else {
     
    321318        void ConversionCost::visit(StructInstType *inst) {
    322319                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    323                         if ( inst->name == destAsInst->name ) {
     320                        if ( inst->get_name() == destAsInst->get_name() ) {
    324321                                cost = Cost::zero;
    325322                        } // if
     
    328325
    329326        void ConversionCost::visit(UnionInstType *inst) {
    330                 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    331                         if ( inst->name == destAsInst->name ) {
     327                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
     328                        if ( inst->get_name() == destAsInst->get_name() ) {
    332329                                cost = Cost::zero;
    333330                        } // if
  • src/ResolvExpr/ResolveTypeof.cc

    r6840e7c rb96ec83  
    1818#include <cassert>               // for assert
    1919
    20 #include "Common/PassVisitor.h"  // for PassVisitor
    2120#include "Resolver.h"            // for resolveInVoidContext
    2221#include "SynTree/Expression.h"  // for Expression
     
    4241        }
    4342
    44         class ResolveTypeof : public WithShortCircuiting {
     43        class ResolveTypeof : public Mutator {
    4544          public:
    4645                ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    47                 void premutate( TypeofType *typeofType );
    48                 Type * postmutate( TypeofType *typeofType );
     46                Type *mutate( TypeofType *typeofType );
    4947
    5048          private:
     
    5250        };
    5351
    54         Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
    55                 PassVisitor<ResolveTypeof> mutator( indexer );
     52        Type *resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
     53                ResolveTypeof mutator( indexer );
    5654                return type->acceptMutator( mutator );
    5755        }
    5856
    59         void ResolveTypeof::premutate( TypeofType * ) {
    60                 visit_children = false;
    61         }
    62 
    63         Type * ResolveTypeof::postmutate( TypeofType *typeofType ) {
     57        Type *ResolveTypeof::mutate( TypeofType *typeofType ) {
    6458#if 0
    65                 std::cerr << "resolving typeof: ";
    66                 typeofType->print( std::cerr );
    67                 std::cerr << std::endl;
     59                std::cout << "resolving typeof: ";
     60                typeofType->print( std::cout );
     61                std::cout << std::endl;
    6862#endif
    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;
     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 );
    7468                        delete typeofType;
    7569                        delete newExpr;
  • src/ResolvExpr/Resolver.cc

    r6840e7c rb96ec83  
    5353                void previsit( FunctionDecl *functionDecl );
    5454                void postvisit( FunctionDecl *functionDecl );
    55                 void previsit( ObjectDecl *objectDecll );
     55                void previsit( ObjectDecl *functionDecl );
    5656                void previsit( TypeDecl *typeDecl );
    5757                void previsit( EnumDecl * enumDecl );
     
    109109
    110110        namespace {
    111                 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
    112                         expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
     111                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     112                        expr->set_env( new TypeSubstitution );
    113113                        env.makeSubstitution( *expr->get_env() );
    114114                }
    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                 }
    127115        } // namespace
    128116
    129         void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
     117        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130118                global_renamer.reset();
    131119                TypeEnvironment env;
    132120                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    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;
     121                finishExpr( newExpr, env );
     122                return newExpr;
     123        }
     124
     125        Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    140126                TypeEnvironment env;
    141127                AlternativeFinder finder( indexer, env );
     
    143129                #if 0
    144130                if ( finder.get_alternatives().size() != 1 ) {
    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 );
     131                        std::cout << "untyped expr is ";
     132                        untyped->print( std::cout );
     133                        std::cout << 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 );
    150136                        } // for
    151137                } // if
     
    154140                Alternative &choice = finder.get_alternatives().front();
    155141                Expression *newExpr = choice.expr->clone();
    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 );
     142                finishExpr( newExpr, choice.env );
     143                return newExpr;
    166144        }
    167145
     
    179157                }
    180158
    181                 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
     159                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    182160                        TypeEnvironment env;
    183161                        AlternativeFinder finder( indexer, env );
     
    208186                                throw SemanticError( "No interpretations for case control expression", untyped );
    209187                        } // if
    210                         finishExpr( newExpr, *newEnv, untyped->env );
    211                         delete untyped;
    212                         untyped = newExpr;
     188                        finishExpr( newExpr, *newEnv );
     189                        return newExpr;
    213190                }
    214191
     
    235212        void Resolver::handlePtrType( PtrType * type ) {
    236213                if ( type->get_dimension() ) {
    237                         findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
     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 );
    238218                }
    239219        }
     
    265245                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    266246        }
     247
    267248
    268249        void Resolver::postvisit( FunctionDecl *functionDecl ) {
     
    288269        void Resolver::previsit( ExprStmt *exprStmt ) {
    289270                visit_children = false;
    290                 assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" );
    291                 findVoidExpression( exprStmt->expr, indexer );
     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 );
    292275        }
    293276
    294277        void Resolver::previsit( AsmExpr *asmExpr ) {
    295278                visit_children = false;
    296                 findVoidExpression( asmExpr->operand, indexer );
     279                Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
     280                delete asmExpr->get_operand();
     281                asmExpr->set_operand( newExpr );
    297282                if ( asmExpr->get_inout() ) {
    298                         findVoidExpression( asmExpr->inout, indexer );
     283                        newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
     284                        delete asmExpr->get_inout();
     285                        asmExpr->set_inout( newExpr );
    299286                } // if
    300287        }
     
    307294
    308295        void Resolver::previsit( IfStmt *ifStmt ) {
    309                 findSingleExpression( ifStmt->condition, indexer );
     296                Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer );
     297                delete ifStmt->get_condition();
     298                ifStmt->set_condition( newExpr );
    310299        }
    311300
    312301        void Resolver::previsit( WhileStmt *whileStmt ) {
    313                 findSingleExpression( whileStmt->condition, indexer );
     302                Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
     303                delete whileStmt->get_condition();
     304                whileStmt->set_condition( newExpr );
    314305        }
    315306
    316307        void Resolver::previsit( ForStmt *forStmt ) {
    317                 if ( forStmt->condition ) {
    318                         findSingleExpression( forStmt->condition, indexer );
     308                if ( forStmt->get_condition() ) {
     309                        Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
     310                        delete forStmt->get_condition();
     311                        forStmt->set_condition( newExpr );
    319312                } // if
    320313
    321                 if ( forStmt->increment ) {
    322                         findVoidExpression( forStmt->increment, indexer );
     314                if ( forStmt->get_increment() ) {
     315                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
     316                        delete forStmt->get_increment();
     317                        forStmt->set_increment( newExpr );
    323318                } // if
    324319        }
     
    326321        void Resolver::previsit( SwitchStmt *switchStmt ) {
    327322                GuardValue( currentObject );
    328                 findIntegralExpression( switchStmt->condition, indexer );
    329 
    330                 currentObject = CurrentObject( switchStmt->condition->result );
     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() );
    331329        }
    332330
     
    335333                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    336334                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    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;
     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 );
    343340                        delete castExpr;
    344341                }
     
    349346                // must resolve the argument for a computed goto
    350347                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
    351                         if ( branchStmt->computedTarget ) {
    352                                 // computed goto argument is void *
    353                                 findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer );
     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 );
    354354                        } // if
    355355                } // if
     
    358358        void Resolver::previsit( ReturnStmt *returnStmt ) {
    359359                visit_children = false;
    360                 if ( returnStmt->expr ) {
    361                         findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer );
     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 );
    362365                } // if
    363366        }
     
    370373                                indexer.lookupStruct( "__cfaehm__base_exception_t" );
    371374                        assert( exception_decl );
    372                         Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
    373                         findSingleExpression( throwStmt->expr, exceptType, indexer );
     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 );
    374387                }
    375388        }
    376389
    377390        void Resolver::previsit( CatchStmt *catchStmt ) {
    378                 if ( catchStmt->cond ) {
    379                         findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
    380                 }
     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;
    381412        }
    382413
     
    548579                        // Resolve the conditions as if it were an IfStmt
    549580                        // Resolve the statments normally
    550                         findSingleExpression( clause.condition, this->indexer );
     581                        resolveAsIf( clause.condition, this->indexer );
    551582                        clause.statement->accept( *visitor );
    552583                }
     
    557588                        // Resolve the conditions as if it were an IfStmt
    558589                        // Resolve the statments normally
    559                         findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
    560                         findSingleExpression( stmt->timeout.condition, this->indexer );
     590                        resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
     591                        resolveAsIf  ( stmt->timeout.condition, this->indexer );
    561592                        stmt->timeout.statement->accept( *visitor );
    562593                }
     
    565596                        // Resolve the conditions as if it were an IfStmt
    566597                        // Resolve the statments normally
    567                         findSingleExpression( stmt->orelse.condition, this->indexer );
     598                        resolveAsIf( stmt->orelse.condition, this->indexer );
    568599                        stmt->orelse.statement->accept( *visitor );
    569600                }
     
    582613                visit_children = false;
    583614                // resolve initialization using the possibilities as determined by the currentObject cursor
    584                 Expression * newExpr = new UntypedInitExpr( singleInit->value, currentObject.getOptions() );
    585                 findSingleExpression( newExpr, indexer );
     615                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
     616                Expression * newExpr = findSingleExpression( untyped, indexer );
    586617                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    587618
     
    590621
    591622                // discard InitExpr wrapper and retain relevant pieces
    592                 newExpr = initExpr->expr;
    593                 initExpr->expr = nullptr;
    594                 std::swap( initExpr->env, newExpr->env );
     623                newExpr = initExpr->get_expr();
     624                newExpr->set_env( initExpr->get_env() );
     625                initExpr->set_expr( nullptr );
     626                initExpr->set_env( nullptr );
    595627                delete initExpr;
    596628
    597629                // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
    598630                Type * initContext = currentObject.getCurrentType();
    599 
    600                 removeExtraneousCast( newExpr, indexer );
    601631
    602632                // check if actual object's type is char[]
     
    606636                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    607637                                        if ( isCharType( pt->get_base() ) ) {
    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                                                 }
     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;
    615643                                        }
    616644                                }
     
    619647
    620648                // set initializer expr to resolved express
    621                 singleInit->value = newExpr;
     649                singleInit->set_value( newExpr );
    622650
    623651                // move cursor to next object in preparation for next initializer
  • src/ResolvExpr/Resolver.h

    r6840e7c rb96ec83  
    3030        void resolve( std::list< Declaration * > translationUnit );
    3131        void resolveDecl( Declaration *, 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 );
     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 );
    3535        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3636        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    r6840e7c rb96ec83  
    6868        }
    6969
    70         void EqvClass::print( std::ostream &os, Indenter indent ) const {
    71                 os << "( ";
     70        void EqvClass::print( std::ostream &os, int indent ) const {
     71                os << std::string( indent, ' ' ) << "( ";
    7272                std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) );
    7373                os << ")";
    7474                if ( type ) {
    7575                        os << " -> ";
    76                         type->print( os, indent+1 );
     76                        type->print( os, indent );
    7777                } // if
    7878                if ( ! allowWidening ) {
     
    144144        }
    145145
    146         void TypeEnvironment::print( std::ostream &os, Indenter indent ) const {
     146        void TypeEnvironment::print( std::ostream &os, int indent ) const {
    147147                for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    148148                        i->print( os, indent );
  • src/ResolvExpr/TypeEnvironment.h

    r6840e7c rb96ec83  
    6868                EqvClass &operator=( const EqvClass &other );
    6969                ~EqvClass();
    70                 void print( std::ostream &os, Indenter indent = {} ) const;
     70                void print( std::ostream &os, int indent = 0 ) const;
    7171        };
    7272
     
    8080                void makeSubstitution( TypeSubstitution &result ) const;
    8181                bool isEmpty() const { return env.empty(); }
    82                 void print( std::ostream &os, Indenter indent = {} ) const;
     82                void print( std::ostream &os, int indent = 0 ) const;
    8383                void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
    8484                void simpleCombine( const TypeEnvironment &second );
  • src/ResolvExpr/Unify.cc

    r6840e7c rb96ec83  
    2222#include <utility>                // for pair
    2323
    24 #include "Common/PassVisitor.h"   // for PassVisitor
    2524#include "FindOpenVars.h"         // for findOpenVars
    2625#include "Parser/LinkageSpec.h"   // for C
     
    538537        /// If this isn't done then argument lists can have wildly different
    539538        /// size and structure, when they should be compatible.
    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 ) {
     539        struct TtypeExpander : public Mutator {
     540                TypeEnvironment & env;
     541                TtypeExpander( TypeEnvironment & env ) : env( env ) {}
     542                Type * mutate( TypeInstType * typeInst ) {
    545543                        EqvClass eqvClass;
    546                         if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
     544                        if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
    547545                                if ( eqvClass.data.kind == TypeDecl::Ttype ) {
    548546                                        // expand ttype parameter into its actual type
     
    562560                dst.clear();
    563561                for ( DeclarationWithType * dcl : src ) {
    564                         PassVisitor<TtypeExpander> expander( env );
     562                        TtypeExpander expander( env );
    565563                        dcl->acceptMutator( expander );
    566564                        std::list< Type * > types;
     
    752750                        std::list<Type *> types1, types2;
    753751
    754                         PassVisitor<TtypeExpander> expander( env );
     752                        TtypeExpander expander( env );
    755753                        flat1->acceptMutator( expander );
    756754                        flat2->acceptMutator( expander );
  • src/SymTab/Autogen.cc

    r6840e7c rb96ec83  
    4343namespace SymTab {
    4444        Type * SizeType = 0;
    45 
    46         /// Data used to generate functions generically. Specifically, the name of the generated function and a function which generates the routine protoype
     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.
    4748        struct FuncData {
    4849                typedef FunctionType * (*TypeGen)( Type * );
    49                 FuncData( const std::string & fname, const TypeGen & genType ) : fname( fname ), genType( genType ) {}
     50                FuncData( const std::string & fname, const TypeGen & genType, TypeMap & map ) : fname( fname ), genType( genType ), map( map ) {}
    5051                std::string fname;
    5152                TypeGen genType;
     53                TypeMap & map;
    5254        };
    5355
    54         struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting, public WithIndexer {
     56        struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
    5557                AutogenerateRoutines();
    5658
     
    6870
    6971          private:
    70 
    7172                GenPoly::ScopedSet< std::string > structsDone;
    7273                unsigned int functionNesting = 0;     // current level of nested functions
    73 
    74                 InitTweak::ManagedTypes managedTypes;
     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;
    7578                std::vector< FuncData > data;
    7679        };
     
    7881        /// generates routines for tuple types.
    7982        struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting {
    80                 void previsit( FunctionDecl * functionDecl );
    81 
    82                 void postvisit( TupleType * tupleType );
    83 
    84                 void previsit( CompoundStmt * compoundStmt );
     83                void previsit( FunctionDecl *functionDecl );
     84
     85                void postvisit( TupleType *tupleType );
     86
     87                void previsit( CompoundStmt *compoundStmt );
    8588
    8689          private:
     
    98101        }
    99102
    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 
    214103        bool isUnnamedBitfield( ObjectDecl * obj ) {
    215                 return obj != nullptr && obj->name == "" && obj->bitfieldWidth != nullptr;
     104                return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
    216105        }
    217106
     
    219108        void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
    220109                FunctionDecl * decl = functionDecl->clone();
    221                 delete decl->statements;
    222                 decl->statements = nullptr;
     110                delete decl->get_statements();
     111                decl->set_statements( nullptr );
    223112                declsToAdd.push_back( decl );
    224113                decl->fixUniqueId();
    225114        }
    226115
    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 
    237116        /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *)
    238117        FunctionType * genDefaultType( Type * paramType ) {
    239                 const auto & typeParams = getGenericParams( paramType );
    240118                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    241                 cloneAll( typeParams, ftype->forall );
    242119                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
    243                 ftype->parameters.push_back( dstParam );
     120                ftype->get_parameters().push_back( dstParam );
    244121                return ftype;
    245122        }
     
    249126                FunctionType *ftype = genDefaultType( paramType );
    250127                ObjectDecl *srcParam = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
    251                 ftype->parameters.push_back( srcParam );
     128                ftype->get_parameters().push_back( srcParam );
    252129                return ftype;
    253130        }
     
    257134                FunctionType *ftype = genCopyType( paramType );
    258135                ObjectDecl *returnVal = new ObjectDecl( "_ret", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
    259                 ftype->returnVals.push_back( returnVal );
     136                ftype->get_returnVals().push_back( returnVal );
    260137                return ftype;
    261138        }
     
    274151        }
    275152
    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
     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
    318205                        if ( concurrent_type && CodeGen::isDestructor( data.fname ) ) {
    319206                                ftype->parameters.front()->get_type()->set_mutex( true );
    320207                        }
    321208
    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 ) {
     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 ) {
    387284                InitTweak::InitExpander srcParam( src );
    388285
    389286                // assign to destination
    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 
     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
    394292        template<typename Iterator>
    395         void StructFuncGenerator::makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward ) {
     293        void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ) {
    396294                for ( ; member != end; ++member ) {
    397295                        if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
     
    403301                                }
    404302
    405                                 if ( type->get_const() && CodeGen::isAssignment( func->name ) ) {
     303                                if ( type->get_const() && func->get_name() == "?=?" ) {
    406304                                        // don't assign const members, but do construct/destruct
     305                                        continue;
     306                                }
     307
     308                                if ( field->get_name() == "" ) {
     309                                        // don't assign to anonymous members
     310                                        // xxx - this is a temporary fix. Anonymous members tie into
     311                                        // our inheritance model. I think the correct way to handle this is to
     312                                        // cast the structure to the type of the member and let the resolver
     313                                        // figure out whether it's valid and have a pass afterwards that fixes
     314                                        // the assignment to use pointer arithmetic with the offset of the
     315                                        // member, much like how generic type members are handled.
    407316                                        continue;
    408317                                }
     
    414323                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
    415324                                }
    416 
    417325                                // srcParam may be NULL, in which case we have default ctor/dtor
    418326                                assert( dstParam );
    419327
    420328                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
    421                                 makeMemberOp( dstParam, srcselect, field, func, forward );
     329                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    422330                        } // if
    423331                } // for
    424         } // makeFunctionBody
    425 
     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.
    426336        template<typename Iterator>
    427         void StructFuncGenerator::makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) {
    428                 FunctionType * ftype = func->type;
    429                 std::list<DeclarationWithType*> & params = ftype->parameters;
     337        void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) {
     338                FunctionType * ftype = func->get_functionType();
     339                std::list<DeclarationWithType*> & params = ftype->get_parameters();
    430340                assert( params.size() >= 2 );  // should not call this function for default ctor, etc.
    431341
     
    439349                                        // don't make a function whose parameter is an unnamed bitfield
    440350                                        continue;
     351                                } else if ( field->get_name() == "" ) {
     352                                        // don't assign to anonymous members
     353                                        // xxx - this is a temporary fix. Anonymous members tie into
     354                                        // our inheritance model. I think the correct way to handle this is to
     355                                        // cast the structure to the type of the member and let the resolver
     356                                        // figure out whether it's valid and have a pass afterwards that fixes
     357                                        // the assignment to use pointer arithmetic with the offset of the
     358                                        // member, much like how generic type members are handled.
     359                                        continue;
    441360                                } else if ( parameter != params.end() ) {
    442361                                        // matching parameter, initialize field with copy ctor
    443362                                        Expression *srcselect = new VariableExpr(*parameter);
    444                                         makeMemberOp( dstParam, srcselect, field, func );
     363                                        makeStructMemberOp( dstParam, srcselect, field, func );
    445364                                        ++parameter;
    446365                                } else {
    447366                                        // no matching parameter, initialize field with default ctor
    448                                         makeMemberOp( dstParam, nullptr, field, func );
     367                                        makeStructMemberOp( dstParam, nullptr, field, func );
    449368                                }
    450369                        }
     
    452371        }
    453372
    454         bool UnionFuncGenerator::shouldAutogen() const {
     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 ) {
    455382                // Builtins do not use autogeneration.
    456                 return ! aggregateDecl->linkage.is_builtin;
    457         }
    458 
    459         // xxx - is this right?
    460         bool UnionFuncGenerator::isConcurrentType() const { return false; };
     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
     398                // 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)
     432                // Field constructors are only generated if default and copy constructor
     433                // 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        }
    461459
    462460        /// generate a single union assignment expression (using memcpy)
    463461        template< typename OutputIterator >
    464         void UnionFuncGenerator::makeMemberOp( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
     462        void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
    465463                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() ) );
     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() ) );
    469467                *out++ = new ExprStmt( noLabels, copy );
    470468        }
    471469
    472470        /// 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() {
    491                 // field ctors are only generated if default constructor and copy constructor are both generated
    492                 unsigned numCtors = std::count_if( definitions.begin(), definitions.end(), [](Declaration * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } );
    493 
    494                 // Field constructors are only generated if default and copy constructor
    495                 // are generated, since they need access to both
    496                 if ( numCtors != 2 ) return;
     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 );
    497522
    498523                // create a constructor which takes the first member type as a parameter.
     
    500525                // void ?{}(A *, int)
    501526                // This is to mimic C's behaviour which initializes the first member of the union.
    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
     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
    507539                                break;
    508540                        }
    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         //=============================================================================================
     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
    577550        AutogenerateRoutines::AutogenerateRoutines() {
    578551                // the order here determines the order that these functions are generated.
    579552                // assignment should come last since it uses copy constructor in return.
    580                 data.emplace_back( "?{}", genDefaultType );
    581                 data.emplace_back( "?{}", genCopyType );
    582                 data.emplace_back( "^?{}", genDefaultType );
    583                 data.emplace_back( "?=?", genAssignType );
     553                data.emplace_back( "?{}", genDefaultType, constructable );
     554                data.emplace_back( "?{}", genCopyType, copyable );
     555                data.emplace_back( "^?{}", genDefaultType, destructable );
     556                data.emplace_back( "?=?", genAssignType, assignable );
    584557        }
    585558
    586559        void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
    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 );
     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 );
    593565                }
    594566        }
     
    596568        void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
    597569                visit_children = false;
    598                 if ( structDecl->has_body() ) {
     570                if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
    599571                        StructInstType structInst( Type::Qualifiers(), structDecl->name );
     572                        for ( TypeDecl * typeDecl : structDecl->parameters ) {
     573                                // need to visit assertions so that they are added to the appropriate maps
     574                                acceptAll( typeDecl->assertions, *visitor );
     575                                structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
     576                        }
    600577                        structInst.set_baseStruct( structDecl );
    601                         for ( TypeDecl * typeDecl : structDecl->parameters ) {
    602                                 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
    603                         }
    604                         StructFuncGenerator gen( structDecl, &structInst, data, functionNesting, indexer );
    605                         generateFunctions( gen, declsToAddAfter );
     578                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
     579                        structsDone.insert( structDecl->name );
    606580                } // if
    607581        }
     
    609583        void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
    610584                visit_children = false;
    611                 if ( unionDecl->has_body() ) {
     585                if ( ! unionDecl->get_members().empty() ) {
    612586                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    613587                        unionInst.set_baseUnion( unionDecl );
     
    615589                                unionInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
    616590                        }
    617                         UnionFuncGenerator gen( unionDecl, &unionInst, data, functionNesting, indexer );
    618                         generateFunctions( gen, declsToAddAfter );
     591                        makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAddAfter );
    619592                } // if
     593        }
     594
     595        Type * declToTypeDeclBase( Declaration * decl ) {
     596                if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) {
     597                        return td->base;
     598                }
     599                return nullptr;
    620600        }
    621601
     
    625605                if ( ! typeDecl->base ) return;
    626606
     607                // generate each of the functions based on the supplied FuncData objects
     608                std::list< FunctionDecl * > newFuncs;
     609                std::list< Declaration * > tds { typeDecl };
     610                std::list< TypeDecl * > typeParams;
    627611                TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl );
    628                 TypeFuncGenerator gen( typeDecl, &refType, data, functionNesting, indexer );
    629                 generateFunctions( gen, declsToAddAfter );
     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                }
    630647        }
    631648
     
    648665                visit_children = false;
    649666                // record the existence of this function as appropriate
    650                 managedTypes.handleDWT( functionDecl );
     667                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     668                insert( functionDecl, assignable, InitTweak::isAssignment );
     669                insert( functionDecl, copyable, InitTweak::isCopyConstructor );
     670                insert( functionDecl, destructable, InitTweak::isDestructor );
    651671
    652672                maybeAccept( functionDecl->type, *visitor );
     
    657677
    658678        void AutogenerateRoutines::previsit( CompoundStmt * ) {
    659                 GuardScope( managedTypes );
     679                GuardScope( constructable );
     680                GuardScope( assignable );
     681                GuardScope( copyable );
     682                GuardScope( destructable );
    660683                GuardScope( structsDone );
    661684        }
  • src/SymTab/Autogen.h

    r6840e7c rb96ec83  
    1919#include <string>                 // for string
    2020
    21 #include "CodeGen/OperatorTable.h"
    2221#include "Common/UniqueName.h"    // for UniqueName
    2322#include "InitTweak/InitTweak.h"  // for InitExpander
     
    5251
    5352        // generate the type of a copy constructor for paramType
    54         FunctionType * genCopyType( Type * paramType );
     53        FunctionType * genDefaultType( Type * paramType );
    5554
    5655        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
     
    6160        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    6261        template< typename OutputIterator >
    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 
     62        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    7463                // want to be able to generate assignment, ctor, and dtor generically,
    7564                // so fname is either ?=?, ?{}, or ^?{}
    76                 UntypedExpr * fExpr = new UntypedExpr( new NameExpr( fname ) );
     65                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    7766
    7867                if ( addCast ) {
     
    8978                        dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) );
    9079                }
    91                 fExpr->args.push_back( dstParam );
     80                fExpr->get_args().push_back( dstParam );
    9281
    9382                Statement * listInit = srcParam.buildListInit( fExpr );
    9483
    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 );
     84                std::list< Expression * > args = *++srcParam;
     85                fExpr->get_args().splice( fExpr->get_args().end(), args );
    10686
    10787                *out++ = new ExprStmt( noLabels, fExpr );
     
    125105                        // generate: for ( int i = 0; i < N; ++i )
    126106                        begin = new ConstantExpr( Constant::from_int( 0 ) );
    127                         end = array->dimension->clone();
     107                        end = array->get_dimension()->clone();
    128108                        cmp = new NameExpr( "?<?" );
    129109                        update = new NameExpr( "++?" );
     
    131111                        // generate: for ( int i = N-1; i >= 0; --i )
    132112                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
    133                         ((UntypedExpr*)begin)->args.push_back( array->dimension->clone() );
    134                         ((UntypedExpr*)begin)->args.push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     113                        ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     114                        ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
    135115                        end = new ConstantExpr( Constant::from_int( 0 ) );
    136116                        cmp = new NameExpr( "?>=?" );
     
    141121
    142122                UntypedExpr *cond = new UntypedExpr( cmp );
    143                 cond->args.push_back( new VariableExpr( index ) );
    144                 cond->args.push_back( end );
     123                cond->get_args().push_back( new VariableExpr( index ) );
     124                cond->get_args().push_back( end );
    145125
    146126                UntypedExpr *inc = new UntypedExpr( update );
    147                 inc->args.push_back( new VariableExpr( index ) );
     127                inc->get_args().push_back( new VariableExpr( index ) );
    148128
    149129                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    150                 dstIndex->args.push_back( dstParam );
    151                 dstIndex->args.push_back( new VariableExpr( index ) );
     130                dstIndex->get_args().push_back( dstParam );
     131                dstIndex->get_args().push_back( new VariableExpr( index ) );
    152132                dstParam = dstIndex;
    153133
    154134                // srcParam must keep track of the array indices to build the
    155135                // source parameter and/or array list initializer
    156                 srcParam.addArrayIndex( new VariableExpr( index ), array->dimension->clone() );
     136                srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    157137
    158138                // for stmt's body, eventually containing call
    159139                CompoundStmt * body = new CompoundStmt( noLabels );
    160                 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->kids ), array->base, addCast, forward );
     140                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
    161141
    162142                // block containing for stmt and index variable
    163143                std::list<Statement *> initList;
    164144                CompoundStmt * block = new CompoundStmt( noLabels );
    165                 block->push_back( new DeclStmt( noLabels, index ) );
     145                block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    166146                if ( listInit ) block->get_kids().push_back( listInit );
    167                 block->push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     147                block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
    168148
    169149                *out++ = block;
     
    171151
    172152        template< typename OutputIterator >
    173         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
     153        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    174154                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    175155                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     
    185165        /// ImplicitCtorDtorStmt node.
    186166        template< typename OutputIterator >
    187         void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     167        void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    188168                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    189169                assert( obj );
     
    193173                bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) );
    194174                std::list< Statement * > stmts;
    195                 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward );
     175                genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
    196176
    197177                // 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

    r6840e7c rb96ec83  
    2626        FixFunction::FixFunction() : isVoid( false ) {}
    2727
    28 
    29         DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) {
     28        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
    3029                // can't delete function type because it may contain assertions, so transfer ownership to new object
    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();
     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();
    3332                functionDecl->type = nullptr;
    3433                delete functionDecl;
     
    3635        }
    3736
    38         Type * FixFunction::postmutate(ArrayType *arrayType) {
     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) {
    3951                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    40                 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );
    41                 arrayType->base = nullptr;
    42                 arrayType->dimension = nullptr;
     52                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
    4353                delete arrayType;
    4454                return pointerType;
    4555        }
    4656
    47         void FixFunction::premutate(VoidType *) {
    48                 isVoid = true;
     57        Type * FixFunction::mutate(StructInstType *aggregateUseType) {
     58                return aggregateUseType;
    4959        }
    5060
    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; }
     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        }
    6392} // namespace SymTab
    6493
  • src/SymTab/FixFunction.h

    r6840e7c rb96ec83  
    1616#pragma once
    1717
    18 #include "Common/PassVisitor.h" // for PassVisitor
    19 #include "SynTree/SynTree.h"    // for Types
     18#include "SynTree/Mutator.h"  // for Mutator
     19#include "SynTree/SynTree.h"  // for Types
    2020
    2121namespace SymTab {
    2222        /// Replaces function and array types by equivalent pointer types.
    23         class FixFunction : public WithShortCircuiting {
     23        class FixFunction : public Mutator {
    2424                typedef Mutator Parent;
    2525          public:
    2626                FixFunction();
    2727
    28                 void premutate(FunctionDecl *functionDecl);
    29                 DeclarationWithType* postmutate(FunctionDecl *functionDecl);
     28                bool get_isVoid() const { return isVoid; }
     29                void set_isVoid( bool newValue ) { isVoid = newValue; }
     30          private:
     31                virtual DeclarationWithType* mutate(FunctionDecl *functionDecl);
    3032
    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);
     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);
    4546
    4647                bool isVoid;
  • src/SymTab/Indexer.cc

    r6840e7c rb96ec83  
    407407                makeWritable();
    408408
    409                 const std::string &name = decl->name;
     409                const std::string &name = decl->get_name();
    410410                std::string mangleName;
    411                 if ( LinkageSpec::isOverridable( decl->linkage ) ) {
     411                if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
    412412                        // mangle the name without including the appropriate suffix, so overridable routines are placed into the
    413413                        // same "bucket" as their user defined versions.
     
    418418
    419419                // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
    420                 if ( ! LinkageSpec::isMangled( decl->linkage ) ) {
     420                if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) {
    421421                        // NOTE this is broken in Richard's original code in such a way that it never triggers (it
    422422                        // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
     
    571571
    572572                if ( doDebug ) {
    573                         std::cerr << "--- Entering scope " << scope << std::endl;
     573                        std::cout << "--- Entering scope " << scope << std::endl;
    574574                }
    575575        }
    576576
    577577        void Indexer::leaveScope() {
    578                 using std::cerr;
     578                using std::cout;
    579579
    580580                assert( scope > 0 && "cannot leave initial scope" );
    581                 if ( doDebug ) {
    582                         cerr << "--- Leaving scope " << scope << " containing" << std::endl;
    583                 }
    584581                --scope;
    585582
    586583                while ( tables && tables->scope > scope ) {
    587584                        if ( doDebug ) {
    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 );
     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 );
    594592                        }
    595593
  • src/SymTab/Mangler.cc

    r6840e7c rb96ec83  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:40:29 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:49:26 2017
    13 // Update Count     : 23
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 28 15:31:00 2017
     13// Update Count     : 21
    1414//
    1515#include "Mangler.h"
     
    115115                        "Id",   // DoubleImaginary
    116116                        "Ir",   // LongDoubleImaginary
    117                         "w",    // SignedInt128
    118                         "Uw",   // UnsignedInt128
    119117                };
    120118
  • src/SymTab/Validate.cc

    r6840e7c rb96ec83  
    153153                void previsit( ObjectDecl * object );
    154154                void previsit( FunctionDecl * func );
    155                 void previsit( StructDecl * aggrDecl );
    156                 void previsit( UnionDecl * aggrDecl );
    157155        };
    158156
     
    272270                acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
    273271                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
    276272                Concurrency::applyKeywords( translationUnit );
    277                 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    278273                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    279274                Concurrency::implementMutexFuncs( translationUnit );
    280275                Concurrency::implementThreadStarter( translationUnit );
     276                ReturnChecker::checkFunctionReturns( translationUnit );
    281277                mutateAll( translationUnit, compoundliteral );
     278                acceptAll( translationUnit, fpd );
    282279                ArrayLength::computeLength( translationUnit );
    283                 acceptAll( translationUnit, finder ); // xxx - remove this pass soon
     280                acceptAll( translationUnit, finder );
    284281                mutateAll( translationUnit, labelAddrFixer );
    285282        }
     
    372369                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
    373370                        if ( begin == end ) return;
    374                         PassVisitor<FixFunction> fixer;
     371                        FixFunction fixer;
    375372                        DWTIterator i = begin;
    376373                        *i = (*i)->acceptMutator( fixer );
    377                         if ( fixer.pass.isVoid ) {
     374                        if ( fixer.get_isVoid() ) {
    378375                                DWTIterator j = i;
    379376                                ++i;
     
    386383                                ++i;
    387384                                for ( ; i != end; ++i ) {
    388                                         PassVisitor<FixFunction> fixer;
     385                                        FixFunction fixer;
    389386                                        *i = (*i)->acceptMutator( fixer );
    390                                         if ( fixer.pass.isVoid ) {
     387                                        if ( fixer.get_isVoid() ) {
    391388                                                throw SemanticError( "invalid type void in function type ", func );
    392389                                        } // if
     
    600597                        // apply FixFunction to every assertion to check for invalid void type
    601598                        for ( DeclarationWithType *& assertion : type->assertions ) {
    602                                 PassVisitor<FixFunction> fixer;
     599                                FixFunction fixer;
    603600                                assertion = assertion->acceptMutator( fixer );
    604                                 if ( fixer.pass.isVoid ) {
     601                                if ( fixer.get_isVoid() ) {
    605602                                        throw SemanticError( "invalid type void in assertion of function ", node );
    606603                                } // if
     
    621618                forallFixer( func->type->forall, func );
    622619                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 );
    631620        }
    632621
  • src/SynTree/AddressExpr.cc

    r6840e7c rb96ec83  
    3333        Type * addrType( Type * type ) {
    3434                if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) {
    35                         return new ReferenceType( refType->get_qualifiers(), addrType( refType->base ) );
     35                        return new ReferenceType( refType->get_qualifiers(), addrType( refType->get_base() ) );
    3636                } else {
    3737                        return new PointerType( Type::Qualifiers(), type->clone() );
     
    4040}
    4141
    42 AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) {
    43         if ( arg->result ) {
    44                 if ( arg->result->get_lvalue() ) {
     42AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) {
     43        if ( arg->has_result() ) {
     44                if ( arg->get_result()->get_lvalue() ) {
    4545                        // lvalue, retains all layers of reference and gains a pointer inside the references
    46                         set_result( addrType( arg->result ) );
     46                        set_result( addrType( arg->get_result() ) );
    4747                } else {
    4848                        // taking address of non-lvalue -- must be a reference, loses one layer of reference
    49                         ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg->result );
    50                         set_result( addrType( refType->base ) );
     49                        ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg->get_result() );
     50                        set_result( addrType( refType->get_base() ) );
    5151                }
    5252                // result of & is never an lvalue
     
    6262}
    6363
    64 void AddressExpr::print( std::ostream &os, Indenter indent ) const {
     64void AddressExpr::print( std::ostream &os, int indent ) const {
    6565        os << "Address of:" << std::endl;
    6666        if ( arg ) {
    67                 os << indent+1;
    68                 arg->print( os, indent+1 );
     67                os << std::string( indent+2, ' ' );
     68                arg->print( os, indent+2 );
    6969        } // if
    7070}
     
    7777LabelAddressExpr::~LabelAddressExpr() {}
    7878
    79 void LabelAddressExpr::print( std::ostream & os, Indenter ) const {
    80         os << "Address of label:" << arg;
     79void LabelAddressExpr::print( std::ostream & os, int indent ) const {
     80        os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;
    8181}
    8282
  • src/SynTree/AggregateDecl.cc

    r6840e7c rb96ec83  
    4141}
    4242
    43 void AggregateDecl::print( std::ostream &os, Indenter indent ) const {
     43void AggregateDecl::print( std::ostream &os, int indent ) const {
    4444        using std::string;
    4545        using std::endl;
    4646
    47         os << typeString() << " " << name << ":";
     47        os << typeString() << " " << get_name() << ":";
    4848        if ( get_linkage() != LinkageSpec::Cforall ) {
    49                 os << " " << LinkageSpec::linkageName( linkage );
     49                os << " " << LinkageSpec::linkageName( get_linkage() );
    5050        } // if
    51         os << " with body " << has_body();
     51        os << " with body " << has_body() << endl;
    5252
    5353        if ( ! parameters.empty() ) {
    54                 os << endl << indent << "... with parameters" << endl;
    55                 printAll( parameters, os, indent+1 );
     54                os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
     55                printAll( parameters, os, indent+4 );
    5656        } // if
    5757        if ( ! members.empty() ) {
    58                 os << endl << indent << "... with members" << endl;
    59                 printAll( members, os, indent+1 );
     58                os << endl << string( indent+2, ' ' ) << "with members" << endl;
     59                printAll( members, os, indent+4 );
    6060        } // if
    6161        if ( ! attributes.empty() ) {
    62                 os << endl << indent << "... with attributes" << endl;
    63                 printAll( attributes, os, indent+1 );
     62                os << endl << string( indent+2, ' ' ) << "with attributes" << endl;
     63                printAll( attributes, os, indent+4 );
    6464        } // if
    65         os << endl;
    6665}
    6766
    68 void AggregateDecl::printShort( std::ostream &os, Indenter indent ) const {
     67void AggregateDecl::printShort( std::ostream &os, int indent ) const {
    6968        using std::string;
    7069        using std::endl;
    7170
    72         os << typeString() << " " << name << " with body " << has_body() << endl;
     71        os << typeString() << " " << get_name();
     72        os << string( indent+2, ' ' ) << "with body " << has_body() << endl;
    7373
    7474        if ( ! parameters.empty() ) {
    75                 os << indent << "... with parameters" << endl;
    76                 printAll( parameters, os, indent+1 );
     75                os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
     76                printAll( parameters, os, indent+4 );
    7777        } // if
    7878}
  • src/SynTree/ApplicationExpr.cc

    r6840e7c rb96ec83  
    5555        set_result( ResolvExpr::extractResultType( function ) );
    5656
    57         assert( result );
     57        assert( has_result() );
    5858}
    5959
     
    6868}
    6969
    70 void printInferParams( const InferredParams & inferParams, std::ostream &os, Indenter indent, int level ) {
     70void printInferParams( const InferredParams & inferParams, std::ostream &os, int indent, int level ) {
    7171        if ( ! inferParams.empty() ) {
    72                 os << indent << "with inferred parameters " << level << ":" << std::endl;
     72                os << std::string(indent, ' ') << "with inferred parameters " << level << ":" << std::endl;
    7373                for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
    74                         os << indent+1;
    75                         Declaration::declFromId( i->second.decl )->printShort( os, indent+1 );
     74                        os << std::string(indent+2, ' ');
     75                        Declaration::declFromId( i->second.decl )->printShort( os, indent+2 );
    7676                        os << std::endl;
    77                         printInferParams( *i->second.inferParams, os, indent+1, level+1 );
     77                        printInferParams( *i->second.inferParams, os, indent+2, level+1 );
    7878                } // for
    7979        } // if
    8080}
    8181
    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;
     82void ApplicationExpr::print( std::ostream &os, int indent ) const {
     83        os << "Application of" << std::endl << std::string(indent+2, ' ');
     84        function->print( os, indent+2 );
    8685        if ( ! args.empty() ) {
    87                 os << indent << "... to arguments" << std::endl;
    88                 printAll( args, os, indent+1 );
     86                os << std::string( indent, ' ' ) << "to arguments" << std::endl;
     87                printAll( args, os, indent+2 );
    8988        } // if
    90         printInferParams( inferParams, os, indent+1, 0 );
     89        printInferParams( inferParams, os, indent+2, 0 );
    9190        Expression::print( os, indent );
    9291}
  • src/SynTree/ArrayType.cc

    r6840e7c rb96ec83  
    3939}
    4040
    41 void ArrayType::print( std::ostream &os, Indenter indent ) const {
     41void ArrayType::print( std::ostream &os, int indent ) const {
    4242        Type::print( os, indent );
    4343        if ( isStatic ) {
  • src/SynTree/AttrType.cc

    r6840e7c rb96ec83  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AttrType.cc.cc --
     7// AttrType.cc.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    4242}
    4343
    44 void AttrType::print( std::ostream &os, Indenter indent ) const {
     44void AttrType::print( std::ostream &os, int indent ) const {
    4545        Type::print( os, indent );
    4646        os << "attribute " << name << " applied to ";
  • src/SynTree/Attribute.cc

    r6840e7c rb96ec83  
    2828}
    2929
    30 void Attribute::print( std::ostream &os, Indenter indent ) const {
     30void Attribute::print( std::ostream &os, int indent ) const {
    3131  using std::endl;
    3232  using std::string;
     
    3636    if ( ! parameters.empty() ) {
    3737      os << " with parameters: " << endl;
    38       printAll( parameters, os, indent+1 );
     38      printAll( parameters, os, indent );
    3939    }
    4040  }
  • src/SynTree/Attribute.h

    r6840e7c rb96ec83  
    4343        bool empty() const { return name == ""; }
    4444
    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;
     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;
    4949};
    5050
  • src/SynTree/BaseSyntaxNode.h

    r6840e7c rb96ec83  
    1717
    1818#include "Common/CodeLocation.h"
    19 #include "Common/Indenter.h"
    2019class Visitor;
    2120class Mutator;
     
    3029        virtual void accept( Visitor & v ) = 0;
    3130        virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 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   }
     31        virtual void print( std::ostream & os, int indent = 0 ) const = 0;
    3932};
    4033
  • src/SynTree/BasicType.cc

    r6840e7c rb96ec83  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // BasicType.cc --
     7// BasicType.cc -- 
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 14:14:03 2017
    13 // Update Count     : 11
     12// Last Modified On : Mon Sep 11 12:52:05 2017
     13// Update Count     : 9
    1414//
    1515
     
    2424BasicType::BasicType( const Type::Qualifiers &tq, Kind bt, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), kind( bt ) {}
    2525
    26 void BasicType::print( std::ostream &os, Indenter indent ) const {
     26void BasicType::print( std::ostream &os, int indent ) const {
    2727        Type::print( os, indent );
    2828        os << BasicType::typeNames[ kind ];
     
    4343          case LongLongSignedInt:
    4444          case LongLongUnsignedInt:
    45           case SignedInt128:
    46           case UnsignedInt128:
    4745                return true;
    4846          case Float:
  • src/SynTree/CommaExpr.cc

    r6840e7c rb96ec83  
    2121#include "Type.h"            // for Type
    2222
    23 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 )
    24                 : Expression(), arg1( arg1 ), arg2( arg2 ) {
     23CommaExpr::CommaExpr( Expression *arg1, Expression *arg2, Expression *_aname )
     24                : Expression( _aname ), arg1( arg1 ), arg2( arg2 ) {
    2525        // xxx - result of a comma expression is never an lvalue, so should set lvalue
    2626        // to false on all result types. Actually doing this causes some strange things
     
    3939}
    4040
    41 void CommaExpr::print( std::ostream &os, Indenter indent ) const {
     41void CommaExpr::print( std::ostream &os, int indent ) const {
    4242        os << "Comma Expression:" << std::endl;
    43         os << (indent+1);
    44         arg1->print( os, indent+1 );
     43        os << std::string( indent+2, ' ' );
     44        arg1->print( os, indent+2 );
    4545        os << std::endl;
    46         os << (indent+1);
    47         arg2->print( os, indent+1 );
     46        os << std::string( indent+2, ' ' );
     47        arg2->print( os, indent+2 );
    4848        Expression::print( os, indent );
    4949}
  • src/SynTree/CompoundStmt.cc

    r6840e7c rb96ec83  
    7373}
    7474
    75 void CompoundStmt::print( std::ostream &os, Indenter indent ) const {
    76         os << "CompoundStmt" << endl;
    77         printAll( kids, os, indent+1 );
     75void CompoundStmt::print( std::ostream &os, int indent ) const {
     76        os << "CompoundStmt" << endl ;
     77        printAll( kids, os, indent + 2 );
    7878}
    7979
  • src/SynTree/Constant.cc

    r6840e7c rb96ec83  
    7171}
    7272
    73 void Constant::print( std::ostream &os, Indenter ) const {
     73void Constant::print( std::ostream &os ) const {
    7474        os << "(" << rep << " " << val.ival;
    7575        if ( type ) {
  • src/SynTree/Constant.h

    r6840e7c rb96ec83  
    1919#include <string>     // for string
    2020
    21 #include "BaseSyntaxNode.h"
    2221#include "Mutator.h"  // for Mutator
    2322#include "Visitor.h"  // for Visitor
     
    2524class Type;
    2625
    27 class Constant : public BaseSyntaxNode {
     26class Constant {
    2827  public:
    2928        Constant( Type * type, std::string rep, unsigned long long val );
     
    3130        Constant( const Constant & other );
    3231        virtual ~Constant();
    33 
    34         virtual Constant * clone() const { return new Constant( *this ); }
    3532
    3633        Type * get_type() { return type; }
     
    5754        virtual void accept( Visitor & v ) { v.visit( this ); }
    5855        virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    59         virtual void print( std::ostream & os, Indenter indent = 0 ) const;
     56        virtual void print( std::ostream & os ) const;
    6057  private:
    6158        Type * type;
  • src/SynTree/DeclStmt.cc

    r6840e7c rb96ec83  
    3333}
    3434
    35 void DeclStmt::print( std::ostream &os, Indenter indent ) const {
     35void DeclStmt::print( std::ostream &os, int indent ) const {
    3636        assert( decl != 0 );
    3737        os << "Declaration of ";
  • src/SynTree/Declaration.cc

    r6840e7c rb96ec83  
    4242
    4343void Declaration::fixUniqueId() {
    44         // don't need to set unique ID twice
    45         if ( uniqueId ) return;
    4644        uniqueId = ++lastUniqueId;
    4745        idMap[ uniqueId ] = this;
     
    7270}
    7371
    74 void AsmDecl::print( std::ostream &os, Indenter indent ) const {
     72void AsmDecl::print( std::ostream &os, int indent ) const {
    7573        stmt->print( os, indent );
    7674}
    7775
    78 void AsmDecl::printShort( std::ostream &os, Indenter indent ) const {
     76void AsmDecl::printShort( std::ostream &os, int indent ) const {
    7977        stmt->print( os, indent );
    8078}
  • src/SynTree/Declaration.h

    r6840e7c rb96ec83  
    6161
    6262        void fixUniqueId( void );
    63         virtual Declaration *clone() const override = 0;
     63        virtual Declaration *clone() const = 0;
    6464        virtual void accept( Visitor &v ) override = 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;
     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;
    6868
    6969        static void dumpIds( std::ostream &os );
     
    142142        virtual void accept( Visitor &v ) override { v.visit( this ); }
    143143        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    144         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    145         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     144        virtual void print( std::ostream &os, int indent = 0 ) const override;
     145        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    146146};
    147147
     
    170170        virtual void accept( Visitor &v ) override { v.visit( this ); }
    171171        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    172         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    173         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     172        virtual void print( std::ostream &os, int indent = 0 ) const override;
     173        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    174174};
    175175
     
    193193
    194194        virtual NamedTypeDecl *clone() const override = 0;
    195         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    196         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     195        virtual void print( std::ostream &os, int indent = 0 ) const override;
     196        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    197197};
    198198
     
    235235        virtual void accept( Visitor &v ) override { v.visit( this ); }
    236236        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    237         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     237        virtual void print( std::ostream &os, int indent = 0 ) const override;
    238238
    239239  private:
     
    276276        AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; }
    277277
    278         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    279         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     278        virtual void print( std::ostream &os, int indent = 0 ) const override;
     279        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    280280  protected:
    281281        virtual std::string typeString() const = 0;
     
    355355        virtual void accept( Visitor &v ) override { v.visit( this ); }
    356356        virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    357         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    358         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     357        virtual void print( std::ostream &os, int indent = 0 ) const override;
     358        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    359359};
    360360
  • src/SynTree/Expression.cc

    r6840e7c rb96ec83  
    3333#include "GenPoly/Lvalue.h"
    3434
    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 ) {
     35Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname ) {}
     36
     37Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
    3838}
    3939
    4040Expression::~Expression() {
    4141        delete env;
     42        delete argName; // xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix
    4243        delete result;
    4344}
    4445
    45 void Expression::print( std::ostream &os, Indenter indent ) const {
     46void Expression::print( std::ostream &os, int indent ) const {
    4647        if ( env ) {
    47                 os << std::endl << indent << "... with environment:" << std::endl;
    48                 env->print( os, indent+1 );
     48                os << std::string( indent, ' ' ) << "with environment:" << std::endl;
     49                env->print( os, indent+2 );
    4950        } // if
    5051
     52        if ( argName ) {
     53                os << std::string( indent, ' ' ) << "with designator:";
     54                argName->print( os, indent+2 );
     55        } // if
     56
    5157        if ( extension ) {
    52                 os << std::endl << indent << "... with extension:";
     58                os << std::string( indent, ' ' ) << "with extension:";
    5359        } // if
    5460}
    5561
    56 ConstantExpr::ConstantExpr( Constant _c ) : Expression(), constant( _c ) {
     62ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) {
    5763        set_result( constant.get_type()->clone() );
    5864}
     
    6369ConstantExpr::~ConstantExpr() {}
    6470
    65 void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
     71void ConstantExpr::print( std::ostream &os, int indent ) const {
    6672        os << "constant expression " ;
    6773        constant.print( os );
     
    6975}
    7076
    71 VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) {
     77VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var ) {
    7278        assert( var );
    7379        assert( var->get_type() );
     
    9096}
    9197
    92 void VariableExpr::print( std::ostream &os, Indenter indent ) const {
     98void VariableExpr::print( std::ostream &os, int indent ) const {
    9399        os << "Variable Expression: ";
    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) {
     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
     107SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) :
     108                Expression( _aname ), expr(expr_), type(0), isType(false) {
    100109        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    101110}
    102111
    103 SizeofExpr::SizeofExpr( Type *type_ ) :
    104                 Expression(), expr(0), type(type_), isType(true) {
     112SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) :
     113                Expression( _aname ), expr(0), type(type_), isType(true) {
    105114        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    106115}
     
    115124}
    116125
    117 void SizeofExpr::print( std::ostream &os, Indenter indent) const {
     126void SizeofExpr::print( std::ostream &os, int indent) const {
    118127        os << "Sizeof Expression on: ";
    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) {
     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
     138AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
     139                Expression( _aname ), expr(expr_), type(0), isType(false) {
    126140        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    127141}
    128142
    129 AlignofExpr::AlignofExpr( Type *type_ ) :
    130                 Expression(), expr(0), type(type_), isType(true) {
     143AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
     144                Expression( _aname ), expr(0), type(type_), isType(true) {
    131145        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    132146}
     
    141155}
    142156
    143 void AlignofExpr::print( std::ostream &os, Indenter indent) const {
     157void AlignofExpr::print( std::ostream &os, int indent) const {
    144158        os << "Alignof Expression on: ";
    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 );
     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
     169UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) :
     170                Expression( _aname ), type(type_), member(member_) {
    153171        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    154172}
     
    161179}
    162180
    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 );
     181void 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
     194OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
     195                Expression( _aname ), type(type_), member(member_) {
    173196        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    174197}
     
    181204}
    182205
    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 );
     206void 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
     227OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) {
    191228        set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
    192229}
     
    196233OffsetPackExpr::~OffsetPackExpr() { delete type; }
    197234
    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) {
     235void 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
     248AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) :
     249                Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false) {
     250}
     251
     252AttrExpr::AttrExpr( Expression *attr, Type *type_, Expression *_aname ) :
     253                Expression( _aname ), attr( attr ), expr(0), type(type_), isType(true) {
    210254}
    211255
     
    220264}
    221265
    222 void AttrExpr::print( std::ostream &os, Indenter indent) const {
     266void AttrExpr::print( std::ostream &os, int indent) const {
    223267        os << "Attr ";
    224         attr->print( os, indent+1);
     268        attr->print( os, indent + 2 );
    225269        if ( isType || expr ) {
    226270                os << "applied to: ";
    227                 if (isType) type->print(os, indent+1);
    228                 else expr->print(os, indent+1);
     271
     272                if (isType)
     273                        type->print(os, indent + 2);
     274                else
     275                        expr->print(os, indent + 2);
    229276        } // if
    230         Expression::print( os, indent );
    231 }
    232 
    233 CastExpr::CastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
     277
     278        os << std::endl;
     279        Expression::print( os, indent );
     280}
     281
     282CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) {
    234283        set_result(toType);
    235284}
    236285
    237 CastExpr::CastExpr( Expression *arg_ ) : Expression(), arg(arg_) {
     286CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) {
    238287        set_result( new VoidType( Type::Qualifiers() ) );
    239288}
     
    246295}
    247296
    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:";
     297void 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, ' ' );
    252302        if ( result->isVoid() ) {
    253                 os << " nothing";
     303                os << "nothing";
    254304        } else {
    255                 os << std::endl << indent+1;
    256                 result->print( os, indent+1 );
     305                result->print( os, indent+2 );
    257306        } // if
     307        os << std::endl;
    258308        Expression::print( os, indent );
    259309}
     
    270320}
    271321
    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:";
     322void 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, ' ' );
    276327        if ( ! result ) {
    277                 os << " unknown";
     328                os << "unknown";
    278329        } else {
    279                 os << std::endl << indent+1;
    280                 result->print( os, indent+1 );
     330                result->print( os, indent+2 );
    281331        } // if
    282         Expression::print( os, indent );
    283 }
    284 
    285 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) :
    286                 Expression(), member(member), aggregate(aggregate) {
    287         assert( aggregate );
    288 }
     332        os << std::endl;
     333        Expression::print( os, indent );
     334}
     335
     336UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) :
     337                Expression( _aname ), member(_member), aggregate(_aggregate) {}
    289338
    290339UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
     
    297346}
    298347
    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);
     348void 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, ' ' );
    304361        Expression::print( os, indent );
    305362}
     
    320377
    321378
    322 MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) :
    323                 Expression(), member(member), aggregate(aggregate) {
    324         assert( member );
    325         assert( aggregate );
     379MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) :
     380                Expression( _aname ), member(_member), aggregate(_aggregate) {
    326381
    327382        TypeSubstitution sub( makeSub( aggregate->get_result() ) );
     
    341396}
    342397
    343 void MemberExpr::print( std::ostream &os, Indenter indent ) const {
     398void MemberExpr::print( std::ostream &os, int indent ) const {
    344399        os << "Member Expression, with field: " << std::endl;
    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) {}
     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
     416UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) :
     417                Expression( _aname ), function(_function), args(_args) {}
    354418
    355419UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
     
    392456
    393457
    394 void UntypedExpr::print( std::ostream &os, Indenter indent ) const {
     458void UntypedExpr::print( std::ostream &os, int indent ) const {
    395459        os << "Applying untyped: " << std::endl;
    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");
     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
     467void 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
     475NameExpr::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");
    406478}
    407479
     
    411483NameExpr::~NameExpr() {}
    412484
    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) {
     485void NameExpr::print( std::ostream &os, int indent ) const {
     486        os << "Name: " << get_name() << std::endl;
     487        Expression::print( os, indent );
     488}
     489
     490LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) :
     491                Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp) {
    420492        set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    421493}
     
    430502}
    431503
    432 void LogicalExpr::print( std::ostream &os, Indenter indent )const {
    433         os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: ";
     504void LogicalExpr::print( std::ostream &os, int indent )const {
     505        os << "Short-circuited operation (" << (isAnd?"and":"or") << ") on: ";
    434506        arg1->print(os);
    435507        os << " and ";
    436508        arg2->print(os);
    437         Expression::print( os, indent );
    438 }
    439 
    440 ConditionalExpr::ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 ) :
    441                 Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {}
     509        os << std::endl;
     510        Expression::print( os, indent );
     511}
     512
     513ConditionalExpr::ConditionalExpr( Expression *arg1_, Expression *arg2_, Expression *arg3_, Expression *_aname ) :
     514                Expression( _aname ), arg1(arg1_), arg2(arg2_), arg3(arg3_) {}
    442515
    443516ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) :
     
    451524}
    452525
    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 );
     526void 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;
    460537        Expression::print( os, indent );
    461538}
     
    464541
    465542
    466 void AsmExpr::print( std::ostream &os, Indenter indent ) const {
     543void AsmExpr::print( std::ostream &os, int indent ) const {
    467544        os << "Asm Expression: " << std::endl;
    468         if ( inout ) inout->print( os, indent+1 );
    469         if ( constraint ) constraint->print( os, indent+1 );
    470         if ( operand ) operand->print( os, indent+1 );
     545        if ( inout ) inout->print( os, indent + 2 );
     546        if ( constraint ) constraint->print( os, indent + 2 );
     547        if ( operand ) operand->print( os, indent + 2 );
    471548}
    472549
     
    474551ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
    475552        assert( callExpr );
    476         assert( callExpr->result );
     553        assert( callExpr->has_result() );
    477554        set_result( callExpr->get_result()->clone() );
    478555}
     
    492569}
    493570
    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 );
     571void 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);
    501580        Expression::print( os, indent );
    502581}
     
    508587        Expression * arg = InitTweak::getCallArg( callExpr, 0 );
    509588        assert( arg );
    510         set_result( maybeClone( arg->result ) );
     589        set_result( maybeClone( arg->get_result() ) );
    511590}
    512591
     
    518597}
    519598
    520 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
    521         os <<  "Constructor Expression: " << std::endl << indent+1;
     599void ConstructorExpr::print( std::ostream &os, int indent ) const {
     600        os <<  "Constructor Expression: " << std::endl;
     601        assert( callExpr );
     602        os << std::string( indent+2, ' ' );
    522603        callExpr->print( os, indent + 2 );
    523604        Expression::print( os, indent );
     
    537618}
    538619
    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 );
     620void 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 );
    544626        Expression::print( os, indent );
    545627}
     
    547629RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    548630RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
    549 void RangeExpr::print( std::ostream &os, Indenter indent ) const {
     631void RangeExpr::print( std::ostream &os, int indent ) const {
    550632        os << "Range Expression: ";
    551633        low->print( os, indent );
     
    577659        deleteAll( returnDecls );
    578660}
    579 void StmtExpr::print( std::ostream &os, Indenter indent ) const {
    580         os << "Statement Expression: " << std::endl << indent+1;
    581         statements->print( os, indent+1 );
     661void StmtExpr::print( std::ostream &os, int indent ) const {
     662        os << "Statement Expression: " << std::endl << std::string( indent, ' ' );
     663        statements->print( os, indent+2 );
    582664        if ( ! returnDecls.empty() ) {
    583                 os << indent+1 << "... with returnDecls: ";
    584                 printAll( returnDecls, os, indent+1 );
     665                os << std::string( indent+2, ' ' ) << "with returnDecls: ";
     666                printAll( returnDecls, os, indent+2 );
    585667        }
    586668        if ( ! dtors.empty() ) {
    587                 os << indent+1 << "... with dtors: ";
    588                 printAll( dtors, os, indent+1 );
     669                os << std::string( indent+2, ' ' ) << "with dtors: ";
     670                printAll( dtors, os, indent+2 );
    589671        }
    590672        Expression::print( os, indent );
     
    608690        delete var;
    609691}
    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 );
     692void UniqueExpr::print( std::ostream &os, int indent ) 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 );
    616698        }
    617699        Expression::print( os, indent );
     
    631713}
    632714
    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 );
     715void UntypedInitExpr::print( std::ostream & os, int indent ) const {
     716        os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' );
     717        expr->print( os, indent+2 );
    636718        if ( ! initAlts.empty() ) {
    637719                for ( const InitAlternative & alt : initAlts ) {
    638                         os << indent+1 <<  "InitAlternative: ";
    639                         alt.type->print( os, indent+1 );
    640                         alt.designation->print( os, indent+1 );
     720                        os << std::string( indent+2, ' ' ) <<  "InitAlternative: ";
     721                        alt.type->print( os, indent+2 );
     722                        alt.designation->print( os, indent+2 );
    641723                }
    642724        }
     
    652734}
    653735
    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 );
     736void InitExpr::print( std::ostream & os, int indent ) 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 );
    659741}
    660742
  • src/SynTree/Expression.h

    r6840e7c rb96ec83  
    3636        Type * result;
    3737        TypeSubstitution * env;
     38        Expression * argName; // if expression is used as an argument, it can be "designated" by this name
    3839        bool extension = false;
    3940
    40         Expression();
     41        Expression( Expression * _aname = nullptr );
    4142        Expression( const Expression & other );
    4243        virtual ~Expression();
     
    4546        const Type * get_result() const { return result; }
    4647        void set_result( Type * newValue ) { result = newValue; }
     48        bool has_result() const { return result != nullptr; }
    4749
    4850        TypeSubstitution * get_env() const { return env; }
    4951        void set_env( TypeSubstitution * newValue ) { env = newValue; }
     52        Expression * get_argName() const { return argName; }
     53        void set_argName( Expression * name ) { argName = name; }
    5054        bool get_extension() const { return extension; }
    5155        Expression * set_extension( bool exten ) { extension = exten; return this; }
    5256
    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;
     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;
    5761};
    5862
     
    97101        virtual void accept( Visitor & v ) { v.visit( this ); }
    98102        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    99         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     103        virtual void print( std::ostream & os, int indent = 0 ) const;
    100104};
    101105
     
    108112        std::list<Expression*> args;
    109113
    110         UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );
     114        UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >(), Expression *_aname = nullptr );
    111115        UntypedExpr( const UntypedExpr & other );
    112116        virtual ~UntypedExpr();
     
    115119        void set_function( Expression * newValue ) { function = newValue; }
    116120
     121        void set_args( std::list<Expression *> & listArgs ) { args = listArgs; }
    117122        std::list<Expression*>::iterator begin_args() { return args.begin(); }
    118123        std::list<Expression*>::iterator end_args() { return args.end(); }
     
    125130        virtual void accept( Visitor & v ) { v.visit( this ); }
    126131        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    127         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     132        virtual void print( std::ostream & os, int indent = 0 ) const;
     133        virtual void printArgs(std::ostream & os, int indent = 0) const;
    128134};
    129135
     
    133139        std::string name;
    134140
    135         NameExpr( std::string name );
     141        NameExpr( std::string name, Expression *_aname = nullptr );
    136142        NameExpr( const NameExpr & other );
    137143        virtual ~NameExpr();
     
    143149        virtual void accept( Visitor & v ) { v.visit( this ); }
    144150        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    145         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     151        virtual void print( std::ostream & os, int indent = 0 ) const;
    146152};
    147153
     
    154160        Expression * arg;
    155161
    156         AddressExpr( Expression * arg );
     162        AddressExpr( Expression * arg, Expression *_aname = nullptr );
    157163        AddressExpr( const AddressExpr & other );
    158164        virtual ~AddressExpr();
     
    164170        virtual void accept( Visitor & v ) { v.visit( this ); }
    165171        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    166         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     172        virtual void print( std::ostream & os, int indent = 0 ) const;
    167173};
    168174
     
    180186        virtual void accept( Visitor & v ) { v.visit( this ); }
    181187        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    182         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     188        virtual void print( std::ostream & os, int indent = 0 ) const;
    183189};
    184190
     
    188194        Expression * arg;
    189195
    190         CastExpr( Expression * arg );
    191         CastExpr( Expression * arg, Type * toType );
     196        CastExpr( Expression * arg, Expression *_aname = nullptr );
     197        CastExpr( Expression * arg, Type * toType, Expression *_aname = nullptr );
    192198        CastExpr( const CastExpr & other );
    193199        virtual ~CastExpr();
     
    199205        virtual void accept( Visitor & v ) { v.visit( this ); }
    200206        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    201         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     207        virtual void print( std::ostream & os, int indent = 0 ) const;
    202208};
    203209
     
    217223        virtual void accept( Visitor & v ) { v.visit( this ); }
    218224        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    219         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     225        virtual void print( std::ostream & os, int indent = 0 ) const;
    220226};
    221227
     
    226232        Expression * aggregate;
    227233
    228         UntypedMemberExpr( Expression * member, Expression * aggregate );
     234        UntypedMemberExpr( Expression * member, Expression * aggregate, Expression *_aname = nullptr );
    229235        UntypedMemberExpr( const UntypedMemberExpr & other );
    230236        virtual ~UntypedMemberExpr();
     
    238244        virtual void accept( Visitor & v ) { v.visit( this ); }
    239245        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    240         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     246        virtual void print( std::ostream & os, int indent = 0 ) const;
    241247};
    242248
     
    248254        Expression * aggregate;
    249255
    250         MemberExpr( DeclarationWithType * member, Expression * aggregate );
     256        MemberExpr( DeclarationWithType * member, Expression * aggregate, Expression *_aname = nullptr );
    251257        MemberExpr( const MemberExpr & other );
    252258        virtual ~MemberExpr();
     
    260266        virtual void accept( Visitor & v ) { v.visit( this ); }
    261267        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    262         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     268        virtual void print( std::ostream & os, int indent = 0 ) const;
    263269};
    264270
     
    269275        DeclarationWithType * var;
    270276
    271         VariableExpr( DeclarationWithType * var );
     277        VariableExpr( DeclarationWithType * var, Expression *_aname = nullptr );
    272278        VariableExpr( const VariableExpr & other );
    273279        virtual ~VariableExpr();
     
    281287        virtual void accept( Visitor & v ) { v.visit( this ); }
    282288        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    283         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     289        virtual void print( std::ostream & os, int indent = 0 ) const;
    284290};
    285291
     
    289295        Constant constant;
    290296
    291         ConstantExpr( Constant constant );
     297        ConstantExpr( Constant constant, Expression *_aname = nullptr );
    292298        ConstantExpr( const ConstantExpr & other );
    293299        virtual ~ConstantExpr();
     
    299305        virtual void accept( Visitor & v ) { v.visit( this ); }
    300306        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    301         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     307        virtual void print( std::ostream & os, int indent = 0 ) const;
    302308};
    303309
     
    309315        bool isType;
    310316
    311         SizeofExpr( Expression * expr );
     317        SizeofExpr( Expression * expr, Expression *_aname = nullptr );
    312318        SizeofExpr( const SizeofExpr & other );
    313         SizeofExpr( Type * type );
     319        SizeofExpr( Type * type, Expression *_aname = nullptr );
    314320        virtual ~SizeofExpr();
    315321
     
    324330        virtual void accept( Visitor & v ) { v.visit( this ); }
    325331        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    326         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     332        virtual void print( std::ostream & os, int indent = 0 ) const;
    327333};
    328334
     
    334340        bool isType;
    335341
    336         AlignofExpr( Expression * expr );
     342        AlignofExpr( Expression * expr, Expression *_aname = nullptr );
    337343        AlignofExpr( const AlignofExpr & other );
    338         AlignofExpr( Type * type );
     344        AlignofExpr( Type * type, Expression *_aname = nullptr );
    339345        virtual ~AlignofExpr();
    340346
     
    349355        virtual void accept( Visitor & v ) { v.visit( this ); }
    350356        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    351         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     357        virtual void print( std::ostream & os, int indent = 0 ) const;
    352358};
    353359
     
    358364        std::string member;
    359365
    360         UntypedOffsetofExpr( Type * type, const std::string & member );
     366        UntypedOffsetofExpr( Type * type, const std::string & member, Expression *_aname = nullptr );
    361367        UntypedOffsetofExpr( const UntypedOffsetofExpr & other );
    362368        virtual ~UntypedOffsetofExpr();
     
    370376        virtual void accept( Visitor & v ) { v.visit( this ); }
    371377        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    372         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     378        virtual void print( std::ostream & os, int indent = 0 ) const;
    373379};
    374380
     
    379385        DeclarationWithType * member;
    380386
    381         OffsetofExpr( Type * type, DeclarationWithType * member );
     387        OffsetofExpr( Type * type, DeclarationWithType * member, Expression *_aname = nullptr );
    382388        OffsetofExpr( const OffsetofExpr & other );
    383389        virtual ~OffsetofExpr();
     
    391397        virtual void accept( Visitor & v ) { v.visit( this ); }
    392398        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    393         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     399        virtual void print( std::ostream & os, int indent = 0 ) const;
    394400};
    395401
     
    399405        StructInstType * type;
    400406
    401         OffsetPackExpr( StructInstType * type );
     407        OffsetPackExpr( StructInstType * type_, Expression * aname_ = 0 );
    402408        OffsetPackExpr( const OffsetPackExpr & other );
    403409        virtual ~OffsetPackExpr();
     
    409415        virtual void accept( Visitor & v ) { v.visit( this ); }
    410416        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    411         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     417        virtual void print( std::ostream & os, int indent = 0 ) const;
    412418};
    413419
     
    420426        bool isType;
    421427
    422         AttrExpr(Expression * attr, Expression * expr );
     428        AttrExpr(Expression * attr, Expression * expr, Expression *_aname = nullptr );
    423429        AttrExpr( const AttrExpr & other );
    424         AttrExpr( Expression * attr, Type * type );
     430        AttrExpr( Expression * attr, Type * type, Expression *_aname = nullptr );
    425431        virtual ~AttrExpr();
    426432
     
    437443        virtual void accept( Visitor & v ) { v.visit( this ); }
    438444        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    439         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     445        virtual void print( std::ostream & os, int indent = 0 ) const;
    440446};
    441447
     
    446452        Expression * arg2;
    447453
    448         LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true );
     454        LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true, Expression *_aname = nullptr );
    449455        LogicalExpr( const LogicalExpr & other );
    450456        virtual ~LogicalExpr();
     
    459465        virtual void accept( Visitor & v ) { v.visit( this ); }
    460466        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    461         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     467        virtual void print( std::ostream & os, int indent = 0 ) const;
    462468
    463469  private:
     
    472478        Expression * arg3;
    473479
    474         ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 );
     480        ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3, Expression *_aname = nullptr );
    475481        ConditionalExpr( const ConditionalExpr & other );
    476482        virtual ~ConditionalExpr();
     
    486492        virtual void accept( Visitor & v ) { v.visit( this ); }
    487493        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    488         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     494        virtual void print( std::ostream & os, int indent = 0 ) const;
    489495};
    490496
     
    495501        Expression * arg2;
    496502
    497         CommaExpr( Expression * arg1, Expression * arg2 );
     503        CommaExpr( Expression * arg1, Expression * arg2, Expression *_aname = nullptr );
    498504        CommaExpr( const CommaExpr & other );
    499505        virtual ~CommaExpr();
     
    507513        virtual void accept( Visitor & v ) { v.visit( this ); }
    508514        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    509         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     515        virtual void print( std::ostream & os, int indent = 0 ) const;
    510516};
    511517
     
    525531        virtual void accept( Visitor & v ) { v.visit( this ); }
    526532        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    527         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     533        virtual void print( std::ostream & os, int indent = 0 ) const;
    528534};
    529535
     
    551557        virtual void accept( Visitor & v ) { v.visit( this ); }
    552558        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    553         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     559        virtual void print( std::ostream & os, int indent = 0 ) const;
    554560
    555561        // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints
     
    579585        virtual void accept( Visitor & v ) { v.visit( this ); }
    580586        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    581         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     587        virtual void print( std::ostream & os, int indent = 0 ) const;
    582588};
    583589
     
    597603        virtual void accept( Visitor & v ) { v.visit( this ); }
    598604        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    599         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     605        virtual void print( std::ostream & os, int indent = 0 ) const;
    600606};
    601607
     
    615621        virtual void accept( Visitor & v ) { v.visit( this ); }
    616622        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    617         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     623        virtual void print( std::ostream & os, int indent = 0 ) const;
    618624};
    619625
     
    634640        virtual void accept( Visitor & v ) { v.visit( this ); }
    635641        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    636         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     642        virtual void print( std::ostream & os, int indent = 0 ) const;
    637643};
    638644
     
    642648        std::list<Expression*> exprs;
    643649
    644         UntypedTupleExpr( const std::list< Expression * > & exprs );
     650        UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr );
    645651        UntypedTupleExpr( const UntypedTupleExpr & other );
    646652        virtual ~UntypedTupleExpr();
     
    651657        virtual void accept( Visitor & v ) { v.visit( this ); }
    652658        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    653         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     659        virtual void print( std::ostream & os, int indent = 0 ) const;
    654660};
    655661
     
    659665        std::list<Expression*> exprs;
    660666
    661         TupleExpr( const std::list< Expression * > & exprs );
     667        TupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr );
    662668        TupleExpr( const TupleExpr & other );
    663669        virtual ~TupleExpr();
     
    668674        virtual void accept( Visitor & v ) { v.visit( this ); }
    669675        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    670         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     676        virtual void print( std::ostream & os, int indent = 0 ) const;
    671677};
    672678
     
    689695        virtual void accept( Visitor & v ) { v.visit( this ); }
    690696        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    691         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     697        virtual void print( std::ostream & os, int indent = 0 ) const;
    692698};
    693699
     
    697703        StmtExpr * stmtExpr = nullptr;
    698704
    699         TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls );
     705        TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr );
    700706        TupleAssignExpr( const TupleAssignExpr & other );
    701707        virtual ~TupleAssignExpr();
     
    707713        virtual void accept( Visitor & v ) { v.visit( this ); }
    708714        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    709         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     715        virtual void print( std::ostream & os, int indent = 0 ) const;
    710716};
    711717
     
    730736        virtual void accept( Visitor & v ) { v.visit( this ); }
    731737        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    732         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     738        virtual void print( std::ostream & os, int indent = 0 ) const;
    733739};
    734740
     
    757763        virtual void accept( Visitor & v ) { v.visit( this ); }
    758764        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    759         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     765        virtual void print( std::ostream & os, int indent = 0 ) const;
    760766
    761767private:
     
    791797        virtual void accept( Visitor & v ) { v.visit( this ); }
    792798        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    793         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     799        virtual void print( std::ostream & os, int indent = 0 ) const;
    794800};
    795801
     
    812818        virtual void accept( Visitor & v ) { v.visit( this ); }
    813819        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    814         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     820        virtual void print( std::ostream & os, int indent = 0 ) const;
    815821};
    816822
  • src/SynTree/FunctionDecl.cc

    r6840e7c rb96ec83  
    6363}
    6464
    65 void FunctionDecl::print( std::ostream &os, Indenter indent ) const {
     65void FunctionDecl::print( std::ostream &os, int indent ) const {
    6666        using std::endl;
    6767        using std::string;
    6868
    69         if ( name != "" ) {
    70                 os << name << ": ";
     69        if ( get_name() != "" ) {
     70                os << get_name() << ": ";
    7171        } // if
    72         if ( linkage != LinkageSpec::Cforall ) {
    73                 os << LinkageSpec::linkageName( linkage ) << " ";
     72        if ( get_linkage() != LinkageSpec::Cforall ) {
     73                os << LinkageSpec::linkageName( get_linkage() ) << " ";
    7474        } // if
    7575
    76         printAll( attributes, os, indent );
     76        printAll( get_attributes(), os, indent );
    7777
    7878        get_storageClasses().print( os );
    7979        get_funcSpec().print( os );
    8080
    81         if ( type ) {
    82                 type->print( os, indent );
     81        if ( get_type() ) {
     82                get_type()->print( os, indent );
    8383        } else {
    8484                os << "untyped entity ";
     
    8686
    8787        if ( statements ) {
    88                 os << indent << "... with body " << endl << indent+1;
    89                 statements->print( os, indent+1 );
     88                os << string( indent + 2, ' ' ) << "with body " << endl;
     89                os << string( indent + 4, ' ' );
     90                statements->print( os, indent + 4 );
    9091        } // if
    9192}
    9293
    93 void FunctionDecl::printShort( std::ostream &os, Indenter indent ) const {
     94void FunctionDecl::printShort( std::ostream &os, int indent ) const {
    9495        using std::endl;
    9596        using std::string;
    9697
    97         if ( name != "" ) {
    98                 os << name << ": ";
     98        if ( get_name() != "" ) {
     99                os << get_name() << ": ";
    99100        } // if
     101
     102        // xxx - should printShort print attributes?
    100103
    101104        get_storageClasses().print( os );
    102105        get_funcSpec().print( os );
    103106
    104         if ( type ) {
    105                 type->print( os, indent );
     107        if ( get_type() ) {
     108                get_type()->print( os, indent );
    106109        } else {
    107110                os << "untyped entity ";
  • src/SynTree/FunctionType.cc

    r6840e7c rb96ec83  
    5151}
    5252
    53 void FunctionType::print( std::ostream &os, Indenter indent ) const {
     53void FunctionType::print( std::ostream &os, int indent ) const {
    5454        using std::string;
    5555        using std::endl;
     
    5858        os << "function" << endl;
    5959        if ( ! parameters.empty() ) {
    60                 os << indent << "... with parameters" << endl;
    61                 printAll( parameters, os, indent+1 );
     60                os << string( indent + 2, ' ' ) << "with parameters" << endl;
     61                printAll( parameters, os, indent + 4 );
    6262                if ( isVarArgs ) {
    63                         os << indent+1 << "and a variable number of other arguments" << endl;
     63                        os << string( indent + 4, ' ' ) << "and a variable number of other arguments" << endl;
    6464                } // if
    6565        } else if ( isVarArgs ) {
    66                 os << indent+1 << "accepting unspecified arguments" << endl;
     66                os << string( indent + 4, ' ' ) << "accepting unspecified arguments" << endl;
    6767        } // if
    68         os << indent << "... returning ";
     68        os << string( indent + 2, ' ' ) << "returning ";
    6969        if ( returnVals.empty() ) {
    70                 os << "nothing " << endl;
     70                os << endl << string( indent + 4, ' ' ) << "nothing " << endl;
    7171        } else {
    7272                os << endl;
    73                 printAll( returnVals, os, indent+1 );
     73                printAll( returnVals, os, indent + 4 );
    7474        } // if
    7575}
  • src/SynTree/Initializer.cc

    r6840e7c rb96ec83  
    3838}
    3939
    40 void Designation::print( std::ostream &os, Indenter indent ) const {
     40void Designation::print( std::ostream &os, int indent ) const {
    4141        if ( ! designators.empty() ) {
    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;
     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 );
    4746                }
     47                os << std::endl;
    4848        } // if
    4949}
     
    6464}
    6565
    66 void SingleInit::print( std::ostream &os, Indenter indent ) const {
    67         os << "Simple Initializer: ";
    68         value->print( os, indent );
     66void 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 );
    6970}
    7071
     
    9293}
    9394
    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 );
     95void 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 );
    101103                os << std::endl;
    102                 if ( ! d->designators.empty() ) {
    103                         os << indent+1;
    104                         d->print( os, indent+1 );
    105                 }
    106104        }
    107105}
     
    118116}
    119117
    120 void ConstructorInit::print( std::ostream &os, Indenter indent ) const {
    121         os << "Constructor initializer: " << std::endl;
     118void ConstructorInit::print( std::ostream &os, int indent ) const {
     119        os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl;
    122120        if ( ctor ) {
    123                 os << indent << "... initially constructed with ";
    124                 ctor->print( os, indent+1 );
     121                os << std::string(indent+2, ' ');
     122                os << "initially constructed with ";
     123                ctor->print( os, indent+4 );
    125124        } // if
    126125
    127126        if ( dtor ) {
    128                 os << indent << "... destructed with ";
    129                 dtor->print( os, indent+1 );
     127                os << std::string(indent+2, ' ');
     128                os << "destructed with ";
     129                dtor->print( os, indent+4 );
    130130        }
    131131
    132132        if ( init ) {
    133                 os << indent << "... with fallback C-style initializer: ";
    134                 init->print( os, indent+1 );
     133                os << std::string(indent+2, ' ');
     134                os << "with fallback C-style initializer: ";
     135                init->print( os, indent+4 );
    135136        }
    136137}
  • src/SynTree/Initializer.h

    r6840e7c rb96ec83  
    3737        std::list< Expression * > & get_designators() { return designators; }
    3838
    39         virtual Designation * clone() const override { return new Designation( *this ); };
     39        virtual Designation * clone() const { return new Designation( *this ); };
    4040        virtual void accept( Visitor &v ) override { v.visit( this ); }
    41         virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); }
    42         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     41        virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
     42        virtual void print( std::ostream &os, int indent = 0 ) const override;
    4343};
    4444
     
    5454        bool get_maybeConstructed() { return maybeConstructed; }
    5555
    56         virtual Initializer *clone() const override = 0;
     56        virtual Initializer *clone() const = 0;
    5757        virtual void accept( Visitor &v ) override = 0;
    58         virtual Initializer *acceptMutator( Mutator &m ) override = 0;
    59         virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
     58        virtual Initializer *acceptMutator( Mutator &m ) = 0;
     59        virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
    6060  private:
    6161        bool maybeConstructed;
     
    7878        virtual void accept( Visitor &v ) override { v.visit( this ); }
    7979        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    80         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     80        virtual void print( std::ostream &os, int indent = 0 ) const override;
    8181};
    8282
     
    106106        virtual void accept( Visitor &v ) override { v.visit( this ); }
    107107        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    108         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     108        virtual void print( std::ostream &os, int indent = 0 ) const override;
    109109};
    110110
     
    135135        virtual void accept( Visitor &v ) override { v.visit( this ); }
    136136        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    137         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     137        virtual void print( std::ostream &os, int indent = 0 ) const override;
    138138
    139139  private:
  • src/SynTree/Mutator.cc

    r6840e7c rb96ec83  
    626626}
    627627
    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 
    638628// Local Variables: //
    639629// tab-width: 4 //
  • src/SynTree/Mutator.h

    r6840e7c rb96ec83  
    117117
    118118        virtual Attribute * mutate( Attribute * attribute );
    119 
    120         virtual TypeSubstitution * mutate( TypeSubstitution * sub );
    121 
    122119  private:
    123120        virtual Declaration * handleAggregateDecl(AggregateDecl * aggregateDecl );
  • src/SynTree/NamedTypeDecl.cc

    r6840e7c rb96ec83  
    3838}
    3939
    40 void NamedTypeDecl::print( std::ostream &os, Indenter indent ) const {
     40void NamedTypeDecl::print( std::ostream &os, int indent ) const {
    4141        using namespace std;
    4242
    43         if ( name != "" ) os << name << ": ";
    44 
    45         if ( linkage != LinkageSpec::Cforall ) {
    46                 os << LinkageSpec::linkageName( linkage ) << " ";
     43        if ( get_name() != "" ) {
     44                os << get_name() << ": ";
     45        } // if
     46        if ( get_linkage() != LinkageSpec::Cforall ) {
     47                os << LinkageSpec::linkageName( get_linkage() ) << " ";
    4748        } // if
    4849        get_storageClasses().print( os );
     
    5051        if ( base ) {
    5152                os << " for ";
    52                 base->print( os, indent+1 );
     53                base->print( os, indent );
    5354        } // if
    5455        if ( ! parameters.empty() ) {
    55                 os << endl << indent << "... with parameters" << endl;
    56                 printAll( parameters, os, indent+1 );
     56                os << endl << string( indent, ' ' ) << "with parameters" << endl;
     57                printAll( parameters, os, indent+2 );
    5758        } // if
    5859        if ( ! assertions.empty() ) {
    59                 os << endl << indent << "... with assertions" << endl;
    60                 printAll( assertions, os, indent+1 );
     60                os << endl << string( indent, ' ' ) << "with assertions" << endl;
     61                printAll( assertions, os, indent+2 );
    6162        } // if
    6263}
    6364
    64 void NamedTypeDecl::printShort( std::ostream &os, Indenter indent ) const {
     65void NamedTypeDecl::printShort( std::ostream &os, int indent ) const {
    6566        using namespace std;
    6667
    67         if ( name != "" ) os << name << ": ";
     68        if ( get_name() != "" ) {
     69                os << get_name() << ": ";
     70        } // if
    6871        get_storageClasses().print( os );
    6972        os << typeString();
    7073        if ( base ) {
    7174                os << " for ";
    72                 base->print( os, indent+1 );
     75                base->print( os, indent );
    7376        } // if
    7477        if ( ! parameters.empty() ) {
    75                 os << endl << indent << "... with parameters" << endl;
    76                 printAll( parameters, os, indent+1 );
     78                os << endl << string( indent, ' ' ) << "with parameters" << endl;
     79                printAll( parameters, os, indent+2 );
    7780        } // if
    7881}
  • src/SynTree/ObjectDecl.cc

    r6840e7c rb96ec83  
    4444}
    4545
    46 void ObjectDecl::print( std::ostream &os, Indenter indent ) const {
    47         if ( name != "" ) os << name << ": ";
     46void ObjectDecl::print( std::ostream &os, int indent ) const {
     47        if ( get_name() != "" ) {
     48                os << get_name() << ": ";
     49        } // if
    4850
    49         if ( linkage != LinkageSpec::Cforall ) {
    50                 os << LinkageSpec::linkageName( linkage ) << " ";
     51        if ( get_linkage() != LinkageSpec::Cforall ) {
     52                os << LinkageSpec::linkageName( get_linkage() ) << " ";
    5153        } // if
     54
     55        printAll( get_attributes(), os, indent );
    5256
    5357        get_storageClasses().print( os );
    5458
    55         if ( type ) {
    56                 type->print( os, indent );
     59        if ( get_type() ) {
     60                get_type()->print( os, indent );
    5761        } else {
    5862                os << " untyped entity ";
     
    6064
    6165        if ( init ) {
    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;
     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();
    6570        } // if
    6671
    67         if ( ! attributes.empty() ) {
    68                 os << std::endl << indent << "... with attributes: " << std::endl;
    69                 printAll( attributes, os, indent+1 );
    70         }
    71 
    7272        if ( bitfieldWidth ) {
    73                 os << indent << " with bitfield width ";
     73                os << std::string(indent, ' ');
     74                os << " with bitfield width ";
    7475                bitfieldWidth->print( os );
    7576        } // if
    7677}
    7778
    78 void ObjectDecl::printShort( std::ostream &os, Indenter indent ) const {
     79void ObjectDecl::printShort( std::ostream &os, int indent ) const {
    7980#if 0
    8081        if ( get_mangleName() != "") {
     
    8283        } else
    8384#endif
    84         if ( name != "" ) os << name << ": ";
     85        if ( get_name() != "" ) {
     86                os << get_name() << ": ";
     87        } // if
     88
     89        // xxx - should printShort print attributes?
    8590
    8691        get_storageClasses().print( os );
    8792
    88         if ( type ) {
    89                 type->print( os, indent );
     93        if ( get_type() ) {
     94                get_type()->print( os, indent );
    9095        } else {
    9196                os << "untyped entity ";
  • src/SynTree/PointerType.cc

    r6840e7c rb96ec83  
    4141}
    4242
    43 void PointerType::print( std::ostream &os, Indenter indent ) const {
     43void PointerType::print( std::ostream &os, int indent ) const {
    4444        Type::print( os, indent );
    4545        if ( ! is_array() ) {
  • src/SynTree/ReferenceToType.cc

    r6840e7c rb96ec83  
    1414//
    1515
     16#include <stddef.h>          // for NULL
    1617#include <cassert>           // for assert
    1718#include <list>              // for list, _List_const_iterator, list<>::cons...
     
    3738}
    3839
    39 void ReferenceToType::print( std::ostream &os, Indenter indent ) const {
     40void ReferenceToType::print( std::ostream &os, int indent ) const {
    4041        using std::endl;
    4142
     
    4344        os << "instance of " << typeString() << " " << name << " ";
    4445        if ( ! parameters.empty() ) {
    45                 os << endl << indent << "... with parameters" << endl;
    46                 printAll( parameters, os, indent+1 );
     46                os << endl << std::string( indent, ' ' ) << "with parameters" << endl;
     47                printAll( parameters, os, indent+2 );
    4748        } // if
    4849}
     
    6465
    6566std::list<TypeDecl*>* StructInstType::get_baseParameters() {
    66         if ( ! baseStruct ) return nullptr;
     67        if ( ! baseStruct ) return NULL;
    6768        return &baseStruct->get_parameters();
    6869}
     
    7576}
    7677
    77 void StructInstType::print( std::ostream &os, Indenter indent ) const {
     78void StructInstType::print( std::ostream &os, int indent ) const {
    7879        using std::endl;
    7980
    80         if ( baseStruct == nullptr ) ReferenceToType::print( os, indent );
     81        if ( baseStruct == NULL ) ReferenceToType::print( os, indent );
    8182        else {
    8283                Type::print( os, indent );
    8384                os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body() << " ";
    8485                if ( ! parameters.empty() ) {
    85                         os << endl << indent << "... with parameters" << endl;
    86                         printAll( parameters, os, indent+1 );
     86                        os << endl << std::string( indent, ' ' ) << "with parameters" << endl;
     87                        printAll( parameters, os, indent+2 );
    8788                } // if
    8889        } // if
     
    9697
    9798std::list< TypeDecl * > * UnionInstType::get_baseParameters() {
    98         if ( ! baseUnion ) return nullptr;
     99        if ( ! baseUnion ) return NULL;
    99100        return &baseUnion->get_parameters();
    100101}
     
    107108}
    108109
    109 void UnionInstType::print( std::ostream &os, Indenter indent ) const {
     110void UnionInstType::print( std::ostream &os, int indent ) const {
    110111        using std::endl;
    111112
    112         if ( baseUnion == nullptr ) ReferenceToType::print( os, indent );
     113        if ( baseUnion == NULL ) ReferenceToType::print( os, indent );
    113114        else {
    114115                Type::print( os, indent );
    115116                os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body() << " ";
    116117                if ( ! parameters.empty() ) {
    117                         os << endl << indent << "... with parameters" << endl;
    118                         printAll( parameters, os, indent+1 );
     118                        os << endl << std::string( indent, ' ' ) << "with parameters" << endl;
     119                        printAll( parameters, os, indent+2 );
    119120                } // if
    120121        } // if
     
    128129
    129130bool 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 
    141131
    142132std::string TraitInstType::typeString() const { return "trait"; }
     
    176166bool TypeInstType::isComplete() const { return baseType->isComplete(); }
    177167
    178 void TypeInstType::print( std::ostream &os, Indenter indent ) const {
     168void TypeInstType::print( std::ostream &os, int indent ) const {
    179169        using std::endl;
    180170
     
    182172        os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type) ";
    183173        if ( ! parameters.empty() ) {
    184                 os << endl << indent << "... with parameters" << endl;
    185                 printAll( parameters, os, indent+1 );
     174                os << endl << std::string( indent, ' ' ) << "with parameters" << endl;
     175                printAll( parameters, os, indent+2 );
    186176        } // if
    187177}
  • src/SynTree/ReferenceType.cc

    r6840e7c rb96ec83  
    3535}
    3636
    37 void ReferenceType::print( std::ostream &os, Indenter indent ) const {
     37void ReferenceType::print( std::ostream &os, int indent ) const {
    3838        Type::print( os, indent );
    3939        os << "reference to ";
  • src/SynTree/Statement.cc

    r6840e7c rb96ec83  
    3434Statement::Statement( std::list<Label> labels ) : labels( labels ) {}
    3535
    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 }
     36void Statement::print( __attribute__((unused)) std::ostream &, __attribute__((unused)) int indent ) const {}
    4537
    4638Statement::~Statement() {}
     
    5446}
    5547
    56 void ExprStmt::print( std::ostream &os, Indenter indent ) const {
    57         os << "Expression Statement:" << endl << indent+1;
    58         expr->print( os, indent+1 );
     48void ExprStmt::print( std::ostream &os, int indent ) const {
     49        os << "Expression Statement:" << endl << std::string( indent + 2, ' ' );
     50        expr->print( os, indent + 2 );
    5951}
    6052
     
    7567}
    7668
    77 void AsmStmt::print( std::ostream &os, Indenter indent ) const {
     69void AsmStmt::print( std::ostream &os, int indent ) const {
    7870        os << "Assembler Statement:" << endl;
    79         os << indent+1 << "instruction: " << endl << indent;
    80         instruction->print( os, indent+1 );
     71        os << std::string( indent, ' ' ) << "instruction: " << endl << std::string( indent, ' ' );
     72        instruction->print( os, indent + 2 );
    8173        if ( ! output.empty() ) {
    82                 os << endl << indent+1 << "output: " << endl;
    83                 printAll( output, os, indent+1 );
     74                os << endl << std::string( indent, ' ' ) << "output: " << endl;
     75                printAll( output, os, indent + 2 );
    8476        } // if
    8577        if ( ! input.empty() ) {
    86                 os << indent+1 << "input: " << endl;
    87                 printAll( input, os, indent+1 );
     78                os << std::string( indent, ' ' ) << "input: " << endl << std::string( indent, ' ' );
     79                printAll( input, os, indent + 2 );
    8880        } // if
    8981        if ( ! clobber.empty() ) {
    90                 os << indent+1 << "clobber: " << endl;
    91                 printAll( clobber, os, indent+1 );
     82                os << std::string( indent, ' ' ) << "clobber: " << endl;
     83                printAll( clobber, os, indent + 2 );
    9284        } // if
    9385}
     
    111103}
    112104
    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;
     105void BranchStmt::print( std::ostream &os, int indent ) 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;
    118110}
    119111
     
    126118}
    127119
    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 );
     120void ReturnStmt::print( std::ostream &os, int indent ) const {
     121        os <<  "Return Statement, returning: ";
     122        if ( expr != 0 ) {
     123                os << endl << string( indent+2, ' ' );
     124                expr->print( os, indent + 2 );
    133125        }
    134126        os << endl;
     
    150142}
    151143
    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 );
     144void IfStmt::print( std::ostream &os, int indent ) const {
     145        os << "If on condition: " << endl ;
     146        os << string( indent+4, ' ' );
     147        condition->print( os, indent + 4 );
    156148
    157149        if ( !initialization.empty() ) {
    158                 os << indent << "... with initialization: \n";
    159                 for ( const Statement * stmt : initialization ) {
    160                         os << indent+1;
    161                         stmt->print( os, indent+1 );
     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 );
    162154                }
    163155                os << endl;
    164156        }
    165157
    166         os << indent << "... then: " << endl;
    167 
    168         os << indent+1;
    169         thenPart->print( os, indent+1 );
     158        os << string( indent+2, ' ' ) << "... then: " << endl;
     159
     160        os << string( indent+4, ' ' );
     161        thenPart->print( os, indent + 4 );
    170162
    171163        if ( elsePart != 0 ) {
    172                 os << indent << "... else: " << endl;
    173                 os << indent+1;
    174                 elsePart->print( os, indent+1 );
     164                os << string( indent+2, ' ' ) << "... else: " << endl;
     165                os << string( indent+4, ' ' );
     166                elsePart->print( os, indent + 4 );
    175167        } // if
    176168}
     
    191183}
    192184
    193 void SwitchStmt::print( std::ostream &os, Indenter indent ) const {
     185void SwitchStmt::print( std::ostream &os, int indent ) const {
    194186        os << "Switch on condition: ";
    195187        condition->print( os );
    196188        os << endl;
    197189
    198         for ( const Statement * stmt : statements ) {
    199                 stmt->print( os, indent+1 );
    200         }
     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 ));
    201196}
    202197
    203198CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
    204199        Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) {
    205         if ( isDefault() && condition != 0 ) throw SemanticError("default case with condition: ", condition);
     200        if ( isDefault() && condition != 0 )
     201                throw SemanticError("default with conditions");
    206202}
    207203
     
    220216}
    221217
    222 void CaseStmt::print( std::ostream &os, Indenter indent ) const {
    223         if ( isDefault() ) os << "Default ";
     218void CaseStmt::print( std::ostream &os, int indent ) const {
     219        os << string( indent, ' ' );
     220
     221        if ( isDefault() )
     222                os << "Default ";
    224223        else {
    225224                os << "Case ";
    226                 condition->print( os, indent );
     225                condition->print( os );
    227226        } // if
     227
    228228        os << endl;
    229229
    230         for ( Statement * stmt : stmts ) {
    231                 stmt->print( os, indent+1 );
    232         }
     230        std::list<Statement *>::const_iterator i;
     231        for ( i = stmts.begin(); i != stmts.end(); i++)
     232                (*i )->print( os, indent + 4 );
    233233}
    234234
     
    246246}
    247247
    248 void WhileStmt::print( std::ostream &os, Indenter indent ) const {
     248void WhileStmt::print( std::ostream &os, int indent ) const {
    249249        os << "While on condition: " << endl ;
    250         condition->print( os, indent+1 );
    251 
    252         os << indent << "... with body: " << endl;
    253 
    254         if ( body != 0 ) body->print( os, indent+1 );
     250        condition->print( os, indent + 4 );
     251
     252        os << string( indent, ' ' ) << ".... with body: " << endl;
     253
     254        if ( body != 0 ) body->print( os, indent + 4 );
    255255}
    256256
     
    272272}
    273273
    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 
     274void 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";
    297302        if ( body != 0 ) {
    298                 os << "\n" << indent << "... with body: \n" << indent+1;
    299                 body->print( os, indent+1 );
    300         }
     303                os << string( indent + 4, ' ' );
     304                body->print( os, indent + 4 );
     305        }
     306
    301307        os << endl;
    302308}
     
    316322}
    317323
    318 void ThrowStmt::print( std::ostream &os, Indenter indent) const {
    319         if ( target ) os << "Non-Local ";
     324void ThrowStmt::print( std::ostream &os, int indent) const {
     325        if ( target ) {
     326                os << "Non-Local ";
     327        }
    320328        os << "Throw Statement, raising: ";
    321         expr->print(os, indent+1);
     329        expr->print(os, indent + 4);
    322330        if ( target ) {
    323                 os << "... at: ";
    324                 target->print(os, indent+1);
     331                os << "At: ";
     332                target->print(os, indent + 4);
    325333        }
    326334}
     
    340348}
    341349
    342 void TryStmt::print( std::ostream &os, Indenter indent ) const {
     350void TryStmt::print( std::ostream &os, int indent ) const {
    343351        os << "Try Statement" << endl;
    344         os << indent << "... with block:" << endl << indent+1;
    345         block->print( os, indent+1 );
     352        os << string( indent + 2, ' ' ) << "with block:" << endl;
     353        os << string( indent + 4, ' ' );
     354        block->print( os, indent + 4 );
    346355
    347356        // handlers
    348         os << indent << "... and handlers:" << endl;
    349         for ( const CatchStmt * stmt : handlers ) {
    350                 os << indent+1;
    351                 stmt->print( os, indent+1 );
     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 );
    352361        }
    353362
    354363        // finally block
    355364        if ( finallyBlock != 0 ) {
    356                 os << indent << "... and finally:" << endl << indent+1;
    357                 finallyBlock->print( os, indent+1 );
     365                os << string( indent + 2, ' ' ) << "and finally:" << endl;
     366                finallyBlock->print( os, indent + 4 );
    358367        } // if
    359368}
     
    361370CatchStmt::CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl, Expression *cond, Statement *body ) :
    362371        Statement( labels ), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) {
    363                 assertf( decl, "Catch clause must have a declaration." );
    364372}
    365373
     
    373381}
    374382
    375 void CatchStmt::print( std::ostream &os, Indenter indent ) const {
     383void CatchStmt::print( std::ostream &os, int indent ) const {
    376384        os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl;
    377385
    378         os << indent << "... catching: ";
    379         decl->printShort( os, indent+1 );
    380         os << endl;
     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;
    381393
    382394        if ( cond ) {
    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 );
     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 );
    390405}
    391406
     
    402417}
    403418
    404 void FinallyStmt::print( std::ostream &os, Indenter indent ) const {
     419void FinallyStmt::print( std::ostream &os, int indent ) const {
    405420        os << "Finally Statement" << endl;
    406         os << indent << "... with block:" << endl << indent+1;
    407         block->print( os, indent+1 );
     421        os << string( indent + 2, ' ' ) << "with block:" << endl;
     422        os << string( indent + 4, ' ' );
     423        block->print( os, indent + 4 );
    408424}
    409425
     
    449465}
    450466
    451 void WaitForStmt::print( std::ostream &os, Indenter indent ) const {
     467void WaitForStmt::print( std::ostream &os, int indent ) const {
    452468        os << "Waitfor Statement" << endl;
    453         os << indent << "... with block:" << endl << indent+1;
     469        os << string( indent + 2, ' ' ) << "with block:" << endl;
     470        os << string( indent + 4, ' ' );
    454471        // block->print( os, indent + 4 );
    455472}
     
    458475NullStmt::NullStmt() : Statement( std::list<Label>() ) {}
    459476
    460 void NullStmt::print( std::ostream &os, Indenter ) const {
    461         os << "Null Statement" << endl;
     477void NullStmt::print( std::ostream &os, __attribute__((unused)) int indent ) const {
     478        os << "Null Statement" << endl ;
    462479}
    463480
     
    473490}
    474491
    475 void ImplicitCtorDtorStmt::print( std::ostream &os, Indenter indent ) const {
     492void ImplicitCtorDtorStmt::print( std::ostream &os, int indent ) const {
    476493        os << "Implicit Ctor Dtor Statement" << endl;
    477         os << indent << "... with Ctor/Dtor: ";
    478         callStmt->print( os, indent+1);
     494        os << string( indent + 2, ' ' ) << "with Ctor/Dtor: ";
     495        callStmt->print( os, indent + 2);
    479496        os << endl;
    480497}
  • src/SynTree/Statement.h

    r6840e7c rb96ec83  
    4343        const std::list<Label> & get_labels() const { return labels; }
    4444
    45         virtual Statement *clone() const override = 0;
     45        virtual Statement *clone() const = 0;
    4646        virtual void accept( Visitor &v ) override = 0;
    47         virtual Statement *acceptMutator( Mutator &m ) override = 0;
    48         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     47        virtual Statement *acceptMutator( Mutator &m ) = 0;
     48        virtual void print( std::ostream &os, int indent = 0 ) const override;
    4949};
    5050
     
    6565        virtual void accept( Visitor &v ) override { v.visit( this ); }
    6666        virtual CompoundStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    67         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     67        virtual void print( std::ostream &os, int indent = 0 ) const override;
    6868};
    6969
     
    7676        virtual void accept( Visitor &v ) override { v.visit( this ); }
    7777        virtual NullStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    78         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     78        virtual void print( std::ostream &os, int indent = 0 ) const override;
    7979};
    8080
     
    9393        virtual void accept( Visitor &v ) override { v.visit( this ); }
    9494        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    95         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     95        virtual void print( std::ostream &os, int indent = 0 ) const override;
    9696};
    9797
     
    124124        virtual void accept( Visitor & v ) { v.visit( this ); }
    125125        virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    126         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     126        virtual void print( std::ostream & os, int indent = 0 ) const;
    127127};
    128128
     
    150150        virtual void accept( Visitor &v ) override { v.visit( this ); }
    151151        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    152         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     152        virtual void print( std::ostream &os, int indent = 0 ) const override;
    153153};
    154154
     
    171171
    172172        virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); }
    173         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     173        virtual void print( std::ostream &os, int indent = 0 ) const override;
    174174
    175175};
     
    199199
    200200        virtual CaseStmt *clone() const override { return new CaseStmt( *this ); }
    201         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     201        virtual void print( std::ostream &os, int indent = 0 ) const override;
    202202  private:
    203203        bool _isDefault;
     
    225225        virtual void accept( Visitor &v ) override { v.visit( this ); }
    226226        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    227         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     227        virtual void print( std::ostream &os, int indent = 0 ) const override;
    228228};
    229229
     
    251251        virtual void accept( Visitor &v ) override { v.visit( this ); }
    252252        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    253         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     253        virtual void print( std::ostream &os, int indent = 0 ) const override;
    254254};
    255255
     
    280280        virtual void accept( Visitor &v ) override { v.visit( this ); }
    281281        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    282         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     282        virtual void print( std::ostream &os, int indent = 0 ) const override;
    283283  private:
    284284        static const char *brType[];
     
    299299        virtual void accept( Visitor &v ) override { v.visit( this ); }
    300300        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    301         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     301        virtual void print( std::ostream &os, int indent = 0 ) const override;
    302302};
    303303
     
    323323        virtual void accept( Visitor &v ) override { v.visit( this ); }
    324324        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    325         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     325        virtual void print( std::ostream &os, int indent = 0 ) const override;
    326326};
    327327
     
    346346        virtual void accept( Visitor &v ) override { v.visit( this ); }
    347347        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    348         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     348        virtual void print( std::ostream &os, int indent = 0 ) const override;
    349349};
    350350
     
    374374        virtual void accept( Visitor &v ) override { v.visit( this ); }
    375375        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    376         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     376        virtual void print( std::ostream &os, int indent = 0 ) const override;
    377377};
    378378
     
    391391        virtual void accept( Visitor &v ) override { v.visit( this ); }
    392392        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    393         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     393        virtual void print( std::ostream &os, int indent = 0 ) const override;
    394394};
    395395
     
    428428        virtual void accept( Visitor &v ) override { v.visit( this ); }
    429429        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    430         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     430        virtual void print( std::ostream &os, int indent = 0 ) const override;
    431431
    432432};
     
    448448        virtual void accept( Visitor &v ) override { v.visit( this ); }
    449449        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    450         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     450        virtual void print( std::ostream &os, int indent = 0 ) const override;
    451451};
    452452
     
    470470        virtual void accept( Visitor &v ) override { v.visit( this ); }
    471471        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    472         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     472        virtual void print( std::ostream &os, int indent = 0 ) const override;
    473473};
    474474
  • src/SynTree/TupleExpr.cc

    r6840e7c rb96ec83  
    2828#include "Type.h"               // for TupleType, Type
    2929
    30 UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs ) : Expression(), exprs( exprs ) {
     30UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
    3131}
    3232
     
    3939}
    4040
    41 void UntypedTupleExpr::print( std::ostream &os, Indenter indent ) const {
     41void UntypedTupleExpr::print( std::ostream &os, int indent ) const {
    4242        os << "Untyped Tuple:" << std::endl;
    43         printAll( exprs, os, indent+1 );
     43        printAll( exprs, os, indent+2 );
    4444        Expression::print( os, indent );
    4545}
    4646
    47 TupleExpr::TupleExpr( const std::list< Expression * > & exprs ) : Expression(), exprs( exprs ) {
     47TupleExpr::TupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
    4848        set_result( Tuples::makeTupleType( exprs ) );
    4949}
     
    5757}
    5858
    59 void TupleExpr::print( std::ostream &os, Indenter indent ) const {
     59void TupleExpr::print( std::ostream &os, int indent ) const {
    6060        os << "Tuple:" << std::endl;
    61         printAll( exprs, os, indent+1 );
     61        printAll( exprs, os, indent+2 );
    6262        Expression::print( os, indent );
    6363}
     
    7878}
    7979
    80 void TupleIndexExpr::print( std::ostream &os, Indenter indent ) const {
     80void TupleIndexExpr::print( std::ostream &os, int indent ) const {
    8181        os << "Tuple Index Expression, with tuple:" << std::endl;
    82         os << indent+1;
    83         tuple->print( os, indent+1 );
    84         os << indent+1 << "with index: " << index << 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;
    8585        Expression::print( os, indent );
    8686}
    8787
    88 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls ) : Expression() {
     88TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ) {
    8989        // convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments
    9090        set_result( Tuples::makeTupleType( assigns ) );
     
    109109}
    110110
    111 void TupleAssignExpr::print( std::ostream &os, Indenter indent ) const {
     111void TupleAssignExpr::print( std::ostream &os, int indent ) const {
    112112        os << "Tuple Assignment Expression, with stmt expr:" << std::endl;
    113         os << indent+1;
    114         stmtExpr->print( os, indent+1 );
     113        os << std::string( indent+2, ' ' );
     114        stmtExpr->print( os, indent+4 );
    115115        Expression::print( os, indent );
    116116}
  • src/SynTree/TupleType.cc

    r6840e7c rb96ec83  
    4848}
    4949
    50 void TupleType::print( std::ostream &os, Indenter indent ) const {
     50void TupleType::print( std::ostream &os, int indent ) const {
    5151        Type::print( os, indent );
    5252        os << "tuple of types" << std::endl;
    53         printAll( types, os, indent+1 );
     53        printAll( types, os, indent+2 );
    5454}
    5555
  • src/SynTree/Type.cc

    r6840e7c rb96ec83  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:16:32 2017
    13 // Update Count     : 38
     12// Last Modified On : Mon Sep 11 13:21:25 2017
     13// Update Count     : 37
    1414//
    1515#include "Type.h"
     
    4545        "double _Imaginary",
    4646        "long double _Imaginary",
    47         "__int128",
    48         "unsigned __int128",
    4947};
    5048
     
    7573        Type * type;
    7674        ReferenceType * ref;
    77         for ( type = this; (ref = dynamic_cast<ReferenceType *>( type )); type = ref->base );
     75        for ( type = this; (ref = dynamic_cast<ReferenceType *>( type )); type = ref->get_base() );
    7876        return type;
    7977}
     
    8179int Type::referenceDepth() const { return 0; }
    8280
    83 void Type::print( std::ostream &os, Indenter indent ) const {
     81void Type::print( std::ostream &os, int indent ) const {
    8482        if ( ! forall.empty() ) {
    8583                os << "forall" << std::endl;
    86                 printAll( forall, os, indent+1 );
    87                 os << ++indent;
     84                printAll( forall, os, indent + 4 );
     85                os << std::string( indent+2, ' ' );
    8886        } // if
    8987
    9088        if ( ! attributes.empty() ) {
    91                 os << "with attributes" << endl;
    92                 printAll( attributes, os, indent+1 );
     89                os << endl << string( indent+2, ' ' ) << "with attributes" << endl;
     90                printAll( attributes, os, indent+4 );
    9391        } // if
    9492
  • src/SynTree/Type.h

    r6840e7c rb96ec83  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 14:14:01 2017
    13 // Update Count     : 154
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug  9 14:25:00 2017
     13// Update Count     : 152
    1414//
    1515
     
    181181        virtual void accept( Visitor & v ) = 0;
    182182        virtual Type *acceptMutator( Mutator & m ) = 0;
    183         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     183        virtual void print( std::ostream & os, int indent = 0 ) const;
    184184};
    185185
     
    198198        virtual void accept( Visitor & v ) override { v.visit( this ); }
    199199        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    200         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     200        virtual void print( std::ostream & os, int indent = 0 ) const override;
    201201};
    202202
     
    225225                DoubleImaginary,
    226226                LongDoubleImaginary,
    227                 SignedInt128,
    228                 UnsignedInt128,
    229227                NUMBER_OF_BASIC_TYPES
    230228        } kind;
     
    240238        virtual void accept( Visitor & v ) override { v.visit( this ); }
    241239        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    242         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     240        virtual void print( std::ostream & os, int indent = 0 ) const override;
    243241
    244242        bool isInteger() const;
     
    275273        virtual void accept( Visitor & v ) override { v.visit( this ); }
    276274        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    277         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     275        virtual void print( std::ostream & os, int indent = 0 ) const override;
    278276};
    279277
     
    303301        virtual void accept( Visitor & v ) override { v.visit( this ); }
    304302        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    305         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     303        virtual void print( std::ostream & os, int indent = 0 ) const override;
    306304};
    307305
     
    327325        virtual void accept( Visitor & v ) override { v.visit( this ); }
    328326        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    329         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     327        virtual void print( std::ostream & os, int indent = 0 ) const override;
    330328};
    331329
     
    354352        virtual void accept( Visitor & v ) override { v.visit( this ); }
    355353        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    356         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     354        virtual void print( std::ostream & os, int indent = 0 ) const override;
    357355};
    358356
     
    376374        virtual void accept( Visitor & v ) override = 0;
    377375        virtual Type *acceptMutator( Mutator & m ) override = 0;
    378         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     376        virtual void print( std::ostream & os, int indent = 0 ) const override;
    379377
    380378        virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {}
     
    410408        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    411409
    412         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     410        virtual void print( std::ostream & os, int indent = 0 ) const override;
    413411  private:
    414412        virtual std::string typeString() const override;
     
    442440        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    443441
    444         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     442        virtual void print( std::ostream & os, int indent = 0 ) const override;
    445443  private:
    446444        virtual std::string typeString() const override;
     
    466464        virtual void accept( Visitor & v ) override { v.visit( this ); }
    467465        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    468 
    469         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    470466  private:
    471467        virtual std::string typeString() const override;
     
    516512        virtual void accept( Visitor & v ) override { v.visit( this ); }
    517513        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    518         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     514        virtual void print( std::ostream & os, int indent = 0 ) const override;
    519515  private:
    520516        virtual std::string typeString() const override;
     
    553549        virtual void accept( Visitor & v ) override { v.visit( this ); }
    554550        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    555         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     551        virtual void print( std::ostream & os, int indent = 0 ) const override;
    556552};
    557553
     
    572568        virtual void accept( Visitor & v ) override { v.visit( this ); }
    573569        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    574         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     570        virtual void print( std::ostream & os, int indent = 0 ) const override;
    575571};
    576572
     
    601597        virtual void accept( Visitor & v ) override { v.visit( this ); }
    602598        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    603         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     599        virtual void print( std::ostream & os, int indent = 0 ) const override;
    604600};
    605601
     
    615611        virtual void accept( Visitor & v ) override { v.visit( this ); }
    616612        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    617         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     613        virtual void print( std::ostream & os, int indent = 0 ) const override;
    618614};
    619615
     
    627623        virtual void accept( Visitor & v ) override { v.visit( this ); }
    628624        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    629         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     625        virtual void print( std::ostream & os, int indent = 0 ) const override;
    630626};
    631627
     
    639635        virtual void accept( Visitor & v ) override { v.visit( this ); }
    640636        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    641         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     637        virtual void print( std::ostream & os, int indent = 0 ) const override;
    642638};
    643639
  • src/SynTree/TypeDecl.cc

    r6840e7c rb96ec83  
    4141}
    4242
    43 void TypeDecl::print( std::ostream &os, Indenter indent ) const {
     43void TypeDecl::print( std::ostream &os, int indent ) const {
    4444  NamedTypeDecl::print( os, indent );
    4545  if ( init ) {
    46     os << std::endl << indent << "with type initializer: ";
    47     init->print( os, indent + 1 );
     46    os << std::endl << std::string( indent, ' ' ) << "with type initializer: ";
     47    init->print( os, indent + 2 );
    4848  }
    4949}
  • src/SynTree/TypeExpr.cc

    r6840e7c rb96ec83  
    3030}
    3131
    32 void TypeExpr::print( std::ostream &os, Indenter indent ) const {
     32void TypeExpr::print( std::ostream &os, int indent ) const {
    3333        if ( type ) type->print( os, indent );
    3434        Expression::print( os, indent );
  • src/SynTree/TypeSubstitution.cc

    r6840e7c rb96ec83  
    148148template< typename TypeClass >
    149149Type *TypeSubstitution::handleType( TypeClass *type ) {
    150         ValueGuard<BoundVarsType> oldBoundVars( boundVars );
     150        BoundVarsType oldBoundVars( boundVars );
    151151        // bind type variables from forall-qualifiers
    152152        if ( freeOnly ) {
     
    156156        } // if
    157157        Type *ret = Mutator::mutate( type );
     158        boundVars = oldBoundVars;
    158159        return ret;
    159160}
     
    161162template< typename TypeClass >
    162163Type *TypeSubstitution::handleAggregateType( TypeClass *type ) {
    163         ValueGuard<BoundVarsType> oldBoundVars( boundVars );
     164        BoundVarsType oldBoundVars( boundVars );
    164165        // bind type variables from forall-qualifiers
    165166        if ( freeOnly ) {
     
    176177        } // if
    177178        Type *ret = Mutator::mutate( type );
     179        boundVars = oldBoundVars;
    178180        return ret;
    179181}
     
    231233}
    232234
    233 void TypeSubstitution::print( std::ostream &os, Indenter indent ) const {
    234         os << indent << "Types:" << std::endl;
     235TypeSubstitution * 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
     245void TypeSubstitution::print( std::ostream &os, int indent ) const {
     246        os << std::string( indent, ' ' ) << "Types:" << std::endl;
    235247        for ( TypeEnvType::const_iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
    236                 os << indent+1 << i->first << " -> ";
    237                 i->second->print( os, indent+2 );
     248                os << std::string( indent+2, ' ' ) << i->first << " -> ";
     249                i->second->print( os, indent+4 );
    238250                os << std::endl;
    239251        } // for
    240         os << indent << "Non-types:" << std::endl;
     252        os << std::string( indent, ' ' ) << "Non-types:" << std::endl;
    241253        for ( VarEnvType::const_iterator i = varEnv.begin(); i != varEnv.end(); ++i ) {
    242                 os << indent+1 << i->first << " -> ";
    243                 i->second->print( os, indent+2 );
     254                os << std::string( indent+2, ' ' ) << i->first << " -> ";
     255                i->second->print( os, indent+4 );
    244256                os << std::endl;
    245257        } // for
  • src/SynTree/TypeSubstitution.h

    r6840e7c rb96ec83  
    5959        void normalize();
    6060
    61         TypeSubstitution * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     61        TypeSubstitution * acceptMutator( Mutator & mutator );
    6262
    63         void print( std::ostream &os, Indenter indent = {} ) const;
     63        void print( std::ostream &os, int indent = 0 ) const;
    6464        TypeSubstitution *clone() const { return new TypeSubstitution( *this ); }
    6565  private:
     
    8989
    9090        void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
    91 
    92         friend class Mutator;
    93 
    94         template<typename pass_type>
    95         friend class PassVisitor;
    9691
    9792        typedef std::map< std::string, Type* > TypeEnvType;
  • src/SynTree/TypeofType.cc

    r6840e7c rb96ec83  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeofType.cc --
     7// TypeofType.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    3333}
    3434
    35 void TypeofType::print( std::ostream &os, Indenter indent ) const {
     35void TypeofType::print( std::ostream &os, int indent ) const {
    3636        Type::print( os, indent );
    3737        os << "type-of expression ";
  • src/SynTree/VarArgsType.cc

    r6840e7c rb96ec83  
    2525VarArgsType::VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {}
    2626
    27 void VarArgsType::print( std::ostream &os, Indenter indent ) const {
     27void VarArgsType::print( std::ostream &os, int indent ) const {
    2828        Type::print( os, indent );
    2929        os << "builtin var args pack";
  • src/SynTree/VoidType.cc

    r6840e7c rb96ec83  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // VoidType.cc --
     7// VoidType.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    2424}
    2525
    26 void VoidType::print( std::ostream &os, Indenter indent ) const {
     26void VoidType::print( std::ostream &os, int indent ) const {
    2727        Type::print( os, indent );
    2828        os << "void ";
  • src/SynTree/ZeroOneType.cc

    r6840e7c rb96ec83  
    2525ZeroType::ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {}
    2626
    27 void ZeroType::print( std::ostream &os, Indenter ) const {
     27void ZeroType::print( std::ostream &os, __attribute__((unused)) int indent ) const {
    2828        os << "zero_t";
    2929}
     
    3333OneType::OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {}
    3434
    35 void OneType::print( std::ostream &os, Indenter ) const {
     35void OneType::print( std::ostream &os, __attribute__((unused)) int indent ) const {
    3636        os << "one_t";
    3737}
  • src/Tuples/Explode.h

    r6840e7c rb96ec83  
    3030        Expression * distributeReference( Expression * );
    3131
    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 
    4132        /// helper function used by explode
    4233        template< typename OutputIterator >
     
    4435                if ( isTupleAssign ) {
    4536                        // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
    46                         if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
     37                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    4738                                ResolvExpr::AltList alts;
    4839                                explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
  • src/Tuples/TupleAssignment.cc

    r6840e7c rb96ec83  
    4141#include "SynTree/Visitor.h"               // for Visitor
    4242
    43 #if 0
    44 #define PRINT(x) x
    45 #else
    46 #define PRINT(x)
    47 #endif
    48 
    4943namespace Tuples {
    5044        class TupleAssignSpotter {
     
    9084        bool isTuple( Expression *expr ) {
    9185                if ( ! expr ) return false;
    92                 assert( expr->result );
     86                assert( expr->has_result() );
    9387                return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() );
    9488        }
     
    125119                if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
    126120                        if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) {
    127                                fname = op->get_name();
    128                                 PRINT( std::cerr << "TupleAssignment: " << fname << std::endl; )
     121                                fname = op->get_name();
    129122                                for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
    130123                                        if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal
     
    138131                                        const ResolvExpr::Alternative & alt1 = ali->front();
    139132                                        auto begin = std::next(ali->begin(), 1), end = ali->end();
    140                                         PRINT( std::cerr << "alt1 is " << alt1.expr << std::endl; )
    141133                                        if ( refToTuple(alt1.expr) ) {
    142                                                 PRINT( std::cerr << "and is reference to tuple" << std::endl; )
    143134                                                if ( isMultAssign( begin, end ) ) {
    144                                                         PRINT( std::cerr << "possible multiple assignment" << std::endl; )
    145135                                                        matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
    146136                                                } else {
    147137                                                        // mass assignment
    148                                                         PRINT( std::cerr << "possible mass assignment" << std::endl; )
    149138                                                        matcher.reset( new MassAssignMatcher( *this,  *ali ) );
    150139                                                }
     
    170159                // now resolve new assignments
    171160                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 
    177161                        ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() );
    178162                        try {
     
    254238
    255239        ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) {
    256                 assert( expr->result && ! expr->get_result()->isVoid() );
     240                assert( expr->has_result() && ! expr->get_result()->isVoid() );
    257241                ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
    258242                // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
     
    264248                        ctorInit->accept( rm );
    265249                }
    266                 PRINT( std::cerr << "new object: " << ret << std::endl; )
    267250                return ret;
    268251        }
  • src/benchmark/Makefile.am

    r6840e7c rb96ec83  
    4848        @rm -f a.out .result.log
    4949
    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 
    5950sched-int$(EXEEXT):
    6051        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c
  • src/benchmark/Makefile.in

    r6840e7c rb96ec83  
    598598        @rm -f a.out .result.log
    599599
    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 
    609600sched-int$(EXEEXT):
    610601        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c
  • src/benchmark/bench.h

    r6840e7c rb96ec83  
    1010}
    1111#endif
     12
    1213
    1314static inline unsigned long long int Time() {
  • src/benchmark/create_cfaThrd.c

    r6840e7c rb96ec83  
    44
    55thread MyThread {};
    6 void main(MyThread & this) {}
     6void main(MyThread * this) {}
    77
    88int main(int argc, char* argv[]) {
  • src/driver/cfa.cc

    r6840e7c rb96ec83  
    99// Author           : Peter A. Buhr
    1010// Created On       : Tue Aug 20 13:44:49 2002
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Sep 26 23:12:38 2017
    13 // Update Count     : 159
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 17 15:24:00 2017
     13// Update Count     : 156
    1414//
    1515
     
    346346                args[nargs] = "-fgnu89-inline";
    347347                nargs += 1;
    348                 args[nargs] = "-D__int8_t_defined";                             // prevent gcc type-size attributes
    349                 nargs += 1;
    350348                args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
    351349                nargs += 1;
  • src/include/cassert

    r6840e7c rb96ec83  
    4141static inline T strict_dynamic_cast( const U & src ) {
    4242        T ret = dynamic_cast<T>(src);
    43         assertf(ret, "%s", toString(src).c_str());
     43        assert(ret);
    4444        return ret;
    4545}
  • src/libcfa/Makefile.am

    r6840e7c rb96ec83  
    3131
    3232libcfa_a-libcfa-prelude.o : libcfa-prelude.c
    33          ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -Wall -O2 -c -o $@ $<
     33         ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -O2 -c -o $@ $<
    3434
    3535libcfa_d_a-libcfa-prelude.o : libcfa-prelude.c
    36          ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -Wall -O0 -c -o $@ $<
     36         ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $<
    3737
    3838EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
  • src/libcfa/Makefile.in

    r6840e7c rb96ec83  
    14981498
    14991499libcfa_a-libcfa-prelude.o : libcfa-prelude.c
    1500          ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -Wall -O2 -c -o $@ $<
     1500         ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -O2 -c -o $@ $<
    15011501
    15021502libcfa_d_a-libcfa-prelude.o : libcfa-prelude.c
    1503          ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -Wall -O0 -c -o $@ $<
     1503         ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $<
    15041504
    15051505# extensionless header files are overridden by -o flag in default makerule => explicitly override default rule to silently do nothing
  • src/libcfa/concurrency/invoke.h

    r6840e7c rb96ec83  
    9696            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    9797            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
    99             struct __condition_node_t * dtor_node;    // node used to signal the dtor in a waitfor dtor
     98            struct __waitfor_mask_t mask;               // mask used to know if some thread is waiting for something while holding the monitor
    10099      };
    101100
     
    111110            struct monitor_desc    self_mon;          // monitor body used for mutual exclusion
    112111            struct monitor_desc *  self_mon_p;        // pointer to monitor with sufficient lifetime for current monitors
    113             struct __monitor_group_t monitors;        // monitors currently held by this thread
     112            struct __monitor_group_t monitors;          // monitors currently held by this thread
    114113
    115114            // Link lists fields
  • src/libcfa/concurrency/monitor

    r6840e7c rb96ec83  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Oct  7 18:06:45 2017
    13 // Update Count     : 10
     12// Last Modified On : Sat Jul 22 09:59:01 2017
     13// Update Count     : 3
    1414//
    1515
     
    2929static inline void ?{}(monitor_desc & this) {
    3030        (this.lock){};
     31        this.owner = NULL;
    3132        (this.entry_queue){};
    3233        (this.signal_stack){};
    33         this.owner         = NULL;
    34         this.recursion     = 0;
     34        this.recursion = 0;
    3535        this.mask.accepted = NULL;
    3636        this.mask.clauses  = NULL;
    3737        this.mask.size     = 0;
    38         this.dtor_node     = NULL;
    3938}
    40 
    41 // static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
    42 //      return ((intptr_t)lhs) < ((intptr_t)rhs);
    43 // }
    4439
    4540struct monitor_guard_t {
     
    5146};
    5247
     48static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
     49        return ((intptr_t)lhs) < ((intptr_t)rhs);
     50}
     51
    5352void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
    5453void ^?{}( 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 }
    7154
    7255//-----------------------------------------------------------------------------
     
    9275        __condition_node_t ** tail;
    9376};
    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 );
    9877
    9978void ?{}( __condition_blocked_queue_t & );
  • src/libcfa/concurrency/monitor.c

    r6840e7c rb96ec83  
    2323//-----------------------------------------------------------------------------
    2424// 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 );
    28 static inline void reset_mask( monitor_desc * this );
     25static inline void set_owner( monitor_desc * this, thread_desc * owner );
     26static inline void set_owner( monitor_desc ** storage, short count, thread_desc * owner );
     27static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
    2928
    3029static inline thread_desc * next_thread( monitor_desc * this );
     
    7372#define monitor_restore restore( monitors, count, locks, recursions, masks )
    7473
     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
    7579
    7680//-----------------------------------------------------------------------------
     
    9498                }
    9599                else if( this->owner == thrd) {
    96                         // We already have the monitor, just note how many times we took it
     100                        // We already have the monitor, just not how many times we took it
    97101                        verify( this->recursion > 0 );
    98102                        this->recursion += 1;
     
    104108                        set_owner( this, thrd );
    105109
    106                         // Reset mask
    107                         reset_mask( this );
    108 
    109110                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts \n");
    110111                }
     
    127128                unlock( &this->lock );
    128129                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 
    192130        }
    193131
     
    221159        }
    222160
    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 
    235161        // Leave the thread monitor
    236162        // last routine called by a thread.
     
    285211// Ctor for monitor guard
    286212// Sorts monitors before entering
    287 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
     213void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
    288214        // Store current array
    289215        this.m = m;
     
    303229        this_thread->monitors.func = func;
    304230
    305         // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     231        LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
    306232
    307233        // Enter the monitors in order
     
    309235        enter( group );
    310236
    311         // LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");
     237        LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");
    312238}
    313239
     
    315241// Dtor for monitor guard
    316242void ^?{}( monitor_guard_t & this ) {
    317         // LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);
     243        LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);
    318244
    319245        // Leave the monitors in order
    320246        leave( this.m, this.count );
    321247
    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 );
     248        LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");
    355249
    356250        // Restore thread context
     
    409303        short thread_count = 0;
    410304        thread_desc * threads[ count ];
    411         __builtin_memset( threads, 0, sizeof( threads ) );
     305        for(int i = 0; i < count; i++) {
     306                threads[i] = 0;
     307        }
    412308
    413309        // Save monitor states
     
    533429        short max = count_max( mask );
    534430        monitor_desc * mon_storage[max];
    535         __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );
    536431        short actual_count = aggregate( mon_storage, mask );
    537432
    538         LIB_DEBUG_PRINT_SAFE("Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (short)max);
    539 
    540433        if(actual_count == 0) return;
    541 
    542         LIB_DEBUG_PRINT_SAFE("Kernel : waitfor internal proceeding\n");
    543434
    544435        // Create storage for monitor context
     
    554445
    555446                if( next ) {
    556                         *mask.accepted = index;
    557447                        if( mask.clauses[index].is_dtor ) {
    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 );
     448                                #warning case not implemented
    568449                        }
    569450                        else {
    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");
     451                                blockAndWake( &next, 1 );
    588452                        }
    589453
    590                         LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);
    591 
    592                         return;
     454                        return index;
    593455                }
    594456        }
     
    596458
    597459        if( duration == 0 ) {
    598                 LIB_DEBUG_PRINT_SAFE("Kernel : non-blocking, exiting\n");
    599 
    600460                unlock_all( locks, count );
    601 
    602                 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);
    603461                return;
    604462        }
     
    607465        verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");
    608466
    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 );
    613467
    614468        monitor_save;
    615469        set_mask( monitors, count, mask );
    616470
    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);
     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
    634474}
    635475
     
    638478
    639479static inline void set_owner( monitor_desc * this, thread_desc * owner ) {
    640         // LIB_DEBUG_PRINT_SAFE("Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
     480        LIB_DEBUG_PRINT_SAFE("Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
    641481
    642482        //Pass the monitor appropriately
     
    657497                storage[i]->mask = mask;
    658498        }
    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;
    665499}
    666500
     
    750584}
    751585
    752 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
     586static inline void save   ( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
    753587        for( int i = 0; i < count; i++ ) {
    754588                recursions[i] = ctx[i]->recursion;
  • src/libcfa/iostream

    r6840e7c rb96ec83  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Oct 10 14:51:10 2017
    13 // Update Count     : 140
     12// Last Modified On : Wed Sep 13 12:53:46 2017
     13// Update Count     : 138
    1414//
    1515
     
    7979forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char * );
    8080forall( 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
    8281forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char32_t * );
    83 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    8482forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const wchar_t * );
    8583forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const void * );
  • src/libcfa/iostream.c

    r6840e7c rb96ec83  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Oct 10 14:51:09 2017
    13 // Update Count     : 424
     12// Last Modified On : Sun Sep 17 23:24:25 2017
     13// Update Count     : 422
    1414//
    1515
     
    191191} // ?|?
    192192
    193 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    194193forall( dtype ostype | ostream( ostype ) )
    195194ostype * ?|?( ostype * os, const char32_t * str ) {
     
    198197        return os;
    199198} // ?|?
    200 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    201199
    202200forall( dtype ostype | ostream( ostype ) )
  • src/main.cc

    r6840e7c rb96ec83  
    4444#include "ControlStruct/Mutate.h"           // for mutate
    4545#include "GenPoly/Box.h"                    // for box
     46#include "GenPoly/CopyParams.h"             // for copyParams
    4647#include "GenPoly/InstantiateGeneric.h"     // for instantiateGeneric
    4748#include "GenPoly/Lvalue.h"                 // for convertLvalue
     
    320321                OPTPRINT("instantiateGenerics")
    321322                GenPoly::instantiateGeneric( translationUnit );
     323                OPTPRINT( "copyParams" );
     324                GenPoly::copyParams( translationUnit );
    322325                OPTPRINT( "convertLvalue" )
    323326                GenPoly::convertLvalue( translationUnit );
  • src/prelude/extras.c

    r6840e7c rb96ec83  
    11#include <stddef.h>                                     // size_t, ptrdiff_t
    2 #include <stdint.h>                                     // intX_t, uintX_t, where X is 8, 16, 32, 64
    32#include <uchar.h>                                      // char16_t, char32_t
    43#include <wchar.h>                                      // wchar_t
  • src/prelude/extras.regx

    r6840e7c rb96ec83  
    11typedef.* size_t;
    22typedef.* 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;
    113typedef.* char16_t;
    124typedef.* char32_t;
  • src/prelude/prelude.cf

    r6840e7c rb96ec83  
    77// Created On       : Sat Nov 29 07:23:41 2014
    88// Last Modified By : Peter A. Buhr
    9 // Last Modified On : Sun Oct  8 12:21:33 2017
    10 // Update Count     : 97
     9// Last Modified On : Wed Aug 30 07:56:07 2017
     10// Update Count     : 93
    1111//
    1212
     
    558558signed long long int    ?+=?( signed long long int &, signed long long int ),   ?+=?( volatile signed long long int &, signed long long int );
    559559unsigned 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 );
    562560
    563561_Bool                   ?-=?( _Bool &, _Bool ),                                 ?-=?( volatile _Bool &, _Bool );
  • src/tests/.expect/32/KRfunctions.txt

    r6840e7c rb96ec83  
    2121static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1);
    2222static 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);
    2423static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){
    2524    ((void)((*___dst__R2sS_1).__i__i_1) /* ?{} */);
     
    3433    struct S ___ret__2sS_1;
    3534    ((void)((*___dst__R2sS_1).__i__i_1=___src__2sS_1.__i__i_1));
    36     ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));
    37     return ___ret__2sS_1;
     35    ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));
     36    return ((struct S )___ret__2sS_1);
    3837}
    3938static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1){
     
    6665    signed int *__x__FPi_ii__2(signed int __anonymous_object2, signed int __anonymous_object3);
    6766    ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */);
    68     return ___retval_f10__PFPi_ii__1;
     67    return ((signed int *(*)(signed int __x__i_1, signed int __y__i_1))___retval_f10__PFPi_ii__1);
    6968}
    7069signed 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

    r6840e7c rb96ec83  
    2323static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
    2424    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;
     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);
    2727}
    2828__attribute__ ((unused)) struct Agn1;
     
    4141static inline struct Agn2 ___operator_assign__F5sAgn2_R5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__R5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
    4242    struct Agn2 ___ret__5sAgn2_1;
    43     ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__R5sAgn2_1)));
    44     return ___ret__5sAgn2_1;
     43    ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), ___src__5sAgn2_1));
     44    return ((struct Agn2 )___ret__5sAgn2_1);
    4545}
    4646enum __attribute__ ((unused)) __anonymous1 {
     
    6969static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1);
    7070static 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);
    8171static inline void ___constructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){
    8272    ((void)((*___dst__R4sFdl_1).__f1__i_1) /* ?{} */);
     
    8878    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    8979    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    90     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    9180    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    9281}
     
    10089    ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */);
    10190    ((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) /* ?{} */);
    10391    ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */);
    10492}
    10593static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){
    10694    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ^?{} */);
    107     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ^?{} */);
    10895    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ^?{} */);
    10996    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ^?{} */);
     
    125112    ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1));
    126113    ((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));
    128114    ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1));
    129     ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__R4sFdl_1)));
    130     return ___ret__4sFdl_1;
     115    ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), ___src__4sFdl_1));
     116    return ((struct Fdl )___ret__4sFdl_1);
    131117}
    132118static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1){
     
    139125    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    140126    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    141     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    142127    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    143128}
     
    151136    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    152137    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    153     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    154138    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    155139}
     
    163147    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    164148    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    165     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    166149    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    167150}
     
    175158    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    176159    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    177     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    178160    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    179161}
     
    187169    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    188170    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    189     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    190171    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    191172}
     
    199180    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    200181    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    201     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    202182    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    203183}
     
    211191    ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
    212192    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    213     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    214193    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    215194}
     
    223202    ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
    224203    ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_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){
     204    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
     205}
     206static 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){
    229207    ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
    230208    ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     
    235213    ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
    236214    ((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) /* ?{} */);
    250215    ((void)((*___dst__R4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */);
    251216}
     
    267232    __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1;
    268233}
    269 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object5))[];
     234__attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object1))[];
    270235__attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{
    271236    __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[];
    272237}
    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);
     238__attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object2);
     239__attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object3){
     240    __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object4);
    276241}
    277242signed int __vtr__Fi___1(){
     
    303268signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1);
    304269signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1);
    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)]));
     270signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object5)(__attribute__ ((unused,unused)) signed int __anonymous_object6[((unsigned int )5)]));
    306271signed int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)());
    307272signed int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)());
    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)));
     273signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object7)(__attribute__ ((unused)) signed int (*__anonymous_object8)(__attribute__ ((unused,unused)) signed int __anonymous_object9)));
    309274signed int __ad__Fi___1(){
    310275    __attribute__ ((unused)) signed int ___retval_ad__i_1;
     
    335300        struct __anonymous4 ___ret__13s__anonymous4_2;
    336301        ((void)((*___dst__R13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2));
    337         ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), (*___dst__R13s__anonymous4_2)));
    338         return ___ret__13s__anonymous4_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);
    339304    }
    340305    inline void ___constructor__F_R13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__R13s__anonymous4_2, signed int __i__i_2){
     
    348313    }
    349314    inline void ___constructor__F_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){
    350         ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) /* ?{} */);
     315        ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2));
    351316    }
    352317    inline void ___destructor__F_R13e__anonymous5_intrinsic___2(__attribute__ ((unused)) enum __anonymous5 *___dst__R13e__anonymous5_2){
     
    354319    inline enum __anonymous5 ___operator_assign__F13e__anonymous5_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){
    355320        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;
     321        ((void)(___ret__13e__anonymous5_2=((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)) /* ?{} */);
     322        return ((enum __anonymous5 )___ret__13e__anonymous5_2);
    359323    }
    360324    ((void)sizeof(enum __anonymous5 ));
    361325}
    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));
     326signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object10, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object11);
     327signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object13);
     328signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);
     329signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)());
     330signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object18)(__attribute__ ((unused)) signed int __anonymous_object19), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(__attribute__ ((unused)) signed int __anonymous_object21));
     331signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)());
     332signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(__attribute__ ((unused)) signed int __anonymous_object27));
    369333struct Vad {
    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)();
     334    __attribute__ ((unused)) signed int __anonymous_object28;
     335    __attribute__ ((unused,unused)) signed int *__anonymous_object29;
     336    __attribute__ ((unused,unused)) signed int __anonymous_object30[((unsigned int )10)];
     337    __attribute__ ((unused,unused)) signed int (*__anonymous_object31)();
    374338};
    375339static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1);
     
    377341static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1);
    378342static 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)());
    383343static 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) /* ?{} */);
    395344}
    396345static 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) /* ?{} */);
    408346}
    409347static 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) /* ^?{} */);
    421348}
    422349static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){
    423350    struct Vad ___ret__4sVad_1;
    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 }
     351    ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), ___src__4sVad_1));
     352    return ((struct Vad )___ret__4sVad_1);
     353}
  • src/tests/.expect/32/declarationSpecifier.txt

    r6840e7c rb96ec83  
    2020static inline void ___destructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1);
    2121static 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);
    2322static inline void ___constructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1){
    2423    ((void)((*___dst__R13s__anonymous0_1).__i__i_1) /* ?{} */);
     
    3332    struct __anonymous0 ___ret__13s__anonymous0_1;
    3433    ((void)((*___dst__R13s__anonymous0_1).__i__i_1=___src__13s__anonymous0_1.__i__i_1));
    35     ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1)));
    36     return ___ret__13s__anonymous0_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);
    3736}
    3837static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1){
     
    4746static inline void ___destructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1);
    4847static 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);
    5048static inline void ___constructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1){
    5149    ((void)((*___dst__R13s__anonymous1_1).__i__i_1) /* ?{} */);
     
    6058    struct __anonymous1 ___ret__13s__anonymous1_1;
    6159    ((void)((*___dst__R13s__anonymous1_1).__i__i_1=___src__13s__anonymous1_1.__i__i_1));
    62     ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), (*___dst__R13s__anonymous1_1)));
    63     return ___ret__13s__anonymous1_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);
    6462}
    6563static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1){
     
    7472static inline void ___destructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1);
    7573static 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);
    7774static inline void ___constructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1){
    7875    ((void)((*___dst__R13s__anonymous2_1).__i__i_1) /* ?{} */);
     
    8784    struct __anonymous2 ___ret__13s__anonymous2_1;
    8885    ((void)((*___dst__R13s__anonymous2_1).__i__i_1=___src__13s__anonymous2_1.__i__i_1));
    89     ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__R13s__anonymous2_1)));
    90     return ___ret__13s__anonymous2_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);
    9188}
    9289static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1){
     
    10198static inline void ___destructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1);
    10299static 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);
    104100static inline void ___constructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1){
    105101    ((void)((*___dst__R13s__anonymous3_1).__i__i_1) /* ?{} */);
     
    114110    struct __anonymous3 ___ret__13s__anonymous3_1;
    115111    ((void)((*___dst__R13s__anonymous3_1).__i__i_1=___src__13s__anonymous3_1.__i__i_1));
    116     ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), (*___dst__R13s__anonymous3_1)));
    117     return ___ret__13s__anonymous3_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);
    118114}
    119115static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1){
     
    128124static inline void ___destructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1);
    129125static 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);
    131126static inline void ___constructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1){
    132127    ((void)((*___dst__R13s__anonymous4_1).__i__i_1) /* ?{} */);
     
    141136    struct __anonymous4 ___ret__13s__anonymous4_1;
    142137    ((void)((*___dst__R13s__anonymous4_1).__i__i_1=___src__13s__anonymous4_1.__i__i_1));
    143     ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), (*___dst__R13s__anonymous4_1)));
    144     return ___ret__13s__anonymous4_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);
    145140}
    146141static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1){
     
    155150static inline void ___destructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1);
    156151static 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);
    158152static inline void ___constructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1){
    159153    ((void)((*___dst__R13s__anonymous5_1).__i__i_1) /* ?{} */);
     
    168162    struct __anonymous5 ___ret__13s__anonymous5_1;
    169163    ((void)((*___dst__R13s__anonymous5_1).__i__i_1=___src__13s__anonymous5_1.__i__i_1));
    170     ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), (*___dst__R13s__anonymous5_1)));
    171     return ___ret__13s__anonymous5_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);
    172166}
    173167static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1){
     
    182176static inline void ___destructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1);
    183177static 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);
    185178static inline void ___constructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1){
    186179    ((void)((*___dst__R13s__anonymous6_1).__i__i_1) /* ?{} */);
     
    195188    struct __anonymous6 ___ret__13s__anonymous6_1;
    196189    ((void)((*___dst__R13s__anonymous6_1).__i__i_1=___src__13s__anonymous6_1.__i__i_1));
    197     ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), (*___dst__R13s__anonymous6_1)));
    198     return ___ret__13s__anonymous6_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);
    199192}
    200193static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1){
     
    209202static inline void ___destructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1);
    210203static 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);
    212204static inline void ___constructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1){
    213205    ((void)((*___dst__R13s__anonymous7_1).__i__i_1) /* ?{} */);
     
    222214    struct __anonymous7 ___ret__13s__anonymous7_1;
    223215    ((void)((*___dst__R13s__anonymous7_1).__i__i_1=___src__13s__anonymous7_1.__i__i_1));
    224     ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), (*___dst__R13s__anonymous7_1)));
    225     return ___ret__13s__anonymous7_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);
    226218}
    227219static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1){
     
    244236static inline void ___destructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1);
    245237static 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);
    247238static inline void ___constructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1){
    248239    ((void)((*___dst__R13s__anonymous8_1).__i__s_1) /* ?{} */);
     
    257248    struct __anonymous8 ___ret__13s__anonymous8_1;
    258249    ((void)((*___dst__R13s__anonymous8_1).__i__s_1=___src__13s__anonymous8_1.__i__s_1));
    259     ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), (*___dst__R13s__anonymous8_1)));
    260     return ___ret__13s__anonymous8_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);
    261252}
    262253static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1){
     
    271262static inline void ___destructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1);
    272263static 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);
    274264static inline void ___constructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1){
    275265    ((void)((*___dst__R13s__anonymous9_1).__i__s_1) /* ?{} */);
     
    284274    struct __anonymous9 ___ret__13s__anonymous9_1;
    285275    ((void)((*___dst__R13s__anonymous9_1).__i__s_1=___src__13s__anonymous9_1.__i__s_1));
    286     ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), (*___dst__R13s__anonymous9_1)));
    287     return ___ret__13s__anonymous9_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);
    288278}
    289279static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1){
     
    298288static inline void ___destructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1);
    299289static 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);
    301290static inline void ___constructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1){
    302291    ((void)((*___dst__R14s__anonymous10_1).__i__s_1) /* ?{} */);
     
    311300    struct __anonymous10 ___ret__14s__anonymous10_1;
    312301    ((void)((*___dst__R14s__anonymous10_1).__i__s_1=___src__14s__anonymous10_1.__i__s_1));
    313     ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), (*___dst__R14s__anonymous10_1)));
    314     return ___ret__14s__anonymous10_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);
    315304}
    316305static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1){
     
    325314static inline void ___destructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1);
    326315static 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);
    328316static inline void ___constructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1){
    329317    ((void)((*___dst__R14s__anonymous11_1).__i__s_1) /* ?{} */);
     
    338326    struct __anonymous11 ___ret__14s__anonymous11_1;
    339327    ((void)((*___dst__R14s__anonymous11_1).__i__s_1=___src__14s__anonymous11_1.__i__s_1));
    340     ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), (*___dst__R14s__anonymous11_1)));
    341     return ___ret__14s__anonymous11_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);
    342330}
    343331static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1){
     
    352340static inline void ___destructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1);
    353341static 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);
    355342static inline void ___constructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1){
    356343    ((void)((*___dst__R14s__anonymous12_1).__i__s_1) /* ?{} */);
     
    365352    struct __anonymous12 ___ret__14s__anonymous12_1;
    366353    ((void)((*___dst__R14s__anonymous12_1).__i__s_1=___src__14s__anonymous12_1.__i__s_1));
    367     ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), (*___dst__R14s__anonymous12_1)));
    368     return ___ret__14s__anonymous12_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);
    369356}
    370357static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1){
     
    379366static inline void ___destructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1);
    380367static 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);
    382368static inline void ___constructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1){
    383369    ((void)((*___dst__R14s__anonymous13_1).__i__s_1) /* ?{} */);
     
    392378    struct __anonymous13 ___ret__14s__anonymous13_1;
    393379    ((void)((*___dst__R14s__anonymous13_1).__i__s_1=___src__14s__anonymous13_1.__i__s_1));
    394     ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), (*___dst__R14s__anonymous13_1)));
    395     return ___ret__14s__anonymous13_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);
    396382}
    397383static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1){
     
    406392static inline void ___destructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1);
    407393static 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);
    409394static inline void ___constructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1){
    410395    ((void)((*___dst__R14s__anonymous14_1).__i__s_1) /* ?{} */);
     
    419404    struct __anonymous14 ___ret__14s__anonymous14_1;
    420405    ((void)((*___dst__R14s__anonymous14_1).__i__s_1=___src__14s__anonymous14_1.__i__s_1));
    421     ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), (*___dst__R14s__anonymous14_1)));
    422     return ___ret__14s__anonymous14_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);
    423408}
    424409static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1){
     
    433418static inline void ___destructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1);
    434419static 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);
    436420static inline void ___constructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1){
    437421    ((void)((*___dst__R14s__anonymous15_1).__i__s_1) /* ?{} */);
     
    446430    struct __anonymous15 ___ret__14s__anonymous15_1;
    447431    ((void)((*___dst__R14s__anonymous15_1).__i__s_1=___src__14s__anonymous15_1.__i__s_1));
    448     ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), (*___dst__R14s__anonymous15_1)));
    449     return ___ret__14s__anonymous15_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);
    450434}
    451435static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1){
     
    476460static inline void ___destructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1);
    477461static 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);
    479462static inline void ___constructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1){
    480463    ((void)((*___dst__R14s__anonymous16_1).__i__i_1) /* ?{} */);
     
    489472    struct __anonymous16 ___ret__14s__anonymous16_1;
    490473    ((void)((*___dst__R14s__anonymous16_1).__i__i_1=___src__14s__anonymous16_1.__i__i_1));
    491     ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), (*___dst__R14s__anonymous16_1)));
    492     return ___ret__14s__anonymous16_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);
    493476}
    494477static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1){
     
    503486static inline void ___destructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1);
    504487static 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);
    506488static inline void ___constructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1){
    507489    ((void)((*___dst__R14s__anonymous17_1).__i__i_1) /* ?{} */);
     
    516498    struct __anonymous17 ___ret__14s__anonymous17_1;
    517499    ((void)((*___dst__R14s__anonymous17_1).__i__i_1=___src__14s__anonymous17_1.__i__i_1));
    518     ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), (*___dst__R14s__anonymous17_1)));
    519     return ___ret__14s__anonymous17_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);
    520502}
    521503static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1){
     
    530512static inline void ___destructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1);
    531513static 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);
    533514static inline void ___constructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1){
    534515    ((void)((*___dst__R14s__anonymous18_1).__i__i_1) /* ?{} */);
     
    543524    struct __anonymous18 ___ret__14s__anonymous18_1;
    544525    ((void)((*___dst__R14s__anonymous18_1).__i__i_1=___src__14s__anonymous18_1.__i__i_1));
    545     ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), (*___dst__R14s__anonymous18_1)));
    546     return ___ret__14s__anonymous18_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);
    547528}
    548529static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1){
     
    557538static inline void ___destructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1);
    558539static 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);
    560540static inline void ___constructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1){
    561541    ((void)((*___dst__R14s__anonymous19_1).__i__i_1) /* ?{} */);
     
    570550    struct __anonymous19 ___ret__14s__anonymous19_1;
    571551    ((void)((*___dst__R14s__anonymous19_1).__i__i_1=___src__14s__anonymous19_1.__i__i_1));
    572     ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), (*___dst__R14s__anonymous19_1)));
    573     return ___ret__14s__anonymous19_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);
    574554}
    575555static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1){
     
    584564static inline void ___destructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1);
    585565static 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);
    587566static inline void ___constructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1){
    588567    ((void)((*___dst__R14s__anonymous20_1).__i__i_1) /* ?{} */);
     
    597576    struct __anonymous20 ___ret__14s__anonymous20_1;
    598577    ((void)((*___dst__R14s__anonymous20_1).__i__i_1=___src__14s__anonymous20_1.__i__i_1));
    599     ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), (*___dst__R14s__anonymous20_1)));
    600     return ___ret__14s__anonymous20_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);
    601580}
    602581static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1){
     
    611590static inline void ___destructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1);
    612591static 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);
    614592static inline void ___constructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1){
    615593    ((void)((*___dst__R14s__anonymous21_1).__i__i_1) /* ?{} */);
     
    624602    struct __anonymous21 ___ret__14s__anonymous21_1;
    625603    ((void)((*___dst__R14s__anonymous21_1).__i__i_1=___src__14s__anonymous21_1.__i__i_1));
    626     ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), (*___dst__R14s__anonymous21_1)));
    627     return ___ret__14s__anonymous21_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);
    628606}
    629607static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1){
     
    638616static inline void ___destructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1);
    639617static 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);
    641618static inline void ___constructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1){
    642619    ((void)((*___dst__R14s__anonymous22_1).__i__i_1) /* ?{} */);
     
    651628    struct __anonymous22 ___ret__14s__anonymous22_1;
    652629    ((void)((*___dst__R14s__anonymous22_1).__i__i_1=___src__14s__anonymous22_1.__i__i_1));
    653     ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), (*___dst__R14s__anonymous22_1)));
    654     return ___ret__14s__anonymous22_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);
    655632}
    656633static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1){
     
    665642static inline void ___destructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1);
    666643static 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);
    668644static inline void ___constructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1){
    669645    ((void)((*___dst__R14s__anonymous23_1).__i__i_1) /* ?{} */);
     
    678654    struct __anonymous23 ___ret__14s__anonymous23_1;
    679655    ((void)((*___dst__R14s__anonymous23_1).__i__i_1=___src__14s__anonymous23_1.__i__i_1));
    680     ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), (*___dst__R14s__anonymous23_1)));
    681     return ___ret__14s__anonymous23_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);
    682658}
    683659static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1){
     
    696672    __attribute__ ((unused)) signed int ___retval_main__i_1;
    697673    ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */);
    698     return ___retval_main__i_1;
     674    return ((signed int )___retval_main__i_1);
    699675    ((void)(___retval_main__i_1=0) /* ?{} */);
    700     return ___retval_main__i_1;
     676    return ((signed int )___retval_main__i_1);
    701677}
    702678static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
     
    713689    ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */);
    714690    ((void)(_tmp_cp_ret0) /* ^?{} */);
    715     return ___retval_main__i_1;
    716 }
     691    return ((signed int )___retval_main__i_1);
     692}
  • src/tests/.expect/32/extension.txt

    r6840e7c rb96ec83  
    1717static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1);
    1818static 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);
    2219static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){
    2320    ((void)((*___dst__R2sS_1).__a__i_1) /* ?{} */);
     
    4037    ((void)((*___dst__R2sS_1).__b__i_1=___src__2sS_1.__b__i_1));
    4138    ((void)((*___dst__R2sS_1).__c__i_1=___src__2sS_1.__c__i_1));
    42     ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));
    43     return ___ret__2sS_1;
     39    ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));
     40    return ((struct S )___ret__2sS_1);
    4441}
    4542static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1){
     
    6360    __extension__ signed int __c__i_1;
    6461};
    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);
    7062static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1){
    7163}
     
    7870    union U ___ret__2uU_1;
    7971    ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&___src__2uU_1)), sizeof(union U )));
    80     ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), (*___dst__R2uU_1)));
    81     return ___ret__2uU_1;
     72    ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), ___src__2uU_1));
     73    return ((union U )___ret__2uU_1);
    8274}
    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 )));
     75static 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 )));
    8577}
    8678__extension__ enum E {
     
    10294        __extension__ signed int *__z__Pi_2;
    10395    };
    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);
     96    signed int __i__i_2 = ((signed int )(__extension__ __a__i_1+__extension__ 3));
    18897    ((void)__extension__ 3);
    18998    ((void)__extension__ __a__i_1);
  • src/tests/.expect/32/gccExtensions.txt

    r6840e7c rb96ec83  
    6363        ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2));
    6464        ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2));
    65         ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2)));
    66         return ___ret__2sS_2;
     65        ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), ___src__2sS_2));
     66        return ((struct S )___ret__2sS_2);
    6767    }
    6868    inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){
     
    8181        ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */);
    8282    }
    83     signed int __i__i_2 = __extension__ 3;
     83    signed int __i__i_2 = ((signed int )__extension__ 3);
    8484    __extension__ signed int __a__i_2;
    8585    __extension__ signed int __b__i_2;
     
    113113        struct s2 ___ret__3ss2_2;
    114114        ((void)((*___dst__R3ss2_2).__i__i_2=___src__3ss2_2.__i__i_2));
    115         ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), (*___dst__R3ss2_2)));
    116         return ___ret__3ss2_2;
     115        ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), ___src__3ss2_2));
     116        return ((struct s2 )___ret__3ss2_2);
    117117    }
    118118    inline void ___constructor__F_R3ss2i_autogen___2(struct s2 *___dst__R3ss2_2, signed int __i__i_2){
     
    134134        struct s3 ___ret__3ss3_2;
    135135        ((void)((*___dst__R3ss3_2).__i__i_2=___src__3ss3_2.__i__i_2));
    136         ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), (*___dst__R3ss3_2)));
    137         return ___ret__3ss3_2;
     136        ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), ___src__3ss3_2));
     137        return ((struct s3 )___ret__3ss3_2);
    138138    }
    139139    inline void ___constructor__F_R3ss3i_autogen___2(struct s3 *___dst__R3ss3_2, signed int __i__i_2){
     
    157157        struct s4 ___ret__3ss4_2;
    158158        ((void)((*___dst__R3ss4_2).__i__i_2=___src__3ss4_2.__i__i_2));
    159         ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), (*___dst__R3ss4_2)));
    160         return ___ret__3ss4_2;
     159        ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), ___src__3ss4_2));
     160        return ((struct s4 )___ret__3ss4_2);
    161161    }
    162162    inline void ___constructor__F_R3ss4i_autogen___2(struct s4 *___dst__R3ss4_2, signed int __i__i_2){
     
    169169    signed int __m3__A0A0i_2[((unsigned int )10)][((unsigned int )10)];
    170170    ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */);
    171     return ___retval_main__i_1;
     171    return ((signed int )___retval_main__i_1);
    172172    ((void)(___retval_main__i_1=0) /* ?{} */);
    173     return ___retval_main__i_1;
     173    return ((signed int )___retval_main__i_1);
    174174}
    175175static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
     
    186186    ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */);
    187187    ((void)(_tmp_cp_ret0) /* ^?{} */);
    188     return ___retval_main__i_1;
     188    return ((signed int )___retval_main__i_1);
    189189}
  • src/tests/.expect/32/literals.txt

    r6840e7c rb96ec83  
    6464static inline void ___destructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1);
    6565static 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);
    6766static inline void ___constructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1){
    6867    ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1) /* ?{} */);
     
    7776    struct _Istream_cstrUC ___ret__16s_Istream_cstrUC_1;
    7877    ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1=___src__16s_Istream_cstrUC_1.__s__Pc_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;
     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);
    8180}
    8281static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1){
     
    9392static inline void ___destructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1);
    9493static 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);
    9794static inline void ___constructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1){
    9895    ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1) /* ?{} */);
     
    111108    ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1=___src__15s_Istream_cstrC_1.__s__Pc_1));
    112109    ((void)((*___dst__R15s_Istream_cstrC_1).__size__i_1=___src__15s_Istream_cstrC_1.__size__i_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;
     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);
    115112}
    116113static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1){
     
    125122void *___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);
    126123enum __anonymous0 {
    127     __sepSize__C13e__anonymous0_1 = 16,
     124    __sepSize__C13e__anonymous0_1 = ((signed int )16),
    128125};
    129126struct ofstream {
     
    140137static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1);
    141138static 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)]);
    149139static inline void ___constructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){
    150140    ((void)((*___dst__R9sofstream_1).__file__Pv_1) /* ?{} */);
     
    154144    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    155145    {
    156         signed int _index0 = 0;
     146        signed int _index0 = ((signed int )0);
    157147        for (;(_index0<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index0))) {
    158148            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index0])))) /* ?{} */);
     
    160150
    161151    }
    162 
    163     {
    164         signed int _index1 = 0;
     152    {
     153        signed int _index1 = ((signed int )0);
    165154        for (;(_index1<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index1))) {
    166155            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index1])))) /* ?{} */);
     
    168157
    169158    }
    170 
    171159}
    172160static inline void ___constructor__F_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1){
     
    177165    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1) /* ?{} */);
    178166    {
    179         signed int _index2 = 0;
     167        signed int _index2 = ((signed int )0);
    180168        for (;(_index2<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index2))) {
    181169            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index2])))=___src__9sofstream_1.__separator__A0c_1[_index2]) /* ?{} */);
     
    183171
    184172    }
    185 
    186     {
    187         signed int _index3 = 0;
     173    {
     174        signed int _index3 = ((signed int )0);
    188175        for (;(_index3<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index3))) {
    189176            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index3])))=___src__9sofstream_1.__tupleSeparator__A0c_1[_index3]) /* ?{} */);
     
    191178
    192179    }
    193 
    194180}
    195181static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){
    196182    {
    197         signed int _index4 = (((signed int )__sepSize__C13e__anonymous0_1)-1);
     183        signed int _index4 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1));
    198184        for (;(_index4>=0);((void)(--_index4))) {
    199185            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index4])))) /* ^?{} */);
     
    201187
    202188    }
    203 
    204     {
    205         signed int _index5 = (((signed int )__sepSize__C13e__anonymous0_1)-1);
     189    {
     190        signed int _index5 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1));
    206191        for (;(_index5>=0);((void)(--_index5))) {
    207192            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index5])))) /* ^?{} */);
     
    209194
    210195    }
    211 
    212196    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ^?{} */);
    213197    ((void)((*___dst__R9sofstream_1).__sawNL__b_1) /* ^?{} */);
     
    224208    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1));
    225209    {
    226         signed int _index6 = 0;
     210        signed int _index6 = ((signed int )0);
    227211        for (;(_index6<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index6))) {
    228212            ((void)((*___dst__R9sofstream_1).__separator__A0c_1[_index6]=___src__9sofstream_1.__separator__A0c_1[_index6]));
     
    232216
    233217    {
    234         signed int _index7 = 0;
     218        signed int _index7 = ((signed int )0);
    235219        for (;(_index7<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index7))) {
    236220            ((void)((*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index7]=___src__9sofstream_1.__tupleSeparator__A0c_1[_index7]));
     
    239223    }
    240224
    241     ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), (*___dst__R9sofstream_1)));
    242     return ___ret__9sofstream_1;
     225    ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), ___src__9sofstream_1));
     226    return ((struct ofstream )___ret__9sofstream_1);
    243227}
    244228static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1){
     
    249233    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    250234    {
    251         signed int _index8 = 0;
     235        signed int _index8 = ((signed int )0);
    252236        for (;(_index8<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index8))) {
    253237            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index8])))) /* ?{} */);
     
    255239
    256240    }
    257 
    258     {
    259         signed int _index9 = 0;
     241    {
     242        signed int _index9 = ((signed int )0);
    260243        for (;(_index9<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index9))) {
    261244            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index9])))) /* ?{} */);
     
    263246
    264247    }
    265 
    266248}
    267249static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1){
     
    272254    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    273255    {
    274         signed int _index10 = 0;
     256        signed int _index10 = ((signed int )0);
    275257        for (;(_index10<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index10))) {
    276258            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index10])))) /* ?{} */);
     
    278260
    279261    }
    280 
    281     {
    282         signed int _index11 = 0;
     262    {
     263        signed int _index11 = ((signed int )0);
    283264        for (;(_index11<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index11))) {
    284265            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index11])))) /* ?{} */);
     
    286267
    287268    }
    288 
    289269}
    290270static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1){
     
    295275    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    296276    {
    297         signed int _index12 = 0;
     277        signed int _index12 = ((signed int )0);
    298278        for (;(_index12<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index12))) {
    299279            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index12])))) /* ?{} */);
     
    301281
    302282    }
    303 
    304     {
    305         signed int _index13 = 0;
     283    {
     284        signed int _index13 = ((signed int )0);
    306285        for (;(_index13<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index13))) {
    307286            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index13])))) /* ?{} */);
     
    309288
    310289    }
    311 
    312290}
    313291static 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){
     
    318296    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    319297    {
    320         signed int _index14 = 0;
     298        signed int _index14 = ((signed int )0);
    321299        for (;(_index14<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index14))) {
    322300            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index14])))) /* ?{} */);
     
    324302
    325303    }
    326 
    327     {
    328         signed int _index15 = 0;
     304    {
     305        signed int _index15 = ((signed int )0);
    329306        for (;(_index15<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index15))) {
    330307            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index15])))) /* ?{} */);
     
    332309
    333310    }
    334 
    335311}
    336312static 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){
     
    341317    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */);
    342318    {
    343         signed int _index16 = 0;
     319        signed int _index16 = ((signed int )0);
    344320        for (;(_index16<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index16))) {
    345321            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index16])))) /* ?{} */);
     
    347323
    348324    }
    349 
    350     {
    351         signed int _index17 = 0;
     325    {
     326        signed int _index17 = ((signed int )0);
    352327        for (;(_index17<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index17))) {
    353328            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index17])))) /* ?{} */);
     
    355330
    356331    }
    357 
    358332}
    359333static 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)]){
     
    364338    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */);
    365339    {
    366         signed int _index18 = 0;
     340        signed int _index18 = ((signed int )0);
    367341        for (;(_index18<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index18))) {
    368342            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index18])))=__separator__A0c_1[_index18]) /* ?{} */);
     
    370344
    371345    }
    372 
    373     {
    374         signed int _index19 = 0;
     346    {
     347        signed int _index19 = ((signed int )0);
    375348        for (;(_index19<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index19))) {
    376349            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index19])))) /* ?{} */);
     
    378351
    379352    }
    380 
    381353}
    382354static 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)]){
     
    387359    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */);
    388360    {
    389         signed int _index20 = 0;
     361        signed int _index20 = ((signed int )0);
    390362        for (;(_index20<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index20))) {
    391363            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index20])))=__separator__A0c_1[_index20]) /* ?{} */);
     
    393365
    394366    }
    395 
    396     {
    397         signed int _index21 = 0;
     367    {
     368        signed int _index21 = ((signed int )0);
    398369        for (;(_index21<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index21))) {
    399370            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index21])))=__tupleSeparator__A0c_1[_index21]) /* ?{} */);
     
    401372
    402373    }
    403 
    404374}
    405375_Bool __sepPrt__Fb_P9sofstream__1(struct ofstream *__anonymous_object1294);
     
    434404static inline void ___destructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1);
    435405static 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);
    437406static inline void ___constructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1){
    438407    ((void)((*___dst__R9sifstream_1).__file__Pv_1) /* ?{} */);
     
    447416    struct ifstream ___ret__9sifstream_1;
    448417    ((void)((*___dst__R9sifstream_1).__file__Pv_1=___src__9sifstream_1.__file__Pv_1));
    449     ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), (*___dst__R9sifstream_1)));
    450     return ___ret__9sifstream_1;
     418    ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), ___src__9sifstream_1));
     419    return ((struct ifstream )___ret__9sifstream_1);
    451420}
    452421static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1){
     
    739708    ((void)0123456789.e-09L);
    740709    ((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));
     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));
    747716    ((void)(-0123456789.e-09));
    748717    ((void)(-0123456789.e-09f));
     
    883852    ((void)0123456789.0123456789E-09L);
    884853    ((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));
     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));
    891860    ((void)(-0123456789.0123456789E-09));
    892861    ((void)(-0123456789.0123456789E-09f));
     
    930899    ((void)0x0123456789.p-09F);
    931900    ((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));
     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));
    937906    ((void)(-0x0123456789.p-09));
    938907    ((void)(-0x0123456789.p-09f));
     
    975944    ((void)0x.0123456789P-09F);
    976945    ((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));
     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));
    982951    ((void)(-0x.0123456789P-09));
    983952    ((void)(-0x.0123456789P-09f));
     
    1020989    ((void)0X0123456789.0123456789P-09F);
    1021990    ((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));
    1027991    ((void)(-0X0123456789.0123456789P-09));
    1028992    ((void)(-0X0123456789.0123456789P-09f));
     
    1030994    ((void)(-0X0123456789.0123456789P-09F));
    1031995    ((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)));
     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));
    12641001    ((void)__f__F_c__1('a'));
    12651002    ((void)__f__F_Sc__1(20));
     
    13741111    ((void)L"a" "b" "c");
    13751112    ((void)(___retval_main__i_1=0) /* ?{} */);
    1376     return ___retval_main__i_1;
     1113    return ((signed int )___retval_main__i_1);
    13771114}
    13781115static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); }
     
    13891126    ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */);
    13901127    ((void)(_tmp_cp_ret0) /* ^?{} */);
    1391     return ___retval_main__i_1;
    1392 }
     1128    return ((signed int )___retval_main__i_1);
     1129}
  • src/tests/.expect/64/KRfunctions.txt

    r6840e7c rb96ec83  
    2121static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1);
    2222static 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);
    2423static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){
    2524    ((void)((*___dst__R2sS_1).__i__i_1) /* ?{} */);
     
    3433    struct S ___ret__2sS_1;
    3534    ((void)((*___dst__R2sS_1).__i__i_1=___src__2sS_1.__i__i_1));
    36     ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));
    37     return ___ret__2sS_1;
     35    ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));
     36    return ((struct S )___ret__2sS_1);
    3837}
    3938static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1){
     
    6665    signed int *__x__FPi_ii__2(signed int __anonymous_object2, signed int __anonymous_object3);
    6766    ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */);
    68     return ___retval_f10__PFPi_ii__1;
     67    return ((signed int *(*)(signed int __x__i_1, signed int __y__i_1))___retval_f10__PFPi_ii__1);
    6968}
    7069signed 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

    r6840e7c rb96ec83  
    2323static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
    2424    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;
     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);
    2727}
    2828__attribute__ ((unused)) struct Agn1;
     
    4141static inline struct Agn2 ___operator_assign__F5sAgn2_R5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__R5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
    4242    struct Agn2 ___ret__5sAgn2_1;
    43     ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__R5sAgn2_1)));
    44     return ___ret__5sAgn2_1;
     43    ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), ___src__5sAgn2_1));
     44    return ((struct Agn2 )___ret__5sAgn2_1);
    4545}
    4646enum __attribute__ ((unused)) __anonymous1 {
     
    6969static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1);
    7070static 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);
    8171static inline void ___constructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){
    8272    ((void)((*___dst__R4sFdl_1).__f1__i_1) /* ?{} */);
     
    8878    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    8979    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    90     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    9180    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    9281}
     
    10089    ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */);
    10190    ((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) /* ?{} */);
    10391    ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */);
    10492}
    10593static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){
    10694    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ^?{} */);
    107     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ^?{} */);
    10895    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ^?{} */);
    10996    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ^?{} */);
     
    125112    ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1));
    126113    ((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));
    128114    ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1));
    129     ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__R4sFdl_1)));
    130     return ___ret__4sFdl_1;
     115    ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), ___src__4sFdl_1));
     116    return ((struct Fdl )___ret__4sFdl_1);
    131117}
    132118static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1){
     
    139125    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    140126    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    141     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    142127    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    143128}
     
    151136    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    152137    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    153     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    154138    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    155139}
     
    163147    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    164148    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    165     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    166149    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    167150}
     
    175158    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    176159    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    177     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    178160    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    179161}
     
    187169    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    188170    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    189     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    190171    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    191172}
     
    199180    ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */);
    200181    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    201     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    202182    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    203183}
     
    211191    ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
    212192    ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */);
    213     ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);
    214193    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
    215194}
     
    223202    ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
    224203    ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_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){
     204    ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);
     205}
     206static 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){
    229207    ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
    230208    ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     
    235213    ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
    236214    ((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) /* ?{} */);
    250215    ((void)((*___dst__R4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */);
    251216}
     
    267232    __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1;
    268233}
    269 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object5))[];
     234__attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object1))[];
    270235__attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{
    271236    __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[];
    272237}
    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);
     238__attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object2);
     239__attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object3){
     240    __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object4);
    276241}
    277242signed int __vtr__Fi___1(){
     
    303268signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1);
    304269signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1);
    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)]));
     270signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object5)(__attribute__ ((unused,unused)) signed int __anonymous_object6[((unsigned long int )5)]));
    306271signed int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)());
    307272signed int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)());
    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)));
     273signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object7)(__attribute__ ((unused)) signed int (*__anonymous_object8)(__attribute__ ((unused,unused)) signed int __anonymous_object9)));
    309274signed int __ad__Fi___1(){
    310275    __attribute__ ((unused)) signed int ___retval_ad__i_1;
     
    335300        struct __anonymous4 ___ret__13s__anonymous4_2;
    336301        ((void)((*___dst__R13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2));
    337         ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), (*___dst__R13s__anonymous4_2)));
    338         return ___ret__13s__anonymous4_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);
    339304    }
    340305    inline void ___constructor__F_R13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__R13s__anonymous4_2, signed int __i__i_2){
     
    348313    }
    349314    inline void ___constructor__F_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){
    350         ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) /* ?{} */);
     315        ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2));
    351316    }
    352317    inline void ___destructor__F_R13e__anonymous5_intrinsic___2(__attribute__ ((unused)) enum __anonymous5 *___dst__R13e__anonymous5_2){
     
    354319    inline enum __anonymous5 ___operator_assign__F13e__anonymous5_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){
    355320        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;
     321        ((void)(___ret__13e__anonymous5_2=((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)) /* ?{} */);
     322        return ((enum __anonymous5 )___ret__13e__anonymous5_2);
    359323    }
    360324    ((void)sizeof(enum __anonymous5 ));
    361325}
    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));
     326signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object10, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object11);
     327signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object13);
     328signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);
     329signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)());
     330signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object18)(__attribute__ ((unused)) signed int __anonymous_object19), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(__attribute__ ((unused)) signed int __anonymous_object21));
     331signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)());
     332signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(__attribute__ ((unused)) signed int __anonymous_object27));
    369333struct Vad {
    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)();
     334    __attribute__ ((unused)) signed int __anonymous_object28;
     335    __attribute__ ((unused,unused)) signed int *__anonymous_object29;
     336    __attribute__ ((unused,unused)) signed int __anonymous_object30[((unsigned long int )10)];
     337    __attribute__ ((unused,unused)) signed int (*__anonymous_object31)();
    374338};
    375339static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1);
     
    377341static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1);
    378342static 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)());
    383343static 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) /* ?{} */);
    395344}
    396345static 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) /* ?{} */);
    408346}
    409347static 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) /* ^?{} */);
    421348}
    422349static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){
    423350    struct Vad ___ret__4sVad_1;
    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 }
     351    ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), ___src__4sVad_1));
     352    return ((struct Vad )___ret__4sVad_1);
     353}
  • src/tests/.expect/64/declarationSpecifier.txt

    r6840e7c rb96ec83  
    2020static inline void ___destructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1);
    2121static 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);
    2322static inline void ___constructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1){
    2423    ((void)((*___dst__R13s__anonymous0_1).__i__i_1) /* ?{} */);
     
    3332    struct __anonymous0 ___ret__13s__anonymous0_1;
    3433    ((void)((*___dst__R13s__anonymous0_1).__i__i_1=___src__13s__anonymous0_1.__i__i_1));
    35     ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1)));
    36     return ___ret__13s__anonymous0_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);
    3736}
    3837static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1){
     
    4746static inline void ___destructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1);
    4847static 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);
    5048static inline void ___constructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1){
    5149    ((void)((*___dst__R13s__anonymous1_1).__i__i_1) /* ?{} */);
     
    6058    struct __anonymous1 ___ret__13s__anonymous1_1;
    6159    ((void)((*___dst__R13s__anonymous1_1).__i__i_1=___src__13s__anonymous1_1.__i__i_1));
    62     ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), (*___dst__R13s__anonymous1_1)));
    63     return ___ret__13s__anonymous1_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);
    6462}
    6563static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1){
     
    7472static inline void ___destructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1);
    7573static 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);
    7774static inline void ___constructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1){
    7875    ((void)((*___dst__R13s__anonymous2_1).__i__i_1) /* ?{} */);
     
    8784    struct __anonymous2 ___ret__13s__anonymous2_1;
    8885    ((void)((*___dst__R13s__anonymous2_1).__i__i_1=___src__13s__anonymous2_1.__i__i_1));
    89     ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__R13s__anonymous2_1)));
    90     return ___ret__13s__anonymous2_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);
    9188}
    9289static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1){
     
    10198static inline void ___destructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1);
    10299static 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);
    104100static inline void ___constructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1){
    105101    ((void)((*___dst__R13s__anonymous3_1).__i__i_1) /* ?{} */);
     
    114110    struct __anonymous3 ___ret__13s__anonymous3_1;
    115111    ((void)((*___dst__R13s__anonymous3_1).__i__i_1=___src__13s__anonymous3_1.__i__i_1));
    116     ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), (*___dst__R13s__anonymous3_1)));
    117     return ___ret__13s__anonymous3_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);
    118114}
    119115static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1){
     
    128124static inline void ___destructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1);
    129125static 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);
    131126static inline void ___constructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1){
    132127    ((void)((*___dst__R13s__anonymous4_1).__i__i_1) /* ?{} */);
     
    141136    struct __anonymous4 ___ret__13s__anonymous4_1;
    142137    ((void)((*___dst__R13s__anonymous4_1).__i__i_1=___src__13s__anonymous4_1.__i__i_1));
    143     ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), (*___dst__R13s__anonymous4_1)));
    144     return ___ret__13s__anonymous4_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);
    145140}
    146141static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1){
     
    155150static inline void ___destructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1);
    156151static 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);
    158152static inline void ___constructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1){
    159153    ((void)((*___dst__R13s__anonymous5_1).__i__i_1) /* ?{} */);
     
    168162    struct __anonymous5 ___ret__13s__anonymous5_1;
    169163    ((void)((*___dst__R13s__anonymous5_1).__i__i_1=___src__13s__anonymous5_1.__i__i_1));
    170     ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), (*___dst__R13s__anonymous5_1)));
    171     return ___ret__13s__anonymous5_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);
    172166}
    173167static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1){
     
    182176static inline void ___destructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1);
    183177static 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);
    185178static inline void ___constructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1){
    186179    ((void)((*___dst__R13s__anonymous6_1).__i__i_1) /* ?{} */);
     
    195188    struct __anonymous6 ___ret__13s__anonymous6_1;
    196189    ((void)((*___dst__R13s__anonymous6_1).__i__i_1=___src__13s__anonymous6_1.__i__i_1));
    197     ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), (*___dst__R13s__anonymous6_1)));
    198     return ___ret__13s__anonymous6_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);
    199192}
    200193static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1){
     
    209202static inline void ___destructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1);
    210203static 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);
    212204static inline void ___constructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1){
    213205    ((void)((*___dst__R13s__anonymous7_1).__i__i_1) /* ?{} */);
     
    222214    struct __anonymous7 ___ret__13s__anonymous7_1;
    223215    ((void)((*___dst__R13s__anonymous7_1).__i__i_1=___src__13s__anonymous7_1.__i__i_1));
    224     ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), (*___dst__R13s__anonymous7_1)));
    225     return ___ret__13s__anonymous7_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);
    226218}
    227219static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1){
     
    244236static inline void ___destructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1);
    245237static 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);
    247238static inline void ___constructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1){
    248239    ((void)((*___dst__R13s__anonymous8_1).__i__s_1) /* ?{} */);
     
    257248    struct __anonymous8 ___ret__13s__anonymous8_1;
    258249    ((void)((*___dst__R13s__anonymous8_1).__i__s_1=___src__13s__anonymous8_1.__i__s_1));
    259     ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), (*___dst__R13s__anonymous8_1)));
    260     return ___ret__13s__anonymous8_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);
    261252}
    262253static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1){
     
    271262static inline void ___destructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1);
    272263static 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);
    274264static inline void ___constructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1){
    275265    ((void)((*___dst__R13s__anonymous9_1).__i__s_1) /* ?{} */);
     
    284274    struct __anonymous9 ___ret__13s__anonymous9_1;
    285275    ((void)((*___dst__R13s__anonymous9_1).__i__s_1=___src__13s__anonymous9_1.__i__s_1));
    286     ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), (*___dst__R13s__anonymous9_1)));
    287     return ___ret__13s__anonymous9_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);
    288278}
    289279static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1){
     
    298288static inline void ___destructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1);
    299289static 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);
    301290static inline void ___constructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1){
    302291    ((void)((*___dst__R14s__anonymous10_1).__i__s_1) /* ?{} */);
     
    311300    struct __anonymous10 ___ret__14s__anonymous10_1;
    312301    ((void)((*___dst__R14s__anonymous10_1).__i__s_1=___src__14s__anonymous10_1.__i__s_1));
    313     ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), (*___dst__R14s__anonymous10_1)));
    314     return ___ret__14s__anonymous10_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);
    315304}
    316305static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1){
     
    325314static inline void ___destructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1);
    326315static 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);
    328316static inline void ___constructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1){
    329317    ((void)((*___dst__R14s__anonymous11_1).__i__s_1) /* ?{} */);
     
    338326    struct __anonymous11 ___ret__14s__anonymous11_1;
    339327    ((void)((*___dst__R14s__anonymous11_1).__i__s_1=___src__14s__anonymous11_1.__i__s_1));
    340     ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), (*___dst__R14s__anonymous11_1)));
    341     return ___ret__14s__anonymous11_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);
    342330}
    343331static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1){
     
    352340static inline void ___destructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1);
    353341static 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);
    355342static inline void ___constructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1){
    356343    ((void)((*___dst__R14s__anonymous12_1).__i__s_1) /* ?{} */);
     
    365352    struct __anonymous12 ___ret__14s__anonymous12_1;
    366353    ((void)((*___dst__R14s__anonymous12_1).__i__s_1=___src__14s__anonymous12_1.__i__s_1));
    367     ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), (*___dst__R14s__anonymous12_1)));
    368     return ___ret__14s__anonymous12_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);
    369356}
    370357static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1){
     
    379366static inline void ___destructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1);
    380367static 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);
    382368static inline void ___constructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1){
    383369    ((void)((*___dst__R14s__anonymous13_1).__i__s_1) /* ?{} */);
     
    392378    struct __anonymous13 ___ret__14s__anonymous13_1;
    393379    ((void)((*___dst__R14s__anonymous13_1).__i__s_1=___src__14s__anonymous13_1.__i__s_1));
    394     ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), (*___dst__R14s__anonymous13_1)));
    395     return ___ret__14s__anonymous13_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);
    396382}
    397383static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1){
     
    406392static inline void ___destructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1);
    407393static 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);
    409394static inline void ___constructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1){
    410395    ((void)((*___dst__R14s__anonymous14_1).__i__s_1) /* ?{} */);
     
    419404    struct __anonymous14 ___ret__14s__anonymous14_1;
    420405    ((void)((*___dst__R14s__anonymous14_1).__i__s_1=___src__14s__anonymous14_1.__i__s_1));
    421     ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), (*___dst__R14s__anonymous14_1)));
    422     return ___ret__14s__anonymous14_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);
    423408}
    424409static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1){
     
    433418static inline void ___destructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1);
    434419static 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);
    436420static inline void ___constructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1){
    437421    ((void)((*___dst__R14s__anonymous15_1).__i__s_1) /* ?{} */);
     
    446430    struct __anonymous15 ___ret__14s__anonymous15_1;
    447431    ((void)((*___dst__R14s__anonymous15_1).__i__s_1=___src__14s__anonymous15_1.__i__s_1));
    448     ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), (*___dst__R14s__anonymous15_1)));
    449     return ___ret__14s__anonymous15_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);
    450434}
    451435static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1){
     
    476460static inline void ___destructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1);
    477461static 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);
    479462static inline void ___constructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1){
    480463    ((void)((*___dst__R14s__anonymous16_1).__i__i_1) /* ?{} */);
     
    489472    struct __anonymous16 ___ret__14s__anonymous16_1;
    490473    ((void)((*___dst__R14s__anonymous16_1).__i__i_1=___src__14s__anonymous16_1.__i__i_1));
    491     ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), (*___dst__R14s__anonymous16_1)));
    492     return ___ret__14s__anonymous16_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);
    493476}
    494477static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1){
     
    503486static inline void ___destructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1);
    504487static 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);
    506488static inline void ___constructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1){
    507489    ((void)((*___dst__R14s__anonymous17_1).__i__i_1) /* ?{} */);
     
    516498    struct __anonymous17 ___ret__14s__anonymous17_1;
    517499    ((void)((*___dst__R14s__anonymous17_1).__i__i_1=___src__14s__anonymous17_1.__i__i_1));
    518     ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), (*___dst__R14s__anonymous17_1)));
    519     return ___ret__14s__anonymous17_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);
    520502}
    521503static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1){
     
    530512static inline void ___destructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1);
    531513static 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);
    533514static inline void ___constructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1){
    534515    ((void)((*___dst__R14s__anonymous18_1).__i__i_1) /* ?{} */);
     
    543524    struct __anonymous18 ___ret__14s__anonymous18_1;
    544525    ((void)((*___dst__R14s__anonymous18_1).__i__i_1=___src__14s__anonymous18_1.__i__i_1));
    545     ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), (*___dst__R14s__anonymous18_1)));
    546     return ___ret__14s__anonymous18_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);
    547528}
    548529static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1){
     
    557538static inline void ___destructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1);
    558539static 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);
    560540static inline void ___constructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1){
    561541    ((void)((*___dst__R14s__anonymous19_1).__i__i_1) /* ?{} */);
     
    570550    struct __anonymous19 ___ret__14s__anonymous19_1;
    571551    ((void)((*___dst__R14s__anonymous19_1).__i__i_1=___src__14s__anonymous19_1.__i__i_1));
    572     ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), (*___dst__R14s__anonymous19_1)));
    573     return ___ret__14s__anonymous19_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);
    574554}
    575555static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1){
     
    584564static inline void ___destructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1);
    585565static 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);
    587566static inline void ___constructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1){
    588567    ((void)((*___dst__R14s__anonymous20_1).__i__i_1) /* ?{} */);
     
    597576    struct __anonymous20 ___ret__14s__anonymous20_1;
    598577    ((void)((*___dst__R14s__anonymous20_1).__i__i_1=___src__14s__anonymous20_1.__i__i_1));
    599     ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), (*___dst__R14s__anonymous20_1)));
    600     return ___ret__14s__anonymous20_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);
    601580}
    602581static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1){
     
    611590static inline void ___destructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1);
    612591static 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);
    614592static inline void ___constructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1){
    615593    ((void)((*___dst__R14s__anonymous21_1).__i__i_1) /* ?{} */);
     
    624602    struct __anonymous21 ___ret__14s__anonymous21_1;
    625603    ((void)((*___dst__R14s__anonymous21_1).__i__i_1=___src__14s__anonymous21_1.__i__i_1));
    626     ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), (*___dst__R14s__anonymous21_1)));
    627     return ___ret__14s__anonymous21_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);
    628606}
    629607static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1){
     
    638616static inline void ___destructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1);
    639617static 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);
    641618static inline void ___constructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1){
    642619    ((void)((*___dst__R14s__anonymous22_1).__i__i_1) /* ?{} */);
     
    651628    struct __anonymous22 ___ret__14s__anonymous22_1;
    652629    ((void)((*___dst__R14s__anonymous22_1).__i__i_1=___src__14s__anonymous22_1.__i__i_1));
    653     ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), (*___dst__R14s__anonymous22_1)));
    654     return ___ret__14s__anonymous22_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);
    655632}
    656633static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1){
     
    665642static inline void ___destructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1);
    666643static 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);
    668644static inline void ___constructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1){
    669645    ((void)((*___dst__R14s__anonymous23_1).__i__i_1) /* ?{} */);
     
    678654    struct __anonymous23 ___ret__14s__anonymous23_1;
    679655    ((void)((*___dst__R14s__anonymous23_1).__i__i_1=___src__14s__anonymous23_1.__i__i_1));
    680     ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), (*___dst__R14s__anonymous23_1)));
    681     return ___ret__14s__anonymous23_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);
    682658}
    683659static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1){
     
    696672    __attribute__ ((unused)) signed int ___retval_main__i_1;
    697673    ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */);
    698     return ___retval_main__i_1;
     674    return ((signed int )___retval_main__i_1);
    699675    ((void)(___retval_main__i_1=0) /* ?{} */);
    700     return ___retval_main__i_1;
     676    return ((signed int )___retval_main__i_1);
    701677}
    702678static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
     
    713689    ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */);
    714690    ((void)(_tmp_cp_ret0) /* ^?{} */);
    715     return ___retval_main__i_1;
    716 }
     691    return ((signed int )___retval_main__i_1);
     692}
  • src/tests/.expect/64/extension.txt

    r6840e7c rb96ec83  
    1717static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1);
    1818static 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);
    2219static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){
    2320    ((void)((*___dst__R2sS_1).__a__i_1) /* ?{} */);
     
    4037    ((void)((*___dst__R2sS_1).__b__i_1=___src__2sS_1.__b__i_1));
    4138    ((void)((*___dst__R2sS_1).__c__i_1=___src__2sS_1.__c__i_1));
    42     ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));
    43     return ___ret__2sS_1;
     39    ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1));
     40    return ((struct S )___ret__2sS_1);
    4441}
    4542static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1){
     
    6360    __extension__ signed int __c__i_1;
    6461};
    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);
    7062static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1){
    7163}
     
    7870    union U ___ret__2uU_1;
    7971    ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&___src__2uU_1)), sizeof(union U )));
    80     ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), (*___dst__R2uU_1)));
    81     return ___ret__2uU_1;
     72    ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), ___src__2uU_1));
     73    return ((union U )___ret__2uU_1);
    8274}
    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 )));
     75static 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 )));
    8577}
    8678__extension__ enum E {
     
    10294        __extension__ signed int *__z__Pi_2;
    10395    };
    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);
     96    signed int __i__i_2 = ((signed int )(__extension__ __a__i_1+__extension__ 3));
    18897    ((void)__extension__ 3);
    18998    ((void)__extension__ __a__i_1);
  • src/tests/.expect/64/gccExtensions.txt

    r6840e7c rb96ec83  
    6363        ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2));
    6464        ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2));
    65         ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2)));
    66         return ___ret__2sS_2;
     65        ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), ___src__2sS_2));
     66        return ((struct S )___ret__2sS_2);
    6767    }
    6868    inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){
     
    8181        ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */);
    8282    }
    83     signed int __i__i_2 = __extension__ 3;
     83    signed int __i__i_2 = ((signed int )__extension__ 3);
    8484    __extension__ signed int __a__i_2;
    8585    __extension__ signed int __b__i_2;
     
    113113        struct s2 ___ret__3ss2_2;
    114114        ((void)((*___dst__R3ss2_2).__i__i_2=___src__3ss2_2.__i__i_2));
    115         ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), (*___dst__R3ss2_2)));
    116         return ___ret__3ss2_2;
     115        ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), ___src__3ss2_2));
     116        return ((struct s2 )___ret__3ss2_2);
    117117    }
    118118    inline void ___constructor__F_R3ss2i_autogen___2(struct s2 *___dst__R3ss2_2, signed int __i__i_2){
     
    134134        struct s3 ___ret__3ss3_2;
    135135        ((void)((*___dst__R3ss3_2).__i__i_2=___src__3ss3_2.__i__i_2));
    136         ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), (*___dst__R3ss3_2)));
    137         return ___ret__3ss3_2;
     136        ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), ___src__3ss3_2));
     137        return ((struct s3 )___ret__3ss3_2);
    138138    }
    139139    inline void ___constructor__F_R3ss3i_autogen___2(struct s3 *___dst__R3ss3_2, signed int __i__i_2){
     
    157157        struct s4 ___ret__3ss4_2;
    158158        ((void)((*___dst__R3ss4_2).__i__i_2=___src__3ss4_2.__i__i_2));
    159         ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), (*___dst__R3ss4_2)));
    160         return ___ret__3ss4_2;
     159        ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), ___src__3ss4_2));
     160        return ((struct s4 )___ret__3ss4_2);
    161161    }
    162162    inline void ___constructor__F_R3ss4i_autogen___2(struct s4 *___dst__R3ss4_2, signed int __i__i_2){
     
    169169    signed int __m3__A0A0i_2[((unsigned long int )10)][((unsigned long int )10)];
    170170    ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */);
    171     return ___retval_main__i_1;
     171    return ((signed int )___retval_main__i_1);
    172172    ((void)(___retval_main__i_1=0) /* ?{} */);
    173     return ___retval_main__i_1;
     173    return ((signed int )___retval_main__i_1);
    174174}
    175175static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
     
    186186    ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */);
    187187    ((void)(_tmp_cp_ret0) /* ^?{} */);
    188     return ___retval_main__i_1;
     188    return ((signed int )___retval_main__i_1);
    189189}
  • src/tests/.expect/64/literals.txt

    r6840e7c rb96ec83  
    6464static inline void ___destructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1);
    6565static 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);
    6766static inline void ___constructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1){
    6867    ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1) /* ?{} */);
     
    7776    struct _Istream_cstrUC ___ret__16s_Istream_cstrUC_1;
    7877    ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1=___src__16s_Istream_cstrUC_1.__s__Pc_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;
     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);
    8180}
    8281static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1){
     
    9392static inline void ___destructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1);
    9493static 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);
    9794static inline void ___constructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1){
    9895    ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1) /* ?{} */);
     
    111108    ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1=___src__15s_Istream_cstrC_1.__s__Pc_1));
    112109    ((void)((*___dst__R15s_Istream_cstrC_1).__size__i_1=___src__15s_Istream_cstrC_1.__size__i_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;
     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);
    115112}
    116113static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1){
     
    125122void *___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);
    126123enum __anonymous0 {
    127     __sepSize__C13e__anonymous0_1 = 16,
     124    __sepSize__C13e__anonymous0_1 = ((signed int )16),
    128125};
    129126struct ofstream {
     
    140137static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1);
    141138static 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)]);
    149139static inline void ___constructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){
    150140    ((void)((*___dst__R9sofstream_1).__file__Pv_1) /* ?{} */);
     
    154144    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    155145    {
    156         signed int _index0 = 0;
     146        signed int _index0 = ((signed int )0);
    157147        for (;(_index0<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index0))) {
    158148            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index0)])))) /* ?{} */);
     
    160150
    161151    }
    162 
    163     {
    164         signed int _index1 = 0;
     152    {
     153        signed int _index1 = ((signed int )0);
    165154        for (;(_index1<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index1))) {
    166155            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index1)])))) /* ?{} */);
     
    168157
    169158    }
    170 
    171159}
    172160static inline void ___constructor__F_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1){
     
    177165    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1) /* ?{} */);
    178166    {
    179         signed int _index2 = 0;
     167        signed int _index2 = ((signed int )0);
    180168        for (;(_index2<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index2))) {
    181169            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index2)])))=___src__9sofstream_1.__separator__A0c_1[((signed long int )_index2)]) /* ?{} */);
     
    183171
    184172    }
    185 
    186     {
    187         signed int _index3 = 0;
     173    {
     174        signed int _index3 = ((signed int )0);
    188175        for (;(_index3<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index3))) {
    189176            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index3)])))=___src__9sofstream_1.__tupleSeparator__A0c_1[((signed long int )_index3)]) /* ?{} */);
     
    191178
    192179    }
    193 
    194180}
    195181static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){
    196182    {
    197         signed int _index4 = (((signed int )__sepSize__C13e__anonymous0_1)-1);
     183        signed int _index4 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1));
    198184        for (;(_index4>=0);((void)(--_index4))) {
    199185            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index4)])))) /* ^?{} */);
     
    201187
    202188    }
    203 
    204     {
    205         signed int _index5 = (((signed int )__sepSize__C13e__anonymous0_1)-1);
     189    {
     190        signed int _index5 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1));
    206191        for (;(_index5>=0);((void)(--_index5))) {
    207192            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index5)])))) /* ^?{} */);
     
    209194
    210195    }
    211 
    212196    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ^?{} */);
    213197    ((void)((*___dst__R9sofstream_1).__sawNL__b_1) /* ^?{} */);
     
    224208    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1));
    225209    {
    226         signed int _index6 = 0;
     210        signed int _index6 = ((signed int )0);
    227211        for (;(_index6<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index6))) {
    228212            ((void)((*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index6)]=___src__9sofstream_1.__separator__A0c_1[((signed long int )_index6)]));
     
    232216
    233217    {
    234         signed int _index7 = 0;
     218        signed int _index7 = ((signed int )0);
    235219        for (;(_index7<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index7))) {
    236220            ((void)((*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index7)]=___src__9sofstream_1.__tupleSeparator__A0c_1[((signed long int )_index7)]));
     
    239223    }
    240224
    241     ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), (*___dst__R9sofstream_1)));
    242     return ___ret__9sofstream_1;
     225    ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), ___src__9sofstream_1));
     226    return ((struct ofstream )___ret__9sofstream_1);
    243227}
    244228static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1){
     
    249233    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    250234    {
    251         signed int _index8 = 0;
     235        signed int _index8 = ((signed int )0);
    252236        for (;(_index8<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index8))) {
    253237            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index8)])))) /* ?{} */);
     
    255239
    256240    }
    257 
    258     {
    259         signed int _index9 = 0;
     241    {
     242        signed int _index9 = ((signed int )0);
    260243        for (;(_index9<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index9))) {
    261244            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index9)])))) /* ?{} */);
     
    263246
    264247    }
    265 
    266248}
    267249static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1){
     
    272254    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    273255    {
    274         signed int _index10 = 0;
     256        signed int _index10 = ((signed int )0);
    275257        for (;(_index10<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index10))) {
    276258            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index10)])))) /* ?{} */);
     
    278260
    279261    }
    280 
    281     {
    282         signed int _index11 = 0;
     262    {
     263        signed int _index11 = ((signed int )0);
    283264        for (;(_index11<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index11))) {
    284265            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index11)])))) /* ?{} */);
     
    286267
    287268    }
    288 
    289269}
    290270static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1){
     
    295275    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    296276    {
    297         signed int _index12 = 0;
     277        signed int _index12 = ((signed int )0);
    298278        for (;(_index12<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index12))) {
    299279            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index12)])))) /* ?{} */);
     
    301281
    302282    }
    303 
    304     {
    305         signed int _index13 = 0;
     283    {
     284        signed int _index13 = ((signed int )0);
    306285        for (;(_index13<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index13))) {
    307286            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index13)])))) /* ?{} */);
     
    309288
    310289    }
    311 
    312290}
    313291static 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){
     
    318296    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */);
    319297    {
    320         signed int _index14 = 0;
     298        signed int _index14 = ((signed int )0);
    321299        for (;(_index14<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index14))) {
    322300            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index14)])))) /* ?{} */);
     
    324302
    325303    }
    326 
    327     {
    328         signed int _index15 = 0;
     304    {
     305        signed int _index15 = ((signed int )0);
    329306        for (;(_index15<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index15))) {
    330307            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index15)])))) /* ?{} */);
     
    332309
    333310    }
    334 
    335311}
    336312static 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){
     
    341317    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */);
    342318    {
    343         signed int _index16 = 0;
     319        signed int _index16 = ((signed int )0);
    344320        for (;(_index16<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index16))) {
    345321            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index16)])))) /* ?{} */);
     
    347323
    348324    }
    349 
    350     {
    351         signed int _index17 = 0;
     325    {
     326        signed int _index17 = ((signed int )0);
    352327        for (;(_index17<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index17))) {
    353328            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index17)])))) /* ?{} */);
     
    355330
    356331    }
    357 
    358332}
    359333static 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)]){
     
    364338    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */);
    365339    {
    366         signed int _index18 = 0;
     340        signed int _index18 = ((signed int )0);
    367341        for (;(_index18<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index18))) {
    368342            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index18)])))=__separator__A0c_1[((signed long int )_index18)]) /* ?{} */);
     
    370344
    371345    }
    372 
    373     {
    374         signed int _index19 = 0;
     346    {
     347        signed int _index19 = ((signed int )0);
    375348        for (;(_index19<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index19))) {
    376349            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index19)])))) /* ?{} */);
     
    378351
    379352    }
    380 
    381353}
    382354static 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)]){
     
    387359    ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */);
    388360    {
    389         signed int _index20 = 0;
     361        signed int _index20 = ((signed int )0);
    390362        for (;(_index20<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index20))) {
    391363            ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index20)])))=__separator__A0c_1[((signed long int )_index20)]) /* ?{} */);
     
    393365
    394366    }
    395 
    396     {
    397         signed int _index21 = 0;
     367    {
     368        signed int _index21 = ((signed int )0);
    398369        for (;(_index21<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index21))) {
    399370            ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index21)])))=__tupleSeparator__A0c_1[((signed long int )_index21)]) /* ?{} */);
     
    401372
    402373    }
    403 
    404374}
    405375_Bool __sepPrt__Fb_P9sofstream__1(struct ofstream *__anonymous_object1294);
     
    434404static inline void ___destructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1);
    435405static 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);
    437406static inline void ___constructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1){
    438407    ((void)((*___dst__R9sifstream_1).__file__Pv_1) /* ?{} */);
     
    447416    struct ifstream ___ret__9sifstream_1;
    448417    ((void)((*___dst__R9sifstream_1).__file__Pv_1=___src__9sifstream_1.__file__Pv_1));
    449     ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), (*___dst__R9sifstream_1)));
    450     return ___ret__9sifstream_1;
     418    ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), ___src__9sifstream_1));
     419    return ((struct ifstream )___ret__9sifstream_1);
    451420}
    452421static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1){
     
    739708    ((void)0123456789.e-09L);
    740709    ((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));
     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));
    747716    ((void)(-0123456789.e-09));
    748717    ((void)(-0123456789.e-09f));
     
    883852    ((void)0123456789.0123456789E-09L);
    884853    ((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));
     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));
    891860    ((void)(-0123456789.0123456789E-09));
    892861    ((void)(-0123456789.0123456789E-09f));
     
    930899    ((void)0x0123456789.p-09F);
    931900    ((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));
     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));
    937906    ((void)(-0x0123456789.p-09));
    938907    ((void)(-0x0123456789.p-09f));
     
    975944    ((void)0x.0123456789P-09F);
    976945    ((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));
     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));
    982951    ((void)(-0x.0123456789P-09));
    983952    ((void)(-0x.0123456789P-09f));
     
    1020989    ((void)0X0123456789.0123456789P-09F);
    1021990    ((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));
    1027991    ((void)(-0X0123456789.0123456789P-09));
    1028992    ((void)(-0X0123456789.0123456789P-09f));
     
    1030994    ((void)(-0X0123456789.0123456789P-09F));
    1031995    ((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)));
     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));
    12641001    ((void)__f__F_c__1('a'));
    12651002    ((void)__f__F_Sc__1(20));
     
    13741111    ((void)L"a" "b" "c");
    13751112    ((void)(___retval_main__i_1=0) /* ?{} */);
    1376     return ___retval_main__i_1;
     1113    return ((signed int )___retval_main__i_1);
    13771114}
    13781115static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); }
     
    13891126    ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */);
    13901127    ((void)(_tmp_cp_ret0) /* ^?{} */);
    1391     return ___retval_main__i_1;
    1392 }
     1128    return ((signed int )___retval_main__i_1);
     1129}
  • src/tests/.expect/castError.txt

    r6840e7c rb96ec83  
    1 castError.c:7:1 error: Cannot choose between 3 alternatives for expression
    2 Cast of:
     1castError.c:7:1 error: Cannot choose between 3 alternatives for expression Cast of:
    32  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
    103
    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:
     4to:
     5  char
     6Alternatives are:        Cost ( 1, 0, 0, 0 ): Cast of:
     7          Variable Expression: f: function
     8                accepting unspecified arguments
     9              returning
     10                nothing
    3511
    3612
     13        to:
     14          char
     15(types:
     16            char
     17)
     18        Environment:
     19
     20        Cost ( 1, 0, 0, 0 ): Cast of:
     21          Variable Expression: f: signed int
     22
     23        to:
     24          char
     25(types:
     26            char
     27)
     28        Environment:
     29
     30        Cost ( 1, 0, 0, 0 ): Cast of:
     31          Variable Expression: f: double
     32
     33        to:
     34          char
     35(types:
     36            char
     37)
     38        Environment:
     39
     40
  • src/tests/.expect/scopeErrors.txt

    r6840e7c rb96ec83  
    11scopeErrors.c:2:1 error: duplicate object definition for thisIsAnError: signed int
    22scopeErrors.c:20:1 error: duplicate function definition for butThisIsAnError: function
    3 ... with parameters
    4   double
    5 ... returning
    6   _retval_butThisIsAnError: double
    7   ... with attributes:
    8     Attribute with name: unused
     3  with parameters
     4    double
     5  returning
     6    _retval_butThisIsAnError:       Attribute with name: unused
     7double
     8  with body
     9    CompoundStmt
    910
    10 ... with body
    11   CompoundStmt
    12 
  • src/tests/Makefile.am

    r6840e7c rb96ec83  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Tue Oct 10 14:04:40 2017
    14 ## Update Count     : 47
     13## Last Modified On : Mon Sep 11 16:17:16 2017
     14## Update Count     : 45
    1515###############################################################################
    1616
     
    2222concurrent = yes
    2323quick_test += coroutine thread monitor
    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
     24concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
    4525else
    4626concurrent=no
     
    133113        ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
    134114
    135 ctor-autogen-ERR1: ctor-autogen.c @CFA_BINDIR@/@CFA_NAME@
    136         ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
    137 
    138115completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@
    139116        ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
  • src/tests/Makefile.in

    r6840e7c rb96ec83  
    320320@BUILD_CONCURRENCY_TRUE@concurrent = yes
    321321@BUILD_CONCURRENCY_FALSE@concurrent_test =
    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 
     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
    344323
    345324# applies to both programs
     
    886865        ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
    887866
    888 ctor-autogen-ERR1: ctor-autogen.c @CFA_BINDIR@/@CFA_NAME@
    889         ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
    890 
    891867completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@
    892868        ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
  • src/tests/coroutine.c

    r6840e7c rb96ec83  
    1010// Created On       : Thu Jun  8 07:29:37 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep 17 21:38:15 2017
    13 // Update Count     : 7
     12// Last Modified On : Thu Jun  8 07:37:12 2017
     13// Update Count     : 5
    1414//
    1515
     
    1818
    1919coroutine Fibonacci {
    20         int fn;                                                                                         // used for communication
     20        int fn;                                         // used for communication
    2121};
    2222
     
    2626
    2727void main( Fibonacci & this ) {
    28         int fn1, fn2;                                                                           // retained between resumes
    29         this.fn = 0;                                                                            // case 0
     28        int fn1, fn2;                                   // retained between resumes
     29        this.fn = 0;                                    // case 0
    3030        fn1 = this.fn;
    31         suspend();                                                                                      // restart last resume
     31        suspend();                                              // return to last resume
    3232
    33         this.fn = 1;                                                                            // case 1
    34         fn2 = fn1;  fn1 = this.fn;
    35         suspend();                                                                                      // restart last resume
     33        this.fn = 1;                                    // case 1
     34        fn2 = fn1;
     35        fn1 = this.fn;
     36        suspend();                                              // return to last resume
    3637
    37         for ( ;; ) {                                                                            // general case
     38        for ( ;; ) {                                    // general case
    3839                this.fn = fn1 + fn2;
    39                 fn2 = fn1;  fn1 = this.fn;
    40                 suspend();                                                                              // restart last resume
     40                fn2 = fn1;
     41                fn1 = this.fn;
     42                suspend();                                      // return to last resume
    4143        } // for
    4244}
    4345
    4446int next( Fibonacci & this ) {
    45         resume( this );                                                                         // restart last suspend
     47        resume( this );                                 // transfer to last suspend
    4648        return this.fn;
    4749}
     
    5052        Fibonacci f1, f2;
    5153        for ( int i = 1; i <= 10; i += 1 ) {
    52                 sout | next( f1 ) | next( f2 ) | endl;
     54                sout | next( f1 ) | ' ' | next( f2 ) | endl;
    5355        } // for
    5456}
  • src/tests/fmtLines.c

    r6840e7c rb96ec83  
    1010// Created On       : Sun Sep 17 21:56:15 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Oct  1 11:57:19 2017
    13 // Update Count     : 34
     12// Last Modified On : Mon Sep 18 11:35:57 2017
     13// Update Count     : 31
    1414//
    1515
     
    2323
    2424void ?{}( Format & fmt ) {
    25         resume( fmt );                                                                          // prime (start) coroutine
     25    resume( fmt );                                                                              // start coroutine
    2626}
    2727
    2828void ^?{}( Format & fmt ) {
    29         if ( fmt.g != 0 || fmt.b != 0 ) sout | endl;
     29    if ( fmt.g != 0 || fmt.b != 0 ) sout | endl;
    3030}
    3131
     
    4747
    4848void prt( Format & fmt, char ch ) {
    49         fmt.ch = ch;
    50         resume( fmt );
     49    fmt.ch = ch;
     50    resume( fmt );
    5151} // prt
    5252
    5353int main() {
    54         Format fmt;                                                                                     // format characters into blocks of 4 and groups of 5 blocks per line
     54        Format fmt;
    5555        char ch;
    5656
    57         Eof: for ( ;; ) {                                                                       // read until end of file
     57        for ( ;; ) {
    5858                sin | ch;                                                                               // read one character
    59           if ( eof( sin ) ) break Eof;                                          // eof ?
    60                 prt( fmt, ch );                                                                 // push character for formatting
     59          if ( eof( sin ) ) break;                                                      // eof ?
     60                prt( fmt, ch );
    6161        } // for
    6262} // main
  • src/tests/gmp.c

    r6840e7c rb96ec83  
    1010// Created On       : Tue Apr 19 08:55:51 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Sep 28 18:33:51 2017
    13 // Update Count     : 555
     12// Last Modified On : Mon Sep  4 09:51:18 2017
     13// Update Count     : 550
    1414//
    1515
     
    9797
    9898        sout | "Factorial Numbers" | endl;
    99         Int fact = 1;                                                                           // 1st case
     99        Int fact;
     100        fact = 1;                                                                                       // 1st case
    100101        sout | (int)0 | fact | endl;
    101102        for ( unsigned int i = 1; i <= 40; i += 1 ) {
  • src/tests/literals.c

    r6840e7c rb96ec83  
    1010// Created On       : Sat Sep  9 16:34:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 20:26:00 2017
    13 // Update Count     : 132
     12// Last Modified On : Tue Sep 12 07:45:46 2017
     13// Update Count     : 88
    1414//
    1515
    1616#ifdef __CFA__
    17 #include <stdint.h>
    1817#include <fstream>
    1918
     
    7372
    7473         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;
     74        -0123456789.e-09;  -0123456789.e-09f;  -0123456789.e-09l;  -0123456789.e-09F;  -0123456789.e-09L;  -0123456789.e-09DL;
    7675        -0123456789.e-09;  -0123456789.e-09f;  -0123456789.e-09l;  -0123456789.e-09F;  -0123456789.e-09L;  -0123456789.e-09DL;
    7776
     
    105104
    106105         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;
     106        -0123456789.0123456789E-09;  -0123456789.0123456789E-09f;  -0123456789.0123456789E-09l;  -0123456789.0123456789E-09F;  -0123456789.0123456789E-09L;  -0123456789.0123456789E-09DL;
    108107        -0123456789.0123456789E-09;  -0123456789.0123456789E-09f;  -0123456789.0123456789E-09l;  -0123456789.0123456789E-09F;  -0123456789.0123456789E-09L;  -0123456789.0123456789E-09DL;
    109108
     
    119118
    120119         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;
     120        -0x0123456789.p-09;  -0x0123456789.p-09f;  -0x0123456789.p-09l;  -0x0123456789.p-09F;  -0x0123456789.p-09L;
    122121        -0x0123456789.p-09;  -0x0123456789.p-09f;  -0x0123456789.p-09l;  -0x0123456789.p-09F;  -0x0123456789.p-09L;
    123122
     
    131130
    132131         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;
     132        -0x.0123456789P-09;  -0x.0123456789P-09f;  -0x.0123456789P-09l;  -0x.0123456789P-09F;  -0x.0123456789P-09L;
    134133        -0x.0123456789P-09;  -0x.0123456789P-09f;  -0x.0123456789P-09l;  -0x.0123456789P-09F;  -0x.0123456789P-09L;
    135134
     
    143142
    144143         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;
    146144        -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;
     146
     147// char, short, int suffix overloading
    147148
    148149#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;
    203 
    204 // char, short, int suffix overloading
    205 
    206150        f( 'a' );
    207151        f( 20_hh );
  • src/tests/sched-ext-parse.c

    r6840e7c rb96ec83  
    1 //----------------------------------------------------------------------------------------
    2 //----------------------------------------------------------------------------------------
    3 //
    4 //              DEPRECATED TEST
    5 //              DIFFERS BETWEEN DEBUG AND RELEASE
    6 //
    7 //----------------------------------------------------------------------------------------
    8 //----------------------------------------------------------------------------------------
    9 
    101#include <monitor>
    112
  • src/tests/sched-int-barge.c

    r6840e7c rb96ec83  
    1 //----------------------------------------------------------------------------------------
    2 //----------------------------------------------------------------------------------------
    3 //
    4 //              DEPRECATED TEST
    5 //
    6 //----------------------------------------------------------------------------------------
    7 //----------------------------------------------------------------------------------------
    8 
    91#include <fstream>
    102#include <kernel>
  • src/tests/sched-int-block.c

    r6840e7c rb96ec83  
    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 
    91#include <fstream>
    102#include <kernel>
  • src/tests/sched-int-wait.c

    r6840e7c rb96ec83  
    1 //---------------------------------------------------------
    2 // Multi wait test
    3 // Ensures that no deadlock from waiting/signalling conditions
    4 //---------------------------------------------------------
    5 
    6 
    71#include <fstream>
    82#include <kernel>
Note: See TracChangeset for help on using the changeset viewer.