Changes in / [1f44196:3a2128f]


Ignore:
Files:
5 added
22 deleted
70 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/concurrency/Makefile

    r1f44196 r3a2128f  
    99SOURCES = ${addsuffix .tex, \
    1010concurrency \
    11 style \
    12 glossary \
    1311}
    1412
  • doc/proposals/concurrency/concurrency.tex

    r1f44196 r3a2128f  
    1414
    1515% Latex packages used in the document.
    16 \usepackage[T1]{fontenc}                                        % allow Latin1 (extended ASCII) characters
     16\usepackage[T1]{fontenc}                                % allow Latin1 (extended ASCII) characters
    1717\usepackage{textcomp}
    1818\usepackage[latin1]{inputenc}
    1919\usepackage{fullpage,times,comment}
    2020\usepackage{epic,eepic}
    21 \usepackage{upquote}                                            % switch curled `'" to straight
     21\usepackage{upquote}                                                                    % switch curled `'" to straight
    2222\usepackage{calc}
    2323\usepackage{xspace}
     
    2525\usepackage{tabularx}
    2626\usepackage[acronym]{glossaries}
    27 \usepackage{varioref}                                           % extended references
     27\usepackage{varioref}                                                           % extended references
    2828\usepackage{inconsolata}
    29 \usepackage{listings}                                           % format program code
    30 \usepackage[flushmargin]{footmisc}                              % support label/reference in footnote
    31 \usepackage{latexsym}                                           % \Box glyph
    32 \usepackage{mathptmx}                                           % better math font with "times"
     29\usepackage{listings}                                                                   % format program code
     30\usepackage[flushmargin]{footmisc}                                              % support label/reference in footnote
     31\usepackage{latexsym}                                   % \Box glyph
     32\usepackage{mathptmx}                                   % better math font with "times"
    3333\usepackage[usenames]{color}
    3434\usepackage[pagewise]{lineno}
    3535\usepackage{fancyhdr}
    3636\renewcommand{\linenumberfont}{\scriptsize\sffamily}
    37 \input{style}                                                   % bespoke macros used in the document
     37\input{common}                                          % bespoke macros used in the document
    3838\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
    3939\usepackage{breakurl}
     
    4444\renewcommand{\UrlFont}{\small\sf}
    4545
    46 \setlength{\topmargin}{-0.45in}                         % move running title into header
     46\setlength{\topmargin}{-0.45in}                                                 % move running title into header
    4747\setlength{\headsep}{0.25in}
    4848
     
    8686\title{Concurrency in \CFA}
    8787\author{Thierry Delisle \\
    88 School of Computer Science, University of Waterloo, \\ Waterloo, Ontario, Canada
     88Dept. of Computer Science, University of Waterloo, \\ Waterloo, Ontario, Canada
    8989}
    9090
     
    100100
    101101\section{Introduction}
    102 This proposal provides a minimal core concurrency API that is both simple, efficient and can be reused to build higher-level features. The simplest possible concurrency core 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.
    103 
    104 There are actually two problems that need to be solved in the design of the concurrency for a programming language: which concurrency tools are available to the users and which parallelism tools are available. While these two concepts are often seen together, they are in fact distinct concepts that require different sorts of tools~\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization, while parallelism tools are more about performance, cost and resource utilization.
     102This proposal provides a minimal core concurrency API that is both simple, efficient and can be reused to build higher-level features. The simplest possible core 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 construct as the basis of the concurrency in \CFA.
     103Indeed, for highly productive parallel programming high-level approaches are much more popular\cite{HPP:Study}. Examples are task based parallelism, message passing, implicit threading.
     104
     105There are actually two problems that need to be solved in the design of the concurrency for a language. Which concurrency tools are available to the users and which parallelism tools are available. While these two concepts are often seen together, they are in fact distinct concepts that require different sorts of tools\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization while parallelism tools are more about performance, cost and resource utilization.
    105106
    106107%  #####  ####### #     #  #####  #     # ######  ######  ####### #     #  #####  #     #
     
    113114
    114115\section{Concurrency}
    115 Several tool can be used to solve concurrency challenges. Since these challenges always 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). Which in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. This distinction can be hidden away in library code, but effective use of the librairy still has to take both paradigms into account. Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and objects. At a lower level these can be implemented as locks and atomic operations. 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}. 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 add such a paradigm to a language like C or \CC\cit, which is why it was rejected as the core paradigm for concurrency in \CFA. 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.
     116% Several tool can be used to solve concurrency challenges. Since these challenges always 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 rely on message passing or other paradigms that often closely relate to networking concepts. However, in imperative or OO languages, these approaches entail a clear distinction between concurrent and non-concurrent paradigms (i.e. message passing versus routine call). Which in turns mean that programmers need to learn two sets of designs patterns in order to be effective. Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on non-concurrent constructs like routine calls and objects. At a lower level these can be implemented as locks and atomic operations. However, for productivity reasons it is desireable to have a higher-level construct to be the core concurrency paradigm\cite{HPP:Study}. This project proposes Monitors\cite{Hoare74} as the core concurrency construct.
     117% \\
     118
     119Several tool can be used to solve concurrency challenges. Since these challenges always 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 rely on message passing\cite{Thoth,Harmony,V-Kernel} or other paradigms that often closely relate to networking concepts. However, in imperative or OO languages, these approaches entail a clear distinction between concurrent and non-concurrent paradigms (i.e. message passing versus routine call). Which in turns mean that programmers need to learn two sets of designs patterns in order to be effective. Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on non-concurrent constructs like routine calls and objects. At a lower level these can be implemented as locks and atomic operations. 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 to be the core concurrency paradigm\cite{HPP:Study}. One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared memory systems, is the \emph{monitor}.
     120
     121Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}.
     122Many 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.
     123\\
     124
     125Finally, an approach that is worth mentionning because it is gaining in popularity is transactionnal memory\cite{Dice10}. However, the performance and feature set is currently too restrictive to be possible to add such a paradigm to a language like C or \CC\cit, which is why it was rejected as the core paradigm for concurrency in \CFA.
    116126
    117127% #     # ####### #     # ### ####### ####### ######   #####
     
    124134
    125135\subsection{Monitors}
    126 A monitor is a set of routines that ensure mutual exclusion when accessing shared state. This concept is generally associated with Object-Oriented Languages like Java~\cite{Java} or \uC~\cite{uC++book} but does not strictly require OOP semantics. The only requirements is the ability to declare a handle to a shared object and a set of routines that act on it :
     136A 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 OOP semantics. The only requirements is the ability to declare a handle to a shared object and a set of routines that act on it :
    127137\begin{lstlisting}
    128138        typedef /*some monitor type*/ monitor;
     
    144154
    145155\subsubsection{Call semantics} \label{call}
    146 The above monitor example displays some of the intrinsic characteristics. Indeed, it is necessary to use pass-by-reference over pass-by-value for monitor routines. This semantics is important because at their core, monitors are implicit mutual-exclusion objects (locks), and these objects cannot be copied. Therefore, monitors are implicitly non-copyable.
    147 
    148 Another aspect to consider is when a monitor acquires its mutual exclusion. For example, a monitor may need to be passed through multiple helper routines that do not acquire the monitor mutual-exclusion on entry. Pass through can be both generic helper routines (\code{swap}, \code{sort}, etc.) or specific helper routines like the following to implement an atomic counter :
    149 
    150 \begin{lstlisting}
    151         mutex struct counter_t { /*...see section §\ref{data}§...*/ };
    152 
    153         void ?{}(counter_t & nomutex this); //constructor
    154         size_t ++?(counter_t & mutex this); //increment
    155 
    156         //need for mutex is platform dependent here
    157         void ?{}(size_t * this, counter_t & mutex cnt); //conversion
    158 \end{lstlisting}
    159 
    160 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} key word depending on whether or not reading an \code{size_t} is an atomic operation or not.
    161 
    162 Having both \code{mutex} and \code{nomutex} keywords could be argued to be redundant based on the meaning of a routine having neither of these keywords. For example, given a routine without wualifiers \code{void foo(counter_t & this)} then one could argue that it should default to the safest option \code{mutex}. On the other hand, the option of having routine \code{void foo(counter_t & this)} mean \code{nomutex} is unsafe by default and may easily cause subtle errors. It can be argued that \code{nomutex} is the more "normal" behaviour, the \code{nomutex} keyword effectively stating explicitly that "this routine has nothing 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 routine \code{void foo(counter_t & this)}. Mandatory keywords would also have the added benefice of being self-documented but at the cost of extra typing. In the end, which solution should be picked is still up for debate. For the reminder of this proposal, the explicit approach is used for clarity.
    163 
    164 The next semantic decision is to establish when mutex/nomutex may be used as a type qualifier. Consider the following declarations:
     156The above example of monitors already displays some of their intrinsic caracteristics. Indeed, it is necessary to use pass-by-reference over pass-by-value for monitor routines. This semantics is important because at their core, monitors are implicit mutual exclusion objects (locks), and these objects cannot be copied. Therefore, monitors are implicitly non-copyable.
     157\\
     158
     159Another aspect to consider is when a monitor acquires its mutual exclusion. Indeed, a monitor may need to be passed through multiple helper routines that do not acquire the monitor mutual exclusion on entry. Examples of this can be both generic helper routines (\code{swap}, \code{sort}, etc.) or specific helper routines like the following example :
     160
     161\begin{lstlisting}
     162        mutex struct counter_t { /*...*/ };
     163
     164        void ?{}(counter_t & nomutex this);
     165        int ++?(counter_t & mutex this);
     166        void ?{}(Int * this, counter_t & mutex cnt);
     167\end{lstlisting}
     168*semantics of the declaration of \code{mutex struct counter_t} are discussed in details in section \ref{data}
     169\\
     170
     171This example is of a monitor implementing an atomic counter. Here, the constructor uses the \code{nomutex} keyword to signify that it does not acquire the coroutine mutual exclusion when constructing. This is because object not yet constructed should never be shared and therefore do not require mutual exclusion. The prefix increment operator
     172uses \code{mutex} to protect the incrementing process from race conditions. Finally, we have a conversion operator from \code{counter_t} to \code{Int}. This conversion may or may not require the \code{mutex} key word depending whether or not reading an \code{Int} is an atomic operation or not.
     173\\
     174
     175Having both \code{mutex} and \code{nomutex} keywords could be argued to be redundant based on the meaning of a routine having neither of these keywords. If there were a meaning to routine \code{void foo(counter_t & this)} then one could argue that it should be to default to the safest option : \code{mutex}. On the other hand, the option of having routine \code{void foo(counter_t & this)} mean \code{nomutex} is unsafe by default and may easily cause subtle errors. It can be argued that this is the more "normal" behavior, \code{nomutex} effectively stating explicitly that "this routine has nothing special". An other alternative is to make one of these keywords mandatory, which would provide the same semantics but without the ambiguity of supporting routine \code{void foo(counter_t & this)}. Mandatory keywords would also have the added benefice of being more clearly self-documented but at the cost of extra typing. In the end, which solution should be picked is still up for debate. For the reminder of this proposal, the explicit approach will be used for the sake of clarity.
     176\\
     177
     178Regardless of which keyword is kept, it is important to establish when mutex/nomutex may be used depending on type parameters.
    165179\begin{lstlisting}
    166180        int f1(monitor & mutex m);
     
    170184        int f5(graph(monitor*) & mutex m);
    171185\end{lstlisting}
    172 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 we only acquire objects once becomes also 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 (ignoring potential qualifiers and indirections). 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, it would also be reasonnable to disallow mutex in the context where arrays may be passed.
     186
     187The problem is to indentify which object(s) should be acquired. Furthermore we also need to acquire each objects only once. In case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entering. Adding indirections (\code{f3}) still allows the compiler and programmer to indentify which object will be acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths aren't necessarily known in C and even then making sure we only acquire objects once becomes also none trivial. This can be extended to absurd limits like \code{f5} which uses a custom 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 (ignoring potential qualifiers and indirections).
    173188
    174189% ######     #    #######    #
     
    181196
    182197\subsubsection{Data semantics} \label{data}
    183 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 contian 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}:
     198Once 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 contian shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appripriate protection. For example here is a more fleshed-out version of the counter showed in \ref{call}:
    184199\begin{lstlisting}
    185200        mutex struct counter_t {
     
    192207
    193208        int ++?(counter_t & mutex this) {
    194                 return ++this.value;
    195         }
    196 
    197         //need for mutex is platform dependent here
     209                return ++this->value;
     210        }
     211
    198212        void ?{}(int * this, counter_t & mutex cnt) {
    199213                *this = (int)cnt;
    200214        }
    201215\end{lstlisting}
    202 
    203 This simple counter is used as follows:
    204 \begin{center}
    205 \begin{tabular}{c @{\hskip 0.35in} c @{\hskip 0.35in} c}
    206 \begin{lstlisting}
    207         //shared counter
    208         counter_t cnt;
    209 
    210         //multiple threads access counter
    211         thread 1 : cnt++;
    212         thread 2 : cnt++;
    213         thread 3 : cnt++;
    214           ...
    215         thread N : cnt++;
     216\begin{tabular}{ c c }
     217Thread 1 & Thread 2 \\
     218\begin{lstlisting}
     219        void f(counter_t & mutex c) {
     220                for(;;) {
     221                        sout | (int)c | endl;
     222                }
     223        }
     224\end{lstlisting} &\begin{lstlisting}
     225        void g(counter_t & mutex c) {
     226                for(;;) {
     227                        ++c;
     228                }
     229        }
     230
    216231\end{lstlisting}
    217232\end{tabular}
    218 \end{center}
    219 
    220 Notice how the counter is used without any explicit synchronisation and yet supports thread-safe semantics for both reading and writting. Unlike object-oriented monitors, where calling a mutex member \emph{implicitly} acquires mutual-exclusion, \CFA uses an explicit mechanism to acquire mutual-exclusion. A consequence of this approach is that it extends to multi-monitor calls.
     233\\
     234
     235
     236This simple counter offers an example of monitor usage. Notice how the counter is used without any explicit synchronisation and yet supports thread-safe semantics for both reading and writting. \\
     237
     238These simple mutual exclusion semantics also naturally expand to multi-monitor calls.
    221239\begin{lstlisting}
    222240        int f(MonitorA & mutex a, MonitorB & mutex b);
     
    226244        f(a,b);
    227245\end{lstlisting}
    228 This code acquires both locks before entering the critical section, 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 :
    229 \begin{lstlisting}
    230         void foo(A & mutex a, B & mutex b) { //acquire a & b
     246
     247This code acquires both locks before entering the critical section. In practice, writing multi-locking routines that can not lead to deadlocks can be very tricky. Having language level support for such feature is therefore a significant asset for \CFA. However, this does have significant repercussions relating to scheduling (see \ref{insched} and \ref{extsched}). Furthermore, the ability to acquire multiple monitors at the same time does incur a significant pitfall even without looking into scheduling. For example :
     248\begin{lstlisting}
     249        void foo(A & mutex a, B & mutex a) {
    231250                //...
    232251        }
    233252
    234         void bar(A & mutex a, B & nomutex b) { //acquire a
     253        void bar(A & mutex a, B & nomutex a)
    235254                //...
    236                 foo(a, b); //acquire b
     255                foo(a, b);
    237256                //...
    238257        }
    239258
    240         void baz(A & nomutex a, B & mutex b) { //acquire b
     259        void baz(A & nomutex a, B & mutex a)
    241260                //...
    242                 foo(a, b); //acquire a
     261                foo(a, b);
    243262                //...
    244263        }
    245264\end{lstlisting}
    246265
    247 The multi-acquisition monitor lock allows a monitor lock to be acquired by both \code{bar} or \code{baz} and acquired again in \code{foo}. In the calls to \code{bar} and \code{baz} the monitors are acquired in opposite order. such use leads to nested monitor call problems~\cite{Lister77}, which is a specific implementation of 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 :
    248 \begin{enumerate}
    249         \item Dynamically tracking of the monitor-call order.
    250         \item Implement rollback semantics.
    251 \end{enumerate}
    252 
    253 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.
     266Recursive mutex routine calls are allowed in \CFA but if not done carefully it can lead to nested monitor call problems\cite{Lister77}. These problems which are a specific  implementation of the lock acquiring order problem. In the example above, the user uses implicit ordering in the case of function \code{bar} but explicit ordering in the case of \code{baz}. This subtle mistake can mean that calling these two functions concurrently will lead to deadlocks, depending on the implicit ordering matching the explicit ordering. As shown on several occasion\cit, there isn't really any solutions to this problem, users simply need to be carefull when acquiring multiple monitors at the same time.
    254267
    255268% ######  ####### #######    #    ### #        #####
     
    270283
    271284\subsubsection{Implementation Details: Interaction with polymorphism}
    272 At first glance, interaction between monitors and \CFA's concept of polymorphism seems complex to support. However, it is shown that entry-point locking can solve most of the issues.
    273 
    274 Before looking into complex control flow, it is important to present the difference between the two acquiring options : \gls{callsite-locking} and \gls{entry-point-locking}, i.e. acquiring the monitors before making a mutex call or as the first instruction of the mutex call. For example:
    275 
    276 \begin{center}
    277 \begin{tabular}{|c|c|c|}
    278 Code & \gls{callsite-locking} & \gls{entry-point-locking} \\
    279 \CFA & pseudo-code & pseudo-code \\
    280 \hline
    281 \begin{lstlisting}
    282 void foo(monitor & mutex a) {
    283 
    284 
    285 
    286         //Do Work
    287         //...
    288 
    289 }
    290 
    291 void main() {
    292         monitor a;
    293 
    294 
    295 
    296         foo(a);
    297 
    298 }
    299 \end{lstlisting} &\begin{lstlisting}
    300 foo(& a) {
    301 
    302 
    303 
    304         //Do Work
    305         //...
    306 
    307 }
    308 
    309 main() {
    310         monitor a;
    311         //calling routine
    312         //handles concurrency
    313         acquire(a);
    314         foo(a);
    315         release(a);
    316 }
    317 \end{lstlisting} &\begin{lstlisting}
    318 foo(& a) {
    319         //called routine
    320         //handles concurrency
    321         acquire(a);
    322         //Do Work
    323         //...
    324         release(a);
    325 }
    326 
    327 main() {
    328         monitor a;
    329 
    330 
    331 
    332         foo(a);
    333 
    334 }
    335 \end{lstlisting}
    336 \end{tabular}
    337 \end{center}
    338 
    339 First of all, interaction between \code{otype} polymorphism and monitors is impossible since monitors do not support copying. Therefore, the main question is how to support \code{dtype} polymorphism. Since a monitor's main purpose is to ensure mutual exclusion when accessing shared data, this implies that mutual exclusion is only required for routines that do in fact access shared data. However, since \code{dtype} polymorphism always handles incomplete types (by definition), no \code{dtype} polymorphic routine can access shared data since the data requires knowledge about the type. Therefore, the only concern when combining \code{dtype} polymorphism and monitors is to protect access to routines. \Gls{callsite-locking} would require a significant amount of work, 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.
    340 
    341 
     285At first glance, interaction between monitors and \CFA's concept of polymorphism seem complexe to support. However, it can be reasoned that entry-point locking can solve most of the issues that could be present with polymorphism.
     286
     287First 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. We must remember that monitors' 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 handle incomplete types (by definition) no \code{dtype} polymorphic routine can access shared data since the data would require knowledge about the type. Therefore the only concern when combining \code{dtype} polymorphism and monitors is to protect access to routines. With callsite-locking, this would require significant amount of work since any \code{dtype} routine could have to obtain some lock before calling a routine. However, with entry-point-locking calling a monitor routine becomes exactly the same as calling it from anywhere else.
    342288
    343289% ### #     # #######         #####   #####  #     # ####### ######
     
    350296
    351297\subsection{Internal scheduling} \label{insched}
    352 Monitors also need to schedule waiting threads internally as a mean of synchronization. Internal scheduling is one of the simple examples of such a feature. It allows users to declare condition variables and have threads wait and signaled from them. Here is a simple example of such a technique :
     298Monitors should also be able to schedule what threads access it as a mean of synchronization. Internal scheduling is one of the simple examples of such a feature. It allows users to declare condition variables and wait for them to be signaled. Here is a simple example of such a technique :
    353299
    354300\begin{lstlisting}
     
    368314\end{lstlisting}
    369315
    370 Note that 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. This semantic can easily be extended to multi-monitor calls by offering the same guarantee.
     316Here routine \code{foo} waits on the \code{signal} from \code{bar} before making further progress, effectively ensuring a basic ordering. This semantic can easily be extended to multi-monitor calls by offering the same guarantee.
     317
    371318\begin{center}
    372319\begin{tabular}{ c @{\hskip 0.65in} c }
     
    374321\begin{lstlisting}
    375322void foo(monitor & mutex a,
    376            monitor & mutex b) {
     323         monitor & mutex b) {
    377324        //...
    378325        wait(a.e);
     
    383330\end{lstlisting} &\begin{lstlisting}
    384331void bar(monitor & mutex a,
    385            monitor & mutex b) {
     332         monitor & mutex b) {
    386333        signal(a.e);
    387334}
     
    393340\end{tabular}
    394341\end{center}
    395 A direct extension of the single monitor semantics is to release all locks when waiting and transferring ownership of all locks when signalling. However, for the purpose of synchronization it may be usefull to only release some of the locks but keep others. It is possible to support internal scheduling and \gls{group-acquire} without any extra syntax by relying on order of acquisition. Here is an example of the different contexts in which internal scheduling can be used. (Note that here the use of helper routines is irrelevant, only routines acquire mutual exclusion have an impact on internal scheduling):
     342
     343A direct extension of the single monitor semantics would be to release all locks when waiting and transferring ownership of all locks when signalling. However, for the purpose of synchronization it may be usefull to only release some of the locks but keep others. On the technical side, partially releasing lock is feasible but from the user perspective a choice must be made for the syntax of this feature. It is possible to do without any extra syntax by relying on order of acquisition (Note that here the use of helper routines is irrelevant, only routines the acquire mutual exclusion have an impact on internal scheduling):
    396344
    397345\begin{center}
     
    402350condition e;
    403351
    404 //acquire a & b
    405352void foo(monitor & mutex a,
    406            monitor & mutex b) {
    407 
    408         wait(e); //release a & b
     353         monitor & mutex b) {
     354        wait(e);
    409355}
    410356
     
    418364condition e;
    419365
    420 //acquire a
    421366void bar(monitor & mutex a,
    422            monitor & nomutex b) {
     367         monitor & nomutex b) {
    423368        foo(a,b);
    424369}
    425370
    426 //acquire a & b
    427371void foo(monitor & mutex a,
    428            monitor & mutex b) {
    429         wait(e);  //release a & b
     372         monitor & mutex b) {
     373        wait(e);
    430374}
    431375
     
    434378condition e;
    435379
    436 //acquire a
    437380void bar(monitor & mutex a,
    438            monitor & nomutex b) {
    439         baz(a,b);
    440 }
    441 
    442 //acquire b
     381         monitor & nomutex b) {
     382        foo(a,b);
     383}
     384
    443385void baz(monitor & nomutex a,
    444            monitor & mutex b) {
    445         wait(e);  //release b
     386         monitor & mutex b) {
     387        wait(e);
    446388}
    447389
     
    451393\end{center}
    452394
    453 Context 1 is the simplest way of acquiring more than one monitor (\gls{group-acquire}), using a routine with multiple parameters having the \code{mutex} keyword. Context 2 also uses \gls{group-acquire} as well in routine \code{foo}. However, the routine is called by routine \code{bar}, which only acquires monitor \code{a}. Since monitors can be acquired multiple times this does not cause a deadlock by itself but it does force the acquiring order to \code{a} then \code{b}. Context 3 also forces the acquiring order to be \code{a} then \code{b} but does not use \gls{group-acquire}. The previous example tries to illustrate the semantics that must be established to support releasing monitors in a \code{wait} statement. In all cases, the behavior of the wait statment is to release all the locks that were acquired my the inner-most monitor call. That is \code{a & b} in context 1 and 2 and \code{b} only in context 3. Here are a few other examples of this behavior.
    454 
     395This can be interpreted in two different ways :
     396\begin{flushleft}
     397\begin{enumerate}
     398        \item \code{wait} atomically releases the monitors acquired by the inner-most routine, \underline{ignoring} nested calls.
     399        \item \code{wait} atomically releases the monitors acquired by the inner-most routine, \underline{considering} nested calls.
     400\end{enumerate}
     401\end{flushleft}
     402While the difference between these two is subtle, it has a significant impact. In the first case it means that the calls to \code{foo} would behave the same in Context 1 and 2. This semantic would also mean that the call to \code{wait} in routine \code{baz} would only release \code{monitor b}. While this may seem intuitive with these examples, it does have one significant implication, it creates a strong distinction between acquiring multiple monitors in sequence and acquiring the same monitors simulatenously, i.e. :
     403
     404\begin{center}
     405\begin{tabular}{c @{\hskip 0.35in} c @{\hskip 0.35in} c}
     406\begin{lstlisting}
     407enterMonitor(a);
     408enterMonitor(b);
     409// do stuff
     410leaveMonitor(b);
     411leaveMonitor(a);
     412\end{lstlisting} & != &\begin{lstlisting}
     413enterMonitor(a);
     414enterMonitor(a, b);
     415// do stuff
     416leaveMonitor(a, b);
     417leaveMonitor(a);
     418\end{lstlisting}
     419\end{tabular}
     420\end{center}
     421
     422This is not intuitive because even if both methods display the same monitors state both inside and outside the critical section respectively, the behavior is different. Furthermore, the actual acquiring order will be exaclty the same since acquiring a monitor from inside its mutual exclusion is a no-op. This means that even if the data and the actual control flow are the same using both methods, the behavior of the \code{wait} will be different. The alternative is option 2, that is releasing acquired monitors, \underline{considering} nesting. This solves the issue of having the two acquiring method differ at the cost of making routine \code{foo} behave differently depending on from which context it is called (Context 1 or 2). Indeed in Context 2, routine \code{foo} actually behaves like routine \code{baz} rather than having the same behavior than in Context 1. The fact that both implicit approaches can be unintuitive depending on the perspective may be a sign that the explicit approach is superior. For this reason this \CFA does not support implicit monitor releasing and uses explicit semantics.
     423\\
     424
     425The following examples shows three alternatives of explicit wait semantics :
     426\\
    455427
    456428\begin{center}
    457429\begin{tabular}{|c|c|c|}
    458 \begin{lstlisting}
    459 condition e;
    460 
    461 //acquire b
    462 void foo(monitor & nomutex a,
    463            monitor & mutex b) {
    464         bar(a,b);
    465 }
    466 
    467 //acquire a
    468 void bar(monitor & mutex a,
    469            monitor & nomutex b) {
    470 
    471         wait(e); //release a
    472                   //keep b
    473 }
    474 
    475 foo(a, b);
     430Case 1 & Case 2 & Case 3 \\
     431Branding on construction & Explicit release list & Explicit ignore list \\
     432\hline
     433\begin{lstlisting}
     434void foo(monitor & mutex a,
     435         monitor & mutex b,
     436           condition & c)
     437{
     438        // Releases monitors
     439        // branded in ctor
     440        wait(c);
     441}
     442
     443monitor a;
     444monitor b;
     445condition1 c1 = {a};
     446condition2 c2 = {a, b};
     447
     448//Will release only a
     449foo(a,b,c1);
     450
     451//Will release a and b
     452foo(a,b,c2);
    476453\end{lstlisting} &\begin{lstlisting}
    477 condition e;
    478 
    479 //acquire a & b
    480454void foo(monitor & mutex a,
    481            monitor & mutex b) {
    482         bar(a,b);
    483 }
    484 
    485 //acquire b
    486 void bar(monitor & mutex a,
    487            monitor & nomutex b) {
    488 
    489         wait(e); //release b
    490                   //keep a
    491 }
    492 
    493 foo(a, b);
     455         monitor & mutex b,
     456           condition & c)
     457{
     458        // Releases monitor a
     459        // Holds monitor b
     460        waitRelease(c, [a]);
     461}
     462
     463monitor a;
     464monitor b;
     465condition c;
     466
     467
     468
     469foo(a,b,c);
     470
     471
     472
    494473\end{lstlisting} &\begin{lstlisting}
    495 condition e;
    496 
    497 //acquire a & b
    498474void foo(monitor & mutex a,
    499            monitor & mutex b) {
    500         bar(a,b);
    501 }
    502 
    503 //acquire none
    504 void bar(monitor & nomutex a,
    505            monitor & nomutex b) {
    506 
    507         wait(e); //release a & b
    508                   //keep none
    509 }
    510 
    511 foo(a, b);
     475         monitor & mutex b,
     476           condition & c)
     477{
     478        // Releases monitor a
     479        // Holds monitor b
     480        waitHold(c, [b]);
     481}
     482
     483monitor a;
     484monitor b;
     485condition c;
     486
     487
     488
     489foo(a,b,c);
     490
     491
     492
    512493\end{lstlisting}
    513494\end{tabular}
    514495\end{center}
    515 Note the right-most example is actually a trick pulled on the reader. Monitor state information is stored in thread local storage rather then in the routine context, which means that helper routines and other \code{nomutex} routines are invisible to the runtime system in regards to concurrency. This means that in the right-most example, the routine parameters are completly unnecessary. However, calling this routine from outside a valid monitor context is undefined.
    516 
    517 These semantics imply that in order to release of subset of the monitors currently held, users must write (and name) a routine that only acquires the desired subset and simply calls wait. While users can use this method, \CFA offers the \code{wait_release}\footnote{Not sure if an overload of \code{wait} would work...} which will release only the specified monitors. In the center previous examples, the code in the center uses the \code{bar} routine to only release monitor \code{b}. Using the \code{wait_release} helper, this can be rewritten without having the name two routines :
    518 \begin{center}
    519 \begin{tabular}{ c c c }
    520 \begin{lstlisting}
    521         condition e;
    522 
    523         //acquire a & b
    524         void foo(monitor & mutex a,
    525                    monitor & mutex b) {
    526                 bar(a,b);
    527         }
    528 
    529         //acquire b
    530         void bar(monitor & mutex a,
    531                    monitor & nomutex b) {
    532 
    533                 wait(e); //release b
    534                           //keep a
    535         }
    536 
    537         foo(a, b);
    538 \end{lstlisting} &\begin{lstlisting}
    539         =>
    540 \end{lstlisting} &\begin{lstlisting}
    541         condition e;
    542 
    543         //acquire a & b
    544         void foo(monitor & mutex a,
    545                    monitor & mutex b) {
    546                 wait_release(e,b); //release b
    547                                          //keep a
    548         }
    549 
    550         foo(a, b);
    551 \end{lstlisting}
    552 \end{tabular}
    553 \end{center}
    554 
    555 Regardless of the context in which the \code{wait} statement is used, \code{signal} must be called holding the same set of monitors. In all cases, signal only needs a single parameter, the condition variable that needs to be signalled. But \code{signal} needs to be called from the same monitor(s) that call to \code{wait}. Otherwise, mutual exclusion cannot be properly transferred back to the waiting monitor.
    556 
    557 Finally, an additional semantic which can be very usefull is the \code{signal_block} routine. This routine behaves like signal for all of the semantics discussed above, but with the subtelty that mutual exclusion is transferred to the waiting task immediately rather than wating for the end of the critical section.
     496(Note : Case 2 and 3 use tuple semantics to pass a variable length list of elements.)
     497\\
     498
     499All these cases have their pros and cons. Case 1 is more distinct because it means programmers need to be carefull about where the condition is initialized as well as where it is used. On the other hand, it is very clear and explicitly states which monitor is released and which monitor stays acquired. This is similar to Case 2, which releases only the monitors explictly listed. However, in Case 2, calling the \code{wait} routine instead of the \code{waitRelease} routine releases all the acquired monitor. The Case 3 is an improvement on that since it releases all the monitors except those specified. The result is that the \code{wait} routine can be written as follows :
     500\begin{lstlisting}
     501void wait(condition & cond) {
     502        waitHold(cond, []);
     503}
     504\end{lstlisting}
     505This alternative offers nice and consistent behavior between \code{wait} and \code{waitHold}. However, one large pitfall is that mutual exclusion can now be violated by calls to library code. Indeed, even if the following example seems benign there is one significant problem :
     506\begin{lstlisting}
     507monitor global;
     508
     509extern void doStuff(); //uses global
     510
     511void foo(monitor & mutex m) {
     512        //...
     513        doStuff(); //warning can release monitor m
     514        //...
     515}
     516
     517foo(global);
     518\end{lstlisting}
     519
     520Indeed, if Case 2 or 3 are chosen it any code can violate the mutual exclusion of the calling code by issuing calls to \code{wait} or \code{waitHold} in a nested monitor context. Case 2 can be salvaged by removing the \code{wait} routine from the API but Case 3 cannot prevent users from calling \code{waitHold(someCondition, [])}. For this reason the syntax proposed in Case 3 is rejected. Note that the syntax proposed in case 1 and 2 are not exclusive. Indeed, by supporting two types of condition both cases can be supported :
     521\begin{lstlisting}
     522struct condition { /*...*/ };
     523
     524// Second argument is a variable length tuple.
     525void wait(condition & cond, [...] monitorsToRelease);
     526void signal(condition & cond);
     527
     528struct conditionN { /*...*/ };
     529
     530void ?{}(conditionN* this, /*list of N monitors to release*/);
     531void wait(conditionN & cond);
     532void signal(conditionN & cond);
     533\end{lstlisting}
     534
     535Regardless of the option chosen for wait semantics, signal must be symmetrical. In all cases, signal only needs a single parameter, the condition variable that needs to be signalled. But \code{signal} needs to be called from the same monitor(s) that call to \code{wait}. Otherwise, mutual exclusion cannot be properly transferred back to the waiting monitor.
     536
     537Finally, an additionnal semantic which can be very usefull is the \code{signalBlock} routine. This routine behaves like signal for all of the semantics discussed above, but with the subtelty that mutual exclusion is transferred to the waiting task immediately rather than wating for the end of the critical section.
    558538\\
    559539
     
    565545% #        #   #     #    ###    #     # #     # #     # #       #     #
    566546% ####### #     #    #    ###     #####   #####  #     # ####### ######
    567 \newpage
     547
    568548\subsection{External scheduling} \label{extsched}
    569 An alternative to internal scheduling is to use external scheduling instead. This method is more constrained and explicit which may help users tone down the undeterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occuring. External scheduling can generally be done either in terms of control flow (ex: \uC) or in terms of data (ex: Go). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control flow semantics where 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 following example shows a simple use \code{accept} versus \code{wait}/\code{signal} and its advantages.
     549As one might expect, the alternative to Internal scheduling is to use External scheduling instead. This method is somewhat more robust to deadlocks since one of the threads keeps a relatively tight control on scheduling. Indeed, as the following examples will demonstrate, 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 (ex: \uC) or in terms of data (ex: Go). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control flow semantics where 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 following example shows what a simple use \code{accept} versus \code{wait}/\code{signal} and its advantages.
    570550
    571551\begin{center}
     
    585565
    586566        public:
    587                 void f() { /*...*/ }
     567                void f();
    588568                void g() { _Accept(f); }
    589569        private:
     
    593573\end{center}
    594574
    595 In the case of internal scheduling, the call to \code{wait} only guarantees that \code{g} is the last routine to access the monitor. This intails that the routine \code{f} may have acquired mutual exclusion several times while routine \code{h} was waiting. On the other hand, external scheduling guarantees that while routine \code{h} was waiting, no routine other than \code{g} could acquire the monitor.
     575In the case of internal scheduling, the call to \code{wait} only guarantees that \code{g} was the last routine to access the monitor. This intails that the routine \code{f} may have acquired mutual exclusion several times while routine \code{h} was waiting. On the other hand, external scheduling guarantees that while routine \code{h} was waiting, no routine other than \code{g} could acquire the monitor.
    596576\\
    597577
     
    776756% #       #     # #     # #     # ####### ####### ####### ####### ###  #####  #     #
    777757\section{Parallelism}
    778 Historically, computer performance was about processor speeds and instructions count. However, with heat dissipation being a direct consequence of speed increase, parallelism has become the new source for increased performance~\cite{Sutter05, Sutter05b}. In this decade, it is not longer reasonnable to create a high-performance application without caring about parallelism. Indeed, parallelism is an important aspect of performance and more specifically throughput and hardware utilization. The lowest-level approach of parallelism is to use \glspl{kthread} in combination with semantics like \code{fork}, \code{join}, etc. However, since these have significant costs and limitations, \glspl{kthread} are now mostly used as an implementation tool rather than a user oriented one. There are several alternatives to solve these issues that all have strengths and weaknesses. While there are many variations of the presented paradigms, most of these variations do not actually change the guarantees or the semantics, they simply move costs in order to achieve better performance for certain workloads.
     758Historically, computer performance was about processor speeds and instructions count. However, with heat dissipation being an ever growing challenge, parallelism has become the new source of greatest performance \cite{Sutter05, Sutter05b}. In this decade, it is not longer reasonnable to create high-performance application without caring about parallelism. Indeed, parallelism is an important aspect of performance and more specifically throughput and hardware utilization. The lowest level approach of parallelism is to use \glspl{kthread}. However since these have significant costs and limitations \glspl{kthread} are now mostly used as an implementation tool rather than a user oriented one. There are several alternatives to solve these issues which all have strengths and weaknesses.
    779759
    780760\subsection{User-level threads}
    781 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 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.
    782 
    783 Examples of languages that support \glspl{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
    784 
    785 \subsubsection{Fibers : user-level threads without preemption}
    786 A 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.
    787 
    788 An example of a language that uses fibers is Go~\cite{Go}
     761A 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 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 complexities are hidden, users still have to think about data races, deadlocks and synchronization issues. This can be somewhat alleviated by a concurrency toolkit with strong garantees but the parallelism toolkit offers very little to reduce complexity in itself.
     762
     763Examples of languages that support are Java\cite{Java}, Haskell\cite{Haskell} and \uC\cite{uC++book}.
    789764
    790765\subsection{Jobs and thread pools}
    791 The approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly 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.
    792 
    793 The gold standard of this implementation is Intel's TBB library~\cite{TBB}.
     766The approach on the opposite end of the spectrum is to base parallelism on \glspl{job}. Indeed, \glspl{job} offer limited flexibility but at the benefit of a simpler user interface. In \gls{job} based systems users express parallelism as units of work and the dependency graph (either explicit or implicit) that tie them together. This means users need not to worry about concurrency but significantly limits the interaction that can occur between different jobs. Indeed, any \gls{job} that blocks also blocks the underlying \gls{kthread}, this effectively mean the CPU utilization, and therefore throughput, will suffer noticeably.
     767The golden standard of this implementation is Intel's TBB library\cite{TBB}.
     768
     769\subsection{Fibers : user-level threads without preemption}
     770Finally, in the middle of the flexibility versus complexity spectrum lay \glspl{fiber} which offer \glspl{uthread} without the complexity of preemption. This means users don't have to worry about other \glspl{fiber} suddenly executing between two instructions which signficantly reduces complexity. However, any call to IO or other concurrency primitives can lead to context switches. Furthermore, users can also block \glspl{fiber} in the middle of their execution without blocking a full processor core. This means users still have to worry about mutual exclusion, deadlocks and race conditions in their code, raising the complexity significantly.
     771An example of a language that uses fibers is Go\cite{Go}
    794772
    795773\subsection{Paradigm performance}
    796 While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pindown the performance implications of chosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantess that the \gls{pool} based system has the best performance thanks to the lower memory overhead. However, interactions between jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilisation, but context switches will be more expansive and the extra control means users need to tweak more variables to get the desired performance. Furthermore, if the units of uninterrupted work are large enough the paradigm choice is largely amorticised by the actual work done.
     774While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pin the performance implications of chosing a model at the language level. Indeed, in many situations one of these paradigms will show better performance but it all strongly depends on the usage. Having mostly indepent units of work to execute almost guarantess that the \gls{job} based system will have the best performance. However, add interactions between jobs and the processor utilisation might suffer. User-level threads may allow maximum ressource utilisation but context switches will be more expansive and it is also harder for users to get perfect tunning. As with every example, fibers sit somewhat in the middle of the spectrum. Furthermore, if the units of uninterrupted work are large enough the paradigm choice will be largely amorticised by the actual work done.
    797775
    798776%  #####  #######    #          ####### ######  ######
     
    805783
    806784\section{\CFA 's Thread Building Blocks}
    807 As a system-level language, \CFA should offer both performance and flexibilty as its primary goals, simplicity and user-friendliness being a secondary concern. Therefore, the core of parallelism in \CFA should prioritize power and efficiency. With this said, deconstructing popular paradigms in order to get simple building blocks yields \glspl{uthread} as the core parallelism block. \Glspl{pool} and other parallelism paradigms can then be built on top of the underlying threading model.
     785As a system level language, \CFA should offer both performance and flexibilty as its primary goals, simplicity and user-friendliness being a secondary concern. Therefore, the core of parallelism in \CFA should prioritize power and efficiency. With this said, it is possible to deconstruct the three paradigms details aboved in order to get simple building blocks. Here is a table showing the core caracteristics of the mentionned paradigms :
     786\begin{center}
     787\begin{tabular}[t]{| r | c | c |}
     788\cline{2-3}
     789\multicolumn{1}{ c| }{} & Has a stack & Preemptive \\
     790\hline
     791\Glspl{job} & X & X \\
     792\hline
     793\Glspl{fiber} & \checkmark & X \\
     794\hline
     795\Glspl{uthread} & \checkmark & \checkmark \\
     796\hline
     797\end{tabular}
     798\end{center}
     799
     800As shown in section \ref{cfaparadigms} these different blocks being available in \CFA it is trivial to reproduce any of these paradigm.
    808801
    809802% ####### #     # ######  #######    #    ######   #####
     
    816809
    817810\subsection{Thread Interface}
    818 The basic building blocks of \CFA are \glspl{cfathread}. By default these are implemented as \glspl{uthread}, and as such, offer a flexible and lightweight threading interface (lightweight compared to \glspl{kthread}). A thread can be declared using a struct declaration with prefix \code{thread} as follows :
     811The basic building blocks of \CFA are \glspl{cfathread}. By default these are implemented as \glspl{uthread} and as such offer a flexible and lightweight threading interface (lightweight comparatievely to \glspl{kthread}). A thread can be declared using a struct declaration prefix with the \code{thread} as follows :
    819812
    820813\begin{lstlisting}
     
    822815\end{lstlisting}
    823816
    824 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), the existing syntax for declaring routines names with special semantics can be extended, i.e. operator overloading. As such the \code{main} routine of a thread can be defined as :
     817Obviously, for this thread implementation to be usefull it must run some user code. Several other threading interfaces use some function pointer representation as the interface of threads (for example : \Csharp \cite{Csharp} and Scala \cite{Scala}). However, we consider that statically tying a \code{main} routine to a thread superseeds this approach. Since the \code{main} routine is definetely a special routine in \CFA, we can reuse the existing syntax for declaring routines with unordinary name, i.e. operator overloading. As such the \code{main} routine of a thread can be defined as such :
    825818\begin{lstlisting}
    826819        thread struct foo {};
    827820
    828         void ?main(foo* this) {
    829                 sout | "Hello World!" | endl;
    830         }
    831 \end{lstlisting}
    832 
    833 In this example, threads of type \code{foo} will start there execution in the \code{void ?main(foo*)} routine which in this case prints \code{"Hello World!"}. While this proposoal encourages this approach which is enforces strongly type 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 :
     821        void ?main(thread foo* this) {
     822                /*... Some useful code ...*/
     823        }
     824\end{lstlisting}
     825
     826With these semantics it is trivial to write a thread type that takes a function pointer as parameter and executes it on its stack asynchronously :
    834827\begin{lstlisting}
    835828        typedef void (*voidFunc)(void);
     
    840833
    841834        //ctor
    842         void ?{}(FuncRunner* this, voidFunc inFunc) {
     835        void ?{}(thread FuncRunner* this, voidFunc inFunc) {
    843836                func = inFunc;
    844837        }
    845838
    846839        //main
    847         void ?main(FuncRunner* this) {
     840        void ?main(thread FuncRunner* this) {
    848841                this->func();
    849842        }
    850843\end{lstlisting}
    851844
    852 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} once the constructor has completed and \code{join} before the destructor runs.
    853 \begin{lstlisting}
    854 thread struct World; //FuncRunner declared above
    855 
    856 void ?main(thread World* this) {
     845% In this example \code{func} is a function pointer stored in \acrfull{tls}, which is \CFA is both easy to use and completly typesafe.
     846
     847Of 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 not needed. 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.
     848\begin{lstlisting}
     849thread struct FuncRunner; //FuncRunner declared above
     850
     851void world() {
    857852        sout | "World!" | endl;
    858853}
    859854
    860855void main() {
    861         World w;
     856        FuncRunner run = {world};
    862857        //Thread run forks here
    863858
     
    868863}
    869864\end{lstlisting}
    870 This semantic has several advantages over explicit semantics : typesafety is guaranteed, a thread is always started and stopped exaclty once and users cannot make any progamming errors. However, one of the apparent drawbacks of this system is that threads now always form a lattice, that is they are always destroyed in opposite order of construction. While this seems like a significant limitation, existing \CFA semantics can solve this problem. Indeed, by using dynamic allocation to create threads will naturally let threads outlive the scope in which the thread was created much like dynamically allocating memory will let objects outlive the scope in which thy were created :
    871 
     865This semantic has several advantages over explicit semantics : typesafety is guaranteed, any thread will always be started and stopped exaclty once and users can't make any progamming errors. Furthermore it naturally follows the memory allocation semantics which means users don't need to learn multiple semantics.
     866
     867These semantics also naturally scale to multiple threads meaning basic synchronisation is very simple :
    872868\begin{lstlisting}
    873869        thread struct MyThread {
     
    876872
    877873        //ctor
    878         void ?{}(MyThread* this,
    879                      bool is_special = false) {
    880                 //...
    881         }
     874        void ?{}(thread MyThread* this) {}
    882875
    883876        //main
    884         void ?main(MyThread* this) {
    885                 //...
    886         }
    887 
    888         void foo() {
    889                 MyThread* special_thread;
    890                 {
    891                         MyThread thrds = {false};
    892                         //Start a thread at the beginning of the scope
    893 
    894                         DoStuff();
    895 
    896                         //create a other thread that will outlive the thread in this scope
    897                         special_thread = new MyThread{true};
    898 
    899                         //Wait for the thread to finish
    900                 }
    901                 DoMoreStuff();
    902 
    903                 //Now wait for the special
    904         }
    905 \end{lstlisting}
    906 
    907 Another advantage of this semantic is that it naturally scale to multiple threads meaning basic synchronisation is very simple :
    908 
    909 \begin{lstlisting}
    910         thread struct MyThread {
    911                 //...
    912         };
    913 
    914         //ctor
    915         void ?{}(MyThread* this) {}
    916 
    917         //main
    918         void ?main(MyThread* this) {
     877        void ?main(thread MyThread* this) {
    919878                //...
    920879        }
     
    930889\end{lstlisting}
    931890
    932 \subsection{Coroutines : A stepping stone}\label{coroutine}
    933 While the main focus of this proposal is concurrency and paralellism, it is important to adress coroutines which are actually a significant underlying aspect of the concurrency system. Indeed, while having nothing todo with parallelism and arguably very little to do with concurrency, coroutines need to deal with context-switchs and 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.
    934 
    935 The core API of coroutines revolve around two features : independent stacks and suspedn/resume. Much like threads the syntax for declaring a coroutine is declaring a type and a main routine for it to start :
    936 \begin{lstlisting}
    937         coroutine struct MyCoroutine {
    938                 //...
    939         };
    940 
    941         //ctor
    942         void ?{}(MyCoroutine* this) {
    943 
    944         }
    945 
    946         //main
    947         void ?main(MyCoroutine* this) {
    948                 sout | "Hello World!" | endl;
    949         }
    950 \end{lstlisting}
    951 
    952 One a coroutine is created, users can context switch to it using \code{suspend} and come back using \code{resume}. Here is an example of a solution to the fibonnaci problem using coroutines :
    953 \begin{lstlisting}
    954         coroutine struct Fibonacci {
    955                 int fn; // used for communication
    956         };
    957 
    958         void ?main(Fibonacci* this) {
    959                 int fn1, fn2;           // retained between resumes
    960                 this->fn = 0;
    961                 fn1 = this->fn;
    962                 suspend(this);          // return to last resume
    963 
    964                 this->fn = 1;
    965                 fn2 = fn1;
    966                 fn1 = this->fn;
    967                 suspend(this);          // return to last resume
    968 
    969                 for ( ;; ) {
    970                         this->fn = fn1 + fn2;
    971                         fn2 = fn1;
    972                         fn1 = this->fn;
    973                         suspend(this);  // return to last resume
    974                 }
    975         }
    976 
    977         int next(Fibonacci& this) {
    978                 resume(&this); // transfer to last suspend
    979                 return this.fn;
    980         }
    981 
    982         void main() {
    983                 Fibonacci f1, f2;
    984                 for ( int i = 1; i <= 10; i += 1 ) {
    985                         sout | next(f1) | '§\verb+ +§' | next(f2) | endl;
    986                 }
    987         }
    988 \end{lstlisting}
    989 
    990891\newpage
    991 \bf{WORK IN PROGRESS}
     892\large{\textbf{WORK IN PROGRESS}}
    992893\subsection{The \CFA Kernel : Processors, Clusters and Threads}\label{kernel}
    993894
  • doc/proposals/concurrency/glossary.tex

    r1f44196 r3a2128f  
    11\makeglossaries
    2 
    3 \longnewglossaryentry{callsite-locking}
    4 {name={callsite-locking}}
    5 {
    6 Locking done by the calling routine. With this technique, a routine calling a monitor routine will aquire the monitor \emph{before} making the call to the actuall routine.
    7 }
    8 
    9 \longnewglossaryentry{entry-point-locking}
    10 {name={entry-point-locking}}
    11 {
    12 Locking done by the called routine. With this technique, a monitor routine called by another routine will aquire the monitor \emph{after} entering the routine body but prior to any other code.
    13 }
    14 
    15 \longnewglossaryentry{group-acquire}
    16 {name={bulked acquiring}}
    17 {
    18 Implicitly acquiring several monitors when entering a monitor.
    19 }
    20 
    21 
    222\longnewglossaryentry{uthread}
    233{name={user-level thread}}
     
    5030
    5131\textit{Synonyms : Tasks.}
    52 }
    53 
    54 \longnewglossaryentry{pool}
    55 {name={thread-pool}}
    56 {
    57 Group of homogeneuous threads that loop executing units of works after another.
    58 
    59 \textit{Synonyms : }
    6032}
    6133
  • doc/proposals/concurrency/version

    r1f44196 r3a2128f  
    1 0.7.48
     10.4.99
  • doc/working/resolver_design.md

    r1f44196 r3a2128f  
    13821382hypothesis needs to be empirically validated.
    13831383
    1384 Another approach would be to abandon expression-tree ordering for
    1385 subexpression matching, and order by "most constrained symbol"; symbols would 
    1386 be more constrained if there were fewer matching declarations, fewer
    1387 subexpressions yet to resolve, or possibly fewer possible types the expression
    1388 could resolve to. Ordering the expressions in a priority-queue by this metric
    1389 would not necessarily produce a top-down or a bottom-up order, but would add
    1390 opportunities for pruning based on memoized upper and lower bounds.
    1391 
    13921384Both Baker and Cormack explicitly generate all possible interpretations of a
    13931385given expression; thinking of the set of interpretations of an expression as a
  • src/CodeGen/CodeGenerator.cc

    r1f44196 r3a2128f  
    307307                                                } else {
    308308                                                        // no address-of operator, so must be a pointer - add dereference
    309                                                         // NOTE: if the assertion starts to trigger, check that the application expr isn't being shared.
    310                                                         // Since its arguments are modified here, this assertion most commonly triggers when the application
    311                                                         // is visited multiple times.
    312309                                                        UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    313310                                                        newExpr->get_args().push_back( *arg );
    314                                                         Type * type = InitTweak::getPointerBase( (*arg)->get_result() );
    315                                                         assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." );
    316                                                         newExpr->set_result( type->clone() );
     311                                                        assert( (*arg)->get_results().size() == 1 );
     312                                                        Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() );
     313                                                        assert( type );
     314                                                        newExpr->get_results().push_back( type->clone() );
    317315                                                        *arg = newExpr;
    318316                                                } // if
     
    529527                extension( castExpr );
    530528                output << "(";
    531                 if ( castExpr->get_result()->isVoid() ) {
     529                if ( castExpr->get_results().empty() ) {
    532530                        output << "(void)" ;
    533                 } else if ( ! castExpr->get_result()->get_isLvalue() ) {
     531                } else if ( ! castExpr->get_results().front()->get_isLvalue() ) {
    534532                        // at least one result type of cast, but not an lvalue
    535533                        output << "(";
    536                         output << genType( castExpr->get_result(), "" );
     534                        output << genType( castExpr->get_results().front(), "" );
    537535                        output << ")";
    538536                } else {
     
    642640        }
    643641
    644         void CodeGenerator::visit( TupleExpr * tupleExpr ) { assert( false ); }
     642        void CodeGenerator::visit( TupleExpr * tupleExpr ) {}
    645643
    646644        void CodeGenerator::visit( TypeExpr * typeExpr ) {}
     
    656654                asmExpr->get_operand()->accept( *this );
    657655                output << " )";
    658         }
    659 
    660         void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
    661                 assert( compLitExpr->get_type() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    662                 output << "(" << genType( compLitExpr->get_type(), "" ) << ")";
    663                 compLitExpr->get_initializer()->accept( *this );
    664         }
    665 
    666         void CodeGenerator::visit( StmtExpr * stmtExpr ) {
    667                 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    668                 output << "({" << std::endl;
    669                 cur_indent += CodeGenerator::tabsize;
    670                 unsigned int numStmts = stmts.size();
    671                 unsigned int i = 0;
    672                 for ( Statement * stmt : stmts ) {
    673                         output << indent << printLabels( stmt->get_labels() );
    674                         if ( i+1 == numStmts ) {
    675                                 // last statement in a statement expression needs to be handled specially -
    676                                 // cannot cast to void, otherwise the expression statement has no value
    677                                 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    678                                         exprStmt->get_expr()->accept( *this );
    679                                         output << ";" << endl;
    680                                         ++i;
    681                                         break;
    682                                 }
    683                         }
    684                         stmt->accept( *this );
    685                         output << endl;
    686                         if ( wantSpacing( stmt ) ) {
    687                                 output << endl;
    688                         } // if
    689                         ++i;
    690                 }
    691                 cur_indent -= CodeGenerator::tabsize;
    692                 output << indent << "})";
    693656        }
    694657
  • src/CodeGen/CodeGenerator.h

    r1f44196 r3a2128f  
    7070                virtual void visit( ConditionalExpr *conditionalExpr );
    7171                virtual void visit( CommaExpr *commaExpr );
    72                 virtual void visit( CompoundLiteralExpr *compLitExpr );
    7372                virtual void visit( TupleExpr *tupleExpr );
    7473                virtual void visit( TypeExpr *typeExpr );
    7574                virtual void visit( AsmExpr * );
    76                 virtual void visit( StmtExpr * );
    7775
    7876                //*** Statements
  • src/CodeGen/GenType.cc

    r1f44196 r3a2128f  
    227227                        typeString = "_Atomic " + typeString;
    228228                } // if
     229                if ( type->get_isAttribute() ) {
     230                        typeString = "__attribute(( )) " + typeString;
     231                } // if
    229232        }
    230233} // namespace CodeGen
  • src/Common/utility.h

    r1f44196 r3a2128f  
    148148}
    149149
    150 // replace element of list with all elements of another list
    151150template< typename T >
    152151void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) {
     
    159158
    160159        return;
    161 }
    162 
    163 // replace range of a list with a single element
    164 template< typename T >
    165 void replace( std::list< T > &org, typename std::list< T >::iterator begin, typename std::list< T >::iterator end, const T & with ) {
    166         org.insert( begin, with );
    167         org.erase( begin, end );
    168160}
    169161
  • src/ControlStruct/Mutate.cc

    r1f44196 r3a2128f  
    2323#include "MLEMutator.h"
    2424#include "ForExprMutator.h"
     25#include "LabelTypeChecker.h"
    2526//#include "ExceptMutator.h"
    2627
     
    4041
    4142                //ExceptMutator exc;
     43                // LabelTypeChecker lbl;
    4244
    4345                mutateAll( translationUnit, formut );
    4446                acceptAll( translationUnit, lfix );
    4547                //mutateAll( translationUnit, exc );
     48                //acceptAll( translationUnit, lbl );
    4649        }
    4750} // namespace CodeGen
  • src/ControlStruct/module.mk

    r1f44196 r3a2128f  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk --
     8## module.mk -- 
    99##
    1010## Author           : Richard C. Bilson
     
    1919        ControlStruct/MLEMutator.cc \
    2020        ControlStruct/Mutate.cc \
    21         ControlStruct/ForExprMutator.cc
     21        ControlStruct/ForExprMutator.cc \
     22        ControlStruct/LabelTypeChecker.cc
    2223
  • src/GenPoly/Box.cc

    r1f44196 r3a2128f  
    113113                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
    114114                        /// Stores assignment operators from assertion list in local map of assignment operations
    115                         void findTypeOps( const Type::ForallList &forall );
     115                        void findTypeOps( const std::list< TypeDecl *> &forall );
    116116                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    117117                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     
    619619                }
    620620
    621                 void Pass1::findTypeOps( const Type::ForallList &forall ) {
     621                void Pass1::findTypeOps( const std::list< TypeDecl *> &forall ) {
    622622                        // what if a nested function uses an assignment operator?
    623623                        // assignOps.clear();
    624                         for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
     624                        for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    625625                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    626626                                        std::string typeName;
     
    687687                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    688688                                std::list< FunctionType *> functions;
    689                                 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     689                                for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    690690                                        for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    691691                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
     
    789789
    790790                        // add size/align for generic types to parameter list
    791                         if ( ! appExpr->get_function()->has_result() ) return;
    792                         FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
     791                        if ( appExpr->get_function()->get_results().empty() ) return;
     792                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
    793793                        assert( funcType );
    794794
     
    806806                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    807807                                VariableExpr *fnArgBase = getBaseVar( *fnArg );
    808                                 if ( ! fnArgBase ) continue; // xxx - previously had check for non-empty fnArgBase results
    809                                 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_result(), arg, exprTyVars, seenTypes );
     808                                if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;
     809                                passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes );
    810810                        }
    811811                }
     
    897897                        Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
    898898                        appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
    899                         appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr
     899                        appExpr->set_function( new NameExpr( adapterName ) );
    900900
    901901                        return ret;
     
    903903
    904904                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    905                         assert( arg->has_result() );
     905                        assert( ! arg->get_results().empty() );
    906906                        if ( isPolyType( param, exprTyVars ) ) {
    907                                 if ( isPolyType( arg->get_result() ) ) {
     907                                if ( isPolyType( arg->get_results().front() ) ) {
    908908                                        // if the argument's type is polymorphic, we don't need to box again!
    909909                                        return;
    910                                 } else if ( arg->get_result()->get_isLvalue() ) {
     910                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    911911                                        // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    912912                                        // xxx - need to test that this code is still reachable
     
    953953                void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    954954                        std::list< Expression *>::iterator cur = arg;
    955                         for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     955                        for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    956956                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    957957                                        InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
     
    994994                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    995995                                        deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    996                                         deref->set_result( arg->get_type()->clone() );
     996                                        deref->get_results().push_back( arg->get_type()->clone() );
    997997                                        return deref;
    998998                                } // if
     
    10201020                        Statement *bodyStmt;
    10211021
    1022                         Type::ForallList::iterator tyArg = realType->get_forall().begin();
    1023                         Type::ForallList::iterator tyParam = adapterType->get_forall().begin();
    1024                         Type::ForallList::iterator realTyParam = adaptee->get_forall().begin();
     1022                        std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin();
     1023                        std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin();
     1024                        std::list< TypeDecl *>::iterator realTyParam = adaptee->get_forall().begin();
    10251025                        for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
    10261026                                assert( tyArg != realType->get_forall().end() );
     
    10711071                        std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    10721072                        std::list< FunctionType *> functions;
    1073                         for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     1073                        for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    10741074                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    10751075                                        findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter );
     
    11311131                        } // if
    11321132                        addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) );
    1133                         addAssign->set_result( appExpr->get_result()->clone() );
     1133                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    11341134                        if ( appExpr->get_env() ) {
    11351135                                addAssign->set_env( appExpr->get_env() );
     
    11451145                                if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    11461146                                        if ( varExpr->get_var()->get_name() == "?[?]" ) {
    1147                                                 assert( appExpr->has_result() );
     1147                                                assert( ! appExpr->get_results().empty() );
    11481148                                                assert( appExpr->get_args().size() == 2 );
    1149                                                 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
    1150                                                 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env );
     1149                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     1150                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
    11511151                                                assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
    11521152                                                UntypedExpr *ret = 0;
     
    11681168                                                } // if
    11691169                                                if ( baseType1 || baseType2 ) {
    1170                                                         ret->set_result( appExpr->get_result()->clone() );
     1170                                                        ret->get_results().push_front( appExpr->get_results().front()->clone() );
    11711171                                                        if ( appExpr->get_env() ) {
    11721172                                                                ret->set_env( appExpr->get_env() );
     
    11781178                                                } // if
    11791179                                        } else if ( varExpr->get_var()->get_name() == "*?" ) {
    1180                                                 assert( appExpr->has_result() );
     1180                                                assert( ! appExpr->get_results().empty() );
    11811181                                                assert( ! appExpr->get_args().empty() );
    1182                                                 if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
     1182                                                if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
    11831183                                                        Expression *ret = appExpr->get_args().front();
    1184                                                         delete ret->get_result();
    1185                                                         ret->set_result( appExpr->get_result()->clone() );
     1184                                                        delete ret->get_results().front();
     1185                                                        ret->get_results().front() = appExpr->get_results().front()->clone();
    11861186                                                        if ( appExpr->get_env() ) {
    11871187                                                                ret->set_env( appExpr->get_env() );
     
    11931193                                                } // if
    11941194                                        } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
    1195                                                 assert( appExpr->has_result() );
     1195                                                assert( ! appExpr->get_results().empty() );
    11961196                                                assert( appExpr->get_args().size() == 1 );
    1197                                                 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
    1198                                                         Type *tempType = appExpr->get_result()->clone();
     1197                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
     1198                                                        Type *tempType = appExpr->get_results().front()->clone();
    11991199                                                        if ( env ) {
    12001200                                                                env->apply( tempType );
     
    12131213                                                } // if
    12141214                                        } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
    1215                                                 assert( appExpr->has_result() );
     1215                                                assert( ! appExpr->get_results().empty() );
    12161216                                                assert( appExpr->get_args().size() == 1 );
    1217                                                 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
     1217                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
    12181218                                                        return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
    12191219                                                } // if
    12201220                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    1221                                                 assert( appExpr->has_result() );
     1221                                                assert( ! appExpr->get_results().empty() );
    12221222                                                assert( appExpr->get_args().size() == 2 );
    1223                                                 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
    1224                                                 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env );
     1223                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     1224                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
    12251225                                                if ( baseType1 && baseType2 ) {
    12261226                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    12271227                                                        divide->get_args().push_back( appExpr );
    12281228                                                        divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
    1229                                                         divide->set_result( appExpr->get_result()->clone() );
     1229                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    12301230                                                        if ( appExpr->get_env() ) {
    12311231                                                                divide->set_env( appExpr->get_env() );
     
    12451245                                                } // if
    12461246                                        } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
    1247                                                 assert( appExpr->has_result() );
     1247                                                assert( ! appExpr->get_results().empty() );
    12481248                                                assert( appExpr->get_args().size() == 2 );
    1249                                                 Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env );
     1249                                                Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
    12501250                                                if ( baseType ) {
    12511251                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
     
    12731273                        useRetval = oldUseRetval;
    12741274
    1275                         assert( appExpr->get_function()->has_result() );
    1276                         PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
    1277                         FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
     1275                        assert( ! appExpr->get_function()->get_results().empty() );
     1276                        PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     1277                        assert( pointer );
     1278                        FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
     1279                        assert( function );
    12781280
    12791281                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    13131315
    13141316                Expression *Pass1::mutate( UntypedExpr *expr ) {
    1315                         if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
     1317                        if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
    13161318                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    13171319                                        if ( name->get_name() == "*?" ) {
     
    13271329
    13281330                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    1329                         assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
     1331                        assert( ! addrExpr->get_arg()->get_results().empty() );
    13301332
    13311333                        bool needs = false;
    13321334                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    1333                                 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
     1335                                if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
    13341336                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    13351337                                                if ( name->get_name() == "*?" ) {
    13361338                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    1337                                                                 assert( appExpr->get_function()->has_result() );
    1338                                                                 PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
    1339                                                                 FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
     1339                                                                assert( ! appExpr->get_function()->get_results().empty() );
     1340                                                                PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     1341                                                                assert( pointer );
     1342                                                                FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
     1343                                                                assert( function );
    13401344                                                                needs = needsAdapter( function, scopeTyVars );
    13411345                                                        } // if
     
    13461350                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    13471351                        // out of the if condition.
    1348                         bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     1352                        bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );
    13491353                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    13501354                        if ( polytype || needs ) {
    13511355                                Expression *ret = addrExpr->get_arg();
    1352                                 delete ret->get_result();
    1353                                 ret->set_result( addrExpr->get_result()->clone() );
     1356                                delete ret->get_results().front();
     1357                                ret->get_results().front() = addrExpr->get_results().front()->clone();
    13541358                                addrExpr->set_arg( 0 );
    13551359                                delete addrExpr;
     
    13891393                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    13901394                        if ( retval && returnStmt->get_expr() ) {
    1391                                 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
     1395                                assert( ! returnStmt->get_expr()->get_results().empty() );
    13921396                                // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
    13931397                                // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     
    14231427                                        // find each of its needed secondary assignment operators
    14241428                                        std::list< Expression* > &tyParams = refType->get_parameters();
    1425                                         Type::ForallList &forallParams = functionDecl->get_type()->get_forall();
     1429                                        std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
    14261430                                        std::list< Expression* >::const_iterator tyIt = tyParams.begin();
    1427                                         Type::ForallList::const_iterator forallIt = forallParams.begin();
     1431                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    14281432                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    14291433                                                // Add appropriate mapping to assignment expression environment
     
    14691473                                // replace return statement with appropriate assignment to out parameter
    14701474                                Expression *retParm = new NameExpr( retval->get_name() );
    1471                                 retParm->set_result( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     1475                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    14721476                                assignExpr->get_args().push_back( retParm );
    14731477                                assignExpr->get_args().push_back( returnStmt->get_expr() );
     
    15991603                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
    16001604                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    1601                         for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     1605                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    16021606                                ObjectDecl *sizeParm, *alignParm;
    16031607                                // add all size and alignment parameters to parameter list
  • src/GenPoly/CopyParams.cc

    r1f44196 r3a2128f  
    5454                                std::map< std::string, DeclarationWithType* > assignOps;
    5555                                // assume the assignment operator is the first assert param after any "type" parameter
    56                                 for ( Type::ForallList::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) {
     56                                for ( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) {
    5757                                        if ( (*tyVar)->get_kind() == TypeDecl::Any ) {
    5858                                                assert( !(*tyVar)->get_assertions().empty() );
  • src/GenPoly/FindFunction.cc

    r1f44196 r3a2128f  
    2929                virtual Type *mutate( PointerType *pointerType );
    3030          private:
    31                 void handleForall( const Type::ForallList &forall );
     31                void handleForall( const std::list< TypeDecl* > &forall );
    3232
    3333                std::list< FunctionType* > &functions;
     
    5151        }
    5252
    53         void FindFunction::handleForall( const Type::ForallList &forall ) {
    54                 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
     53        void FindFunction::handleForall( const std::list< TypeDecl* > &forall ) {
     54                for ( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    5555                        TyVarMap::iterator var = tyVars.find( (*i)->get_name() );
    5656                        if ( var != tyVars.end() ) {
  • src/GenPoly/GenPoly.cc

    r1f44196 r3a2128f  
    110110        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
    111111                if ( function->get_returnVals().empty() ) return 0;
    112 
     112               
    113113                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
    114114        }
     
    127127//              } // if
    128128                if ( isDynRet( adaptee, tyVars ) ) return true;
    129 
     129               
    130130                for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
    131131//                      if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
     
    228228
    229229        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
    230                 for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
     230                for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
    231231                        assert( *tyVar );
    232232                        tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
  • src/GenPoly/Lvalue.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Lvalue.cc --
     7// Lvalue.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    4141                  public:
    4242                        Pass1();
    43 
     43 
    4444                        virtual Expression *mutate( ApplicationExpr *appExpr );
    4545                        virtual Statement *mutate( ReturnStmt *appExpr );
     
    5555                  private:
    5656                };
    57 
    58                 /// GCC-like Generalized Lvalues (which have since been removed from GCC)
    59                 /// https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Lvalues.html#Lvalues
    60                 /// Replaces &(a,b) with (a, &b), &(a ? b : c) with (a ? &b : &c)
    61                 class GeneralizedLvalue : public Mutator {
    62                         typedef Mutator Parent;
    63 
    64                         virtual Expression * mutate( AddressExpr * addressExpr );
    65                 };
    6657        } // namespace
    6758
     
    6960                Pass1 p1;
    7061                Pass2 p2;
    71                 GeneralizedLvalue genLval;
    7262                mutateAll( translationUnit, p1 );
    7363                acceptAll( translationUnit, p2 );
    74                 mutateAll( translationUnit, genLval );
    7564        }
    7665
     
    11099                        appExpr->get_function()->acceptMutator( *this );
    111100                        mutateAll( appExpr->get_args(), *this );
     101 
     102                        assert( ! appExpr->get_function()->get_results().empty() );
    112103
    113                         PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    114                         FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
     104                        PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     105                        assert( pointer );
     106                        FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     107                        assert( function );
    115108
    116109                        Type *funType = isLvalueRet( function );
    117110                        if ( funType && ! isIntrinsicApp( appExpr ) ) {
    118111                                Expression *expr = appExpr;
    119                                 Type *appType = appExpr->get_result();
     112                                Type *appType = appExpr->get_results().front();
    120113                                if ( isPolyType( funType ) && ! isPolyType( appType ) ) {
    121114                                        // make sure cast for polymorphic type is inside dereference
     
    123116                                }
    124117                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    125                                 deref->set_result( appType->clone() );
    126                                 appExpr->set_result( new PointerType( Type::Qualifiers(), appType ) );
     118                                deref->get_results().push_back( appType->clone() );
     119                                appExpr->get_results().front() = new PointerType( Type::Qualifiers(), appType );
    127120                                deref->get_args().push_back( expr );
    128121                                return deref;
     
    134127                Statement * Pass1::mutate(ReturnStmt *retStmt) {
    135128                        if ( retval && retStmt->get_expr() ) {
    136                                 if ( retStmt->get_expr()->get_result()->get_isLvalue() ) {
     129                                assert( ! retStmt->get_expr()->get_results().empty() );
     130                                if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    137131                                        // ***** Code Removal ***** because casts may be stripped already
    138132
     
    161155                                retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
    162156                        } // if
    163 
     157 
    164158                        Visitor::visit( funType );
    165                 }
    166 
    167                 Expression * GeneralizedLvalue::mutate( AddressExpr * addrExpr ) {
    168                         addrExpr = safe_dynamic_cast< AddressExpr * >( Parent::mutate( addrExpr ) );
    169                         if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( addrExpr->get_arg() ) ) {
    170                                 Expression * arg1 = commaExpr->get_arg1()->clone();
    171                                 Expression * arg2 = commaExpr->get_arg2()->clone();
    172                                 delete addrExpr;
    173                                 return new CommaExpr( arg1, new AddressExpr( arg2 ) );
    174                         } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( addrExpr->get_arg() ) ) {
    175                                 Expression * arg1 = condExpr->get_arg1()->clone();
    176                                 Expression * arg2 = condExpr->get_arg2()->clone();
    177                                 Expression * arg3 = condExpr->get_arg3()->clone();
    178                                 delete addrExpr;
    179                                 return new ConditionalExpr( arg1, new AddressExpr( arg2 ), new AddressExpr( arg3 ) );
    180                         }
    181                         return addrExpr;
    182159                }
    183160        } // namespace
  • src/GenPoly/Specialize.cc

    r1f44196 r3a2128f  
    148148
    149149        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    150                 assertf( actual->has_result(), "attempting to specialize an untyped expression" );
    151                 if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
     150                assert( ! actual->get_results().empty() ); // using front, should have this assert
     151                if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
    152152                        FunctionType *funType;
    153153                        if ( ( funType = getFunctionType( formalType ) ) ) {
     
    172172        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    173173                // create thunks for the explicit parameters
    174                 assert( appExpr->get_function()->has_result() );
    175                 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
     174                assert( ! appExpr->get_function()->get_results().empty() );
     175                FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() );
    176176                assert( function );
    177177                std::list< DeclarationWithType* >::iterator formal;
     
    201201        Expression * Specialize::mutate( AddressExpr *addrExpr ) {
    202202                addrExpr->get_arg()->acceptMutator( *this );
    203                 assert( addrExpr->has_result() );
    204                 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
     203                assert( ! addrExpr->get_results().empty() );
     204                addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) );
    205205                return addrExpr;
    206206        }
     
    208208        Expression * Specialize::mutate( CastExpr *castExpr ) {
    209209                castExpr->get_arg()->acceptMutator( *this );
    210                 if ( castExpr->get_result()->isVoid() ) {
     210                if ( castExpr->get_results().empty() ) {
    211211                        // can't specialize if we don't have a return value
    212212                        return castExpr;
    213213                }
    214                 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
     214                Expression *specialized = doSpecialization( castExpr->get_results().front(), castExpr->get_arg() );
    215215                if ( specialized != castExpr->get_arg() ) {
    216216                        // assume here that the specialization incorporates the cast
  • src/InitTweak/FixInit.cc

    r1f44196 r3a2128f  
    1818#include <iterator>
    1919#include <algorithm>
    20 #include <unordered_map>
    21 #include <unordered_set>
    2220#include "InitTweak.h"
    2321#include "FixInit.h"
     
    3735#include "GenPoly/DeclMutator.h"
    3836#include "SynTree/AddStmtVisitor.h"
    39 #include "CodeGen/GenType.h"  // for warning/error messages
    40 
    41 bool ctordtorp = false; // print all debug
    42 bool ctorp = false; // print ctor debug
    43 bool cpctorp = false; // print copy ctor debug
    44 bool dtorp = false; // print dtor debug
     37#include "CodeGen/GenType.h"  // for warnings
     38
     39bool ctordtorp = false;
     40bool ctorp = false;
     41bool cpctorp = false;
     42bool dtorp = false;
    4543#define PRINT( text ) if ( ctordtorp ) { text }
    4644#define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text }
     
    4947namespace InitTweak {
    5048        namespace {
     49                const std::list<Label> noLabels;
     50                const std::list<Expression*> noDesignators;
     51
    5152                class InsertImplicitCalls final : public GenPoly::PolyMutator {
    5253                public:
     
    6667                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
    6768
    68                         typedef SymTab::Indexer Parent;
    69                         using Parent::visit;
    70 
     69                        using SymTab::Indexer::visit;
    7170                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    72                         virtual void visit( UniqueExpr * unqExpr );
    7371
    7472                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    75                         Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    76                         Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
     73                        ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    7774                        /// true if type does not need to be copy constructed to ensure correctness
    78                         bool skipCopyConstruct( Type * type );
    79                         void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    80                         void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
     75                        bool skipCopyConstruct( Type * );
    8176                private:
    8277                        TypeSubstitution * env;
     
    188183                        using GenPoly::PolyMutator::mutate;
    189184                        virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    190                         virtual Expression * mutate( UniqueExpr * unqExpr ) override;
    191185                };
    192186
     
    374368                }
    375369
    376                 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     370                ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    377371                        assert( var );
    378                         return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
    379                 }
    380 
    381                 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
    382                         assert( thisArg );
    383372                        UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    384                         untyped->get_args().push_back( thisArg );
     373                        untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) );
    385374                        if (cpArg) untyped->get_args().push_back( cpArg->clone() );
    386375
     
    389378                        // (VariableExpr and already resolved expression)
    390379                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    391                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
    392                         assert( resolved );
     380                        ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
    393381                        if ( resolved->get_env() ) {
    394382                                env->add( *resolved->get_env() );
    395383                        } // if
    396384
     385                        assert( resolved );
    397386                        delete untyped;
    398387                        return resolved;
    399388                }
    400389
    401                 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     390                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    402391                        static UniqueName tempNamer("_tmp_cp");
    403                         CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
    404                         assert( arg->has_result() );
    405                         Type * result = arg->get_result();
    406                         if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
    407 
    408                         // type may involve type variables, so apply type substitution to get temporary variable's actual type
    409                         result = result->clone();
    410                         impCpCtorExpr->get_env()->apply( result );
    411                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    412                         tmp->get_type()->set_isConst( false );
    413 
    414                         // create and resolve copy constructor
    415                         CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
    416                         Expression * cpCtor = makeCtorDtor( "?{}", tmp, arg );
    417 
    418                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( cpCtor ) ) {
     392                        static UniqueName retNamer("_tmp_cp_ret");
     393
     394                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
     395                        Visitor::visit( impCpCtorExpr );
     396                        env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer...
     397
     398                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     399
     400                        // take each argument and attempt to copy construct it.
     401                        for ( Expression * & arg : appExpr->get_args() ) {
     402                                CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
     403                                // xxx - need to handle tuple arguments
     404                                assert( ! arg->get_results().empty() );
     405                                Type * result = arg->get_results().front();
     406                                if ( skipCopyConstruct( result ) ) continue; // skip certain non-copyable types
     407                                // type may involve type variables, so apply type substitution to get temporary variable's actual type
     408                                result = result->clone();
     409                                impCpCtorExpr->get_env()->apply( result );
     410                                ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
     411                                tmp->get_type()->set_isConst( false );
     412
     413                                // create and resolve copy constructor
     414                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
     415                                ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg );
     416
    419417                                // if the chosen constructor is intrinsic, the copy is unnecessary, so
    420418                                // don't create the temporary and don't call the copy constructor
    421                                 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     419                                VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() );
    422420                                assert( function );
    423                                 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
    424                         }
    425 
    426                         // replace argument to function call with temporary
    427                         arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
    428                         impCpCtorExpr->get_tempDecls().push_back( tmp );
    429                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
    430                 }
    431 
    432                 void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    433                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
    434                 }
    435 
    436                 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    437                         CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    438                         Parent::visit( impCpCtorExpr );
    439                         env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer...
    440 
    441                         ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
    442 
    443                         // take each argument and attempt to copy construct it.
    444                         for ( Expression * & arg : appExpr->get_args() ) {
    445                                 copyConstructArg( arg, impCpCtorExpr );
     421                                if ( function->get_var()->get_linkage() != LinkageSpec::Intrinsic ) {
     422                                        // replace argument to function call with temporary
     423                                        arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
     424                                        impCpCtorExpr->get_tempDecls().push_back( tmp );
     425                                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
     426                                } // if
    446427                        } // for
    447428
     
    453434                        // level. Trying to pass that environment along.
    454435                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    455                         Type * result = appExpr->get_result();
    456                         if ( ! result->isVoid() ) {
    457                                 static UniqueName retNamer("_tmp_cp_ret");
     436                        for ( Type * result : appExpr->get_results() ) {
    458437                                result = result->clone();
    459438                                impCpCtorExpr->get_env()->apply( result );
     
    462441                                impCpCtorExpr->get_returnDecls().push_back( ret );
    463442                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    464                                 if ( ! result->get_isLvalue() ) {
    465                                         // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    466                                         destructRet( new VariableExpr( ret ), impCpCtorExpr );
    467                                 }
     443                                impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    468444                        } // for
    469445                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
    470                 }
    471 
    472                 void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
    473                         static std::unordered_set< int > vars;
    474                         if ( vars.count( unqExpr->get_id() ) ) {
    475                                 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
    476                                 return;
    477                         }
    478 
    479                         Parent::visit( unqExpr );
    480                         // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
    481                         assert( unqExpr->get_result() );
    482                         if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->get_expr() ) ) {
    483                                 // note the variable used as the result from the call
    484                                 assert( impCpCtorExpr->get_result() && impCpCtorExpr->get_returnDecls().size() == 1 );
    485                                 unqExpr->set_var( new VariableExpr( impCpCtorExpr->get_returnDecls().front() ) );
    486                         } else {
    487                                 // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    488                                 unqExpr->set_object( new ObjectDecl( toString("_unq_expr_", unqExpr->get_id()), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
    489                                 unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    490                         }
    491                         vars.insert( unqExpr->get_id() );
    492446                }
    493447
     
    536490                                // know the result type of the assignment is the type of the LHS (minus the pointer), so
    537491                                // add that onto the assignment expression so that later steps have the necessary information
    538                                 assign->set_result( returnDecl->get_type()->clone() );
     492                                assign->add_result( returnDecl->get_type()->clone() );
    539493
    540494                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    541                                 if ( callExpr->get_result()->get_isLvalue() ) {
     495                                if ( callExpr->get_results().front()->get_isLvalue() ) {
    542496                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
    543497                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     
    546500                                        // an AddressExpr.  Effectively, this turns
    547501                                        //   lvalue T f();
    548                                         //   &*f();
     502                                        //   &*f()
    549503                                        // into
    550                                         //   T * f();
    551504                                        //   T * tmp_cp_retN;
    552                                         //   &*(tmp_cp_retN = &*f(), tmp_cp_retN);              // the first * and second & are generated here
     505                                        //   tmp_cp_ret_N = &*(tmp_cp_ret_N = &*f(), tmp_cp_ret);
    553506                                        // which work out in terms of types, but is pretty messy. It would be nice to find a better way.
    554507                                        assign->get_args().back() = new AddressExpr( assign->get_args().back() );
    555508
     509                                        Type * resultType = returnDecl->get_type()->clone();
    556510                                        returnDecl->set_type( new PointerType( Type::Qualifiers(), returnDecl->get_type() ) );
    557                                         retExpr->set_result( new PointerType( Type::Qualifiers(), retExpr->get_result() ) );
    558                                         retExpr = UntypedExpr::createDeref( retExpr );
     511                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
     512                                        deref->get_args().push_back( retExpr );
     513                                        deref->add_result( resultType );
     514                                        retExpr = deref;
    559515                                } // if
    560516                                retExpr->set_env( env->clone() );
     
    563519                                return callExpr;
    564520                        } // if
    565                 }
    566 
    567                 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
    568                         static std::unordered_map< int, UniqueExpr * > unqMap;
    569                         static std::unordered_set< int > addDeref;
    570                         // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    571                         unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) );
    572                         if ( unqMap.count( unqExpr->get_id() ) ) {
    573                                 // take data from other UniqueExpr to ensure consistency
    574                                 delete unqExpr->get_expr();
    575                                 unqExpr->set_expr( unqMap[unqExpr->get_id()]->get_expr()->clone() );
    576                                 delete unqExpr->get_result();
    577                                 unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) );
    578                                 if ( addDeref.count( unqExpr->get_id() ) ) {
    579                                         // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
    580                                         return UntypedExpr::createDeref( unqExpr );
    581                                 }
    582                                 return unqExpr;
    583                         }
    584                         unqMap[unqExpr->get_id()] = unqExpr;
    585                         if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
    586                                 // unique expression is now a dereference, because the inner expression is an lvalue returning function call.
    587                                 // Normalize the expression by dereferencing the unique expression, rather than the inner expression
    588                                 // (i.e. move the dereference out a level)
    589                                 assert( getFunctionName( deref ) == "*?" );
    590                                 unqExpr->set_expr( getCallArg( deref, 0 ) );
    591                                 getCallArg( deref, 0 ) = unqExpr;
    592                                 addDeref.insert( unqExpr->get_id() );
    593                                 return deref;
    594                         }
    595                         return unqExpr;
    596521                }
    597522
     
    1025950                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    1026951                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    1027                         // xxx - is the size check necessary?
    1028                         assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
    1029                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
     952                        assert( ctorExpr->get_results().size() == 1 );
     953                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_results().front()->clone(), nullptr );
    1030954                        addDeclaration( tmp );
    1031955
     
    1039963                        assign->get_args().push_back( new VariableExpr( tmp ) );
    1040964                        assign->get_args().push_back( firstArg );
    1041                         assign->set_result( ctorExpr->get_result()->clone() );
     965                        cloneAll( ctorExpr->get_results(), assign->get_results() );
    1042966                        firstArg = assign;
    1043967
  • src/InitTweak/GenInit.cc

    r1f44196 r3a2128f  
    2929#include "GenPoly/DeclMutator.h"
    3030#include "GenPoly/ScopedSet.h"
    31 #include "ResolvExpr/typeops.h"
    3231
    3332namespace InitTweak {
     
    5150
    5251          protected:
    53                 FunctionType * ftype;
     52                std::list<DeclarationWithType*> returnVals;
    5453                UniqueName tempNamer;
    5554                std::string funcName;
     
    8786
    8887                bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed
    89                 bool isManaged( Type * type ) const; // determine if type is managed
    9088                void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor
    9189                GenPoly::ScopedSet< std::string > managedTypes;
     
    138136
    139137        Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) {
    140                 std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();
     138                // update for multiple return values
    141139                assert( returnVals.size() == 0 || returnVals.size() == 1 );
    142140                // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
     
    160158
    161159        DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    162                 // xxx - need to handle named return values - this pass may need to happen
    163                 // after resolution? the ordering is tricky because return statements must be
    164                 // constructed - the simplest way to do that (while also handling multiple
    165                 // returns) is to structure the returnVals into a tuple, as done here.
    166                 // however, if the tuple return value is structured before resolution,
    167                 // it's difficult to resolve named return values, since the name is lost
    168                 // in conversion to a tuple. this might be easiest to deal with
    169                 // after reference types are added, as it may then be possible to
    170                 // uniformly move named return values to the parameter list directly
    171                 ValueGuard< FunctionType * > oldFtype( ftype );
     160                ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals );
    172161                ValueGuard< std::string > oldFuncName( funcName );
    173162
    174                 ftype = functionDecl->get_functionType();
    175                 std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
    176                 if ( retVals.size() > 1 ) {
    177                         TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
    178                         ObjectDecl * newRet = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
    179                         retVals.clear();
    180                         retVals.push_back( newRet );
    181                 }
     163                FunctionType * type = functionDecl->get_functionType();
     164                returnVals = type->get_returnVals();
    182165                funcName = functionDecl->get_name();
    183166                DeclarationWithType * decl = Mutator::mutate( functionDecl );
     
    239222        }
    240223
    241         bool CtorDtor::isManaged( Type * type ) const {
    242                 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
    243                         // tuple is also managed if any of its components are managed
    244                         if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
    245                                 return true;
    246                         }
    247                 }
    248                 return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end();
    249         }
    250 
    251224        bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {
    252225                Type * type = objDecl->get_type();
     
    254227                        type = at->get_base();
    255228                }
    256                 return isManaged( type );
     229                return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end();
    257230        }
    258231
     
    265238                        managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
    266239                }
    267         }
    268 
    269         ConstructorInit * genCtorInit( ObjectDecl * objDecl ) {
    270                 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
    271                 // for each constructable object
    272                 std::list< Statement * > ctor;
    273                 std::list< Statement * > dtor;
    274 
    275                 InitExpander srcParam( objDecl->get_init() );
    276                 InitExpander nullParam( (Initializer *)NULL );
    277                 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
    278                 SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
    279 
    280                 // Currently genImplicitCall produces a single Statement - a CompoundStmt
    281                 // which  wraps everything that needs to happen. As such, it's technically
    282                 // possible to use a Statement ** in the above calls, but this is inherently
    283                 // unsafe, so instead we take the slightly less efficient route, but will be
    284                 // immediately informed if somehow the above assumption is broken. In this case,
    285                 // we could always wrap the list of statements at this point with a CompoundStmt,
    286                 // but it seems reasonable at the moment for this to be done by genImplicitCall
    287                 // itself. It is possible that genImplicitCall produces no statements (e.g. if
    288                 // an array type does not have a dimension). In this case, it's fine to ignore
    289                 // the object for the purposes of construction.
    290                 assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
    291                 if ( ctor.size() == 1 ) {
    292                         // need to remember init expression, in case no ctors exist
    293                         // if ctor does exist, want to use ctor expression instead of init
    294                         // push this decision to the resolver
    295                         assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
    296                         return new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() );
    297                 }
    298                 return nullptr;
    299240        }
    300241
     
    309250                        if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl );
    310251
    311                         objDecl->set_init( genCtorInit( objDecl ) );
     252                        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
     253                        // for each constructable object
     254                        std::list< Statement * > ctor;
     255                        std::list< Statement * > dtor;
     256
     257                        InitExpander srcParam( objDecl->get_init() );
     258                        InitExpander nullParam( (Initializer *)NULL );
     259                        SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
     260                        SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
     261
     262                        // Currently genImplicitCall produces a single Statement - a CompoundStmt
     263                        // which  wraps everything that needs to happen. As such, it's technically
     264                        // possible to use a Statement ** in the above calls, but this is inherently
     265                        // unsafe, so instead we take the slightly less efficient route, but will be
     266                        // immediately informed if somehow the above assumption is broken. In this case,
     267                        // we could always wrap the list of statements at this point with a CompoundStmt,
     268                        // but it seems reasonable at the moment for this to be done by genImplicitCall
     269                        // itself. It is possible that genImplicitCall produces no statements (e.g. if
     270                        // an array type does not have a dimension). In this case, it's fine to ignore
     271                        // the object for the purposes of construction.
     272                        assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
     273                        if ( ctor.size() == 1 ) {
     274                                // need to remember init expression, in case no ctors exist
     275                                // if ctor does exist, want to use ctor expression instead of init
     276                                // push this decision to the resolver
     277                                assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
     278                                objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     279                        }
    312280                }
    313281                return Parent::mutate( objDecl );
     
    322290                managedTypes.beginScope();
    323291                // go through assertions and recursively add seen ctor/dtors
    324                 for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
     292                for ( TypeDecl * tyDecl : functionDecl->get_functionType()->get_forall() ) {
    325293                        for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
    326294                                assertion = assertion->acceptMutator( *this );
  • src/InitTweak/GenInit.h

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenInit.h --
     7// RemoveInit.h --
    88//
    99// Author           : Rodolfo G. Esteves
     
    2727        /// Adds return value temporaries and wraps Initializers in ConstructorInit nodes
    2828        void genInit( std::list< Declaration * > & translationUnit );
    29 
    30         /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
    31         ConstructorInit * genCtorInit( ObjectDecl * objDecl );
    3229} // namespace
    3330
  • src/InitTweak/InitTweak.cc

    r1f44196 r3a2128f  
    340340                return allofCtorDtor( stmt, []( Expression * callExpr ){
    341341                        if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
    342                                 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_result() );
     342                                assert( ! appExpr->get_function()->get_results().empty() );
     343                                FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() );
    343344                                assert( funcType );
    344345                                return funcType->get_parameters().size() == 1;
     
    387388                                return memberExpr->get_member()->get_name();
    388389                        } else if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * > ( func ) ) {
    389                                 return funcName( memberExpr->get_member() );
     390                                return memberExpr->get_member();
    390391                        } else {
    391392                                assertf( false, "Unexpected expression type being called as a function in call expression" );
     
    450451                // virtual void visit( LogicalExpr *logicalExpr );
    451452                // virtual void visit( ConditionalExpr *conditionalExpr );
     453                virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
     454                virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
    452455                virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
    453456                virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
    454457                virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
    455458                virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
    456                 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
    457                 virtual void visit( TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
    458459
    459460                bool isConstExpr;
  • src/Makefile.in

    r1f44196 r3a2128f  
    105105        ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
    106106        ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
     107        ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT) \
    107108        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    108109        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
     
    189190        SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
    190191        SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
    191         SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT) \
    192192        Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
    193         Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT) \
    194         Tuples/driver_cfa_cpp-Explode.$(OBJEXT)
     193        Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT)
    195194am_driver_cfa_cpp_OBJECTS = $(am__objects_1)
    196195driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS)
     
    365364        ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
    366365        ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
    367         ControlStruct/ForExprMutator.cc GenPoly/Box.cc \
     366        ControlStruct/ForExprMutator.cc \
     367        ControlStruct/LabelTypeChecker.cc GenPoly/Box.cc \
    368368        GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
    369369        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
     
    404404        SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
    405405        SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \
    406         SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
    407         Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
    408         Tuples/Explode.cc
     406        SynTree/Attribute.cc Tuples/TupleAssignment.cc \
     407        Tuples/NameMatcher.cc
    409408MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    410409        ${cfa_cpplib_PROGRAMS}}
     
    542541        ControlStruct/$(DEPDIR)/$(am__dirstamp)
    543542ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT):  \
     543        ControlStruct/$(am__dirstamp) \
     544        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     545ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT):  \
    544546        ControlStruct/$(am__dirstamp) \
    545547        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     
    767769SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
    768770        SynTree/$(DEPDIR)/$(am__dirstamp)
    769 SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT):  \
    770         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    771771Tuples/$(am__dirstamp):
    772772        @$(MKDIR_P) Tuples
     
    777777Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT):  \
    778778        Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
    779 Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT):  \
    780         Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
    781 Tuples/driver_cfa_cpp-Explode.$(OBJEXT): Tuples/$(am__dirstamp) \
     779Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT): Tuples/$(am__dirstamp) \
    782780        Tuples/$(DEPDIR)/$(am__dirstamp)
    783781driver/$(am__dirstamp):
     
    802800        -rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT)
    803801        -rm -f ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT)
     802        -rm -f ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT)
    804803        -rm -f ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT)
    805804        -rm -f ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT)
     
    885884        -rm -f SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT)
    886885        -rm -f SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT)
    887         -rm -f SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT)
    888886        -rm -f SynTree/driver_cfa_cpp-Visitor.$(OBJEXT)
    889887        -rm -f SynTree/driver_cfa_cpp-VoidType.$(OBJEXT)
    890888        -rm -f SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT)
    891         -rm -f Tuples/driver_cfa_cpp-Explode.$(OBJEXT)
     889        -rm -f Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT)
    892890        -rm -f Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT)
    893         -rm -f Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT)
    894891
    895892distclean-compile:
     
    910907@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
    911908@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po@am__quote@
     909@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po@am__quote@
    912910@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po@am__quote@
    913911@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@
     
    993991@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po@am__quote@
    994992@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po@am__quote@
    995 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Po@am__quote@
    996993@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@
    997994@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@
    998995@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@
    999 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po@am__quote@
     996@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po@am__quote@
    1000997@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po@am__quote@
    1001 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po@am__quote@
    1002998
    1003999.cc.o:
     
    12411237@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
    12421238
     1239ControlStruct/driver_cfa_cpp-LabelTypeChecker.o: ControlStruct/LabelTypeChecker.cc
     1240@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelTypeChecker.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.o `test -f 'ControlStruct/LabelTypeChecker.cc' || echo '$(srcdir)/'`ControlStruct/LabelTypeChecker.cc
     1241@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po
     1242@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/LabelTypeChecker.cc' object='ControlStruct/driver_cfa_cpp-LabelTypeChecker.o' libtool=no @AMDEPBACKSLASH@
     1243@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1244@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.o `test -f 'ControlStruct/LabelTypeChecker.cc' || echo '$(srcdir)/'`ControlStruct/LabelTypeChecker.cc
     1245
     1246ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj: ControlStruct/LabelTypeChecker.cc
     1247@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj `if test -f 'ControlStruct/LabelTypeChecker.cc'; then $(CYGPATH_W) 'ControlStruct/LabelTypeChecker.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelTypeChecker.cc'; fi`
     1248@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po
     1249@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/LabelTypeChecker.cc' object='ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj' libtool=no @AMDEPBACKSLASH@
     1250@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1251@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj `if test -f 'ControlStruct/LabelTypeChecker.cc'; then $(CYGPATH_W) 'ControlStruct/LabelTypeChecker.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelTypeChecker.cc'; fi`
     1252
    12431253GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc
    12441254@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
     
    24172427@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi`
    24182428
    2419 SynTree/driver_cfa_cpp-VarExprReplacer.o: SynTree/VarExprReplacer.cc
    2420 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VarExprReplacer.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Tpo -c -o SynTree/driver_cfa_cpp-VarExprReplacer.o `test -f 'SynTree/VarExprReplacer.cc' || echo '$(srcdir)/'`SynTree/VarExprReplacer.cc
    2421 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Po
    2422 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/VarExprReplacer.cc' object='SynTree/driver_cfa_cpp-VarExprReplacer.o' libtool=no @AMDEPBACKSLASH@
    2423 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2424 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VarExprReplacer.o `test -f 'SynTree/VarExprReplacer.cc' || echo '$(srcdir)/'`SynTree/VarExprReplacer.cc
    2425 
    2426 SynTree/driver_cfa_cpp-VarExprReplacer.obj: SynTree/VarExprReplacer.cc
    2427 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VarExprReplacer.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Tpo -c -o SynTree/driver_cfa_cpp-VarExprReplacer.obj `if test -f 'SynTree/VarExprReplacer.cc'; then $(CYGPATH_W) 'SynTree/VarExprReplacer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VarExprReplacer.cc'; fi`
    2428 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Po
    2429 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/VarExprReplacer.cc' object='SynTree/driver_cfa_cpp-VarExprReplacer.obj' libtool=no @AMDEPBACKSLASH@
    2430 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2431 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VarExprReplacer.obj `if test -f 'SynTree/VarExprReplacer.cc'; then $(CYGPATH_W) 'SynTree/VarExprReplacer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VarExprReplacer.cc'; fi`
    2432 
    24332429Tuples/driver_cfa_cpp-TupleAssignment.o: Tuples/TupleAssignment.cc
    24342430@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleAssignment.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo -c -o Tuples/driver_cfa_cpp-TupleAssignment.o `test -f 'Tuples/TupleAssignment.cc' || echo '$(srcdir)/'`Tuples/TupleAssignment.cc
     
    24452441@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi`
    24462442
    2447 Tuples/driver_cfa_cpp-TupleExpansion.o: Tuples/TupleExpansion.cc
    2448 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
    2449 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
    2450 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.o' libtool=no @AMDEPBACKSLASH@
    2451 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2452 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
    2453 
    2454 Tuples/driver_cfa_cpp-TupleExpansion.obj: Tuples/TupleExpansion.cc
    2455 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
    2456 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
    2457 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.obj' libtool=no @AMDEPBACKSLASH@
    2458 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2459 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
    2460 
    2461 Tuples/driver_cfa_cpp-Explode.o: Tuples/Explode.cc
    2462 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-Explode.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo -c -o Tuples/driver_cfa_cpp-Explode.o `test -f 'Tuples/Explode.cc' || echo '$(srcdir)/'`Tuples/Explode.cc
    2463 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po
    2464 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/Explode.cc' object='Tuples/driver_cfa_cpp-Explode.o' libtool=no @AMDEPBACKSLASH@
    2465 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2466 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-Explode.o `test -f 'Tuples/Explode.cc' || echo '$(srcdir)/'`Tuples/Explode.cc
    2467 
    2468 Tuples/driver_cfa_cpp-Explode.obj: Tuples/Explode.cc
    2469 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-Explode.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo -c -o Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi`
    2470 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po
    2471 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/Explode.cc' object='Tuples/driver_cfa_cpp-Explode.obj' libtool=no @AMDEPBACKSLASH@
    2472 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2473 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi`
     2443Tuples/driver_cfa_cpp-NameMatcher.o: Tuples/NameMatcher.cc
     2444@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-NameMatcher.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo -c -o Tuples/driver_cfa_cpp-NameMatcher.o `test -f 'Tuples/NameMatcher.cc' || echo '$(srcdir)/'`Tuples/NameMatcher.cc
     2445@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po
     2446@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/NameMatcher.cc' object='Tuples/driver_cfa_cpp-NameMatcher.o' libtool=no @AMDEPBACKSLASH@
     2447@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     2448@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-NameMatcher.o `test -f 'Tuples/NameMatcher.cc' || echo '$(srcdir)/'`Tuples/NameMatcher.cc
     2449
     2450Tuples/driver_cfa_cpp-NameMatcher.obj: Tuples/NameMatcher.cc
     2451@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-NameMatcher.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo -c -o Tuples/driver_cfa_cpp-NameMatcher.obj `if test -f 'Tuples/NameMatcher.cc'; then $(CYGPATH_W) 'Tuples/NameMatcher.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/NameMatcher.cc'; fi`
     2452@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po
     2453@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/NameMatcher.cc' object='Tuples/driver_cfa_cpp-NameMatcher.obj' libtool=no @AMDEPBACKSLASH@
     2454@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     2455@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-NameMatcher.obj `if test -f 'Tuples/NameMatcher.cc'; then $(CYGPATH_W) 'Tuples/NameMatcher.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/NameMatcher.cc'; fi`
    24742456
    24752457.ll.cc:
  • src/Parser/ExpressionNode.cc

    r1f44196 r3a2128f  
    172172} // build_constantStr
    173173
    174 Expression * build_field_name_FLOATINGconstant( const std::string & str ) {
    175         // str is of the form A.B -> separate at the . and return member expression
    176         int a, b;
    177         char dot;
    178         std::stringstream ss( str );
    179         ss >> a >> dot >> b;
    180         UntypedMemberExpr * ret = new UntypedMemberExpr(
    181                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::SignedInt ), toString( b ) ) ),
    182                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::SignedInt ), toString( a ) ) ) );
    183         delete &str;
    184         return ret;
    185 } // build_field_name_FLOATINGconstant
    186 
    187 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
    188         if ( fracts ) {
    189                 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
    190                         memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
    191                         return memberExpr;
    192                 } else {
    193                         return new UntypedMemberExpr( fracts, fieldName );
    194                 }
    195         }
    196         return fieldName;
    197 } // make_field_name_fraction_constants
    198 
    199 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
    200         return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
    201 } // build_field_name_fraction_constants
    202 
    203 Expression * build_field_name_REALFRACTIONconstant( const std::string & str ) {
    204         assert( str[0] == '.' );
    205         Expression * ret = build_constantInteger( *new std::string( str.substr(1) ) );
    206         delete &str;
    207         return ret;
    208 } // build_field_name_REALFRACTIONconstant
    209 
    210 Expression * build_field_name_REALDECIMALconstant( const std::string & str ) {
    211         assert( str[str.size()-1] == '.' );
    212         Expression * ret = build_constantInteger( *new std::string( str.substr( 0, str.size()-1 ) ) );
    213         delete &str;
    214         return ret;
    215 } // build_field_name_REALDECIMALconstant
    216 
    217174NameExpr * build_varref( const string *name, bool labelp ) {
    218175        NameExpr *expr = new NameExpr( *name, nullptr );
     
    241198}
    242199
    243 Expression *build_fieldSel( ExpressionNode *expr_node, Expression *member ) {
    244         UntypedMemberExpr *ret = new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
    245         return ret;
    246 }
    247 
    248 Expression *build_pfieldSel( ExpressionNode *expr_node, Expression *member ) {
     200Expression *build_fieldSel( ExpressionNode *expr_node, NameExpr *member ) {
     201        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), maybeMoveBuild< Expression >(expr_node) );
     202        delete member;
     203        return ret;
     204}
     205
     206Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ) {
    249207        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    250208        deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
    251         UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref );
     209        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
     210        delete member;
    252211        return ret;
    253212}
  • src/Parser/ParseNode.h

    r1f44196 r3a2128f  
    155155Expression * build_constantChar( const std::string &str );
    156156ConstantExpr * build_constantStr( const std::string &str );
    157 Expression * build_field_name_FLOATINGconstant( const std::string & str );
    158 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
    159 Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
    160 Expression * build_field_name_REALDECIMALconstant( const std::string & str );
    161157
    162158NameExpr * build_varref( const std::string * name, bool labelp = false );
     
    164160
    165161Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    166 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
    167 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
     162Expression * build_fieldSel( ExpressionNode * expr_node, NameExpr * member );
     163Expression * build_pfieldSel( ExpressionNode * expr_node, NameExpr * member );
    168164Expression * build_addressOf( ExpressionNode * expr_node );
    169165Expression * build_sizeOfexpr( ExpressionNode * expr_node );
     
    387383//##############################################################################
    388384
    389 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
    390 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
     385template< typename SynTreeType, typename NodeType >
     386void buildList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
    391387        SemanticError errors;
    392         std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
     388        std::back_insert_iterator< std::list< SynTreeType * > > out( outputList );
    393389        const NodeType * cur = firstNode;
    394390
  • src/Parser/TypeData.cc

    r1f44196 r3a2128f  
    385385} // TypeData::print
    386386
    387 template< typename ForallList >
    388 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
     387void buildForall( const DeclarationNode * firstNode, list< TypeDecl* > &outputList ) {
    389388        buildList( firstNode, outputList );
    390         for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
    391                 TypeDecl * td = static_cast<TypeDecl*>(*i);
    392                 if ( td->get_kind() == TypeDecl::Any ) {
     389        for ( list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
     390                if ( (*i)->get_kind() == TypeDecl::Any ) {
    393391                        // add assertion parameters to `type' tyvars in reverse order
    394392                        // add dtor:  void ^?{}(T *)
    395393                        FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
    396                         dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    397                         td->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, nullptr, false, false ) );
     394                        dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) );
     395                        (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, nullptr, false, false ) );
    398396
    399397                        // add copy ctor:  void ?{}(T *, T)
    400398                        FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
    401                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    402                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    403                         td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, nullptr, false, false ) );
     399                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) );
     400                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), nullptr ) );
     401                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, nullptr, false, false ) );
    404402
    405403                        // add default ctor:  void ?{}(T *)
    406404                        FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
    407                         ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    408                         td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, nullptr, false, false ) );
     405                        ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) );
     406                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, nullptr, false, false ) );
    409407
    410408                        // add assignment operator:  T * ?=?(T *, T)
    411409                        FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
    412                         assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    413                         assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    414                         assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    415                         td->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, nullptr, false, false ) );
     410                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) );
     411                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), nullptr ) );
     412                        assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), nullptr ) );
     413                        (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, nullptr, false, false ) );
    416414                } // if
    417415        } // for
     
    517515                // character types. The implementation shall define char to have the same range, representation, and behavior as
    518516                // either signed char or unsigned char.
    519                 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
     517                static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; 
    520518
    521519                if ( td->length != DeclarationNode::NoLength ) {
  • src/Parser/parser.cc

    r1f44196 r3a2128f  
    10301030static const yytype_uint16 yyrline[] =
    10311031{
    1032        0,   305,   305,   309,   316,   317,   318,   319,   320,   324,
    1033      325,   326,   330,   331,   335,   336,   340,   341,   345,   349,
    1034      350,   361,   363,   365,   366,   368,   373,   374,   380,   382,
    1035      384,   386,   388,   390,   392,   394,   396,   398,   407,   408,
    1036      414,   415,   419,   420,   424,   425,   427,   429,   431,   433,
    1037      435,   440,   442,   444,   450,   451,   459,   462,   464,   466,
    1038      471,   484,   486,   488,   490,   492,   494,   496,   498,   500,
    1039      502,   504,   511,   512,   518,   519,   520,   521,   525,   526,
    1040      533,   534,   536,   538,   543,   544,   546,   551,   552,   554,
    1041      559,   560,   562,   564,   566,   571,   572,   574,   579,   580,
    1042      585,   586,   591,   592,   597,   598,   603,   604,   609,   610,
    1043      613,   620,   625,   626,   634,   635,   639,   640,   641,   642,
    1044      643,   644,   645,   646,   647,   648,   649,   650,   660,   662,
    1045      667,   668,   673,   674,   680,   681,   687,   688,   689,   690,
    1046      691,   692,   693,   694,   695,   705,   712,   714,   724,   725,
    1047      730,   732,   738,   740,   744,   745,   750,   755,   758,   760,
    1048      762,   772,   774,   785,   786,   788,   792,   794,   798,   799,
    1049      804,   805,   809,   814,   815,   819,   821,   827,   828,   832,
    1050      834,   836,   838,   844,   845,   849,   851,   856,   858,   860,
    1051      865,   867,   872,   874,   878,   881,   885,   888,   892,   894,
    1052      896,   898,   903,   905,   907,   912,   914,   916,   918,   920,
    1053      925,   927,   929,   931,   936,   948,   949,   954,   956,   961,
    1054      965,   967,   969,   971,   973,   979,   980,   986,   987,   991,
    1055      992,   997,   999,  1005,  1006,  1008,  1013,  1018,  1028,  1030,
    1056     1034,  1035,  1040,  1042,  1046,  1047,  1051,  1053,  1057,  1058,
    1057     1062,  1063,  1067,  1068,  1083,  1084,  1085,  1086,  1087,  1091,
    1058     1096,  1103,  1113,  1118,  1123,  1131,  1136,  1141,  1146,  1151,
    1059     1181,  1186,  1193,  1195,  1202,  1207,  1212,  1223,  1228,  1233,
    1060     1238,  1243,  1252,  1257,  1265,  1266,  1267,  1268,  1274,  1279,
    1061     1287,  1288,  1289,  1290,  1294,  1295,  1296,  1297,  1302,  1303,
    1062     1312,  1313,  1318,  1319,  1324,  1326,  1328,  1330,  1332,  1335,
    1063     1334,  1346,  1347,  1349,  1359,  1360,  1365,  1367,  1369,  1371,
    1064     1373,  1376,  1378,  1381,  1386,  1388,  1390,  1392,  1394,  1396,
    1065     1398,  1400,  1402,  1404,  1406,  1408,  1410,  1412,  1414,  1420,
    1066     1421,  1423,  1425,  1427,  1432,  1433,  1439,  1440,  1442,  1444,
    1067     1449,  1451,  1453,  1455,  1460,  1461,  1463,  1465,  1470,  1471,
    1068     1473,  1478,  1479,  1481,  1483,  1488,  1490,  1492,  1497,  1498,
    1069     1502,  1504,  1510,  1509,  1513,  1515,  1520,  1522,  1528,  1529,
    1070     1534,  1535,  1537,  1538,  1547,  1548,  1550,  1552,  1557,  1559,
    1071     1565,  1566,  1568,  1571,  1574,  1579,  1580,  1585,  1590,  1594,
    1072     1596,  1602,  1601,  1608,  1610,  1616,  1617,  1625,  1626,  1630,
    1073     1631,  1632,  1634,  1636,  1643,  1644,  1646,  1648,  1653,  1654,
    1074     1660,  1661,  1665,  1666,  1671,  1672,  1673,  1675,  1683,  1684,
    1075     1686,  1689,  1691,  1695,  1696,  1697,  1699,  1701,  1705,  1710,
    1076     1718,  1719,  1728,  1730,  1735,  1736,  1737,  1741,  1742,  1743,
    1077     1747,  1748,  1749,  1753,  1754,  1755,  1760,  1761,  1762,  1763,
    1078     1769,  1770,  1772,  1777,  1778,  1783,  1784,  1785,  1786,  1787,
    1079     1802,  1803,  1808,  1809,  1815,  1817,  1820,  1822,  1824,  1847,
    1080     1848,  1850,  1852,  1857,  1858,  1860,  1865,  1870,  1871,  1877,
    1081     1876,  1880,  1884,  1886,  1888,  1894,  1895,  1900,  1905,  1907,
    1082     1912,  1914,  1915,  1917,  1922,  1924,  1926,  1931,  1933,  1938,
    1083     1943,  1951,  1957,  1956,  1970,  1971,  1976,  1977,  1981,  1986,
    1084     1991,  1999,  2004,  2015,  2016,  2021,  2022,  2028,  2029,  2033,
    1085     2034,  2035,  2038,  2037,  2048,  2057,  2063,  2069,  2078,  2084,
    1086     2090,  2096,  2102,  2110,  2116,  2124,  2130,  2139,  2140,  2141,
    1087     2145,  2149,  2151,  2156,  2157,  2161,  2162,  2167,  2173,  2174,
    1088     2177,  2179,  2180,  2184,  2185,  2186,  2187,  2221,  2223,  2224,
    1089     2226,  2231,  2236,  2241,  2243,  2245,  2250,  2252,  2254,  2256,
    1090     2261,  2263,  2272,  2274,  2275,  2280,  2282,  2284,  2289,  2291,
    1091     2293,  2298,  2300,  2302,  2311,  2312,  2313,  2317,  2319,  2321,
    1092     2326,  2328,  2330,  2335,  2337,  2339,  2354,  2356,  2357,  2359,
    1093     2364,  2365,  2370,  2372,  2374,  2379,  2381,  2383,  2385,  2390,
    1094     2392,  2394,  2404,  2406,  2407,  2409,  2414,  2416,  2418,  2423,
    1095     2425,  2427,  2429,  2434,  2436,  2438,  2469,  2471,  2472,  2474,
    1096     2479,  2484,  2492,  2494,  2496,  2501,  2503,  2508,  2510,  2524,
    1097     2525,  2527,  2532,  2534,  2536,  2538,  2540,  2545,  2546,  2548,
    1098     2550,  2555,  2557,  2559,  2565,  2567,  2569,  2573,  2575,  2577,
    1099     2579,  2593,  2594,  2596,  2601,  2603,  2605,  2607,  2609,  2614,
    1100     2615,  2617,  2619,  2624,  2626,  2628,  2634,  2635,  2637,  2646,
    1101     2649,  2651,  2654,  2656,  2658,  2671,  2672,  2674,  2679,  2681,
    1102     2683,  2685,  2687,  2692,  2693,  2695,  2697,  2702,  2704,  2712,
    1103     2713,  2714,  2719,  2720,  2724,  2726,  2728,  2730,  2732,  2734,
    1104     2741,  2743,  2745,  2747,  2749,  2752,  2754,  2756,  2758,  2760,
    1105     2765,  2767,  2769,  2774,  2800,  2801,  2803,  2807,  2808,  2812,
    1106     2814,  2816,  2818,  2820,  2822,  2829,  2831,  2833,  2835,  2837,
    1107     2839,  2844,  2851,  2853,  2871,  2873,  2878,  2879
     1032       0,   306,   306,   310,   317,   318,   319,   320,   321,   325,
     1033     326,   327,   331,   332,   336,   337,   341,   342,   346,   350,
     1034     351,   362,   364,   366,   367,   369,   374,   375,   381,   383,
     1035     385,   386,   387,   389,   390,   392,   394,   396,   405,   406,
     1036     412,   413,   417,   418,   422,   424,   426,   428,   430,   432,
     1037     434,   439,   441,   443,   447,   449,   453,   456,   458,   460,
     1038     465,   478,   480,   482,   484,   486,   488,   490,   492,   494,
     1039     496,   498,   505,   506,   512,   513,   514,   515,   519,   520,
     1040     527,   528,   530,   532,   537,   538,   540,   545,   546,   548,
     1041     553,   554,   556,   558,   560,   565,   566,   568,   573,   574,
     1042     579,   580,   585,   586,   591,   592,   597,   598,   603,   604,
     1043     607,   614,   619,   620,   628,   629,   633,   634,   635,   636,
     1044     637,   638,   639,   640,   641,   642,   643,   644,   654,   656,
     1045     661,   662,   667,   668,   674,   675,   681,   682,   683,   684,
     1046     685,   686,   687,   688,   689,   699,   706,   708,   718,   719,
     1047     724,   726,   732,   734,   738,   739,   744,   749,   752,   754,
     1048     756,   766,   768,   779,   780,   782,   786,   788,   792,   793,
     1049     798,   799,   803,   808,   809,   813,   815,   821,   822,   826,
     1050     828,   830,   832,   838,   839,   843,   845,   850,   852,   854,
     1051     859,   861,   866,   868,   872,   875,   879,   882,   886,   888,
     1052     890,   892,   897,   899,   901,   906,   908,   910,   912,   914,
     1053     919,   921,   923,   925,   930,   942,   943,   948,   950,   955,
     1054     959,   961,   963,   965,   967,   973,   974,   980,   981,   985,
     1055     986,   991,   993,   999,  1000,  1002,  1007,  1012,  1022,  1024,
     1056    1028,  1029,  1034,  1036,  1040,  1041,  1045,  1047,  1051,  1052,
     1057    1056,  1057,  1061,  1062,  1077,  1078,  1079,  1080,  1081,  1085,
     1058    1090,  1097,  1107,  1112,  1117,  1125,  1130,  1135,  1140,  1145,
     1059    1175,  1180,  1187,  1189,  1196,  1201,  1206,  1217,  1222,  1227,
     1060    1232,  1237,  1246,  1251,  1259,  1260,  1261,  1262,  1268,  1273,
     1061    1281,  1282,  1283,  1284,  1288,  1289,  1290,  1291,  1296,  1297,
     1062    1306,  1307,  1312,  1313,  1318,  1320,  1322,  1324,  1326,  1329,
     1063    1328,  1340,  1341,  1343,  1353,  1354,  1359,  1361,  1363,  1365,
     1064    1367,  1370,  1372,  1375,  1380,  1382,  1384,  1386,  1388,  1390,
     1065    1392,  1394,  1396,  1398,  1400,  1402,  1404,  1406,  1408,  1414,
     1066    1415,  1417,  1419,  1421,  1426,  1427,  1433,  1434,  1436,  1438,
     1067    1443,  1445,  1447,  1449,  1454,  1455,  1457,  1459,  1464,  1465,
     1068    1467,  1472,  1473,  1475,  1477,  1482,  1484,  1486,  1491,  1492,
     1069    1496,  1498,  1504,  1503,  1507,  1509,  1514,  1516,  1522,  1523,
     1070    1528,  1529,  1531,  1532,  1541,  1542,  1544,  1546,  1551,  1553,
     1071    1559,  1560,  1562,  1565,  1568,  1573,  1574,  1579,  1584,  1588,
     1072    1590,  1596,  1595,  1602,  1604,  1610,  1611,  1619,  1620,  1624,
     1073    1625,  1626,  1628,  1630,  1637,  1638,  1640,  1642,  1647,  1648,
     1074    1654,  1655,  1659,  1660,  1665,  1666,  1667,  1669,  1677,  1678,
     1075    1680,  1683,  1685,  1689,  1690,  1691,  1693,  1695,  1699,  1704,
     1076    1712,  1713,  1722,  1724,  1729,  1730,  1731,  1735,  1736,  1737,
     1077    1741,  1742,  1743,  1747,  1748,  1749,  1754,  1755,  1756,  1757,
     1078    1763,  1764,  1766,  1771,  1772,  1777,  1778,  1779,  1780,  1781,
     1079    1796,  1797,  1802,  1803,  1809,  1811,  1814,  1816,  1818,  1841,
     1080    1842,  1844,  1846,  1851,  1852,  1854,  1859,  1864,  1865,  1871,
     1081    1870,  1874,  1878,  1880,  1882,  1888,  1889,  1894,  1899,  1901,
     1082    1906,  1908,  1909,  1911,  1916,  1918,  1920,  1925,  1927,  1932,
     1083    1937,  1945,  1951,  1950,  1964,  1965,  1970,  1971,  1975,  1980,
     1084    1985,  1993,  1998,  2009,  2010,  2015,  2016,  2022,  2023,  2027,
     1085    2028,  2029,  2032,  2031,  2042,  2051,  2057,  2063,  2072,  2078,
     1086    2084,  2090,  2096,  2104,  2110,  2118,  2124,  2133,  2134,  2135,
     1087    2139,  2143,  2145,  2150,  2151,  2155,  2156,  2161,  2167,  2168,
     1088    2171,  2173,  2174,  2178,  2179,  2180,  2181,  2215,  2217,  2218,
     1089    2220,  2225,  2230,  2235,  2237,  2239,  2244,  2246,  2248,  2250,
     1090    2255,  2257,  2266,  2268,  2269,  2274,  2276,  2278,  2283,  2285,
     1091    2287,  2292,  2294,  2296,  2305,  2306,  2307,  2311,  2313,  2315,
     1092    2320,  2322,  2324,  2329,  2331,  2333,  2348,  2350,  2351,  2353,
     1093    2358,  2359,  2364,  2366,  2368,  2373,  2375,  2377,  2379,  2384,
     1094    2386,  2388,  2398,  2400,  2401,  2403,  2408,  2410,  2412,  2417,
     1095    2419,  2421,  2423,  2428,  2430,  2432,  2463,  2465,  2466,  2468,
     1096    2473,  2478,  2486,  2488,  2490,  2495,  2497,  2502,  2504,  2518,
     1097    2519,  2521,  2526,  2528,  2530,  2532,  2534,  2539,  2540,  2542,
     1098    2544,  2549,  2551,  2553,  2559,  2561,  2563,  2567,  2569,  2571,
     1099    2573,  2587,  2588,  2590,  2595,  2597,  2599,  2601,  2603,  2608,
     1100    2609,  2611,  2613,  2618,  2620,  2622,  2628,  2629,  2631,  2640,
     1101    2643,  2645,  2648,  2650,  2652,  2665,  2666,  2668,  2673,  2675,
     1102    2677,  2679,  2681,  2686,  2687,  2689,  2691,  2696,  2698,  2706,
     1103    2707,  2708,  2713,  2714,  2718,  2720,  2722,  2724,  2726,  2728,
     1104    2735,  2737,  2739,  2741,  2743,  2746,  2748,  2750,  2752,  2754,
     1105    2759,  2761,  2763,  2768,  2794,  2795,  2797,  2801,  2802,  2806,
     1106    2808,  2810,  2812,  2814,  2816,  2823,  2825,  2827,  2829,  2831,
     1107    2833,  2838,  2845,  2847,  2865,  2867,  2872,  2873
    11081108};
    11091109#endif
     
    49284928
    49294929/* Line 1806 of yacc.c  */
    4930 #line 305 "parser.yy"
     4930#line 306 "parser.yy"
    49314931    { typedefTable.enterScope(); }
    49324932    break;
     
    49354935
    49364936/* Line 1806 of yacc.c  */
    4937 #line 309 "parser.yy"
     4937#line 310 "parser.yy"
    49384938    { typedefTable.leaveScope(); }
    49394939    break;
     
    49424942
    49434943/* Line 1806 of yacc.c  */
    4944 #line 316 "parser.yy"
     4944#line 317 "parser.yy"
    49454945    { (yyval.en) = new ExpressionNode( build_constantInteger( *(yyvsp[(1) - (1)].tok) ) ); }
    49464946    break;
    49474947
    49484948  case 5:
    4949 
    4950 /* Line 1806 of yacc.c  */
    4951 #line 317 "parser.yy"
    4952     { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); }
    4953     break;
    4954 
    4955   case 6:
    49564949
    49574950/* Line 1806 of yacc.c  */
     
    49604953    break;
    49614954
    4962   case 7:
     4955  case 6:
    49634956
    49644957/* Line 1806 of yacc.c  */
     
    49674960    break;
    49684961
     4962  case 7:
     4963
     4964/* Line 1806 of yacc.c  */
     4965#line 320 "parser.yy"
     4966    { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); }
     4967    break;
     4968
    49694969  case 8:
    49704970
    49714971/* Line 1806 of yacc.c  */
    4972 #line 320 "parser.yy"
     4972#line 321 "parser.yy"
    49734973    { (yyval.en) = new ExpressionNode( build_constantChar( *(yyvsp[(1) - (1)].tok) ) ); }
    49744974    break;
     
    49774977
    49784978/* Line 1806 of yacc.c  */
    4979 #line 345 "parser.yy"
     4979#line 346 "parser.yy"
    49804980    { (yyval.constant) = build_constantStr( *(yyvsp[(1) - (1)].str) ); }
    49814981    break;
     
    49844984
    49854985/* Line 1806 of yacc.c  */
    4986 #line 349 "parser.yy"
     4986#line 350 "parser.yy"
    49874987    { (yyval.str) = (yyvsp[(1) - (1)].tok); }
    49884988    break;
     
    49914991
    49924992/* Line 1806 of yacc.c  */
    4993 #line 351 "parser.yy"
     4993#line 352 "parser.yy"
    49944994    {
    49954995                        appendStr( (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].tok) );                                            // append 2nd juxtaposed string to 1st
     
    50025002
    50035003/* Line 1806 of yacc.c  */
    5004 #line 362 "parser.yy"
     5004#line 363 "parser.yy"
    50055005    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
    50065006    break;
     
    50095009
    50105010/* Line 1806 of yacc.c  */
    5011 #line 364 "parser.yy"
     5011#line 365 "parser.yy"
    50125012    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
    50135013    break;
     
    50165016
    50175017/* Line 1806 of yacc.c  */
    5018 #line 367 "parser.yy"
     5018#line 368 "parser.yy"
    50195019    { (yyval.en) = (yyvsp[(2) - (3)].en); }
    50205020    break;
     
    50235023
    50245024/* Line 1806 of yacc.c  */
    5025 #line 369 "parser.yy"
     5025#line 370 "parser.yy"
    50265026    { (yyval.en) = new ExpressionNode( build_valexpr( (yyvsp[(2) - (3)].sn) ) ); }
    50275027    break;
     
    50305030
    50315031/* Line 1806 of yacc.c  */
    5032 #line 379 "parser.yy"
     5032#line 380 "parser.yy"
    50335033    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Index, (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en) ) ); }
    50345034    break;
     
    50375037
    50385038/* Line 1806 of yacc.c  */
    5039 #line 381 "parser.yy"
     5039#line 382 "parser.yy"
    50405040    { (yyval.en) = new ExpressionNode( build_func( (yyvsp[(1) - (4)].en), (yyvsp[(3) - (4)].en) ) ); }
    50415041    break;
     
    50445044
    50455045/* Line 1806 of yacc.c  */
    5046 #line 383 "parser.yy"
     5046#line 384 "parser.yy"
    50475047    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); }
    50485048    break;
    50495049
    5050   case 30:
    5051 
    5052 /* Line 1806 of yacc.c  */
    5053 #line 385 "parser.yy"
    5054     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
    5055     break;
    5056 
    5057   case 31:
    5058 
    5059 /* Line 1806 of yacc.c  */
    5060 #line 387 "parser.yy"
    5061     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (2)].en), build_field_name_REALFRACTIONconstant( *(yyvsp[(2) - (2)].tok) ) ) ); }
    5062     break;
    5063 
    50645050  case 32:
    50655051
    50665052/* Line 1806 of yacc.c  */
    5067 #line 389 "parser.yy"
     5053#line 388 "parser.yy"
    50685054    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); }
    50695055    break;
    50705056
    5071   case 33:
     5057  case 34:
    50725058
    50735059/* Line 1806 of yacc.c  */
    50745060#line 391 "parser.yy"
    5075     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
    5076     break;
    5077 
    5078   case 34:
     5061    { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); }
     5062    break;
     5063
     5064  case 35:
    50795065
    50805066/* Line 1806 of yacc.c  */
    50815067#line 393 "parser.yy"
    5082     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); }
    5083     break;
    5084 
    5085   case 35:
     5068    { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); }
     5069    break;
     5070
     5071  case 36:
    50865072
    50875073/* Line 1806 of yacc.c  */
    50885074#line 395 "parser.yy"
    5089     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); }
    5090     break;
    5091 
    5092   case 36:
     5075    { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); }
     5076    break;
     5077
     5078  case 37:
    50935079
    50945080/* Line 1806 of yacc.c  */
    50955081#line 397 "parser.yy"
    5096     { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); }
    5097     break;
    5098 
    5099   case 37:
    5100 
    5101 /* Line 1806 of yacc.c  */
    5102 #line 399 "parser.yy"
    51035082    {
    51045083                        Token fn;
     
    51115090
    51125091/* Line 1806 of yacc.c  */
    5113 #line 409 "parser.yy"
     5092#line 407 "parser.yy"
    51145093    { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
    51155094    break;
     
    51185097
    51195098/* Line 1806 of yacc.c  */
    5120 #line 414 "parser.yy"
     5099#line 412 "parser.yy"
    51215100    { (yyval.en) = 0; }
    51225101    break;
     
    51255104
    51265105/* Line 1806 of yacc.c  */
    5127 #line 420 "parser.yy"
     5106#line 418 "parser.yy"
    51285107    { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
    51295108    break;
    51305109
     5110  case 44:
     5111
     5112/* Line 1806 of yacc.c  */
     5113#line 423 "parser.yy"
     5114    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
     5115    break;
     5116
    51315117  case 45:
    51325118
    51335119/* Line 1806 of yacc.c  */
    5134 #line 426 "parser.yy"
    5135     { (yyval.en) = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *(yyvsp[(1) - (2)].tok) ) ), maybeMoveBuild<Expression>( (yyvsp[(2) - (2)].en) ) ) ); }
     5120#line 425 "parser.yy"
     5121    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(2) - (2)].en), build_varref( (yyvsp[(1) - (2)].tok) ) ) ); }
    51365122    break;
    51375123
     
    51395125
    51405126/* Line 1806 of yacc.c  */
    5141 #line 428 "parser.yy"
    5142     { (yyval.en) = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *(yyvsp[(1) - (6)].tok) ) ), build_tuple( (yyvsp[(4) - (6)].en) ) ) ); }
     5127#line 427 "parser.yy"
     5128    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(4) - (6)].en), build_varref( (yyvsp[(1) - (6)].tok) ) ) ); }
    51435129    break;
    51445130
     
    51465132
    51475133/* Line 1806 of yacc.c  */
    5148 #line 430 "parser.yy"
    5149     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); }
     5134#line 429 "parser.yy"
     5135    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
    51505136    break;
    51515137
     
    51535139
    51545140/* Line 1806 of yacc.c  */
    5155 #line 432 "parser.yy"
    5156     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
     5141#line 431 "parser.yy"
     5142    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
    51575143    break;
    51585144
     
    51605146
    51615147/* Line 1806 of yacc.c  */
    5162 #line 434 "parser.yy"
    5163     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); }
     5148#line 433 "parser.yy"
     5149    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
    51645150    break;
    51655151
     
    51675153
    51685154/* Line 1806 of yacc.c  */
    5169 #line 436 "parser.yy"
    5170     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
     5155#line 435 "parser.yy"
     5156    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
    51715157    break;
    51725158
     
    51745160
    51755161/* Line 1806 of yacc.c  */
    5176 #line 441 "parser.yy"
    5177     { (yyval.en) = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *(yyvsp[(1) - (2)].tok) ), (yyvsp[(2) - (2)].en) ) ); }
     5162#line 440 "parser.yy"
     5163    { (yyval.tok) = (yyvsp[(1) - (2)].tok); }
    51785164    break;
    51795165
     
    51815167
    51825168/* Line 1806 of yacc.c  */
    5183 #line 443 "parser.yy"
    5184     { (yyval.en) = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *(yyvsp[(1) - (2)].tok) ), (yyvsp[(2) - (2)].en) ) ); }
     5169#line 442 "parser.yy"
     5170    { (yyval.tok) = (yyvsp[(1) - (2)].tok); }
    51855171    break;
    51865172
     
    51885174
    51895175/* Line 1806 of yacc.c  */
    5190 #line 445 "parser.yy"
    5191     { (yyval.en) = new ExpressionNode( build_field_name_fraction_constants( build_varref( (yyvsp[(1) - (2)].tok) ), (yyvsp[(2) - (2)].en) ) ); }
    5192     break;
    5193 
    5194   case 54:
    5195 
    5196 /* Line 1806 of yacc.c  */
    5197 #line 450 "parser.yy"
    5198     { (yyval.en) = nullptr; }
    5199     break;
    5200 
    5201   case 55:
    5202 
    5203 /* Line 1806 of yacc.c  */
    5204 #line 452 "parser.yy"
    5205     {
    5206                         Expression * constant = build_field_name_REALFRACTIONconstant( *(yyvsp[(2) - (2)].tok) );
    5207                         (yyval.en) = (yyvsp[(1) - (2)].en) != nullptr ? new ExpressionNode( build_fieldSel( (yyvsp[(1) - (2)].en),  constant ) ) : new ExpressionNode( constant );
    5208                 }
     5176#line 444 "parser.yy"
     5177    { (yyval.tok) = (yyvsp[(1) - (2)].tok); }
    52095178    break;
    52105179
     
    52125181
    52135182/* Line 1806 of yacc.c  */
    5214 #line 463 "parser.yy"
     5183#line 457 "parser.yy"
    52155184    { (yyval.en) = (yyvsp[(1) - (1)].en); }
    52165185    break;
     
    52195188
    52205189/* Line 1806 of yacc.c  */
    5221 #line 465 "parser.yy"
     5190#line 459 "parser.yy"
    52225191    { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); }
    52235192    break;
     
    52265195
    52275196/* Line 1806 of yacc.c  */
    5228 #line 467 "parser.yy"
     5197#line 461 "parser.yy"
    52295198    { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); }
    52305199    break;
     
    52335202
    52345203/* Line 1806 of yacc.c  */
    5235 #line 472 "parser.yy"
     5204#line 466 "parser.yy"
    52365205    {
    52375206                        switch ( (yyvsp[(1) - (2)].op) ) {
     
    52515220
    52525221/* Line 1806 of yacc.c  */
     5222#line 479 "parser.yy"
     5223    { (yyval.en) = new ExpressionNode( build_unary_val( (yyvsp[(1) - (2)].op), (yyvsp[(2) - (2)].en) ) ); }
     5224    break;
     5225
     5226  case 62:
     5227
     5228/* Line 1806 of yacc.c  */
     5229#line 481 "parser.yy"
     5230    { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); }
     5231    break;
     5232
     5233  case 63:
     5234
     5235/* Line 1806 of yacc.c  */
     5236#line 483 "parser.yy"
     5237    { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Decr, (yyvsp[(2) - (2)].en) ) ); }
     5238    break;
     5239
     5240  case 64:
     5241
     5242/* Line 1806 of yacc.c  */
    52535243#line 485 "parser.yy"
    5254     { (yyval.en) = new ExpressionNode( build_unary_val( (yyvsp[(1) - (2)].op), (yyvsp[(2) - (2)].en) ) ); }
    5255     break;
    5256 
    5257   case 62:
     5244    { (yyval.en) = new ExpressionNode( build_sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); }
     5245    break;
     5246
     5247  case 65:
    52585248
    52595249/* Line 1806 of yacc.c  */
    52605250#line 487 "parser.yy"
    5261     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); }
    5262     break;
    5263 
    5264   case 63:
     5251    { (yyval.en) = new ExpressionNode( build_sizeOftype( (yyvsp[(3) - (4)].decl) ) ); }
     5252    break;
     5253
     5254  case 66:
    52655255
    52665256/* Line 1806 of yacc.c  */
    52675257#line 489 "parser.yy"
    5268     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Decr, (yyvsp[(2) - (2)].en) ) ); }
    5269     break;
    5270 
    5271   case 64:
     5258    { (yyval.en) = new ExpressionNode( build_alignOfexpr( (yyvsp[(2) - (2)].en) ) ); }
     5259    break;
     5260
     5261  case 67:
    52725262
    52735263/* Line 1806 of yacc.c  */
    52745264#line 491 "parser.yy"
    5275     { (yyval.en) = new ExpressionNode( build_sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); }
    5276     break;
    5277 
    5278   case 65:
     5265    { (yyval.en) = new ExpressionNode( build_alignOftype( (yyvsp[(3) - (4)].decl) ) ); }
     5266    break;
     5267
     5268  case 68:
    52795269
    52805270/* Line 1806 of yacc.c  */
    52815271#line 493 "parser.yy"
    5282     { (yyval.en) = new ExpressionNode( build_sizeOftype( (yyvsp[(3) - (4)].decl) ) ); }
    5283     break;
    5284 
    5285   case 66:
     5272    { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); }
     5273    break;
     5274
     5275  case 69:
    52865276
    52875277/* Line 1806 of yacc.c  */
    52885278#line 495 "parser.yy"
    5289     { (yyval.en) = new ExpressionNode( build_alignOfexpr( (yyvsp[(2) - (2)].en) ) ); }
    5290     break;
    5291 
    5292   case 67:
     5279    { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); }
     5280    break;
     5281
     5282  case 70:
    52935283
    52945284/* Line 1806 of yacc.c  */
    52955285#line 497 "parser.yy"
    5296     { (yyval.en) = new ExpressionNode( build_alignOftype( (yyvsp[(3) - (4)].decl) ) ); }
    5297     break;
    5298 
    5299   case 68:
     5286    { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); }
     5287    break;
     5288
     5289  case 71:
    53005290
    53015291/* Line 1806 of yacc.c  */
    53025292#line 499 "parser.yy"
    5303     { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); }
    5304     break;
    5305 
    5306   case 69:
    5307 
    5308 /* Line 1806 of yacc.c  */
    5309 #line 501 "parser.yy"
    5310     { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); }
    5311     break;
    5312 
    5313   case 70:
    5314 
    5315 /* Line 1806 of yacc.c  */
    5316 #line 503 "parser.yy"
    5317     { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); }
    5318     break;
    5319 
    5320   case 71:
     5293    { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); }
     5294    break;
     5295
     5296  case 72:
    53215297
    53225298/* Line 1806 of yacc.c  */
    53235299#line 505 "parser.yy"
    5324     { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); }
    5325     break;
    5326 
    5327   case 72:
    5328 
    5329 /* Line 1806 of yacc.c  */
    5330 #line 511 "parser.yy"
    53315300    { (yyval.op) = OperKinds::PointTo; }
    53325301    break;
     
    53355304
    53365305/* Line 1806 of yacc.c  */
     5306#line 506 "parser.yy"
     5307    { (yyval.op) = OperKinds::AddressOf; }
     5308    break;
     5309
     5310  case 74:
     5311
     5312/* Line 1806 of yacc.c  */
    53375313#line 512 "parser.yy"
    5338     { (yyval.op) = OperKinds::AddressOf; }
    5339     break;
    5340 
    5341   case 74:
    5342 
    5343 /* Line 1806 of yacc.c  */
    5344 #line 518 "parser.yy"
    53455314    { (yyval.op) = OperKinds::UnPlus; }
    53465315    break;
     
    53495318
    53505319/* Line 1806 of yacc.c  */
    5351 #line 519 "parser.yy"
     5320#line 513 "parser.yy"
    53525321    { (yyval.op) = OperKinds::UnMinus; }
    53535322    break;
     
    53565325
    53575326/* Line 1806 of yacc.c  */
    5358 #line 520 "parser.yy"
     5327#line 514 "parser.yy"
    53595328    { (yyval.op) = OperKinds::Neg; }
    53605329    break;
     
    53635332
    53645333/* Line 1806 of yacc.c  */
     5334#line 515 "parser.yy"
     5335    { (yyval.op) = OperKinds::BitNeg; }
     5336    break;
     5337
     5338  case 79:
     5339
     5340/* Line 1806 of yacc.c  */
    53655341#line 521 "parser.yy"
    5366     { (yyval.op) = OperKinds::BitNeg; }
    5367     break;
    5368 
    5369   case 79:
    5370 
    5371 /* Line 1806 of yacc.c  */
    5372 #line 527 "parser.yy"
    53735342    { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); }
    53745343    break;
     
    53775346
    53785347/* Line 1806 of yacc.c  */
    5379 #line 535 "parser.yy"
     5348#line 529 "parser.yy"
    53805349    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mul, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    53815350    break;
     
    53845353
    53855354/* Line 1806 of yacc.c  */
    5386 #line 537 "parser.yy"
     5355#line 531 "parser.yy"
    53875356    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Div, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    53885357    break;
     
    53915360
    53925361/* Line 1806 of yacc.c  */
     5362#line 533 "parser.yy"
     5363    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5364    break;
     5365
     5366  case 85:
     5367
     5368/* Line 1806 of yacc.c  */
    53935369#line 539 "parser.yy"
    5394     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5395     break;
    5396 
    5397   case 85:
    5398 
    5399 /* Line 1806 of yacc.c  */
    5400 #line 545 "parser.yy"
    54015370    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Plus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    54025371    break;
     
    54055374
    54065375/* Line 1806 of yacc.c  */
     5376#line 541 "parser.yy"
     5377    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5378    break;
     5379
     5380  case 88:
     5381
     5382/* Line 1806 of yacc.c  */
    54075383#line 547 "parser.yy"
    5408     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5409     break;
    5410 
    5411   case 88:
    5412 
    5413 /* Line 1806 of yacc.c  */
    5414 #line 553 "parser.yy"
    54155384    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    54165385    break;
     
    54195388
    54205389/* Line 1806 of yacc.c  */
     5390#line 549 "parser.yy"
     5391    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5392    break;
     5393
     5394  case 91:
     5395
     5396/* Line 1806 of yacc.c  */
    54215397#line 555 "parser.yy"
    5422     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5423     break;
    5424 
    5425   case 91:
     5398    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5399    break;
     5400
     5401  case 92:
     5402
     5403/* Line 1806 of yacc.c  */
     5404#line 557 "parser.yy"
     5405    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5406    break;
     5407
     5408  case 93:
     5409
     5410/* Line 1806 of yacc.c  */
     5411#line 559 "parser.yy"
     5412    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5413    break;
     5414
     5415  case 94:
    54265416
    54275417/* Line 1806 of yacc.c  */
    54285418#line 561 "parser.yy"
    5429     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5430     break;
    5431 
    5432   case 92:
    5433 
    5434 /* Line 1806 of yacc.c  */
    5435 #line 563 "parser.yy"
    5436     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5437     break;
    5438 
    5439   case 93:
    5440 
    5441 /* Line 1806 of yacc.c  */
    5442 #line 565 "parser.yy"
    5443     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5444     break;
    5445 
    5446   case 94:
     5419    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5420    break;
     5421
     5422  case 96:
    54475423
    54485424/* Line 1806 of yacc.c  */
    54495425#line 567 "parser.yy"
    5450     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5451     break;
    5452 
    5453   case 96:
    5454 
    5455 /* Line 1806 of yacc.c  */
    5456 #line 573 "parser.yy"
    54575426    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Eq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    54585427    break;
     
    54615430
    54625431/* Line 1806 of yacc.c  */
     5432#line 569 "parser.yy"
     5433    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5434    break;
     5435
     5436  case 99:
     5437
     5438/* Line 1806 of yacc.c  */
    54635439#line 575 "parser.yy"
    5464     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5465     break;
    5466 
    5467   case 99:
     5440    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5441    break;
     5442
     5443  case 101:
    54685444
    54695445/* Line 1806 of yacc.c  */
    54705446#line 581 "parser.yy"
    5471     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5472     break;
    5473 
    5474   case 101:
     5447    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5448    break;
     5449
     5450  case 103:
    54755451
    54765452/* Line 1806 of yacc.c  */
    54775453#line 587 "parser.yy"
    5478     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5479     break;
    5480 
    5481   case 103:
     5454    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5455    break;
     5456
     5457  case 105:
    54825458
    54835459/* Line 1806 of yacc.c  */
    54845460#line 593 "parser.yy"
    5485     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5486     break;
    5487 
    5488   case 105:
     5461    { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); }
     5462    break;
     5463
     5464  case 107:
    54895465
    54905466/* Line 1806 of yacc.c  */
    54915467#line 599 "parser.yy"
    5492     { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); }
    5493     break;
    5494 
    5495   case 107:
     5468    { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); }
     5469    break;
     5470
     5471  case 109:
    54965472
    54975473/* Line 1806 of yacc.c  */
    54985474#line 605 "parser.yy"
    5499     { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); }
    5500     break;
    5501 
    5502   case 109:
    5503 
    5504 /* Line 1806 of yacc.c  */
    5505 #line 611 "parser.yy"
    55065475    { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
    55075476    break;
     
    55105479
    55115480/* Line 1806 of yacc.c  */
    5512 #line 614 "parser.yy"
     5481#line 608 "parser.yy"
    55135482    { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (4)].en), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ) ); }
    55145483    break;
     
    55175486
    55185487/* Line 1806 of yacc.c  */
    5519 #line 627 "parser.yy"
     5488#line 621 "parser.yy"
    55205489    { (yyval.en) = new ExpressionNode( build_binary_ptr( (yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    55215490    break;
     
    55245493
    55255494/* Line 1806 of yacc.c  */
     5495#line 628 "parser.yy"
     5496    { (yyval.en) = nullptr; }
     5497    break;
     5498
     5499  case 116:
     5500
     5501/* Line 1806 of yacc.c  */
     5502#line 633 "parser.yy"
     5503    { (yyval.op) = OperKinds::Assign; }
     5504    break;
     5505
     5506  case 117:
     5507
     5508/* Line 1806 of yacc.c  */
    55265509#line 634 "parser.yy"
    5527     { (yyval.en) = nullptr; }
    5528     break;
    5529 
    5530   case 116:
     5510    { (yyval.op) = OperKinds::AtAssn; }
     5511    break;
     5512
     5513  case 118:
     5514
     5515/* Line 1806 of yacc.c  */
     5516#line 635 "parser.yy"
     5517    { (yyval.op) = OperKinds::MulAssn; }
     5518    break;
     5519
     5520  case 119:
     5521
     5522/* Line 1806 of yacc.c  */
     5523#line 636 "parser.yy"
     5524    { (yyval.op) = OperKinds::DivAssn; }
     5525    break;
     5526
     5527  case 120:
     5528
     5529/* Line 1806 of yacc.c  */
     5530#line 637 "parser.yy"
     5531    { (yyval.op) = OperKinds::ModAssn; }
     5532    break;
     5533
     5534  case 121:
     5535
     5536/* Line 1806 of yacc.c  */
     5537#line 638 "parser.yy"
     5538    { (yyval.op) = OperKinds::PlusAssn; }
     5539    break;
     5540
     5541  case 122:
    55315542
    55325543/* Line 1806 of yacc.c  */
    55335544#line 639 "parser.yy"
    5534     { (yyval.op) = OperKinds::Assign; }
    5535     break;
    5536 
    5537   case 117:
     5545    { (yyval.op) = OperKinds::MinusAssn; }
     5546    break;
     5547
     5548  case 123:
    55385549
    55395550/* Line 1806 of yacc.c  */
    55405551#line 640 "parser.yy"
    5541     { (yyval.op) = OperKinds::AtAssn; }
    5542     break;
    5543 
    5544   case 118:
     5552    { (yyval.op) = OperKinds::LSAssn; }
     5553    break;
     5554
     5555  case 124:
    55455556
    55465557/* Line 1806 of yacc.c  */
    55475558#line 641 "parser.yy"
    5548     { (yyval.op) = OperKinds::MulAssn; }
    5549     break;
    5550 
    5551   case 119:
     5559    { (yyval.op) = OperKinds::RSAssn; }
     5560    break;
     5561
     5562  case 125:
    55525563
    55535564/* Line 1806 of yacc.c  */
    55545565#line 642 "parser.yy"
    5555     { (yyval.op) = OperKinds::DivAssn; }
    5556     break;
    5557 
    5558   case 120:
     5566    { (yyval.op) = OperKinds::AndAssn; }
     5567    break;
     5568
     5569  case 126:
    55595570
    55605571/* Line 1806 of yacc.c  */
    55615572#line 643 "parser.yy"
    5562     { (yyval.op) = OperKinds::ModAssn; }
    5563     break;
    5564 
    5565   case 121:
     5573    { (yyval.op) = OperKinds::ERAssn; }
     5574    break;
     5575
     5576  case 127:
    55665577
    55675578/* Line 1806 of yacc.c  */
    55685579#line 644 "parser.yy"
    5569     { (yyval.op) = OperKinds::PlusAssn; }
    5570     break;
    5571 
    5572   case 122:
    5573 
    5574 /* Line 1806 of yacc.c  */
    5575 #line 645 "parser.yy"
    5576     { (yyval.op) = OperKinds::MinusAssn; }
    5577     break;
    5578 
    5579   case 123:
    5580 
    5581 /* Line 1806 of yacc.c  */
    5582 #line 646 "parser.yy"
    5583     { (yyval.op) = OperKinds::LSAssn; }
    5584     break;
    5585 
    5586   case 124:
    5587 
    5588 /* Line 1806 of yacc.c  */
    5589 #line 647 "parser.yy"
    5590     { (yyval.op) = OperKinds::RSAssn; }
    5591     break;
    5592 
    5593   case 125:
    5594 
    5595 /* Line 1806 of yacc.c  */
    5596 #line 648 "parser.yy"
    5597     { (yyval.op) = OperKinds::AndAssn; }
    5598     break;
    5599 
    5600   case 126:
    5601 
    5602 /* Line 1806 of yacc.c  */
    5603 #line 649 "parser.yy"
    5604     { (yyval.op) = OperKinds::ERAssn; }
    5605     break;
    5606 
    5607   case 127:
    5608 
    5609 /* Line 1806 of yacc.c  */
    5610 #line 650 "parser.yy"
    56115580    { (yyval.op) = OperKinds::OrAssn; }
    56125581    break;
     
    56155584
    56165585/* Line 1806 of yacc.c  */
    5617 #line 661 "parser.yy"
     5586#line 655 "parser.yy"
    56185587    { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( (yyvsp[(4) - (6)].en) ) ) ); }
    56195588    break;
     
    56225591
    56235592/* Line 1806 of yacc.c  */
     5593#line 657 "parser.yy"
     5594    { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) ) ) ); }
     5595    break;
     5596
     5597  case 131:
     5598
     5599/* Line 1806 of yacc.c  */
    56245600#line 663 "parser.yy"
    5625     { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) ) ) ); }
    5626     break;
    5627 
    5628   case 131:
     5601    { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     5602    break;
     5603
     5604  case 133:
    56295605
    56305606/* Line 1806 of yacc.c  */
    56315607#line 669 "parser.yy"
    5632     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
    5633     break;
    5634 
    5635   case 133:
    5636 
    5637 /* Line 1806 of yacc.c  */
    5638 #line 675 "parser.yy"
    56395608    { (yyval.en) = new ExpressionNode( build_comma( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    56405609    break;
     
    56435612
    56445613/* Line 1806 of yacc.c  */
    5645 #line 680 "parser.yy"
     5614#line 674 "parser.yy"
    56465615    { (yyval.en) = 0; }
    56475616    break;
     
    56505619
    56515620/* Line 1806 of yacc.c  */
    5652 #line 689 "parser.yy"
     5621#line 683 "parser.yy"
    56535622    { (yyval.sn) = (yyvsp[(1) - (1)].sn); }
    56545623    break;
     
    56575626
    56585627/* Line 1806 of yacc.c  */
    5659 #line 696 "parser.yy"
     5628#line 690 "parser.yy"
    56605629    {
    56615630                        Token fn;
     
    56685637
    56695638/* Line 1806 of yacc.c  */
    5670 #line 706 "parser.yy"
     5639#line 700 "parser.yy"
    56715640    {
    56725641                        (yyval.sn) = (yyvsp[(4) - (4)].sn)->add_label( (yyvsp[(1) - (4)].tok) );
     
    56775646
    56785647/* Line 1806 of yacc.c  */
    5679 #line 713 "parser.yy"
     5648#line 707 "parser.yy"
    56805649    { (yyval.sn) = new StatementNode( build_compound( (StatementNode *)0 ) ); }
    56815650    break;
     
    56845653
    56855654/* Line 1806 of yacc.c  */
     5655#line 714 "parser.yy"
     5656    { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); }
     5657    break;
     5658
     5659  case 149:
     5660
     5661/* Line 1806 of yacc.c  */
    56865662#line 720 "parser.yy"
    5687     { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); }
    5688     break;
    5689 
    5690   case 149:
    5691 
    5692 /* Line 1806 of yacc.c  */
    5693 #line 726 "parser.yy"
    56945663    { if ( (yyvsp[(1) - (3)].sn) != 0 ) { (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ); (yyval.sn) = (yyvsp[(1) - (3)].sn); } }
    56955664    break;
     
    56985667
    56995668/* Line 1806 of yacc.c  */
    5700 #line 731 "parser.yy"
     5669#line 725 "parser.yy"
    57015670    { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
    57025671    break;
     
    57055674
    57065675/* Line 1806 of yacc.c  */
    5707 #line 733 "parser.yy"
     5676#line 727 "parser.yy"
    57085677    {   // mark all fields in list
    57095678                        for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
     
    57165685
    57175686/* Line 1806 of yacc.c  */
    5718 #line 739 "parser.yy"
     5687#line 733 "parser.yy"
    57195688    { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
    57205689    break;
     
    57235692
    57245693/* Line 1806 of yacc.c  */
    5725 #line 746 "parser.yy"
     5694#line 740 "parser.yy"
    57265695    { if ( (yyvsp[(1) - (2)].sn) != 0 ) { (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) ); (yyval.sn) = (yyvsp[(1) - (2)].sn); } }
    57275696    break;
     
    57305699
    57315700/* Line 1806 of yacc.c  */
     5701#line 745 "parser.yy"
     5702    { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); }
     5703    break;
     5704
     5705  case 157:
     5706
     5707/* Line 1806 of yacc.c  */
    57325708#line 751 "parser.yy"
    5733     { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); }
    5734     break;
    5735 
    5736   case 157:
     5709    { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); }
     5710    break;
     5711
     5712  case 158:
     5713
     5714/* Line 1806 of yacc.c  */
     5715#line 753 "parser.yy"
     5716    { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
     5717    break;
     5718
     5719  case 159:
     5720
     5721/* Line 1806 of yacc.c  */
     5722#line 755 "parser.yy"
     5723    { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     5724    break;
     5725
     5726  case 160:
    57375727
    57385728/* Line 1806 of yacc.c  */
    57395729#line 757 "parser.yy"
    5740     { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); }
    5741     break;
    5742 
    5743   case 158:
    5744 
    5745 /* Line 1806 of yacc.c  */
    5746 #line 759 "parser.yy"
    5747     { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
    5748     break;
    5749 
    5750   case 159:
    5751 
    5752 /* Line 1806 of yacc.c  */
    5753 #line 761 "parser.yy"
    5754     { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    5755     break;
    5756 
    5757   case 160:
    5758 
    5759 /* Line 1806 of yacc.c  */
    5760 #line 763 "parser.yy"
    57615730    {
    57625731                        StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
     
    57735742
    57745743/* Line 1806 of yacc.c  */
    5775 #line 773 "parser.yy"
     5744#line 767 "parser.yy"
    57765745    { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    57775746    break;
     
    57805749
    57815750/* Line 1806 of yacc.c  */
    5782 #line 775 "parser.yy"
     5751#line 769 "parser.yy"
    57835752    {
    57845753                        StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
     
    57905759
    57915760/* Line 1806 of yacc.c  */
    5792 #line 785 "parser.yy"
     5761#line 779 "parser.yy"
    57935762    { (yyval.en) = (yyvsp[(1) - (1)].en); }
    57945763    break;
     
    57975766
    57985767/* Line 1806 of yacc.c  */
    5799 #line 787 "parser.yy"
     5768#line 781 "parser.yy"
    58005769    { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    58015770    break;
     
    58045773
    58055774/* Line 1806 of yacc.c  */
     5775#line 786 "parser.yy"
     5776    { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); }
     5777    break;
     5778
     5779  case 167:
     5780
     5781/* Line 1806 of yacc.c  */
     5782#line 788 "parser.yy"
     5783    { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); }
     5784    break;
     5785
     5786  case 168:
     5787
     5788/* Line 1806 of yacc.c  */
    58065789#line 792 "parser.yy"
    5807     { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); }
    5808     break;
    5809 
    5810   case 167:
    5811 
    5812 /* Line 1806 of yacc.c  */
    5813 #line 794 "parser.yy"
    5814     { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); }
    5815     break;
    5816 
    5817   case 168:
    5818 
    5819 /* Line 1806 of yacc.c  */
    5820 #line 798 "parser.yy"
    58215790    { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
    58225791    break;
     
    58255794
    58265795/* Line 1806 of yacc.c  */
     5796#line 793 "parser.yy"
     5797    { (yyval.sn) = new StatementNode( build_default() ); }
     5798    break;
     5799
     5800  case 171:
     5801
     5802/* Line 1806 of yacc.c  */
    58275803#line 799 "parser.yy"
    5828     { (yyval.sn) = new StatementNode( build_default() ); }
    5829     break;
    5830 
    5831   case 171:
    5832 
    5833 /* Line 1806 of yacc.c  */
    5834 #line 805 "parser.yy"
    58355804    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) )); }
    58365805    break;
     
    58395808
    58405809/* Line 1806 of yacc.c  */
    5841 #line 809 "parser.yy"
     5810#line 803 "parser.yy"
    58425811    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
    58435812    break;
     
    58465815
    58475816/* Line 1806 of yacc.c  */
     5817#line 808 "parser.yy"
     5818    { (yyval.sn) = 0; }
     5819    break;
     5820
     5821  case 175:
     5822
     5823/* Line 1806 of yacc.c  */
    58485824#line 814 "parser.yy"
     5825    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
     5826    break;
     5827
     5828  case 176:
     5829
     5830/* Line 1806 of yacc.c  */
     5831#line 816 "parser.yy"
     5832    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(3) - (3)].sn) ) ) ) ) ); }
     5833    break;
     5834
     5835  case 177:
     5836
     5837/* Line 1806 of yacc.c  */
     5838#line 821 "parser.yy"
    58495839    { (yyval.sn) = 0; }
    58505840    break;
    58515841
    5852   case 175:
    5853 
    5854 /* Line 1806 of yacc.c  */
    5855 #line 820 "parser.yy"
    5856     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
    5857     break;
    5858 
    5859   case 176:
    5860 
    5861 /* Line 1806 of yacc.c  */
    5862 #line 822 "parser.yy"
    5863     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(3) - (3)].sn) ) ) ) ) ); }
    5864     break;
    5865 
    5866   case 177:
     5842  case 179:
    58675843
    58685844/* Line 1806 of yacc.c  */
    58695845#line 827 "parser.yy"
     5846    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
     5847    break;
     5848
     5849  case 180:
     5850
     5851/* Line 1806 of yacc.c  */
     5852#line 829 "parser.yy"
     5853    { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(2) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ) ) ) ); }
     5854    break;
     5855
     5856  case 181:
     5857
     5858/* Line 1806 of yacc.c  */
     5859#line 831 "parser.yy"
     5860    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
     5861    break;
     5862
     5863  case 182:
     5864
     5865/* Line 1806 of yacc.c  */
     5866#line 833 "parser.yy"
     5867    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_last( (yyvsp[(2) - (4)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(3) - (4)].sn)->set_last( (yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
     5868    break;
     5869
     5870  case 183:
     5871
     5872/* Line 1806 of yacc.c  */
     5873#line 838 "parser.yy"
     5874    { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
     5875    break;
     5876
     5877  case 185:
     5878
     5879/* Line 1806 of yacc.c  */
     5880#line 844 "parser.yy"
    58705881    { (yyval.sn) = 0; }
    58715882    break;
    58725883
    5873   case 179:
    5874 
    5875 /* Line 1806 of yacc.c  */
    5876 #line 833 "parser.yy"
    5877     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
    5878     break;
    5879 
    5880   case 180:
    5881 
    5882 /* Line 1806 of yacc.c  */
    5883 #line 835 "parser.yy"
    5884     { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(2) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ) ) ) ); }
    5885     break;
    5886 
    5887   case 181:
    5888 
    5889 /* Line 1806 of yacc.c  */
    5890 #line 837 "parser.yy"
    5891     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
    5892     break;
    5893 
    5894   case 182:
    5895 
    5896 /* Line 1806 of yacc.c  */
    5897 #line 839 "parser.yy"
    5898     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_last( (yyvsp[(2) - (4)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(3) - (4)].sn)->set_last( (yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
    5899     break;
    5900 
    5901   case 183:
    5902 
    5903 /* Line 1806 of yacc.c  */
    5904 #line 844 "parser.yy"
     5884  case 186:
     5885
     5886/* Line 1806 of yacc.c  */
     5887#line 846 "parser.yy"
     5888    { (yyval.sn) = 0; }
     5889    break;
     5890
     5891  case 187:
     5892
     5893/* Line 1806 of yacc.c  */
     5894#line 851 "parser.yy"
     5895    { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     5896    break;
     5897
     5898  case 188:
     5899
     5900/* Line 1806 of yacc.c  */
     5901#line 853 "parser.yy"
     5902    { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); }
     5903    break;
     5904
     5905  case 189:
     5906
     5907/* Line 1806 of yacc.c  */
     5908#line 855 "parser.yy"
     5909    { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
     5910    break;
     5911
     5912  case 190:
     5913
     5914/* Line 1806 of yacc.c  */
     5915#line 860 "parser.yy"
     5916    { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
     5917    break;
     5918
     5919  case 191:
     5920
     5921/* Line 1806 of yacc.c  */
     5922#line 862 "parser.yy"
     5923    { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
     5924    break;
     5925
     5926  case 192:
     5927
     5928/* Line 1806 of yacc.c  */
     5929#line 867 "parser.yy"
     5930    { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); }
     5931    break;
     5932
     5933  case 193:
     5934
     5935/* Line 1806 of yacc.c  */
     5936#line 871 "parser.yy"
     5937    { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); }
     5938    break;
     5939
     5940  case 194:
     5941
     5942/* Line 1806 of yacc.c  */
     5943#line 874 "parser.yy"
     5944    { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); }
     5945    break;
     5946
     5947  case 195:
     5948
     5949/* Line 1806 of yacc.c  */
     5950#line 878 "parser.yy"
     5951    { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); }
     5952    break;
     5953
     5954  case 196:
     5955
     5956/* Line 1806 of yacc.c  */
     5957#line 881 "parser.yy"
    59055958    { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
    59065959    break;
    59075960
    5908   case 185:
    5909 
    5910 /* Line 1806 of yacc.c  */
    5911 #line 850 "parser.yy"
    5912     { (yyval.sn) = 0; }
    5913     break;
    5914 
    5915   case 186:
    5916 
    5917 /* Line 1806 of yacc.c  */
    5918 #line 852 "parser.yy"
    5919     { (yyval.sn) = 0; }
    5920     break;
    5921 
    5922   case 187:
    5923 
    5924 /* Line 1806 of yacc.c  */
    5925 #line 857 "parser.yy"
    5926     { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    5927     break;
    5928 
    5929   case 188:
    5930 
    5931 /* Line 1806 of yacc.c  */
    5932 #line 859 "parser.yy"
    5933     { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); }
    5934     break;
    5935 
    5936   case 189:
    5937 
    5938 /* Line 1806 of yacc.c  */
    5939 #line 861 "parser.yy"
    5940     { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
    5941     break;
    5942 
    5943   case 190:
    5944 
    5945 /* Line 1806 of yacc.c  */
    5946 #line 866 "parser.yy"
    5947     { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
    5948     break;
    5949 
    5950   case 191:
    5951 
    5952 /* Line 1806 of yacc.c  */
    5953 #line 868 "parser.yy"
    5954     { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
    5955     break;
    5956 
    5957   case 192:
    5958 
    5959 /* Line 1806 of yacc.c  */
    5960 #line 873 "parser.yy"
    5961     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); }
    5962     break;
    5963 
    5964   case 193:
    5965 
    5966 /* Line 1806 of yacc.c  */
    5967 #line 877 "parser.yy"
    5968     { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); }
    5969     break;
    5970 
    5971   case 194:
    5972 
    5973 /* Line 1806 of yacc.c  */
    5974 #line 880 "parser.yy"
    5975     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); }
    5976     break;
    5977 
    5978   case 195:
    5979 
    5980 /* Line 1806 of yacc.c  */
    5981 #line 884 "parser.yy"
    5982     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); }
    5983     break;
    5984 
    5985   case 196:
     5961  case 197:
     5962
     5963/* Line 1806 of yacc.c  */
     5964#line 885 "parser.yy"
     5965    { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); }
     5966    break;
     5967
     5968  case 198:
    59865969
    59875970/* Line 1806 of yacc.c  */
    59885971#line 887 "parser.yy"
    5989     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
    5990     break;
    5991 
    5992   case 197:
     5972    { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); }
     5973    break;
     5974
     5975  case 199:
     5976
     5977/* Line 1806 of yacc.c  */
     5978#line 889 "parser.yy"
     5979    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
     5980    break;
     5981
     5982  case 200:
    59935983
    59945984/* Line 1806 of yacc.c  */
    59955985#line 891 "parser.yy"
    5996     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); }
    5997     break;
    5998 
    5999   case 198:
     5986    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
     5987    break;
     5988
     5989  case 201:
    60005990
    60015991/* Line 1806 of yacc.c  */
    60025992#line 893 "parser.yy"
    6003     { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); }
    6004     break;
    6005 
    6006   case 199:
    6007 
    6008 /* Line 1806 of yacc.c  */
    6009 #line 895 "parser.yy"
    6010     { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
    6011     break;
    6012 
    6013   case 200:
    6014 
    6015 /* Line 1806 of yacc.c  */
    6016 #line 897 "parser.yy"
    6017     { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
    6018     break;
    6019 
    6020   case 201:
    6021 
    6022 /* Line 1806 of yacc.c  */
    6023 #line 899 "parser.yy"
    60245993    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (5)].en) ) ); }
    60255994    break;
     
    60285997
    60295998/* Line 1806 of yacc.c  */
    6030 #line 904 "parser.yy"
     5999#line 898 "parser.yy"
    60316000    { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), (yyvsp[(3) - (3)].sn), 0 ) ); }
    60326001    break;
     
    60356004
    60366005/* Line 1806 of yacc.c  */
    6037 #line 906 "parser.yy"
     6006#line 900 "parser.yy"
    60386007    { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), 0, (yyvsp[(3) - (3)].sn) ) ); }
    60396008    break;
     
    60426011
    60436012/* Line 1806 of yacc.c  */
    6044 #line 908 "parser.yy"
     6013#line 902 "parser.yy"
    60456014    { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (4)].sn), (yyvsp[(3) - (4)].sn), (yyvsp[(4) - (4)].sn) ) ); }
    60466015    break;
     
    60496018
    60506019/* Line 1806 of yacc.c  */
     6020#line 909 "parser.yy"
     6021    { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
     6022    break;
     6023
     6024  case 207:
     6025
     6026/* Line 1806 of yacc.c  */
     6027#line 911 "parser.yy"
     6028    { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
     6029    break;
     6030
     6031  case 208:
     6032
     6033/* Line 1806 of yacc.c  */
     6034#line 913 "parser.yy"
     6035    { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
     6036    break;
     6037
     6038  case 209:
     6039
     6040/* Line 1806 of yacc.c  */
    60516041#line 915 "parser.yy"
    6052     { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
    6053     break;
    6054 
    6055   case 207:
    6056 
    6057 /* Line 1806 of yacc.c  */
    6058 #line 917 "parser.yy"
    60596042    { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
    60606043    break;
    60616044
    6062   case 208:
    6063 
    6064 /* Line 1806 of yacc.c  */
    6065 #line 919 "parser.yy"
    6066     { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
    6067     break;
    6068 
    6069   case 209:
    6070 
    6071 /* Line 1806 of yacc.c  */
    6072 #line 921 "parser.yy"
    6073     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
    6074     break;
    6075 
    60766045  case 210:
    60776046
    60786047/* Line 1806 of yacc.c  */
     6048#line 920 "parser.yy"
     6049    { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
     6050    break;
     6051
     6052  case 211:
     6053
     6054/* Line 1806 of yacc.c  */
     6055#line 922 "parser.yy"
     6056    { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
     6057    break;
     6058
     6059  case 212:
     6060
     6061/* Line 1806 of yacc.c  */
     6062#line 924 "parser.yy"
     6063    { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
     6064    break;
     6065
     6066  case 213:
     6067
     6068/* Line 1806 of yacc.c  */
    60796069#line 926 "parser.yy"
    6080     { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
    6081     break;
    6082 
    6083   case 211:
    6084 
    6085 /* Line 1806 of yacc.c  */
    6086 #line 928 "parser.yy"
    60876070    { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
    60886071    break;
    60896072
    6090   case 212:
    6091 
    6092 /* Line 1806 of yacc.c  */
    6093 #line 930 "parser.yy"
    6094     { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
    6095     break;
    6096 
    6097   case 213:
    6098 
    6099 /* Line 1806 of yacc.c  */
    6100 #line 932 "parser.yy"
    6101     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
    6102     break;
    6103 
    61046073  case 214:
    61056074
    61066075/* Line 1806 of yacc.c  */
    6107 #line 937 "parser.yy"
     6076#line 931 "parser.yy"
    61086077    {
    61096078                        (yyval.sn) = new StatementNode( build_finally( (yyvsp[(2) - (2)].sn) ) );
     
    61146083
    61156084/* Line 1806 of yacc.c  */
    6116 #line 950 "parser.yy"
     6085#line 944 "parser.yy"
    61176086    {
    61186087                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    61246093
    61256094/* Line 1806 of yacc.c  */
    6126 #line 955 "parser.yy"
     6095#line 949 "parser.yy"
    61276096    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
    61286097    break;
     
    61316100
    61326101/* Line 1806 of yacc.c  */
    6133 #line 957 "parser.yy"
     6102#line 951 "parser.yy"
    61346103    {
    61356104                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    61416110
    61426111/* Line 1806 of yacc.c  */
     6112#line 960 "parser.yy"
     6113    { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ) ); }
     6114    break;
     6115
     6116  case 221:
     6117
     6118/* Line 1806 of yacc.c  */
     6119#line 962 "parser.yy"
     6120    { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); }
     6121    break;
     6122
     6123  case 222:
     6124
     6125/* Line 1806 of yacc.c  */
     6126#line 964 "parser.yy"
     6127    { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); }
     6128    break;
     6129
     6130  case 223:
     6131
     6132/* Line 1806 of yacc.c  */
    61436133#line 966 "parser.yy"
    6144     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ) ); }
    6145     break;
    6146 
    6147   case 221:
     6134    { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].en) ) ); }
     6135    break;
     6136
     6137  case 224:
    61486138
    61496139/* Line 1806 of yacc.c  */
    61506140#line 968 "parser.yy"
    6151     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); }
    6152     break;
    6153 
    6154   case 222:
    6155 
    6156 /* Line 1806 of yacc.c  */
    6157 #line 970 "parser.yy"
    6158     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); }
    6159     break;
    6160 
    6161   case 223:
    6162 
    6163 /* Line 1806 of yacc.c  */
    6164 #line 972 "parser.yy"
    6165     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].en) ) ); }
    6166     break;
    6167 
    6168   case 224:
    6169 
    6170 /* Line 1806 of yacc.c  */
    6171 #line 974 "parser.yy"
    61726141    { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (14)].flag), (yyvsp[(5) - (14)].constant), 0, (yyvsp[(8) - (14)].en), (yyvsp[(10) - (14)].en), (yyvsp[(12) - (14)].label) ) ); }
    61736142    break;
     
    61766145
    61776146/* Line 1806 of yacc.c  */
    6178 #line 979 "parser.yy"
     6147#line 973 "parser.yy"
    61796148    { (yyval.flag) = false; }
    61806149    break;
     
    61836152
    61846153/* Line 1806 of yacc.c  */
    6185 #line 981 "parser.yy"
     6154#line 975 "parser.yy"
    61866155    { (yyval.flag) = true; }
    61876156    break;
     
    61906159
    61916160/* Line 1806 of yacc.c  */
    6192 #line 986 "parser.yy"
     6161#line 980 "parser.yy"
    61936162    { (yyval.en) = 0; }
    61946163    break;
     
    61976166
    61986167/* Line 1806 of yacc.c  */
    6199 #line 993 "parser.yy"
     6168#line 987 "parser.yy"
    62006169    { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
    62016170    break;
     
    62046173
    62056174/* Line 1806 of yacc.c  */
    6206 #line 998 "parser.yy"
     6175#line 992 "parser.yy"
    62076176    { (yyval.en) = new ExpressionNode( build_asmexpr( 0, (yyvsp[(1) - (4)].constant), (yyvsp[(3) - (4)].en) ) ); }
    62086177    break;
     
    62116180
    62126181/* Line 1806 of yacc.c  */
    6213 #line 1000 "parser.yy"
     6182#line 994 "parser.yy"
    62146183    { (yyval.en) = new ExpressionNode( build_asmexpr( (yyvsp[(2) - (7)].en), (yyvsp[(4) - (7)].constant), (yyvsp[(6) - (7)].en) ) ); }
    62156184    break;
     
    62186187
    62196188/* Line 1806 of yacc.c  */
    6220 #line 1005 "parser.yy"
     6189#line 999 "parser.yy"
    62216190    { (yyval.en) = 0; }
    62226191    break;
     
    62256194
    62266195/* Line 1806 of yacc.c  */
    6227 #line 1007 "parser.yy"
     6196#line 1001 "parser.yy"
    62286197    { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); }
    62296198    break;
     
    62326201
    62336202/* Line 1806 of yacc.c  */
    6234 #line 1009 "parser.yy"
     6203#line 1003 "parser.yy"
    62356204    { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( (yyvsp[(3) - (3)].constant) ) ); }
    62366205    break;
     
    62396208
    62406209/* Line 1806 of yacc.c  */
    6241 #line 1014 "parser.yy"
     6210#line 1008 "parser.yy"
    62426211    {
    62436212                        (yyval.label) = new LabelNode(); (yyval.label)->labels.push_back( *(yyvsp[(1) - (1)].tok) );
     
    62496218
    62506219/* Line 1806 of yacc.c  */
    6251 #line 1019 "parser.yy"
     6220#line 1013 "parser.yy"
    62526221    {
    62536222                        (yyval.label) = (yyvsp[(1) - (3)].label); (yyvsp[(1) - (3)].label)->labels.push_back( *(yyvsp[(3) - (3)].tok) );
     
    62596228
    62606229/* Line 1806 of yacc.c  */
    6261 #line 1029 "parser.yy"
     6230#line 1023 "parser.yy"
    62626231    { (yyval.decl) = 0; }
    62636232    break;
     
    62666235
    62676236/* Line 1806 of yacc.c  */
    6268 #line 1036 "parser.yy"
     6237#line 1030 "parser.yy"
    62696238    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
    62706239    break;
     
    62736242
    62746243/* Line 1806 of yacc.c  */
    6275 #line 1041 "parser.yy"
     6244#line 1035 "parser.yy"
    62766245    { (yyval.decl) = 0; }
    62776246    break;
     
    62806249
    62816250/* Line 1806 of yacc.c  */
    6282 #line 1048 "parser.yy"
     6251#line 1042 "parser.yy"
    62836252    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
    62846253    break;
     
    62876256
    62886257/* Line 1806 of yacc.c  */
    6289 #line 1062 "parser.yy"
     6258#line 1056 "parser.yy"
    62906259    {}
    62916260    break;
     
    62946263
    62956264/* Line 1806 of yacc.c  */
    6296 #line 1063 "parser.yy"
     6265#line 1057 "parser.yy"
    62976266    {}
    62986267    break;
     
    63016270
    63026271/* Line 1806 of yacc.c  */
    6303 #line 1092 "parser.yy"
     6272#line 1086 "parser.yy"
    63046273    {
    63056274                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    63116280
    63126281/* Line 1806 of yacc.c  */
    6313 #line 1099 "parser.yy"
     6282#line 1093 "parser.yy"
    63146283    {
    63156284                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    63216290
    63226291/* Line 1806 of yacc.c  */
    6323 #line 1104 "parser.yy"
     6292#line 1098 "parser.yy"
    63246293    {
    63256294                        typedefTable.addToEnclosingScope( *(yyvsp[(5) - (6)].tok), TypedefTable::ID );
     
    63316300
    63326301/* Line 1806 of yacc.c  */
    6333 #line 1114 "parser.yy"
     6302#line 1108 "parser.yy"
    63346303    {
    63356304                        typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
     
    63416310
    63426311/* Line 1806 of yacc.c  */
    6343 #line 1119 "parser.yy"
     6312#line 1113 "parser.yy"
    63446313    {
    63456314                        typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
     
    63516320
    63526321/* Line 1806 of yacc.c  */
    6353 #line 1124 "parser.yy"
     6322#line 1118 "parser.yy"
    63546323    {
    63556324                        typedefTable.setNextIdentifier( *(yyvsp[(3) - (4)].tok) );
     
    63616330
    63626331/* Line 1806 of yacc.c  */
    6363 #line 1132 "parser.yy"
     6332#line 1126 "parser.yy"
    63646333    {
    63656334                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    63716340
    63726341/* Line 1806 of yacc.c  */
    6373 #line 1137 "parser.yy"
     6342#line 1131 "parser.yy"
    63746343    {
    63756344                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    63816350
    63826351/* Line 1806 of yacc.c  */
    6383 #line 1142 "parser.yy"
     6352#line 1136 "parser.yy"
    63846353    {
    63856354                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    63916360
    63926361/* Line 1806 of yacc.c  */
    6393 #line 1147 "parser.yy"
     6362#line 1141 "parser.yy"
    63946363    {
    63956364                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    64016370
    64026371/* Line 1806 of yacc.c  */
    6403 #line 1152 "parser.yy"
     6372#line 1146 "parser.yy"
    64046373    {
    64056374                        typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
     
    64116380
    64126381/* Line 1806 of yacc.c  */
    6413 #line 1183 "parser.yy"
     6382#line 1177 "parser.yy"
    64146383    {
    64156384                        (yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
     
    64206389
    64216390/* Line 1806 of yacc.c  */
    6422 #line 1187 "parser.yy"
     6391#line 1181 "parser.yy"
    64236392    {
    64246393                        (yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
     
    64296398
    64306399/* Line 1806 of yacc.c  */
    6431 #line 1194 "parser.yy"
     6400#line 1188 "parser.yy"
    64326401    { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
    64336402    break;
     
    64366405
    64376406/* Line 1806 of yacc.c  */
    6438 #line 1198 "parser.yy"
     6407#line 1192 "parser.yy"
    64396408    { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (9)].decl)->appendList( (yyvsp[(7) - (9)].decl) ) ); }
    64406409    break;
     
    64436412
    64446413/* Line 1806 of yacc.c  */
    6445 #line 1203 "parser.yy"
     6414#line 1197 "parser.yy"
    64466415    {
    64476416                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    64536422
    64546423/* Line 1806 of yacc.c  */
    6455 #line 1208 "parser.yy"
     6424#line 1202 "parser.yy"
    64566425    {
    64576426                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    64636432
    64646433/* Line 1806 of yacc.c  */
    6465 #line 1213 "parser.yy"
     6434#line 1207 "parser.yy"
    64666435    {
    64676436                        typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::TD );
     
    64736442
    64746443/* Line 1806 of yacc.c  */
    6475 #line 1224 "parser.yy"
     6444#line 1218 "parser.yy"
    64766445    {
    64776446                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    64836452
    64846453/* Line 1806 of yacc.c  */
    6485 #line 1229 "parser.yy"
     6454#line 1223 "parser.yy"
    64866455    {
    64876456                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    64936462
    64946463/* Line 1806 of yacc.c  */
    6495 #line 1234 "parser.yy"
     6464#line 1228 "parser.yy"
    64966465    {
    64976466                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    65036472
    65046473/* Line 1806 of yacc.c  */
    6505 #line 1239 "parser.yy"
     6474#line 1233 "parser.yy"
    65066475    {
    65076476                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    65136482
    65146483/* Line 1806 of yacc.c  */
    6515 #line 1244 "parser.yy"
     6484#line 1238 "parser.yy"
    65166485    {
    65176486                        typedefTable.addToEnclosingScope( TypedefTable::TD );
     
    65236492
    65246493/* Line 1806 of yacc.c  */
    6525 #line 1253 "parser.yy"
     6494#line 1247 "parser.yy"
    65266495    {
    65276496                        typedefTable.addToEnclosingScope( *(yyvsp[(2) - (4)].tok), TypedefTable::TD );
     
    65336502
    65346503/* Line 1806 of yacc.c  */
    6535 #line 1258 "parser.yy"
     6504#line 1252 "parser.yy"
    65366505    {
    65376506                        typedefTable.addToEnclosingScope( *(yyvsp[(5) - (7)].tok), TypedefTable::TD );
     
    65436512
    65446513/* Line 1806 of yacc.c  */
    6545 #line 1275 "parser.yy"
     6514#line 1269 "parser.yy"
    65466515    {
    65476516                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    65536522
    65546523/* Line 1806 of yacc.c  */
    6555 #line 1280 "parser.yy"
     6524#line 1274 "parser.yy"
    65566525    {
    65576526                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    65636532
    65646533/* Line 1806 of yacc.c  */
    6565 #line 1302 "parser.yy"
     6534#line 1296 "parser.yy"
    65666535    { (yyval.decl) = 0; }
    65676536    break;
     
    65706539
    65716540/* Line 1806 of yacc.c  */
    6572 #line 1314 "parser.yy"
     6541#line 1308 "parser.yy"
    65736542    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    65746543    break;
     
    65776546
    65786547/* Line 1806 of yacc.c  */
     6548#line 1319 "parser.yy"
     6549    { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); }
     6550    break;
     6551
     6552  case 305:
     6553
     6554/* Line 1806 of yacc.c  */
     6555#line 1321 "parser.yy"
     6556    { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
     6557    break;
     6558
     6559  case 306:
     6560
     6561/* Line 1806 of yacc.c  */
     6562#line 1323 "parser.yy"
     6563    { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
     6564    break;
     6565
     6566  case 307:
     6567
     6568/* Line 1806 of yacc.c  */
    65796569#line 1325 "parser.yy"
    6580     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); }
    6581     break;
    6582 
    6583   case 305:
     6570    { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
     6571    break;
     6572
     6573  case 308:
    65846574
    65856575/* Line 1806 of yacc.c  */
    65866576#line 1327 "parser.yy"
    6587     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
    6588     break;
    6589 
    6590   case 306:
     6577    { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
     6578    break;
     6579
     6580  case 309:
    65916581
    65926582/* Line 1806 of yacc.c  */
    65936583#line 1329 "parser.yy"
    6594     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
    6595     break;
    6596 
    6597   case 307:
    6598 
    6599 /* Line 1806 of yacc.c  */
    6600 #line 1331 "parser.yy"
    6601     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
    6602     break;
    6603 
    6604   case 308:
    6605 
    6606 /* Line 1806 of yacc.c  */
    6607 #line 1333 "parser.yy"
    6608     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
    6609     break;
    6610 
    6611   case 309:
    6612 
    6613 /* Line 1806 of yacc.c  */
    6614 #line 1335 "parser.yy"
    66156584    {
    66166585                        typedefTable.enterScope();
     
    66216590
    66226591/* Line 1806 of yacc.c  */
    6623 #line 1339 "parser.yy"
     6592#line 1333 "parser.yy"
    66246593    {
    66256594                        typedefTable.leaveScope();
     
    66316600
    66326601/* Line 1806 of yacc.c  */
    6633 #line 1348 "parser.yy"
     6602#line 1342 "parser.yy"
    66346603    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    66356604    break;
     
    66386607
    66396608/* Line 1806 of yacc.c  */
    6640 #line 1350 "parser.yy"
     6609#line 1344 "parser.yy"
    66416610    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
    66426611    break;
     
    66456614
    66466615/* Line 1806 of yacc.c  */
    6647 #line 1361 "parser.yy"
     6616#line 1355 "parser.yy"
    66486617    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    66496618    break;
     
    66526621
    66536622/* Line 1806 of yacc.c  */
     6623#line 1360 "parser.yy"
     6624    { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
     6625    break;
     6626
     6627  case 317:
     6628
     6629/* Line 1806 of yacc.c  */
     6630#line 1362 "parser.yy"
     6631    { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
     6632    break;
     6633
     6634  case 318:
     6635
     6636/* Line 1806 of yacc.c  */
     6637#line 1364 "parser.yy"
     6638    { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
     6639    break;
     6640
     6641  case 319:
     6642
     6643/* Line 1806 of yacc.c  */
    66546644#line 1366 "parser.yy"
    6655     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
    6656     break;
    6657 
    6658   case 317:
    6659 
    6660 /* Line 1806 of yacc.c  */
    6661 #line 1368 "parser.yy"
    6662     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
    6663     break;
    6664 
    6665   case 318:
    6666 
    6667 /* Line 1806 of yacc.c  */
    6668 #line 1370 "parser.yy"
    6669     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
    6670     break;
    6671 
    6672   case 319:
    6673 
    6674 /* Line 1806 of yacc.c  */
    6675 #line 1372 "parser.yy"
    66766645    { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
    66776646    break;
     
    66806649
    66816650/* Line 1806 of yacc.c  */
    6682 #line 1375 "parser.yy"
     6651#line 1369 "parser.yy"
    66836652    { (yyval.decl) = new DeclarationNode; (yyval.decl)->isInline = true; }
    66846653    break;
     
    66876656
    66886657/* Line 1806 of yacc.c  */
    6689 #line 1377 "parser.yy"
     6658#line 1371 "parser.yy"
    66906659    { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
    66916660    break;
     
    66946663
    66956664/* Line 1806 of yacc.c  */
    6696 #line 1380 "parser.yy"
     6665#line 1374 "parser.yy"
    66976666    { (yyval.decl) = new DeclarationNode; (yyval.decl)->isNoreturn = true; }
    66986667    break;
     
    67016670
    67026671/* Line 1806 of yacc.c  */
    6703 #line 1382 "parser.yy"
     6672#line 1376 "parser.yy"
    67046673    { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Threadlocal ); }
    67056674    break;
     
    67086677
    67096678/* Line 1806 of yacc.c  */
     6679#line 1381 "parser.yy"
     6680    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
     6681    break;
     6682
     6683  case 325:
     6684
     6685/* Line 1806 of yacc.c  */
     6686#line 1383 "parser.yy"
     6687    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     6688    break;
     6689
     6690  case 326:
     6691
     6692/* Line 1806 of yacc.c  */
     6693#line 1385 "parser.yy"
     6694    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); }
     6695    break;
     6696
     6697  case 327:
     6698
     6699/* Line 1806 of yacc.c  */
    67106700#line 1387 "parser.yy"
     6701    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); }
     6702    break;
     6703
     6704  case 328:
     6705
     6706/* Line 1806 of yacc.c  */
     6707#line 1389 "parser.yy"
     6708    { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Long ); }
     6709    break;
     6710
     6711  case 329:
     6712
     6713/* Line 1806 of yacc.c  */
     6714#line 1391 "parser.yy"
     6715    { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Short ); }
     6716    break;
     6717
     6718  case 330:
     6719
     6720/* Line 1806 of yacc.c  */
     6721#line 1393 "parser.yy"
     6722    { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }
     6723    break;
     6724
     6725  case 331:
     6726
     6727/* Line 1806 of yacc.c  */
     6728#line 1395 "parser.yy"
     6729    { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }
     6730    break;
     6731
     6732  case 332:
     6733
     6734/* Line 1806 of yacc.c  */
     6735#line 1397 "parser.yy"
     6736    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     6737    break;
     6738
     6739  case 333:
     6740
     6741/* Line 1806 of yacc.c  */
     6742#line 1399 "parser.yy"
     6743    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
     6744    break;
     6745
     6746  case 334:
     6747
     6748/* Line 1806 of yacc.c  */
     6749#line 1401 "parser.yy"
     6750    { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
     6751    break;
     6752
     6753  case 335:
     6754
     6755/* Line 1806 of yacc.c  */
     6756#line 1403 "parser.yy"
     6757    { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); }
     6758    break;
     6759
     6760  case 336:
     6761
     6762/* Line 1806 of yacc.c  */
     6763#line 1405 "parser.yy"
     6764    { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
     6765    break;
     6766
     6767  case 337:
     6768
     6769/* Line 1806 of yacc.c  */
     6770#line 1407 "parser.yy"
    67116771    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
    67126772    break;
    67136773
    6714   case 325:
    6715 
    6716 /* Line 1806 of yacc.c  */
    6717 #line 1389 "parser.yy"
    6718     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); }
    6719     break;
    6720 
    6721   case 326:
    6722 
    6723 /* Line 1806 of yacc.c  */
    6724 #line 1391 "parser.yy"
    6725     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); }
    6726     break;
    6727 
    6728   case 327:
    6729 
    6730 /* Line 1806 of yacc.c  */
    6731 #line 1393 "parser.yy"
    6732     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); }
    6733     break;
    6734 
    6735   case 328:
    6736 
    6737 /* Line 1806 of yacc.c  */
    6738 #line 1395 "parser.yy"
    6739     { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Long ); }
    6740     break;
    6741 
    6742   case 329:
    6743 
    6744 /* Line 1806 of yacc.c  */
    6745 #line 1397 "parser.yy"
    6746     { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Short ); }
    6747     break;
    6748 
    6749   case 330:
    6750 
    6751 /* Line 1806 of yacc.c  */
    6752 #line 1399 "parser.yy"
    6753     { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }
    6754     break;
    6755 
    6756   case 331:
    6757 
    6758 /* Line 1806 of yacc.c  */
    6759 #line 1401 "parser.yy"
    6760     { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }
    6761     break;
    6762 
    6763   case 332:
    6764 
    6765 /* Line 1806 of yacc.c  */
    6766 #line 1403 "parser.yy"
    6767     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); }
    6768     break;
    6769 
    6770   case 333:
    6771 
    6772 /* Line 1806 of yacc.c  */
    6773 #line 1405 "parser.yy"
    6774     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
    6775     break;
    6776 
    6777   case 334:
    6778 
    6779 /* Line 1806 of yacc.c  */
    6780 #line 1407 "parser.yy"
    6781     { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
    6782     break;
    6783 
    6784   case 335:
     6774  case 338:
    67856775
    67866776/* Line 1806 of yacc.c  */
    67876777#line 1409 "parser.yy"
    6788     { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); }
    6789     break;
    6790 
    6791   case 336:
    6792 
    6793 /* Line 1806 of yacc.c  */
    6794 #line 1411 "parser.yy"
    6795     { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
    6796     break;
    6797 
    6798   case 337:
    6799 
    6800 /* Line 1806 of yacc.c  */
    6801 #line 1413 "parser.yy"
    68026778    { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
    68036779    break;
    68046780
    6805   case 338:
    6806 
    6807 /* Line 1806 of yacc.c  */
    6808 #line 1415 "parser.yy"
    6809     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
    6810     break;
    6811 
    68126781  case 340:
    68136782
    68146783/* Line 1806 of yacc.c  */
     6784#line 1416 "parser.yy"
     6785    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     6786    break;
     6787
     6788  case 341:
     6789
     6790/* Line 1806 of yacc.c  */
     6791#line 1418 "parser.yy"
     6792    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     6793    break;
     6794
     6795  case 342:
     6796
     6797/* Line 1806 of yacc.c  */
     6798#line 1420 "parser.yy"
     6799    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     6800    break;
     6801
     6802  case 343:
     6803
     6804/* Line 1806 of yacc.c  */
    68156805#line 1422 "parser.yy"
     6806    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); }
     6807    break;
     6808
     6809  case 345:
     6810
     6811/* Line 1806 of yacc.c  */
     6812#line 1428 "parser.yy"
     6813    { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     6814    break;
     6815
     6816  case 347:
     6817
     6818/* Line 1806 of yacc.c  */
     6819#line 1435 "parser.yy"
    68166820    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    68176821    break;
    68186822
    6819   case 341:
    6820 
    6821 /* Line 1806 of yacc.c  */
    6822 #line 1424 "parser.yy"
     6823  case 348:
     6824
     6825/* Line 1806 of yacc.c  */
     6826#line 1437 "parser.yy"
    68236827    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    68246828    break;
    68256829
    6826   case 342:
    6827 
    6828 /* Line 1806 of yacc.c  */
    6829 #line 1426 "parser.yy"
     6830  case 349:
     6831
     6832/* Line 1806 of yacc.c  */
     6833#line 1439 "parser.yy"
     6834    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); }
     6835    break;
     6836
     6837  case 350:
     6838
     6839/* Line 1806 of yacc.c  */
     6840#line 1444 "parser.yy"
     6841    { (yyval.decl) = (yyvsp[(3) - (4)].decl); }
     6842    break;
     6843
     6844  case 351:
     6845
     6846/* Line 1806 of yacc.c  */
     6847#line 1446 "parser.yy"
     6848    { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); }
     6849    break;
     6850
     6851  case 352:
     6852
     6853/* Line 1806 of yacc.c  */
     6854#line 1448 "parser.yy"
     6855    { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); }
     6856    break;
     6857
     6858  case 353:
     6859
     6860/* Line 1806 of yacc.c  */
     6861#line 1450 "parser.yy"
     6862    { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     6863    break;
     6864
     6865  case 355:
     6866
     6867/* Line 1806 of yacc.c  */
     6868#line 1456 "parser.yy"
     6869    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     6870    break;
     6871
     6872  case 356:
     6873
     6874/* Line 1806 of yacc.c  */
     6875#line 1458 "parser.yy"
     6876    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     6877    break;
     6878
     6879  case 357:
     6880
     6881/* Line 1806 of yacc.c  */
     6882#line 1460 "parser.yy"
    68306883    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
    68316884    break;
    68326885
    6833   case 343:
    6834 
    6835 /* Line 1806 of yacc.c  */
    6836 #line 1428 "parser.yy"
    6837     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); }
    6838     break;
    6839 
    6840   case 345:
    6841 
    6842 /* Line 1806 of yacc.c  */
    6843 #line 1434 "parser.yy"
    6844     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
    6845     break;
    6846 
    6847   case 347:
    6848 
    6849 /* Line 1806 of yacc.c  */
    6850 #line 1441 "parser.yy"
     6886  case 359:
     6887
     6888/* Line 1806 of yacc.c  */
     6889#line 1466 "parser.yy"
    68516890    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    68526891    break;
    68536892
    6854   case 348:
    6855 
    6856 /* Line 1806 of yacc.c  */
    6857 #line 1443 "parser.yy"
     6893  case 360:
     6894
     6895/* Line 1806 of yacc.c  */
     6896#line 1468 "parser.yy"
    68586897    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    68596898    break;
    68606899
    6861   case 349:
    6862 
    6863 /* Line 1806 of yacc.c  */
    6864 #line 1445 "parser.yy"
    6865     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); }
    6866     break;
    6867 
    6868   case 350:
    6869 
    6870 /* Line 1806 of yacc.c  */
    6871 #line 1450 "parser.yy"
    6872     { (yyval.decl) = (yyvsp[(3) - (4)].decl); }
    6873     break;
    6874 
    6875   case 351:
    6876 
    6877 /* Line 1806 of yacc.c  */
    6878 #line 1452 "parser.yy"
    6879     { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); }
    6880     break;
    6881 
    6882   case 352:
    6883 
    6884 /* Line 1806 of yacc.c  */
    6885 #line 1454 "parser.yy"
    6886     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); }
    6887     break;
    6888 
    6889   case 353:
    6890 
    6891 /* Line 1806 of yacc.c  */
    6892 #line 1456 "parser.yy"
    6893     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
    6894     break;
    6895 
    6896   case 355:
    6897 
    6898 /* Line 1806 of yacc.c  */
    6899 #line 1462 "parser.yy"
     6900  case 362:
     6901
     6902/* Line 1806 of yacc.c  */
     6903#line 1474 "parser.yy"
    69006904    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    69016905    break;
    69026906
    6903   case 356:
    6904 
    6905 /* Line 1806 of yacc.c  */
    6906 #line 1464 "parser.yy"
     6907  case 363:
     6908
     6909/* Line 1806 of yacc.c  */
     6910#line 1476 "parser.yy"
    69076911    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    69086912    break;
    69096913
    6910   case 357:
    6911 
    6912 /* Line 1806 of yacc.c  */
    6913 #line 1466 "parser.yy"
     6914  case 364:
     6915
     6916/* Line 1806 of yacc.c  */
     6917#line 1478 "parser.yy"
    69146918    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
    69156919    break;
    69166920
    6917   case 359:
    6918 
    6919 /* Line 1806 of yacc.c  */
    6920 #line 1472 "parser.yy"
    6921     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    6922     break;
    6923 
    6924   case 360:
    6925 
    6926 /* Line 1806 of yacc.c  */
    6927 #line 1474 "parser.yy"
     6921  case 365:
     6922
     6923/* Line 1806 of yacc.c  */
     6924#line 1483 "parser.yy"
     6925    { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); }
     6926    break;
     6927
     6928  case 366:
     6929
     6930/* Line 1806 of yacc.c  */
     6931#line 1485 "parser.yy"
     6932    { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     6933    break;
     6934
     6935  case 367:
     6936
     6937/* Line 1806 of yacc.c  */
     6938#line 1487 "parser.yy"
    69286939    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    69296940    break;
    69306941
    6931   case 362:
    6932 
    6933 /* Line 1806 of yacc.c  */
    6934 #line 1480 "parser.yy"
    6935     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    6936     break;
    6937 
    6938   case 363:
    6939 
    6940 /* Line 1806 of yacc.c  */
    6941 #line 1482 "parser.yy"
    6942     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    6943     break;
    6944 
    6945   case 364:
    6946 
    6947 /* Line 1806 of yacc.c  */
    6948 #line 1484 "parser.yy"
    6949     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
    6950     break;
    6951 
    6952   case 365:
    6953 
    6954 /* Line 1806 of yacc.c  */
    6955 #line 1489 "parser.yy"
    6956     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); }
    6957     break;
    6958 
    6959   case 366:
    6960 
    6961 /* Line 1806 of yacc.c  */
    6962 #line 1491 "parser.yy"
    6963     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    6964     break;
    6965 
    6966   case 367:
    6967 
    6968 /* Line 1806 of yacc.c  */
    6969 #line 1493 "parser.yy"
    6970     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    6971     break;
    6972 
    69736942  case 370:
    69746943
    69756944/* Line 1806 of yacc.c  */
    6976 #line 1503 "parser.yy"
     6945#line 1497 "parser.yy"
    69776946    { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (4)].aggKey), nullptr, nullptr, (yyvsp[(3) - (4)].decl), true ); }
    69786947    break;
     
    69816950
    69826951/* Line 1806 of yacc.c  */
    6983 #line 1505 "parser.yy"
     6952#line 1499 "parser.yy"
    69846953    {
    69856954                        typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
     
    69916960
    69926961/* Line 1806 of yacc.c  */
     6962#line 1504 "parser.yy"
     6963    { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     6964    break;
     6965
     6966  case 373:
     6967
     6968/* Line 1806 of yacc.c  */
     6969#line 1506 "parser.yy"
     6970    { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), nullptr, (yyvsp[(5) - (6)].decl), true ); }
     6971    break;
     6972
     6973  case 374:
     6974
     6975/* Line 1806 of yacc.c  */
     6976#line 1508 "parser.yy"
     6977    { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), nullptr, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); }
     6978    break;
     6979
     6980  case 375:
     6981
     6982/* Line 1806 of yacc.c  */
    69936983#line 1510 "parser.yy"
    6994     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
    6995     break;
    6996 
    6997   case 373:
    6998 
    6999 /* Line 1806 of yacc.c  */
    7000 #line 1512 "parser.yy"
    7001     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), nullptr, (yyvsp[(5) - (6)].decl), true ); }
    7002     break;
    7003 
    7004   case 374:
    7005 
    7006 /* Line 1806 of yacc.c  */
    7007 #line 1514 "parser.yy"
    7008     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), nullptr, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); }
    7009     break;
    7010 
    7011   case 375:
    7012 
    7013 /* Line 1806 of yacc.c  */
    7014 #line 1516 "parser.yy"
    70156984    { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
    70166985    break;
     
    70196988
    70206989/* Line 1806 of yacc.c  */
    7021 #line 1521 "parser.yy"
     6990#line 1515 "parser.yy"
    70226991    { (yyval.aggKey) = DeclarationNode::Struct; }
    70236992    break;
     
    70266995
    70276996/* Line 1806 of yacc.c  */
    7028 #line 1523 "parser.yy"
     6997#line 1517 "parser.yy"
    70296998    { (yyval.aggKey) = DeclarationNode::Union; }
    70306999    break;
     
    70337002
    70347003/* Line 1806 of yacc.c  */
    7035 #line 1528 "parser.yy"
     7004#line 1522 "parser.yy"
    70367005    { (yyval.decl) = 0; }
    70377006    break;
     
    70407009
    70417010/* Line 1806 of yacc.c  */
     7011#line 1524 "parser.yy"
     7012    { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     7013    break;
     7014
     7015  case 381:
     7016
     7017/* Line 1806 of yacc.c  */
    70427018#line 1530 "parser.yy"
    7043     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
    7044     break;
    7045 
    7046   case 381:
    7047 
    7048 /* Line 1806 of yacc.c  */
    7049 #line 1536 "parser.yy"
    70507019    { (yyval.decl) = (yyvsp[(2) - (3)].decl)->set_extension( true ); }
    70517020    break;
     
    70547023
    70557024/* Line 1806 of yacc.c  */
    7056 #line 1539 "parser.yy"
     7025#line 1533 "parser.yy"
    70577026    {   // mark all fields in list
    70587027                        for ( DeclarationNode *iter = (yyvsp[(2) - (3)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
     
    70657034
    70667035/* Line 1806 of yacc.c  */
    7067 #line 1549 "parser.yy"
     7036#line 1543 "parser.yy"
    70687037    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addName( (yyvsp[(2) - (2)].tok) ); }
    70697038    break;
     
    70727041
    70737042/* Line 1806 of yacc.c  */
    7074 #line 1551 "parser.yy"
     7043#line 1545 "parser.yy"
    70757044    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(1) - (3)].decl)->cloneType( (yyvsp[(3) - (3)].tok) ) ); }
    70767045    break;
     
    70797048
    70807049/* Line 1806 of yacc.c  */
    7081 #line 1553 "parser.yy"
     7050#line 1547 "parser.yy"
    70827051    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(1) - (2)].decl)->cloneType( 0 ) ); }
    70837052    break;
     
    70867055
    70877056/* Line 1806 of yacc.c  */
    7088 #line 1558 "parser.yy"
     7057#line 1552 "parser.yy"
    70897058    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
    70907059    break;
     
    70937062
    70947063/* Line 1806 of yacc.c  */
    7095 #line 1560 "parser.yy"
     7064#line 1554 "parser.yy"
    70967065    { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(1) - (4)].decl)->cloneBaseType( (yyvsp[(4) - (4)].decl) ) ); }
    70977066    break;
     
    71007069
    71017070/* Line 1806 of yacc.c  */
    7102 #line 1565 "parser.yy"
     7071#line 1559 "parser.yy"
    71037072    { (yyval.decl) = DeclarationNode::newName( 0 ); /* XXX */ }
    71047073    break;
     
    71077076
    71087077/* Line 1806 of yacc.c  */
     7078#line 1561 "parser.yy"
     7079    { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); }
     7080    break;
     7081
     7082  case 392:
     7083
     7084/* Line 1806 of yacc.c  */
     7085#line 1564 "parser.yy"
     7086    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     7087    break;
     7088
     7089  case 393:
     7090
     7091/* Line 1806 of yacc.c  */
    71097092#line 1567 "parser.yy"
    7110     { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); }
    7111     break;
    7112 
    7113   case 392:
    7114 
    7115 /* Line 1806 of yacc.c  */
    7116 #line 1570 "parser.yy"
    71177093    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
    71187094    break;
    71197095
    7120   case 393:
     7096  case 395:
    71217097
    71227098/* Line 1806 of yacc.c  */
    71237099#line 1573 "parser.yy"
    7124     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
    7125     break;
    7126 
    7127   case 395:
    7128 
    7129 /* Line 1806 of yacc.c  */
    7130 #line 1579 "parser.yy"
    71317100    { (yyval.en) = 0; }
    71327101    break;
     
    71357104
    71367105/* Line 1806 of yacc.c  */
    7137 #line 1581 "parser.yy"
     7106#line 1575 "parser.yy"
    71387107    { (yyval.en) = (yyvsp[(1) - (1)].en); }
    71397108    break;
     
    71427111
    71437112/* Line 1806 of yacc.c  */
    7144 #line 1586 "parser.yy"
     7113#line 1580 "parser.yy"
    71457114    { (yyval.en) = (yyvsp[(2) - (2)].en); }
    71467115    break;
     
    71497118
    71507119/* Line 1806 of yacc.c  */
    7151 #line 1595 "parser.yy"
     7120#line 1589 "parser.yy"
    71527121    { (yyval.decl) = DeclarationNode::newEnum( nullptr, (yyvsp[(3) - (5)].decl) ); }
    71537122    break;
     
    71567125
    71577126/* Line 1806 of yacc.c  */
    7158 #line 1597 "parser.yy"
     7127#line 1591 "parser.yy"
    71597128    {
    71607129                        typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
     
    71667135
    71677136/* Line 1806 of yacc.c  */
    7168 #line 1602 "parser.yy"
     7137#line 1596 "parser.yy"
    71697138    { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
    71707139    break;
     
    71737142
    71747143/* Line 1806 of yacc.c  */
    7175 #line 1604 "parser.yy"
     7144#line 1598 "parser.yy"
    71767145    { (yyval.decl) = DeclarationNode::newEnum( (yyvsp[(2) - (7)].tok), (yyvsp[(5) - (7)].decl) ); }
    71777146    break;
     
    71807149
    71817150/* Line 1806 of yacc.c  */
    7182 #line 1609 "parser.yy"
     7151#line 1603 "parser.yy"
    71837152    { (yyval.decl) = DeclarationNode::newEnumConstant( (yyvsp[(1) - (2)].tok), (yyvsp[(2) - (2)].en) ); }
    71847153    break;
     
    71877156
    71887157/* Line 1806 of yacc.c  */
    7189 #line 1611 "parser.yy"
     7158#line 1605 "parser.yy"
    71907159    { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( DeclarationNode::newEnumConstant( (yyvsp[(3) - (4)].tok), (yyvsp[(4) - (4)].en) ) ); }
    71917160    break;
     
    71947163
    71957164/* Line 1806 of yacc.c  */
    7196 #line 1616 "parser.yy"
     7165#line 1610 "parser.yy"
    71977166    { (yyval.en) = 0; }
    71987167    break;
     
    72017170
    72027171/* Line 1806 of yacc.c  */
    7203 #line 1618 "parser.yy"
     7172#line 1612 "parser.yy"
    72047173    { (yyval.en) = (yyvsp[(2) - (2)].en); }
    72057174    break;
     
    72087177
    72097178/* Line 1806 of yacc.c  */
    7210 #line 1625 "parser.yy"
     7179#line 1619 "parser.yy"
    72117180    { (yyval.decl) = 0; }
    72127181    break;
     
    72157184
    72167185/* Line 1806 of yacc.c  */
    7217 #line 1633 "parser.yy"
     7186#line 1627 "parser.yy"
    72187187    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
    72197188    break;
     
    72227191
    72237192/* Line 1806 of yacc.c  */
    7224 #line 1635 "parser.yy"
     7193#line 1629 "parser.yy"
    72257194    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
    72267195    break;
     
    72297198
    72307199/* Line 1806 of yacc.c  */
    7231 #line 1637 "parser.yy"
     7200#line 1631 "parser.yy"
    72327201    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
    72337202    break;
     
    72367205
    72377206/* Line 1806 of yacc.c  */
    7238 #line 1645 "parser.yy"
     7207#line 1639 "parser.yy"
    72397208    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
    72407209    break;
     
    72437212
    72447213/* Line 1806 of yacc.c  */
    7245 #line 1647 "parser.yy"
     7214#line 1641 "parser.yy"
    72467215    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
    72477216    break;
     
    72507219
    72517220/* Line 1806 of yacc.c  */
     7221#line 1643 "parser.yy"
     7222    { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); }
     7223    break;
     7224
     7225  case 419:
     7226
     7227/* Line 1806 of yacc.c  */
    72527228#line 1649 "parser.yy"
    7253     { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); }
    7254     break;
    7255 
    7256   case 419:
    7257 
    7258 /* Line 1806 of yacc.c  */
    7259 #line 1655 "parser.yy"
    72607229    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
    72617230    break;
     
    72647233
    72657234/* Line 1806 of yacc.c  */
    7266 #line 1660 "parser.yy"
     7235#line 1654 "parser.yy"
    72677236    { (yyval.decl) = 0; }
    72687237    break;
     
    72717240
    72727241/* Line 1806 of yacc.c  */
    7273 #line 1667 "parser.yy"
     7242#line 1661 "parser.yy"
    72747243    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
    72757244    break;
     
    72787247
    72797248/* Line 1806 of yacc.c  */
    7280 #line 1674 "parser.yy"
     7249#line 1668 "parser.yy"
    72817250    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
    72827251    break;
     
    72857254
    72867255/* Line 1806 of yacc.c  */
    7287 #line 1676 "parser.yy"
     7256#line 1670 "parser.yy"
    72887257    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
    72897258    break;
     
    72927261
    72937262/* Line 1806 of yacc.c  */
    7294 #line 1685 "parser.yy"
     7263#line 1679 "parser.yy"
    72957264    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
    72967265    break;
     
    72997268
    73007269/* Line 1806 of yacc.c  */
    7301 #line 1688 "parser.yy"
     7270#line 1682 "parser.yy"
    73027271    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
    73037272    break;
     
    73067275
    73077276/* Line 1806 of yacc.c  */
    7308 #line 1690 "parser.yy"
     7277#line 1684 "parser.yy"
    73097278    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addName( (yyvsp[(3) - (4)].tok) )->addQualifiers( (yyvsp[(1) - (4)].decl) ); }
    73107279    break;
     
    73137282
    73147283/* Line 1806 of yacc.c  */
     7284#line 1694 "parser.yy"
     7285    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     7286    break;
     7287
     7288  case 438:
     7289
     7290/* Line 1806 of yacc.c  */
    73157291#line 1700 "parser.yy"
    7316     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    7317     break;
    7318 
    7319   case 438:
    7320 
    7321 /* Line 1806 of yacc.c  */
    7322 #line 1706 "parser.yy"
    73237292    {
    73247293                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    73307299
    73317300/* Line 1806 of yacc.c  */
    7332 #line 1711 "parser.yy"
     7301#line 1705 "parser.yy"
    73337302    {
    73347303                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    73407309
    73417310/* Line 1806 of yacc.c  */
    7342 #line 1720 "parser.yy"
     7311#line 1714 "parser.yy"
    73437312    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
    73447313    break;
     
    73477316
    73487317/* Line 1806 of yacc.c  */
    7349 #line 1729 "parser.yy"
     7318#line 1723 "parser.yy"
    73507319    { (yyval.decl) = DeclarationNode::newName( (yyvsp[(1) - (1)].tok) ); }
    73517320    break;
     
    73547323
    73557324/* Line 1806 of yacc.c  */
    7356 #line 1731 "parser.yy"
     7325#line 1725 "parser.yy"
    73577326    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( DeclarationNode::newName( (yyvsp[(3) - (3)].tok) ) ); }
    73587327    break;
     
    73617330
    73627331/* Line 1806 of yacc.c  */
    7363 #line 1756 "parser.yy"
     7332#line 1750 "parser.yy"
    73647333    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
    73657334    break;
     
    73687337
    73697338/* Line 1806 of yacc.c  */
    7370 #line 1764 "parser.yy"
     7339#line 1758 "parser.yy"
    73717340    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
    73727341    break;
     
    73757344
    73767345/* Line 1806 of yacc.c  */
    7377 #line 1769 "parser.yy"
     7346#line 1763 "parser.yy"
    73787347    { (yyval.in) = 0; }
    73797348    break;
     
    73827351
    73837352/* Line 1806 of yacc.c  */
     7353#line 1765 "parser.yy"
     7354    { (yyval.in) = (yyvsp[(2) - (2)].in); }
     7355    break;
     7356
     7357  case 462:
     7358
     7359/* Line 1806 of yacc.c  */
     7360#line 1767 "parser.yy"
     7361    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
     7362    break;
     7363
     7364  case 463:
     7365
     7366/* Line 1806 of yacc.c  */
    73847367#line 1771 "parser.yy"
    7385     { (yyval.in) = (yyvsp[(2) - (2)].in); }
    7386     break;
    7387 
    7388   case 462:
    7389 
    7390 /* Line 1806 of yacc.c  */
    7391 #line 1773 "parser.yy"
    7392     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
    7393     break;
    7394 
    7395   case 463:
     7368    { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); }
     7369    break;
     7370
     7371  case 464:
     7372
     7373/* Line 1806 of yacc.c  */
     7374#line 1772 "parser.yy"
     7375    { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); }
     7376    break;
     7377
     7378  case 465:
    73967379
    73977380/* Line 1806 of yacc.c  */
    73987381#line 1777 "parser.yy"
    7399     { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); }
    7400     break;
    7401 
    7402   case 464:
    7403 
    7404 /* Line 1806 of yacc.c  */
    7405 #line 1778 "parser.yy"
    7406     { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); }
    7407     break;
    7408 
    7409   case 465:
    7410 
    7411 /* Line 1806 of yacc.c  */
    7412 #line 1783 "parser.yy"
    74137382    { (yyval.in) = 0; }
    74147383    break;
     
    74177386
    74187387/* Line 1806 of yacc.c  */
    7419 #line 1785 "parser.yy"
     7388#line 1779 "parser.yy"
    74207389    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_designators( (yyvsp[(1) - (2)].en) ); }
    74217390    break;
     
    74247393
    74257394/* Line 1806 of yacc.c  */
    7426 #line 1786 "parser.yy"
     7395#line 1780 "parser.yy"
    74277396    { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (3)].in)->set_last( (yyvsp[(3) - (3)].in) ) ); }
    74287397    break;
     
    74317400
    74327401/* Line 1806 of yacc.c  */
    7433 #line 1788 "parser.yy"
     7402#line 1782 "parser.yy"
    74347403    { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (4)].in)->set_last( (yyvsp[(4) - (4)].in)->set_designators( (yyvsp[(3) - (4)].en) ) ) ); }
    74357404    break;
     
    74387407
    74397408/* Line 1806 of yacc.c  */
     7409#line 1798 "parser.yy"
     7410    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); }
     7411    break;
     7412
     7413  case 473:
     7414
     7415/* Line 1806 of yacc.c  */
    74407416#line 1804 "parser.yy"
    7441     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); }
    7442     break;
    7443 
    7444   case 473:
     7417    { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); }
     7418    break;
     7419
     7420  case 474:
    74457421
    74467422/* Line 1806 of yacc.c  */
    74477423#line 1810 "parser.yy"
    7448     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); }
    7449     break;
    7450 
    7451   case 474:
    7452 
    7453 /* Line 1806 of yacc.c  */
    7454 #line 1816 "parser.yy"
    74557424    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(2) - (2)].tok) ) ); }
    74567425    break;
     
    74597428
    74607429/* Line 1806 of yacc.c  */
     7430#line 1813 "parser.yy"
     7431    { (yyval.en) = (yyvsp[(3) - (5)].en); }
     7432    break;
     7433
     7434  case 476:
     7435
     7436/* Line 1806 of yacc.c  */
     7437#line 1815 "parser.yy"
     7438    { (yyval.en) = (yyvsp[(3) - (5)].en); }
     7439    break;
     7440
     7441  case 477:
     7442
     7443/* Line 1806 of yacc.c  */
     7444#line 1817 "parser.yy"
     7445    { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); }
     7446    break;
     7447
     7448  case 478:
     7449
     7450/* Line 1806 of yacc.c  */
    74617451#line 1819 "parser.yy"
    7462     { (yyval.en) = (yyvsp[(3) - (5)].en); }
    7463     break;
    7464 
    7465   case 476:
    7466 
    7467 /* Line 1806 of yacc.c  */
    7468 #line 1821 "parser.yy"
    7469     { (yyval.en) = (yyvsp[(3) - (5)].en); }
    7470     break;
    7471 
    7472   case 477:
    7473 
    7474 /* Line 1806 of yacc.c  */
    7475 #line 1823 "parser.yy"
    7476     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); }
    7477     break;
    7478 
    7479   case 478:
    7480 
    7481 /* Line 1806 of yacc.c  */
    7482 #line 1825 "parser.yy"
    74837452    { (yyval.en) = (yyvsp[(4) - (6)].en); }
    74847453    break;
     
    74877456
    74887457/* Line 1806 of yacc.c  */
    7489 #line 1849 "parser.yy"
     7458#line 1843 "parser.yy"
    74907459    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    74917460    break;
     
    74947463
    74957464/* Line 1806 of yacc.c  */
    7496 #line 1851 "parser.yy"
     7465#line 1845 "parser.yy"
    74977466    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    74987467    break;
     
    75017470
    75027471/* Line 1806 of yacc.c  */
     7472#line 1847 "parser.yy"
     7473    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     7474    break;
     7475
     7476  case 484:
     7477
     7478/* Line 1806 of yacc.c  */
    75037479#line 1853 "parser.yy"
    7504     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
    7505     break;
    7506 
    7507   case 484:
    7508 
    7509 /* Line 1806 of yacc.c  */
    7510 #line 1859 "parser.yy"
    75117480    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    75127481    break;
     
    75157484
    75167485/* Line 1806 of yacc.c  */
    7517 #line 1861 "parser.yy"
     7486#line 1855 "parser.yy"
    75187487    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    75197488    break;
     
    75227491
    75237492/* Line 1806 of yacc.c  */
     7493#line 1860 "parser.yy"
     7494    { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     7495    break;
     7496
     7497  case 488:
     7498
     7499/* Line 1806 of yacc.c  */
    75247500#line 1866 "parser.yy"
    7525     { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
    7526     break;
    7527 
    7528   case 488:
    7529 
    7530 /* Line 1806 of yacc.c  */
    7531 #line 1872 "parser.yy"
    75327501    { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(3) - (4)].decl) ); }
    75337502    break;
     
    75367505
    75377506/* Line 1806 of yacc.c  */
    7538 #line 1877 "parser.yy"
     7507#line 1871 "parser.yy"
    75397508    { typedefTable.addToEnclosingScope( *(yyvsp[(2) - (2)].tok), TypedefTable::TD ); }
    75407509    break;
     
    75437512
    75447513/* Line 1806 of yacc.c  */
     7514#line 1873 "parser.yy"
     7515    { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); }
     7516    break;
     7517
     7518  case 492:
     7519
     7520/* Line 1806 of yacc.c  */
    75457521#line 1879 "parser.yy"
    7546     { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); }
    7547     break;
    7548 
    7549   case 492:
    7550 
    7551 /* Line 1806 of yacc.c  */
    7552 #line 1885 "parser.yy"
    75537522    { (yyval.tclass) = DeclarationNode::Otype; }
    75547523    break;
     
    75577526
    75587527/* Line 1806 of yacc.c  */
    7559 #line 1887 "parser.yy"
     7528#line 1881 "parser.yy"
    75607529    { (yyval.tclass) = DeclarationNode::Ftype; }
    75617530    break;
     
    75647533
    75657534/* Line 1806 of yacc.c  */
    7566 #line 1889 "parser.yy"
     7535#line 1883 "parser.yy"
    75677536    { (yyval.tclass) = DeclarationNode::Dtype; }
    75687537    break;
     
    75717540
    75727541/* Line 1806 of yacc.c  */
    7573 #line 1894 "parser.yy"
     7542#line 1888 "parser.yy"
    75747543    { (yyval.decl) = 0; }
    75757544    break;
     
    75787547
    75797548/* Line 1806 of yacc.c  */
    7580 #line 1896 "parser.yy"
     7549#line 1890 "parser.yy"
    75817550    { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
    75827551    break;
     
    75857554
    75867555/* Line 1806 of yacc.c  */
    7587 #line 1901 "parser.yy"
     7556#line 1895 "parser.yy"
    75887557    {
    75897558                        typedefTable.openTrait( *(yyvsp[(2) - (5)].tok) );
     
    75957564
    75967565/* Line 1806 of yacc.c  */
    7597 #line 1906 "parser.yy"
     7566#line 1900 "parser.yy"
    75987567    { (yyval.decl) = (yyvsp[(4) - (5)].decl); }
    75997568    break;
     
    76027571
    76037572/* Line 1806 of yacc.c  */
    7604 #line 1908 "parser.yy"
     7573#line 1902 "parser.yy"
    76057574    { (yyval.decl) = 0; }
    76067575    break;
     
    76097578
    76107579/* Line 1806 of yacc.c  */
    7611 #line 1913 "parser.yy"
     7580#line 1907 "parser.yy"
    76127581    { (yyval.en) = new ExpressionNode( build_typevalue( (yyvsp[(1) - (1)].decl) ) ); }
    76137582    break;
     
    76167585
    76177586/* Line 1806 of yacc.c  */
    7618 #line 1916 "parser.yy"
     7587#line 1910 "parser.yy"
    76197588    { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( build_typevalue( (yyvsp[(3) - (3)].decl) ) ) ) ); }
    76207589    break;
     
    76237592
    76247593/* Line 1806 of yacc.c  */
    7625 #line 1918 "parser.yy"
     7594#line 1912 "parser.yy"
    76267595    { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
    76277596    break;
     
    76307599
    76317600/* Line 1806 of yacc.c  */
    7632 #line 1923 "parser.yy"
     7601#line 1917 "parser.yy"
    76337602    { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
    76347603    break;
     
    76377606
    76387607/* Line 1806 of yacc.c  */
    7639 #line 1925 "parser.yy"
     7608#line 1919 "parser.yy"
    76407609    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) ); }
    76417610    break;
     
    76447613
    76457614/* Line 1806 of yacc.c  */
    7646 #line 1927 "parser.yy"
     7615#line 1921 "parser.yy"
    76477616    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl)->copyStorageClasses( (yyvsp[(1) - (3)].decl) ) ); }
    76487617    break;
     
    76517620
    76527621/* Line 1806 of yacc.c  */
    7653 #line 1932 "parser.yy"
     7622#line 1926 "parser.yy"
    76547623    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addAssertions( (yyvsp[(2) - (2)].decl) ); }
    76557624    break;
     
    76587627
    76597628/* Line 1806 of yacc.c  */
    7660 #line 1934 "parser.yy"
     7629#line 1928 "parser.yy"
    76617630    { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addAssertions( (yyvsp[(2) - (4)].decl) )->addType( (yyvsp[(4) - (4)].decl) ); }
    76627631    break;
     
    76657634
    76667635/* Line 1806 of yacc.c  */
    7667 #line 1939 "parser.yy"
     7636#line 1933 "parser.yy"
    76687637    {
    76697638                        typedefTable.addToEnclosingScope( *(yyvsp[(1) - (1)].tok), TypedefTable::TD );
     
    76757644
    76767645/* Line 1806 of yacc.c  */
    7677 #line 1944 "parser.yy"
     7646#line 1938 "parser.yy"
    76787647    {
    76797648                        typedefTable.addToEnclosingScope( *(yyvsp[(1) - (6)].tok), TypedefTable::TG );
     
    76857654
    76867655/* Line 1806 of yacc.c  */
    7687 #line 1952 "parser.yy"
     7656#line 1946 "parser.yy"
    76887657    {
    76897658                        typedefTable.addToEnclosingScope( *(yyvsp[(2) - (9)].tok), TypedefTable::ID );
     
    76957664
    76967665/* Line 1806 of yacc.c  */
    7697 #line 1957 "parser.yy"
     7666#line 1951 "parser.yy"
    76987667    {
    76997668                        typedefTable.enterTrait( *(yyvsp[(2) - (8)].tok) );
     
    77057674
    77067675/* Line 1806 of yacc.c  */
    7707 #line 1962 "parser.yy"
     7676#line 1956 "parser.yy"
    77087677    {
    77097678                        typedefTable.leaveTrait();
     
    77167685
    77177686/* Line 1806 of yacc.c  */
    7718 #line 1972 "parser.yy"
     7687#line 1966 "parser.yy"
    77197688    { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
    77207689    break;
     
    77237692
    77247693/* Line 1806 of yacc.c  */
    7725 #line 1982 "parser.yy"
     7694#line 1976 "parser.yy"
    77267695    {
    77277696                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     
    77337702
    77347703/* Line 1806 of yacc.c  */
    7735 #line 1987 "parser.yy"
     7704#line 1981 "parser.yy"
    77367705    {
    77377706                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     
    77437712
    77447713/* Line 1806 of yacc.c  */
    7745 #line 1992 "parser.yy"
     7714#line 1986 "parser.yy"
    77467715    {
    77477716                        typedefTable.addToEnclosingScope2( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
     
    77537722
    77547723/* Line 1806 of yacc.c  */
    7755 #line 2000 "parser.yy"
     7724#line 1994 "parser.yy"
    77567725    {
    77577726                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     
    77637732
    77647733/* Line 1806 of yacc.c  */
    7765 #line 2005 "parser.yy"
     7734#line 1999 "parser.yy"
    77667735    {
    77677736                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     
    77737742
    77747743/* Line 1806 of yacc.c  */
    7775 #line 2015 "parser.yy"
     7744#line 2009 "parser.yy"
    77767745    {}
    77777746    break;
     
    77807749
    77817750/* Line 1806 of yacc.c  */
     7751#line 2011 "parser.yy"
     7752    { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl);    }
     7753    break;
     7754
     7755  case 526:
     7756
     7757/* Line 1806 of yacc.c  */
    77827758#line 2017 "parser.yy"
    7783     { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl);    }
    7784     break;
    7785 
    7786   case 526:
    7787 
    7788 /* Line 1806 of yacc.c  */
    7789 #line 2023 "parser.yy"
    77907759    { (yyval.decl) = (yyvsp[(1) - (3)].decl) != nullptr ? (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ) : (yyvsp[(3) - (3)].decl); }
    77917760    break;
     
    77947763
    77957764/* Line 1806 of yacc.c  */
    7796 #line 2028 "parser.yy"
     7765#line 2022 "parser.yy"
    77977766    { (yyval.decl) = 0; }
    77987767    break;
     
    78017770
    78027771/* Line 1806 of yacc.c  */
    7803 #line 2036 "parser.yy"
     7772#line 2030 "parser.yy"
    78047773    {}
    78057774    break;
     
    78087777
    78097778/* Line 1806 of yacc.c  */
    7810 #line 2038 "parser.yy"
     7779#line 2032 "parser.yy"
    78117780    {
    78127781                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
     
    78187787
    78197788/* Line 1806 of yacc.c  */
    7820 #line 2043 "parser.yy"
     7789#line 2037 "parser.yy"
    78217790    {
    78227791                        linkage = linkageStack.top();
     
    78297798
    78307799/* Line 1806 of yacc.c  */
    7831 #line 2049 "parser.yy"
     7800#line 2043 "parser.yy"
    78327801    {   // mark all fields in list
    78337802                        for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
     
    78407809
    78417810/* Line 1806 of yacc.c  */
    7842 #line 2064 "parser.yy"
     7811#line 2058 "parser.yy"
    78437812    {
    78447813                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    78517820
    78527821/* Line 1806 of yacc.c  */
    7853 #line 2070 "parser.yy"
     7822#line 2064 "parser.yy"
    78547823    {
    78557824                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    78627831
    78637832/* Line 1806 of yacc.c  */
    7864 #line 2079 "parser.yy"
     7833#line 2073 "parser.yy"
    78657834    {
    78667835                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    78737842
    78747843/* Line 1806 of yacc.c  */
    7875 #line 2085 "parser.yy"
     7844#line 2079 "parser.yy"
    78767845    {
    78777846                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    78827851
    78837852  case 540:
     7853
     7854/* Line 1806 of yacc.c  */
     7855#line 2085 "parser.yy"
     7856    {
     7857                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     7858                        typedefTable.leaveScope();
     7859                        (yyval.decl) = (yyvsp[(2) - (3)].decl)->addFunctionBody( (yyvsp[(3) - (3)].sn) )->addQualifiers( (yyvsp[(1) - (3)].decl) );
     7860                }
     7861    break;
     7862
     7863  case 541:
    78847864
    78857865/* Line 1806 of yacc.c  */
     
    78927872    break;
    78937873
    7894   case 541:
     7874  case 542:
    78957875
    78967876/* Line 1806 of yacc.c  */
    78977877#line 2097 "parser.yy"
    7898     {
    7899                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    7900                         typedefTable.leaveScope();
    7901                         (yyval.decl) = (yyvsp[(2) - (3)].decl)->addFunctionBody( (yyvsp[(3) - (3)].sn) )->addQualifiers( (yyvsp[(1) - (3)].decl) );
    7902                 }
    7903     break;
    7904 
    7905   case 542:
    7906 
    7907 /* Line 1806 of yacc.c  */
    7908 #line 2103 "parser.yy"
    79097878    {
    79107879                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    79177886
    79187887/* Line 1806 of yacc.c  */
    7919 #line 2111 "parser.yy"
     7888#line 2105 "parser.yy"
    79207889    {
    79217890                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    79287897
    79297898/* Line 1806 of yacc.c  */
    7930 #line 2117 "parser.yy"
     7899#line 2111 "parser.yy"
    79317900    {
    79327901                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    79397908
    79407909/* Line 1806 of yacc.c  */
    7941 #line 2125 "parser.yy"
     7910#line 2119 "parser.yy"
    79427911    {
    79437912                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    79507919
    79517920/* Line 1806 of yacc.c  */
    7952 #line 2131 "parser.yy"
     7921#line 2125 "parser.yy"
    79537922    {
    79547923                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     
    79617930
    79627931/* Line 1806 of yacc.c  */
    7963 #line 2146 "parser.yy"
     7932#line 2140 "parser.yy"
    79647933    { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    79657934    break;
     
    79687937
    79697938/* Line 1806 of yacc.c  */
    7970 #line 2151 "parser.yy"
     7939#line 2145 "parser.yy"
    79717940    { delete (yyvsp[(3) - (5)].str); }
    79727941    break;
     
    79757944
    79767945/* Line 1806 of yacc.c  */
    7977 #line 2156 "parser.yy"
     7946#line 2150 "parser.yy"
    79787947    { (yyval.decl) = 0; }
    79797948    break;
     
    79827951
    79837952/* Line 1806 of yacc.c  */
     7953#line 2157 "parser.yy"
     7954    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     7955    break;
     7956
     7957  case 557:
     7958
     7959/* Line 1806 of yacc.c  */
    79847960#line 2163 "parser.yy"
    7985     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    7986     break;
    7987 
    7988   case 557:
    7989 
    7990 /* Line 1806 of yacc.c  */
    7991 #line 2169 "parser.yy"
    79927961    { (yyval.decl) = 0; }
    79937962    break;
     
    79967965
    79977966/* Line 1806 of yacc.c  */
     7967#line 2174 "parser.yy"
     7968    { delete (yyvsp[(3) - (4)].en); }
     7969    break;
     7970
     7971  case 563:
     7972
     7973/* Line 1806 of yacc.c  */
     7974#line 2178 "parser.yy"
     7975    { delete (yyvsp[(1) - (1)].tok); }
     7976    break;
     7977
     7978  case 564:
     7979
     7980/* Line 1806 of yacc.c  */
     7981#line 2179 "parser.yy"
     7982    { delete (yyvsp[(1) - (1)].decl); }
     7983    break;
     7984
     7985  case 565:
     7986
     7987/* Line 1806 of yacc.c  */
    79987988#line 2180 "parser.yy"
    7999     { delete (yyvsp[(3) - (4)].en); }
    8000     break;
    8001 
    8002   case 563:
    8003 
    8004 /* Line 1806 of yacc.c  */
    8005 #line 2184 "parser.yy"
    8006     { delete (yyvsp[(1) - (1)].tok); }
    8007     break;
    8008 
    8009   case 564:
    8010 
    8011 /* Line 1806 of yacc.c  */
    8012 #line 2185 "parser.yy"
    80137989    { delete (yyvsp[(1) - (1)].decl); }
    80147990    break;
    80157991
    8016   case 565:
    8017 
    8018 /* Line 1806 of yacc.c  */
    8019 #line 2186 "parser.yy"
     7992  case 566:
     7993
     7994/* Line 1806 of yacc.c  */
     7995#line 2181 "parser.yy"
    80207996    { delete (yyvsp[(1) - (1)].decl); }
    80217997    break;
    80227998
    8023   case 566:
    8024 
    8025 /* Line 1806 of yacc.c  */
    8026 #line 2187 "parser.yy"
    8027     { delete (yyvsp[(1) - (1)].decl); }
    8028     break;
    8029 
    80307999  case 567:
    80318000
    80328001/* Line 1806 of yacc.c  */
    8033 #line 2222 "parser.yy"
     8002#line 2216 "parser.yy"
    80348003    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    80358004    break;
     
    80388007
    80398008/* Line 1806 of yacc.c  */
    8040 #line 2225 "parser.yy"
     8009#line 2219 "parser.yy"
    80418010    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    80428011    break;
     
    80458014
    80468015/* Line 1806 of yacc.c  */
    8047 #line 2227 "parser.yy"
     8016#line 2221 "parser.yy"
    80488017    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    80498018    break;
     
    80528021
    80538022/* Line 1806 of yacc.c  */
    8054 #line 2232 "parser.yy"
     8023#line 2226 "parser.yy"
    80558024    {
    80568025                        typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
     
    80628031
    80638032/* Line 1806 of yacc.c  */
    8064 #line 2237 "parser.yy"
     8033#line 2231 "parser.yy"
    80658034    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    80668035    break;
     
    80698038
    80708039/* Line 1806 of yacc.c  */
    8071 #line 2242 "parser.yy"
     8040#line 2236 "parser.yy"
    80728041    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    80738042    break;
     
    80768045
    80778046/* Line 1806 of yacc.c  */
    8078 #line 2244 "parser.yy"
     8047#line 2238 "parser.yy"
    80798048    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    80808049    break;
     
    80838052
    80848053/* Line 1806 of yacc.c  */
    8085 #line 2246 "parser.yy"
     8054#line 2240 "parser.yy"
    80868055    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    80878056    break;
     
    80908059
    80918060/* Line 1806 of yacc.c  */
     8061#line 2245 "parser.yy"
     8062    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     8063    break;
     8064
     8065  case 577:
     8066
     8067/* Line 1806 of yacc.c  */
     8068#line 2247 "parser.yy"
     8069    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8070    break;
     8071
     8072  case 578:
     8073
     8074/* Line 1806 of yacc.c  */
     8075#line 2249 "parser.yy"
     8076    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8077    break;
     8078
     8079  case 579:
     8080
     8081/* Line 1806 of yacc.c  */
    80928082#line 2251 "parser.yy"
     8083    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8084    break;
     8085
     8086  case 580:
     8087
     8088/* Line 1806 of yacc.c  */
     8089#line 2256 "parser.yy"
     8090    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     8091    break;
     8092
     8093  case 581:
     8094
     8095/* Line 1806 of yacc.c  */
     8096#line 2258 "parser.yy"
     8097    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8098    break;
     8099
     8100  case 582:
     8101
     8102/* Line 1806 of yacc.c  */
     8103#line 2267 "parser.yy"
     8104    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8105    break;
     8106
     8107  case 584:
     8108
     8109/* Line 1806 of yacc.c  */
     8110#line 2270 "parser.yy"
     8111    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8112    break;
     8113
     8114  case 585:
     8115
     8116/* Line 1806 of yacc.c  */
     8117#line 2275 "parser.yy"
     8118    { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     8119    break;
     8120
     8121  case 586:
     8122
     8123/* Line 1806 of yacc.c  */
     8124#line 2277 "parser.yy"
     8125    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     8126    break;
     8127
     8128  case 587:
     8129
     8130/* Line 1806 of yacc.c  */
     8131#line 2279 "parser.yy"
     8132    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8133    break;
     8134
     8135  case 588:
     8136
     8137/* Line 1806 of yacc.c  */
     8138#line 2284 "parser.yy"
     8139    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     8140    break;
     8141
     8142  case 589:
     8143
     8144/* Line 1806 of yacc.c  */
     8145#line 2286 "parser.yy"
     8146    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     8147    break;
     8148
     8149  case 590:
     8150
     8151/* Line 1806 of yacc.c  */
     8152#line 2288 "parser.yy"
     8153    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8154    break;
     8155
     8156  case 591:
     8157
     8158/* Line 1806 of yacc.c  */
     8159#line 2293 "parser.yy"
     8160    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8161    break;
     8162
     8163  case 592:
     8164
     8165/* Line 1806 of yacc.c  */
     8166#line 2295 "parser.yy"
     8167    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8168    break;
     8169
     8170  case 593:
     8171
     8172/* Line 1806 of yacc.c  */
     8173#line 2297 "parser.yy"
     8174    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8175    break;
     8176
     8177  case 597:
     8178
     8179/* Line 1806 of yacc.c  */
     8180#line 2312 "parser.yy"
     8181    { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); }
     8182    break;
     8183
     8184  case 598:
     8185
     8186/* Line 1806 of yacc.c  */
     8187#line 2314 "parser.yy"
     8188    { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); }
     8189    break;
     8190
     8191  case 599:
     8192
     8193/* Line 1806 of yacc.c  */
     8194#line 2316 "parser.yy"
     8195    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8196    break;
     8197
     8198  case 600:
     8199
     8200/* Line 1806 of yacc.c  */
     8201#line 2321 "parser.yy"
     8202    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     8203    break;
     8204
     8205  case 601:
     8206
     8207/* Line 1806 of yacc.c  */
     8208#line 2323 "parser.yy"
     8209    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     8210    break;
     8211
     8212  case 602:
     8213
     8214/* Line 1806 of yacc.c  */
     8215#line 2325 "parser.yy"
     8216    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8217    break;
     8218
     8219  case 603:
     8220
     8221/* Line 1806 of yacc.c  */
     8222#line 2330 "parser.yy"
     8223    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8224    break;
     8225
     8226  case 604:
     8227
     8228/* Line 1806 of yacc.c  */
     8229#line 2332 "parser.yy"
     8230    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8231    break;
     8232
     8233  case 605:
     8234
     8235/* Line 1806 of yacc.c  */
     8236#line 2334 "parser.yy"
     8237    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8238    break;
     8239
     8240  case 606:
     8241
     8242/* Line 1806 of yacc.c  */
     8243#line 2349 "parser.yy"
     8244    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8245    break;
     8246
     8247  case 608:
     8248
     8249/* Line 1806 of yacc.c  */
     8250#line 2352 "parser.yy"
     8251    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8252    break;
     8253
     8254  case 609:
     8255
     8256/* Line 1806 of yacc.c  */
     8257#line 2354 "parser.yy"
     8258    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8259    break;
     8260
     8261  case 611:
     8262
     8263/* Line 1806 of yacc.c  */
     8264#line 2360 "parser.yy"
     8265    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8266    break;
     8267
     8268  case 612:
     8269
     8270/* Line 1806 of yacc.c  */
     8271#line 2365 "parser.yy"
     8272    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     8273    break;
     8274
     8275  case 613:
     8276
     8277/* Line 1806 of yacc.c  */
     8278#line 2367 "parser.yy"
     8279    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     8280    break;
     8281
     8282  case 614:
     8283
     8284/* Line 1806 of yacc.c  */
     8285#line 2369 "parser.yy"
     8286    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8287    break;
     8288
     8289  case 615:
     8290
     8291/* Line 1806 of yacc.c  */
     8292#line 2374 "parser.yy"
    80938293    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
    80948294    break;
    80958295
    8096   case 577:
    8097 
    8098 /* Line 1806 of yacc.c  */
    8099 #line 2253 "parser.yy"
     8296  case 616:
     8297
     8298/* Line 1806 of yacc.c  */
     8299#line 2376 "parser.yy"
    81008300    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    81018301    break;
    81028302
    8103   case 578:
    8104 
    8105 /* Line 1806 of yacc.c  */
    8106 #line 2255 "parser.yy"
     8303  case 617:
     8304
     8305/* Line 1806 of yacc.c  */
     8306#line 2378 "parser.yy"
    81078307    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    81088308    break;
    81098309
    8110   case 579:
    8111 
    8112 /* Line 1806 of yacc.c  */
    8113 #line 2257 "parser.yy"
     8310  case 618:
     8311
     8312/* Line 1806 of yacc.c  */
     8313#line 2380 "parser.yy"
    81148314    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    81158315    break;
    81168316
    8117   case 580:
    8118 
    8119 /* Line 1806 of yacc.c  */
    8120 #line 2262 "parser.yy"
     8317  case 619:
     8318
     8319/* Line 1806 of yacc.c  */
     8320#line 2385 "parser.yy"
     8321    { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     8322    break;
     8323
     8324  case 620:
     8325
     8326/* Line 1806 of yacc.c  */
     8327#line 2387 "parser.yy"
    81218328    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    81228329    break;
    81238330
    8124   case 581:
    8125 
    8126 /* Line 1806 of yacc.c  */
    8127 #line 2264 "parser.yy"
     8331  case 621:
     8332
     8333/* Line 1806 of yacc.c  */
     8334#line 2389 "parser.yy"
    81288335    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    81298336    break;
    81308337
    8131   case 582:
    8132 
    8133 /* Line 1806 of yacc.c  */
    8134 #line 2273 "parser.yy"
     8338  case 622:
     8339
     8340/* Line 1806 of yacc.c  */
     8341#line 2399 "parser.yy"
    81358342    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    81368343    break;
    81378344
    8138   case 584:
    8139 
    8140 /* Line 1806 of yacc.c  */
    8141 #line 2276 "parser.yy"
     8345  case 624:
     8346
     8347/* Line 1806 of yacc.c  */
     8348#line 2402 "parser.yy"
    81428349    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    81438350    break;
    81448351
    8145   case 585:
    8146 
    8147 /* Line 1806 of yacc.c  */
    8148 #line 2281 "parser.yy"
     8352  case 625:
     8353
     8354/* Line 1806 of yacc.c  */
     8355#line 2404 "parser.yy"
     8356    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8357    break;
     8358
     8359  case 626:
     8360
     8361/* Line 1806 of yacc.c  */
     8362#line 2409 "parser.yy"
     8363    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     8364    break;
     8365
     8366  case 627:
     8367
     8368/* Line 1806 of yacc.c  */
     8369#line 2411 "parser.yy"
     8370    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     8371    break;
     8372
     8373  case 628:
     8374
     8375/* Line 1806 of yacc.c  */
     8376#line 2413 "parser.yy"
     8377    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8378    break;
     8379
     8380  case 629:
     8381
     8382/* Line 1806 of yacc.c  */
     8383#line 2418 "parser.yy"
     8384    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     8385    break;
     8386
     8387  case 630:
     8388
     8389/* Line 1806 of yacc.c  */
     8390#line 2420 "parser.yy"
     8391    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8392    break;
     8393
     8394  case 631:
     8395
     8396/* Line 1806 of yacc.c  */
     8397#line 2422 "parser.yy"
     8398    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8399    break;
     8400
     8401  case 632:
     8402
     8403/* Line 1806 of yacc.c  */
     8404#line 2424 "parser.yy"
     8405    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8406    break;
     8407
     8408  case 633:
     8409
     8410/* Line 1806 of yacc.c  */
     8411#line 2429 "parser.yy"
    81498412    { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
    81508413    break;
    81518414
    8152   case 586:
    8153 
    8154 /* Line 1806 of yacc.c  */
    8155 #line 2283 "parser.yy"
     8415  case 634:
     8416
     8417/* Line 1806 of yacc.c  */
     8418#line 2431 "parser.yy"
    81568419    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    81578420    break;
    81588421
    8159   case 587:
    8160 
    8161 /* Line 1806 of yacc.c  */
    8162 #line 2285 "parser.yy"
     8422  case 635:
     8423
     8424/* Line 1806 of yacc.c  */
     8425#line 2433 "parser.yy"
    81638426    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    81648427    break;
    81658428
    8166   case 588:
    8167 
    8168 /* Line 1806 of yacc.c  */
    8169 #line 2290 "parser.yy"
    8170     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    8171     break;
    8172 
    8173   case 589:
    8174 
    8175 /* Line 1806 of yacc.c  */
    8176 #line 2292 "parser.yy"
    8177     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    8178     break;
    8179 
    8180   case 590:
    8181 
    8182 /* Line 1806 of yacc.c  */
    8183 #line 2294 "parser.yy"
    8184     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8185     break;
    8186 
    8187   case 591:
    8188 
    8189 /* Line 1806 of yacc.c  */
    8190 #line 2299 "parser.yy"
    8191     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8192     break;
    8193 
    8194   case 592:
    8195 
    8196 /* Line 1806 of yacc.c  */
    8197 #line 2301 "parser.yy"
    8198     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8199     break;
    8200 
    8201   case 593:
    8202 
    8203 /* Line 1806 of yacc.c  */
    8204 #line 2303 "parser.yy"
    8205     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8206     break;
    8207 
    8208   case 597:
    8209 
    8210 /* Line 1806 of yacc.c  */
    8211 #line 2318 "parser.yy"
    8212     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); }
    8213     break;
    8214 
    8215   case 598:
    8216 
    8217 /* Line 1806 of yacc.c  */
    8218 #line 2320 "parser.yy"
    8219     { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); }
    8220     break;
    8221 
    8222   case 599:
    8223 
    8224 /* Line 1806 of yacc.c  */
    8225 #line 2322 "parser.yy"
    8226     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8227     break;
    8228 
    8229   case 600:
    8230 
    8231 /* Line 1806 of yacc.c  */
    8232 #line 2327 "parser.yy"
    8233     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    8234     break;
    8235 
    8236   case 601:
    8237 
    8238 /* Line 1806 of yacc.c  */
    8239 #line 2329 "parser.yy"
    8240     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    8241     break;
    8242 
    8243   case 602:
    8244 
    8245 /* Line 1806 of yacc.c  */
    8246 #line 2331 "parser.yy"
    8247     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8248     break;
    8249 
    8250   case 603:
    8251 
    8252 /* Line 1806 of yacc.c  */
    8253 #line 2336 "parser.yy"
    8254     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8255     break;
    8256 
    8257   case 604:
    8258 
    8259 /* Line 1806 of yacc.c  */
    8260 #line 2338 "parser.yy"
    8261     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8262     break;
    8263 
    8264   case 605:
    8265 
    8266 /* Line 1806 of yacc.c  */
    8267 #line 2340 "parser.yy"
    8268     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8269     break;
    8270 
    8271   case 606:
    8272 
    8273 /* Line 1806 of yacc.c  */
    8274 #line 2355 "parser.yy"
     8429  case 636:
     8430
     8431/* Line 1806 of yacc.c  */
     8432#line 2464 "parser.yy"
    82758433    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    82768434    break;
    82778435
    8278   case 608:
    8279 
    8280 /* Line 1806 of yacc.c  */
    8281 #line 2358 "parser.yy"
     8436  case 638:
     8437
     8438/* Line 1806 of yacc.c  */
     8439#line 2467 "parser.yy"
    82828440    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    82838441    break;
    82848442
    8285   case 609:
    8286 
    8287 /* Line 1806 of yacc.c  */
    8288 #line 2360 "parser.yy"
     8443  case 639:
     8444
     8445/* Line 1806 of yacc.c  */
     8446#line 2469 "parser.yy"
    82898447    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    82908448    break;
    82918449
    8292   case 611:
    8293 
    8294 /* Line 1806 of yacc.c  */
    8295 #line 2366 "parser.yy"
    8296     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8297     break;
    8298 
    8299   case 612:
    8300 
    8301 /* Line 1806 of yacc.c  */
    8302 #line 2371 "parser.yy"
    8303     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    8304     break;
    8305 
    8306   case 613:
    8307 
    8308 /* Line 1806 of yacc.c  */
    8309 #line 2373 "parser.yy"
    8310     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    8311     break;
    8312 
    8313   case 614:
    8314 
    8315 /* Line 1806 of yacc.c  */
    8316 #line 2375 "parser.yy"
    8317     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8318     break;
    8319 
    8320   case 615:
    8321 
    8322 /* Line 1806 of yacc.c  */
    8323 #line 2380 "parser.yy"
    8324     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
    8325     break;
    8326 
    8327   case 616:
    8328 
    8329 /* Line 1806 of yacc.c  */
    8330 #line 2382 "parser.yy"
    8331     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8332     break;
    8333 
    8334   case 617:
    8335 
    8336 /* Line 1806 of yacc.c  */
    8337 #line 2384 "parser.yy"
    8338     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8339     break;
    8340 
    8341   case 618:
    8342 
    8343 /* Line 1806 of yacc.c  */
    8344 #line 2386 "parser.yy"
    8345     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8346     break;
    8347 
    8348   case 619:
    8349 
    8350 /* Line 1806 of yacc.c  */
    8351 #line 2391 "parser.yy"
    8352     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
    8353     break;
    8354 
    8355   case 620:
    8356 
    8357 /* Line 1806 of yacc.c  */
    8358 #line 2393 "parser.yy"
    8359     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    8360     break;
    8361 
    8362   case 621:
    8363 
    8364 /* Line 1806 of yacc.c  */
    8365 #line 2395 "parser.yy"
    8366     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8367     break;
    8368 
    8369   case 622:
    8370 
    8371 /* Line 1806 of yacc.c  */
    8372 #line 2405 "parser.yy"
    8373     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8374     break;
    8375 
    8376   case 624:
    8377 
    8378 /* Line 1806 of yacc.c  */
    8379 #line 2408 "parser.yy"
    8380     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8381     break;
    8382 
    8383   case 625:
    8384 
    8385 /* Line 1806 of yacc.c  */
    8386 #line 2410 "parser.yy"
    8387     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8388     break;
    8389 
    8390   case 626:
    8391 
    8392 /* Line 1806 of yacc.c  */
    8393 #line 2415 "parser.yy"
    8394     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    8395     break;
    8396 
    8397   case 627:
    8398 
    8399 /* Line 1806 of yacc.c  */
    8400 #line 2417 "parser.yy"
    8401     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    8402     break;
    8403 
    8404   case 628:
    8405 
    8406 /* Line 1806 of yacc.c  */
    8407 #line 2419 "parser.yy"
    8408     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8409     break;
    8410 
    8411   case 629:
    8412 
    8413 /* Line 1806 of yacc.c  */
    8414 #line 2424 "parser.yy"
    8415     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
    8416     break;
    8417 
    8418   case 630:
    8419 
    8420 /* Line 1806 of yacc.c  */
    8421 #line 2426 "parser.yy"
    8422     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8423     break;
    8424 
    8425   case 631:
    8426 
    8427 /* Line 1806 of yacc.c  */
    8428 #line 2428 "parser.yy"
    8429     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8430     break;
    8431 
    8432   case 632:
    8433 
    8434 /* Line 1806 of yacc.c  */
    8435 #line 2430 "parser.yy"
    8436     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8437     break;
    8438 
    8439   case 633:
    8440 
    8441 /* Line 1806 of yacc.c  */
    8442 #line 2435 "parser.yy"
    8443     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
    8444     break;
    8445 
    8446   case 634:
    8447 
    8448 /* Line 1806 of yacc.c  */
    8449 #line 2437 "parser.yy"
    8450     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    8451     break;
    8452 
    8453   case 635:
    8454 
    8455 /* Line 1806 of yacc.c  */
    8456 #line 2439 "parser.yy"
    8457     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8458     break;
    8459 
    8460   case 636:
    8461 
    8462 /* Line 1806 of yacc.c  */
    8463 #line 2470 "parser.yy"
    8464     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8465     break;
    8466 
    8467   case 638:
    8468 
    8469 /* Line 1806 of yacc.c  */
    8470 #line 2473 "parser.yy"
    8471     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8472     break;
    8473 
    8474   case 639:
    8475 
    8476 /* Line 1806 of yacc.c  */
    8477 #line 2475 "parser.yy"
    8478     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8479     break;
    8480 
    84818450  case 640:
    84828451
    84838452/* Line 1806 of yacc.c  */
    8484 #line 2480 "parser.yy"
     8453#line 2474 "parser.yy"
    84858454    {
    84868455                        typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
     
    84928461
    84938462/* Line 1806 of yacc.c  */
    8494 #line 2485 "parser.yy"
     8463#line 2479 "parser.yy"
    84958464    {
    84968465                        typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
     
    85028471
    85038472/* Line 1806 of yacc.c  */
    8504 #line 2493 "parser.yy"
     8473#line 2487 "parser.yy"
    85058474    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    85068475    break;
     
    85098478
    85108479/* Line 1806 of yacc.c  */
    8511 #line 2495 "parser.yy"
     8480#line 2489 "parser.yy"
    85128481    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    85138482    break;
     
    85168485
    85178486/* Line 1806 of yacc.c  */
    8518 #line 2497 "parser.yy"
     8487#line 2491 "parser.yy"
    85198488    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    85208489    break;
     
    85238492
    85248493/* Line 1806 of yacc.c  */
    8525 #line 2502 "parser.yy"
     8494#line 2496 "parser.yy"
    85268495    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
    85278496    break;
     
    85308499
    85318500/* Line 1806 of yacc.c  */
    8532 #line 2504 "parser.yy"
     8501#line 2498 "parser.yy"
    85338502    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    85348503    break;
     
    85378506
    85388507/* Line 1806 of yacc.c  */
    8539 #line 2509 "parser.yy"
     8508#line 2503 "parser.yy"
    85408509    { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
    85418510    break;
     
    85448513
    85458514/* Line 1806 of yacc.c  */
    8546 #line 2511 "parser.yy"
     8515#line 2505 "parser.yy"
    85478516    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    85488517    break;
     
    85518520
    85528521/* Line 1806 of yacc.c  */
    8553 #line 2526 "parser.yy"
     8522#line 2520 "parser.yy"
    85548523    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    85558524    break;
     
    85588527
    85598528/* Line 1806 of yacc.c  */
    8560 #line 2528 "parser.yy"
     8529#line 2522 "parser.yy"
    85618530    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    85628531    break;
     
    85658534
    85668535/* Line 1806 of yacc.c  */
     8536#line 2527 "parser.yy"
     8537    { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     8538    break;
     8539
     8540  case 653:
     8541
     8542/* Line 1806 of yacc.c  */
     8543#line 2529 "parser.yy"
     8544    { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     8545    break;
     8546
     8547  case 654:
     8548
     8549/* Line 1806 of yacc.c  */
     8550#line 2531 "parser.yy"
     8551    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     8552    break;
     8553
     8554  case 655:
     8555
     8556/* Line 1806 of yacc.c  */
    85678557#line 2533 "parser.yy"
     8558    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     8559    break;
     8560
     8561  case 656:
     8562
     8563/* Line 1806 of yacc.c  */
     8564#line 2535 "parser.yy"
     8565    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8566    break;
     8567
     8568  case 658:
     8569
     8570/* Line 1806 of yacc.c  */
     8571#line 2541 "parser.yy"
     8572    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8573    break;
     8574
     8575  case 659:
     8576
     8577/* Line 1806 of yacc.c  */
     8578#line 2543 "parser.yy"
     8579    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     8580    break;
     8581
     8582  case 660:
     8583
     8584/* Line 1806 of yacc.c  */
     8585#line 2545 "parser.yy"
     8586    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8587    break;
     8588
     8589  case 661:
     8590
     8591/* Line 1806 of yacc.c  */
     8592#line 2550 "parser.yy"
     8593    { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); }
     8594    break;
     8595
     8596  case 662:
     8597
     8598/* Line 1806 of yacc.c  */
     8599#line 2552 "parser.yy"
     8600    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     8601    break;
     8602
     8603  case 663:
     8604
     8605/* Line 1806 of yacc.c  */
     8606#line 2554 "parser.yy"
     8607    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     8608    break;
     8609
     8610  case 664:
     8611
     8612/* Line 1806 of yacc.c  */
     8613#line 2560 "parser.yy"
     8614    { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     8615    break;
     8616
     8617  case 665:
     8618
     8619/* Line 1806 of yacc.c  */
     8620#line 2562 "parser.yy"
     8621    { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); }
     8622    break;
     8623
     8624  case 667:
     8625
     8626/* Line 1806 of yacc.c  */
     8627#line 2568 "parser.yy"
     8628    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); }
     8629    break;
     8630
     8631  case 668:
     8632
     8633/* Line 1806 of yacc.c  */
     8634#line 2570 "parser.yy"
     8635    { (yyval.decl) = DeclarationNode::newVarArray( 0 ); }
     8636    break;
     8637
     8638  case 669:
     8639
     8640/* Line 1806 of yacc.c  */
     8641#line 2572 "parser.yy"
     8642    { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); }
     8643    break;
     8644
     8645  case 670:
     8646
     8647/* Line 1806 of yacc.c  */
     8648#line 2574 "parser.yy"
     8649    { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); }
     8650    break;
     8651
     8652  case 672:
     8653
     8654/* Line 1806 of yacc.c  */
     8655#line 2589 "parser.yy"
     8656    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8657    break;
     8658
     8659  case 673:
     8660
     8661/* Line 1806 of yacc.c  */
     8662#line 2591 "parser.yy"
     8663    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     8664    break;
     8665
     8666  case 674:
     8667
     8668/* Line 1806 of yacc.c  */
     8669#line 2596 "parser.yy"
    85688670    { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
    85698671    break;
    85708672
    8571   case 653:
    8572 
    8573 /* Line 1806 of yacc.c  */
    8574 #line 2535 "parser.yy"
     8673  case 675:
     8674
     8675/* Line 1806 of yacc.c  */
     8676#line 2598 "parser.yy"
    85758677    { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
    85768678    break;
    85778679
    8578   case 654:
    8579 
    8580 /* Line 1806 of yacc.c  */
    8581 #line 2537 "parser.yy"
     8680  case 676:
     8681
     8682/* Line 1806 of yacc.c  */
     8683#line 2600 "parser.yy"
    85828684    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    85838685    break;
    85848686
    8585   case 655:
    8586 
    8587 /* Line 1806 of yacc.c  */
    8588 #line 2539 "parser.yy"
     8687  case 677:
     8688
     8689/* Line 1806 of yacc.c  */
     8690#line 2602 "parser.yy"
    85898691    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    85908692    break;
    85918693
    8592   case 656:
    8593 
    8594 /* Line 1806 of yacc.c  */
    8595 #line 2541 "parser.yy"
     8694  case 678:
     8695
     8696/* Line 1806 of yacc.c  */
     8697#line 2604 "parser.yy"
    85968698    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    85978699    break;
    85988700
    8599   case 658:
    8600 
    8601 /* Line 1806 of yacc.c  */
    8602 #line 2547 "parser.yy"
     8701  case 680:
     8702
     8703/* Line 1806 of yacc.c  */
     8704#line 2610 "parser.yy"
    86038705    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    86048706    break;
    86058707
    8606   case 659:
    8607 
    8608 /* Line 1806 of yacc.c  */
    8609 #line 2549 "parser.yy"
     8708  case 681:
     8709
     8710/* Line 1806 of yacc.c  */
     8711#line 2612 "parser.yy"
    86108712    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    86118713    break;
    86128714
    8613   case 660:
    8614 
    8615 /* Line 1806 of yacc.c  */
    8616 #line 2551 "parser.yy"
     8715  case 682:
     8716
     8717/* Line 1806 of yacc.c  */
     8718#line 2614 "parser.yy"
    86178719    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    86188720    break;
    86198721
    8620   case 661:
    8621 
    8622 /* Line 1806 of yacc.c  */
    8623 #line 2556 "parser.yy"
     8722  case 683:
     8723
     8724/* Line 1806 of yacc.c  */
     8725#line 2619 "parser.yy"
    86248726    { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); }
    86258727    break;
    86268728
    8627   case 662:
    8628 
    8629 /* Line 1806 of yacc.c  */
    8630 #line 2558 "parser.yy"
     8729  case 684:
     8730
     8731/* Line 1806 of yacc.c  */
     8732#line 2621 "parser.yy"
    86318733    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    86328734    break;
    86338735
    8634   case 663:
    8635 
    8636 /* Line 1806 of yacc.c  */
    8637 #line 2560 "parser.yy"
     8736  case 685:
     8737
     8738/* Line 1806 of yacc.c  */
     8739#line 2623 "parser.yy"
    86388740    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    86398741    break;
    86408742
    8641   case 664:
    8642 
    8643 /* Line 1806 of yacc.c  */
    8644 #line 2566 "parser.yy"
     8743  case 687:
     8744
     8745/* Line 1806 of yacc.c  */
     8746#line 2630 "parser.yy"
     8747    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     8748    break;
     8749
     8750  case 689:
     8751
     8752/* Line 1806 of yacc.c  */
     8753#line 2641 "parser.yy"
    86458754    { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
    86468755    break;
    86478756
    8648   case 665:
    8649 
    8650 /* Line 1806 of yacc.c  */
    8651 #line 2568 "parser.yy"
    8652     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); }
    8653     break;
    8654 
    8655   case 667:
    8656 
    8657 /* Line 1806 of yacc.c  */
    8658 #line 2574 "parser.yy"
    8659     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); }
    8660     break;
    8661 
    8662   case 668:
    8663 
    8664 /* Line 1806 of yacc.c  */
    8665 #line 2576 "parser.yy"
    8666     { (yyval.decl) = DeclarationNode::newVarArray( 0 ); }
    8667     break;
    8668 
    8669   case 669:
    8670 
    8671 /* Line 1806 of yacc.c  */
    8672 #line 2578 "parser.yy"
    8673     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); }
    8674     break;
    8675 
    8676   case 670:
    8677 
    8678 /* Line 1806 of yacc.c  */
    8679 #line 2580 "parser.yy"
    8680     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); }
    8681     break;
    8682 
    8683   case 672:
    8684 
    8685 /* Line 1806 of yacc.c  */
    8686 #line 2595 "parser.yy"
     8757  case 690:
     8758
     8759/* Line 1806 of yacc.c  */
     8760#line 2644 "parser.yy"
     8761    { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     8762    break;
     8763
     8764  case 691:
     8765
     8766/* Line 1806 of yacc.c  */
     8767#line 2646 "parser.yy"
     8768    { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); }
     8769    break;
     8770
     8771  case 692:
     8772
     8773/* Line 1806 of yacc.c  */
     8774#line 2649 "parser.yy"
     8775    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     8776    break;
     8777
     8778  case 693:
     8779
     8780/* Line 1806 of yacc.c  */
     8781#line 2651 "parser.yy"
     8782    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); }
     8783    break;
     8784
     8785  case 694:
     8786
     8787/* Line 1806 of yacc.c  */
     8788#line 2653 "parser.yy"
     8789    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); }
     8790    break;
     8791
     8792  case 696:
     8793
     8794/* Line 1806 of yacc.c  */
     8795#line 2667 "parser.yy"
    86878796    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    86888797    break;
    86898798
    8690   case 673:
    8691 
    8692 /* Line 1806 of yacc.c  */
    8693 #line 2597 "parser.yy"
     8799  case 697:
     8800
     8801/* Line 1806 of yacc.c  */
     8802#line 2669 "parser.yy"
    86948803    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    86958804    break;
    86968805
    8697   case 674:
    8698 
    8699 /* Line 1806 of yacc.c  */
    8700 #line 2602 "parser.yy"
     8806  case 698:
     8807
     8808/* Line 1806 of yacc.c  */
     8809#line 2674 "parser.yy"
    87018810    { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
    87028811    break;
    87038812
    8704   case 675:
    8705 
    8706 /* Line 1806 of yacc.c  */
    8707 #line 2604 "parser.yy"
     8813  case 699:
     8814
     8815/* Line 1806 of yacc.c  */
     8816#line 2676 "parser.yy"
    87088817    { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
    87098818    break;
    87108819
    8711   case 676:
    8712 
    8713 /* Line 1806 of yacc.c  */
    8714 #line 2606 "parser.yy"
     8820  case 700:
     8821
     8822/* Line 1806 of yacc.c  */
     8823#line 2678 "parser.yy"
    87158824    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    87168825    break;
    87178826
    8718   case 677:
    8719 
    8720 /* Line 1806 of yacc.c  */
    8721 #line 2608 "parser.yy"
     8827  case 701:
     8828
     8829/* Line 1806 of yacc.c  */
     8830#line 2680 "parser.yy"
    87228831    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    87238832    break;
    87248833
    8725   case 678:
    8726 
    8727 /* Line 1806 of yacc.c  */
    8728 #line 2610 "parser.yy"
     8834  case 702:
     8835
     8836/* Line 1806 of yacc.c  */
     8837#line 2682 "parser.yy"
    87298838    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    87308839    break;
    87318840
    8732   case 680:
    8733 
    8734 /* Line 1806 of yacc.c  */
    8735 #line 2616 "parser.yy"
     8841  case 704:
     8842
     8843/* Line 1806 of yacc.c  */
     8844#line 2688 "parser.yy"
    87368845    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    87378846    break;
    87388847
    8739   case 681:
    8740 
    8741 /* Line 1806 of yacc.c  */
    8742 #line 2618 "parser.yy"
     8848  case 705:
     8849
     8850/* Line 1806 of yacc.c  */
     8851#line 2690 "parser.yy"
    87438852    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    87448853    break;
    87458854
    8746   case 682:
    8747 
    8748 /* Line 1806 of yacc.c  */
    8749 #line 2620 "parser.yy"
     8855  case 706:
     8856
     8857/* Line 1806 of yacc.c  */
     8858#line 2692 "parser.yy"
    87508859    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    87518860    break;
    87528861
    8753   case 683:
    8754 
    8755 /* Line 1806 of yacc.c  */
    8756 #line 2625 "parser.yy"
    8757     { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); }
    8758     break;
    8759 
    8760   case 684:
    8761 
    8762 /* Line 1806 of yacc.c  */
    8763 #line 2627 "parser.yy"
     8862  case 707:
     8863
     8864/* Line 1806 of yacc.c  */
     8865#line 2697 "parser.yy"
    87648866    { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    87658867    break;
    87668868
    8767   case 685:
    8768 
    8769 /* Line 1806 of yacc.c  */
    8770 #line 2629 "parser.yy"
     8869  case 708:
     8870
     8871/* Line 1806 of yacc.c  */
     8872#line 2699 "parser.yy"
    87718873    { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    87728874    break;
    87738875
    8774   case 687:
    8775 
    8776 /* Line 1806 of yacc.c  */
    8777 #line 2636 "parser.yy"
    8778     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
    8779     break;
    8780 
    8781   case 689:
    8782 
    8783 /* Line 1806 of yacc.c  */
    8784 #line 2647 "parser.yy"
    8785     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
    8786     break;
    8787 
    8788   case 690:
    8789 
    8790 /* Line 1806 of yacc.c  */
    8791 #line 2650 "parser.yy"
    8792     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
    8793     break;
    8794 
    8795   case 691:
    8796 
    8797 /* Line 1806 of yacc.c  */
    8798 #line 2652 "parser.yy"
    8799     { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); }
    8800     break;
    8801 
    8802   case 692:
    8803 
    8804 /* Line 1806 of yacc.c  */
    8805 #line 2655 "parser.yy"
    8806     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
    8807     break;
    8808 
    8809   case 693:
    8810 
    8811 /* Line 1806 of yacc.c  */
    8812 #line 2657 "parser.yy"
    8813     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); }
    8814     break;
    8815 
    8816   case 694:
    8817 
    8818 /* Line 1806 of yacc.c  */
    8819 #line 2659 "parser.yy"
    8820     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); }
    8821     break;
    8822 
    8823   case 696:
    8824 
    8825 /* Line 1806 of yacc.c  */
    8826 #line 2673 "parser.yy"
    8827     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8828     break;
    8829 
    8830   case 697:
    8831 
    8832 /* Line 1806 of yacc.c  */
    8833 #line 2675 "parser.yy"
    8834     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
    8835     break;
    8836 
    8837   case 698:
    8838 
    8839 /* Line 1806 of yacc.c  */
    8840 #line 2680 "parser.yy"
    8841     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
    8842     break;
    8843 
    8844   case 699:
    8845 
    8846 /* Line 1806 of yacc.c  */
    8847 #line 2682 "parser.yy"
    8848     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
    8849     break;
    8850 
    8851   case 700:
    8852 
    8853 /* Line 1806 of yacc.c  */
    8854 #line 2684 "parser.yy"
    8855     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
    8856     break;
    8857 
    8858   case 701:
    8859 
    8860 /* Line 1806 of yacc.c  */
    8861 #line 2686 "parser.yy"
    8862     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
    8863     break;
    8864 
    8865   case 702:
    8866 
    8867 /* Line 1806 of yacc.c  */
    8868 #line 2688 "parser.yy"
    8869     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8870     break;
    8871 
    8872   case 704:
    8873 
    8874 /* Line 1806 of yacc.c  */
    8875 #line 2694 "parser.yy"
    8876     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8877     break;
    8878 
    8879   case 705:
    8880 
    8881 /* Line 1806 of yacc.c  */
    8882 #line 2696 "parser.yy"
    8883     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
    8884     break;
    8885 
    8886   case 706:
    8887 
    8888 /* Line 1806 of yacc.c  */
    8889 #line 2698 "parser.yy"
    8890     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8891     break;
    8892 
    8893   case 707:
    8894 
    8895 /* Line 1806 of yacc.c  */
    8896 #line 2703 "parser.yy"
    8897     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
    8898     break;
    8899 
    8900   case 708:
    8901 
    8902 /* Line 1806 of yacc.c  */
    8903 #line 2705 "parser.yy"
    8904     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
    8905     break;
    8906 
    89078876  case 711:
    89088877
    89098878/* Line 1806 of yacc.c  */
    8910 #line 2715 "parser.yy"
     8879#line 2709 "parser.yy"
    89118880    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    89128881    break;
     
    89158884
    89168885/* Line 1806 of yacc.c  */
     8886#line 2719 "parser.yy"
     8887    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     8888    break;
     8889
     8890  case 715:
     8891
     8892/* Line 1806 of yacc.c  */
     8893#line 2721 "parser.yy"
     8894    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     8895    break;
     8896
     8897  case 716:
     8898
     8899/* Line 1806 of yacc.c  */
     8900#line 2723 "parser.yy"
     8901    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     8902    break;
     8903
     8904  case 717:
     8905
     8906/* Line 1806 of yacc.c  */
    89178907#line 2725 "parser.yy"
     8908    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     8909    break;
     8910
     8911  case 718:
     8912
     8913/* Line 1806 of yacc.c  */
     8914#line 2727 "parser.yy"
    89188915    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    89198916    break;
    89208917
    8921   case 715:
    8922 
    8923 /* Line 1806 of yacc.c  */
    8924 #line 2727 "parser.yy"
     8918  case 719:
     8919
     8920/* Line 1806 of yacc.c  */
     8921#line 2729 "parser.yy"
    89258922    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
    89268923    break;
    89278924
    8928   case 716:
    8929 
    8930 /* Line 1806 of yacc.c  */
    8931 #line 2729 "parser.yy"
    8932     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    8933     break;
    8934 
    8935   case 717:
    8936 
    8937 /* Line 1806 of yacc.c  */
    8938 #line 2731 "parser.yy"
    8939     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
    8940     break;
    8941 
    8942   case 718:
    8943 
    8944 /* Line 1806 of yacc.c  */
    8945 #line 2733 "parser.yy"
    8946     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    8947     break;
    8948 
    8949   case 719:
    8950 
    8951 /* Line 1806 of yacc.c  */
    8952 #line 2735 "parser.yy"
    8953     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
    8954     break;
    8955 
    89568925  case 720:
    89578926
    89588927/* Line 1806 of yacc.c  */
     8928#line 2736 "parser.yy"
     8929    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     8930    break;
     8931
     8932  case 721:
     8933
     8934/* Line 1806 of yacc.c  */
     8935#line 2738 "parser.yy"
     8936    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     8937    break;
     8938
     8939  case 722:
     8940
     8941/* Line 1806 of yacc.c  */
     8942#line 2740 "parser.yy"
     8943    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     8944    break;
     8945
     8946  case 723:
     8947
     8948/* Line 1806 of yacc.c  */
    89598949#line 2742 "parser.yy"
    8960     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    8961     break;
    8962 
    8963   case 721:
     8950    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
     8951    break;
     8952
     8953  case 724:
    89648954
    89658955/* Line 1806 of yacc.c  */
     
    89688958    break;
    89698959
    8970   case 722:
    8971 
    8972 /* Line 1806 of yacc.c  */
    8973 #line 2746 "parser.yy"
     8960  case 725:
     8961
     8962/* Line 1806 of yacc.c  */
     8963#line 2747 "parser.yy"
     8964    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     8965    break;
     8966
     8967  case 726:
     8968
     8969/* Line 1806 of yacc.c  */
     8970#line 2749 "parser.yy"
     8971    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     8972    break;
     8973
     8974  case 727:
     8975
     8976/* Line 1806 of yacc.c  */
     8977#line 2751 "parser.yy"
    89748978    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    89758979    break;
    89768980
    8977   case 723:
    8978 
    8979 /* Line 1806 of yacc.c  */
    8980 #line 2748 "parser.yy"
     8981  case 728:
     8982
     8983/* Line 1806 of yacc.c  */
     8984#line 2753 "parser.yy"
    89818985    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
    89828986    break;
    89838987
    8984   case 724:
    8985 
    8986 /* Line 1806 of yacc.c  */
    8987 #line 2750 "parser.yy"
    8988     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
    8989     break;
    8990 
    8991   case 725:
    8992 
    8993 /* Line 1806 of yacc.c  */
    8994 #line 2753 "parser.yy"
    8995     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    8996     break;
    8997 
    8998   case 726:
     8988  case 729:
    89998989
    90008990/* Line 1806 of yacc.c  */
     
    90038993    break;
    90048994
    9005   case 727:
    9006 
    9007 /* Line 1806 of yacc.c  */
    9008 #line 2757 "parser.yy"
    9009     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    9010     break;
    9011 
    9012   case 728:
    9013 
    9014 /* Line 1806 of yacc.c  */
    9015 #line 2759 "parser.yy"
    9016     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
    9017     break;
    9018 
    9019   case 729:
    9020 
    9021 /* Line 1806 of yacc.c  */
    9022 #line 2761 "parser.yy"
     8995  case 730:
     8996
     8997/* Line 1806 of yacc.c  */
     8998#line 2760 "parser.yy"
     8999    { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     9000    break;
     9001
     9002  case 731:
     9003
     9004/* Line 1806 of yacc.c  */
     9005#line 2762 "parser.yy"
     9006    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     9007    break;
     9008
     9009  case 732:
     9010
     9011/* Line 1806 of yacc.c  */
     9012#line 2767 "parser.yy"
     9013    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); }
     9014    break;
     9015
     9016  case 733:
     9017
     9018/* Line 1806 of yacc.c  */
     9019#line 2769 "parser.yy"
     9020    { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); }
     9021    break;
     9022
     9023  case 735:
     9024
     9025/* Line 1806 of yacc.c  */
     9026#line 2796 "parser.yy"
     9027    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     9028    break;
     9029
     9030  case 739:
     9031
     9032/* Line 1806 of yacc.c  */
     9033#line 2807 "parser.yy"
     9034    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     9035    break;
     9036
     9037  case 740:
     9038
     9039/* Line 1806 of yacc.c  */
     9040#line 2809 "parser.yy"
     9041    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     9042    break;
     9043
     9044  case 741:
     9045
     9046/* Line 1806 of yacc.c  */
     9047#line 2811 "parser.yy"
     9048    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     9049    break;
     9050
     9051  case 742:
     9052
     9053/* Line 1806 of yacc.c  */
     9054#line 2813 "parser.yy"
     9055    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     9056    break;
     9057
     9058  case 743:
     9059
     9060/* Line 1806 of yacc.c  */
     9061#line 2815 "parser.yy"
     9062    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     9063    break;
     9064
     9065  case 744:
     9066
     9067/* Line 1806 of yacc.c  */
     9068#line 2817 "parser.yy"
     9069    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     9070    break;
     9071
     9072  case 745:
     9073
     9074/* Line 1806 of yacc.c  */
     9075#line 2824 "parser.yy"
     9076    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     9077    break;
     9078
     9079  case 746:
     9080
     9081/* Line 1806 of yacc.c  */
     9082#line 2826 "parser.yy"
     9083    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     9084    break;
     9085
     9086  case 747:
     9087
     9088/* Line 1806 of yacc.c  */
     9089#line 2828 "parser.yy"
    90239090    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
    90249091    break;
    90259092
    9026   case 730:
    9027 
    9028 /* Line 1806 of yacc.c  */
    9029 #line 2766 "parser.yy"
    9030     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
    9031     break;
    9032 
    9033   case 731:
    9034 
    9035 /* Line 1806 of yacc.c  */
    9036 #line 2768 "parser.yy"
    9037     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
    9038     break;
    9039 
    9040   case 732:
    9041 
    9042 /* Line 1806 of yacc.c  */
    9043 #line 2773 "parser.yy"
    9044     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); }
    9045     break;
    9046 
    9047   case 733:
    9048 
    9049 /* Line 1806 of yacc.c  */
    9050 #line 2775 "parser.yy"
    9051     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); }
    9052     break;
    9053 
    9054   case 735:
    9055 
    9056 /* Line 1806 of yacc.c  */
    9057 #line 2802 "parser.yy"
    9058     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
    9059     break;
    9060 
    9061   case 739:
    9062 
    9063 /* Line 1806 of yacc.c  */
    9064 #line 2813 "parser.yy"
    9065     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    9066     break;
    9067 
    9068   case 740:
    9069 
    9070 /* Line 1806 of yacc.c  */
    9071 #line 2815 "parser.yy"
    9072     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
    9073     break;
    9074 
    9075   case 741:
    9076 
    9077 /* Line 1806 of yacc.c  */
    9078 #line 2817 "parser.yy"
    9079     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    9080     break;
    9081 
    9082   case 742:
    9083 
    9084 /* Line 1806 of yacc.c  */
    9085 #line 2819 "parser.yy"
    9086     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
    9087     break;
    9088 
    9089   case 743:
    9090 
    9091 /* Line 1806 of yacc.c  */
    9092 #line 2821 "parser.yy"
    9093     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    9094     break;
    9095 
    9096   case 744:
    9097 
    9098 /* Line 1806 of yacc.c  */
    9099 #line 2823 "parser.yy"
    9100     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
    9101     break;
    9102 
    9103   case 745:
     9093  case 748:
    91049094
    91059095/* Line 1806 of yacc.c  */
     
    91089098    break;
    91099099
    9110   case 746:
     9100  case 749:
    91119101
    91129102/* Line 1806 of yacc.c  */
     
    91159105    break;
    91169106
    9117   case 747:
     9107  case 750:
    91189108
    91199109/* Line 1806 of yacc.c  */
     
    91229112    break;
    91239113
    9124   case 748:
    9125 
    9126 /* Line 1806 of yacc.c  */
    9127 #line 2836 "parser.yy"
    9128     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    9129     break;
    9130 
    9131   case 749:
    9132 
    9133 /* Line 1806 of yacc.c  */
    9134 #line 2838 "parser.yy"
    9135     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    9136     break;
    9137 
    9138   case 750:
    9139 
    9140 /* Line 1806 of yacc.c  */
    9141 #line 2840 "parser.yy"
    9142     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
    9143     break;
    9144 
    91459114  case 751:
    91469115
    91479116/* Line 1806 of yacc.c  */
    9148 #line 2845 "parser.yy"
     9117#line 2839 "parser.yy"
    91499118    { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
    91509119    break;
     
    91539122
    91549123/* Line 1806 of yacc.c  */
    9155 #line 2852 "parser.yy"
     9124#line 2846 "parser.yy"
    91569125    { (yyval.decl) = DeclarationNode::newFunction( nullptr, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), nullptr ); }
    91579126    break;
     
    91609129
    91619130/* Line 1806 of yacc.c  */
    9162 #line 2854 "parser.yy"
     9131#line 2848 "parser.yy"
    91639132    { (yyval.decl) = DeclarationNode::newFunction( nullptr, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), nullptr ); }
    91649133    break;
     
    91679136
    91689137/* Line 1806 of yacc.c  */
    9169 #line 2878 "parser.yy"
     9138#line 2872 "parser.yy"
    91709139    { (yyval.en) = 0; }
    91719140    break;
     
    91749143
    91759144/* Line 1806 of yacc.c  */
    9176 #line 2880 "parser.yy"
     9145#line 2874 "parser.yy"
    91779146    { (yyval.en) = (yyvsp[(2) - (2)].en); }
    91789147    break;
     
    91819150
    91829151/* Line 1806 of yacc.c  */
    9183 #line 9184 "Parser/parser.cc"
     9152#line 9153 "Parser/parser.cc"
    91849153      default: break;
    91859154    }
     
    94129381
    94139382/* Line 2067 of yacc.c  */
    9414 #line 2883 "parser.yy"
     9383#line 2877 "parser.yy"
    94159384
    94169385// ----end of grammar----
  • src/Parser/parser.yy

    r1f44196 r3a2128f  
    199199
    200200%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
    201 %type<en> field field_list field_name fraction_constants
     201%type<en> field field_list
     202%type<tok> field_name
    202203
    203204%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    383384                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
    384385        | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
    385                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
    386386        | postfix_expression REALFRACTIONconstant                       // CFA, tuple index
    387                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_REALFRACTIONconstant( *$2 ) ) ); }
    388387        | postfix_expression ARROW no_attr_identifier
    389388                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
    390389        | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
    391                         { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
    392390        | postfix_expression ICR
    393391                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
     
    423421field:                                                                                                  // CFA, tuple field selector
    424422        field_name
     423                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    425424        | REALDECIMALconstant field
    426                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
     425                { $$ = new ExpressionNode( build_fieldSel( $2, build_varref( $1 ) ) ); }
    427426        | REALDECIMALconstant '[' push field_list pop ']'
    428                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
     427                { $$ = new ExpressionNode( build_fieldSel( $4, build_varref( $1 ) ) ); }
    429428        | field_name '.' field
    430                 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     429                { $$ = new ExpressionNode( build_fieldSel( $3, build_varref( $1 ) ) ); }
    431430        | field_name '.' '[' push field_list pop ']'
    432                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
     431                { $$ = new ExpressionNode( build_fieldSel( $5, build_varref( $1 ) ) ); }
    433432        | field_name ARROW field
    434                 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     433                { $$ = new ExpressionNode( build_pfieldSel( $3, build_varref( $1 ) ) ); }
    435434        | field_name ARROW '[' push field_list pop ']'
    436                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
     435                { $$ = new ExpressionNode( build_pfieldSel( $5, build_varref( $1 ) ) ); }
    437436        ;
    438437
    439438field_name:
    440439        INTEGERconstant fraction_constants
    441                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
     440                { $$ = $1; }
    442441        | FLOATINGconstant fraction_constants
    443                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
     442                { $$ = $1; }
    444443        | no_attr_identifier fraction_constants
    445                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); }
     444                { $$ = $1; }
    446445        ;
    447446
    448447fraction_constants:
    449448        // empty
    450                 { $$ = nullptr; }
    451449        | fraction_constants REALFRACTIONconstant
    452                 {
    453                         Expression * constant = build_field_name_REALFRACTIONconstant( *$2 );
    454                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1,  constant ) ) : new ExpressionNode( constant );
    455                 }
    456450        ;
    457451
  • src/ResolvExpr/Alternative.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Alternative.cc --
     7// Alternative.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    1212// Last Modified On : Sat May 16 23:54:23 2015
    1313// Update Count     : 2
    14 //
     14// 
    1515
    1616#include "Alternative.h"
     
    2020
    2121namespace ResolvExpr {
    22         Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( 0 ) {}
     22        Alternative::Alternative() : expr( 0 ) {}
    2323
    2424        Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
     
    3535                if ( &other == this ) return *this;
    3636                initialize( other, *this );
    37                 return *this;
    38         }
    39 
    40         Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( other.env ) {
    41                 other.expr = nullptr;
    42         }
    43 
    44         Alternative & Alternative::operator=( Alternative && other ) {
    45                 if ( &other == this )  return *this;
    46                 delete expr;
    47                 cost = other.cost;
    48                 cvtCost = other.cvtCost;
    49                 expr = other.expr;
    50                 env = other.env;
    51                 other.expr = nullptr;
    5237                return *this;
    5338        }
     
    6954                        expr->print( os, indent );
    7055                        os << "(types:" << std::endl;
    71                         os << std::string( indent+4, ' ' );
    72                         expr->get_result()->print( os, indent + 4 );
    73                         os << std::endl << ")" << std::endl;
     56                        printAll( expr->get_results(), os, indent + 4 );
     57                        os << ")" << std::endl;
    7458                } else {
    7559                        os << "Null expression!" << std::endl;
  • src/ResolvExpr/Alternative.h

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Alternative.h --
     7// Alternative.h -- 
    88//
    99// Author           : Richard C. Bilson
     
    1212// Last Modified On : Sat May 16 23:54:39 2015
    1313// Update Count     : 2
    14 //
     14// 
    1515
    1616#ifndef ALTERNATIVE_H
     
    3232                Alternative( const Alternative &other );
    3333                Alternative &operator=( const Alternative &other );
    34                 Alternative( Alternative && other );
    35                 Alternative &operator=( Alternative && other );
    3634                ~Alternative();
    37 
     35 
    3836                void initialize( const Alternative &src, Alternative &dest );
    39 
     37 
    4038                void print( std::ostream &os, int indent = 0 ) const;
    41 
     39 
    4240                Cost cost;
    4341                Cost cvtCost;
  • src/ResolvExpr/AlternativeFinder.cc

    r1f44196 r3a2128f  
    3838#include "SynTree/TypeSubstitution.h"
    3939#include "SymTab/Validate.h"
    40 #include "Tuples/Tuples.h"
    41 #include "Tuples/Explode.h"
     40#include "Tuples/TupleAssignment.h"
     41#include "Tuples/NameMatcher.h"
    4242#include "Common/utility.h"
    4343#include "InitTweak/InitTweak.h"
    44 #include "InitTweak/GenInit.h"
    4544#include "ResolveTypeof.h"
    4645
     
    6564        }
    6665
    67         Cost sumCost( const AltList &in ) {
    68                 Cost total;
    69                 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    70                         total += i->cost;
    71                 }
    72                 return total;
    73         }
    74 
    7566        namespace {
    7667                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     
    8576                                out.push_back( i->expr->clone() );
    8677                        }
     78                }
     79
     80                Cost sumCost( const AltList &in ) {
     81                        Cost total;
     82                        for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     83                                total += i->cost;
     84                        }
     85                        return total;
    8786                }
    8887
     
    102101                                PruneStruct current( candidate );
    103102                                std::string mangleName;
    104                                 {
    105                                         Type * newType = candidate->expr->get_result()->clone();
     103                                for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
     104                                        Type *newType = (*retType)->clone();
    106105                                        candidate->env.apply( newType );
    107                                         mangleName = SymTab::Mangler::mangle( newType );
     106                                        mangleName += SymTab::Mangler::mangle( newType );
    108107                                        delete newType;
    109108                                }
     
    134133                                if ( ! target->second.isAmbiguous ) {
    135134                                        Alternative &alt = *target->second.candidate;
    136                                         alt.env.applyFree( alt.expr->get_result() );
     135                                        for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
     136                                                alt.env.applyFree( *result );
     137                                        }
    137138                                        *out++ = alt;
    138139                                }
    139140                        }
     141
     142                }
     143
     144                template< typename InputIterator, typename OutputIterator >
     145                void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
     146                        AltList alternatives;
     147
     148                        // select the alternatives that have the minimum parameter cost
     149                        Cost minCost = Cost::infinity;
     150                        for ( AltList::iterator i = begin; i != end; ++i ) {
     151                                if ( i->cost < minCost ) {
     152                                        minCost = i->cost;
     153                                        i->cost = i->cvtCost;
     154                                        alternatives.clear();
     155                                        alternatives.push_back( *i );
     156                                } else if ( i->cost == minCost ) {
     157                                        i->cost = i->cvtCost;
     158                                        alternatives.push_back( *i );
     159                                }
     160                        }
     161                        std::copy( alternatives.begin(), alternatives.end(), out );
     162                }
     163
     164                template< typename InputIterator >
     165                void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
     166                        while ( begin != end ) {
     167                                result.simpleCombine( (*begin++).env );
     168                        }
    140169                }
    141170
    142171                void renameTypes( Expression *expr ) {
    143                         expr->get_result()->accept( global_renamer );
     172                        for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     173                                (*i)->accept( global_renamer );
     174                        }
    144175                }
    145176        }
     
    173204                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    174205                        if ( adjust ) {
    175                                 adjustExprType( i->expr->get_result(), i->env, indexer );
     206                                adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
    176207                        }
    177208                }
     
    209240        }
    210241
    211         // std::unordered_map< Expression *, UniqueExpr * > ;
    212 
    213242        template< typename StructOrUnionType >
    214         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    215                 // by this point, member must be a name expr
    216                 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
    217                 const std::string & name = nameExpr->get_name();
     243        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
    218244                std::list< Declaration* > members;
    219245                aggInst->lookup( name, members );
     
    228254        }
    229255
    230         void AlternativeFinder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    231                 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    232                         // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    233                         // xxx - this should be improved by memoizing the value of constant exprs
    234                         // during parsing and reusing that information here.
    235                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    236                         int val;
    237                         std::string tmp;
    238                         if ( ss >> val && ! (ss >> tmp) ) {
    239                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    240                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    241                                 } // if
    242                         } // if
    243                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    244                         // xxx - temporary hack until 0/1 are int constants
    245                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    246                                 std::stringstream ss( nameExpr->get_name() );
    247                                 int val;
    248                                 ss >> val;
    249                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    250                         }
    251                 } // if
    252         }
    253 
    254256        void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
    255257                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     
    257259
    258260        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    259                 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    260                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    261                 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
     261                ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
     262                assert( appExpr );
     263                PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     264                assert( pointer );
     265                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     266                assert( function );
    262267
    263268                Cost convCost( 0, 0, 0 );
     
    265270                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    266271                std::list< Expression* >& actuals = appExpr->get_args();
    267 
    268                 std::list< Type * > formalTypes;
    269                 std::list< Type * >::iterator formalType = formalTypes.end();
    270 
    271272                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    272 
    273273                        PRINT(
    274274                                std::cerr << "actual expression:" << std::endl;
    275275                                (*actualExpr)->print( std::cerr, 8 );
    276276                                std::cerr << "--- results are" << std::endl;
    277                                 (*actualExpr)->get_result()->print( std::cerr, 8 );
     277                                printAll( (*actualExpr)->get_results(), std::cerr, 8 );
    278278                        )
    279279                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    280280                        Cost actualCost;
    281                         std::list< Type * > flatActualTypes;
    282                         flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
    283                         for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
    284 
    285 
    286                                 // tuple handling code
    287                                 if ( formalType == formalTypes.end() ) {
    288                                         // the type of the formal parameter may be a tuple type. To make this easier to work with,
    289                                         // flatten the tuple type and traverse the resulting list of types, incrementing the formal
    290                                         // iterator once its types have been extracted. Once a particular formal parameter's type has
    291                                         // been exhausted load the next formal parameter's type.
    292                                         if ( formal == formals.end() ) {
    293                                                 if ( function->get_isVarArgs() ) {
    294                                                         convCost += Cost( 1, 0, 0 );
    295                                                         break;
    296                                                 } else {
    297                                                         return Cost::infinity;
    298                                                 }
     281                        for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
     282                                if ( formal == formals.end() ) {
     283                                        if ( function->get_isVarArgs() ) {
     284                                                convCost += Cost( 1, 0, 0 );
     285                                                break;
     286                                        } else {
     287                                                return Cost::infinity;
    299288                                        }
    300                                         formalTypes.clear();
    301                                         flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
    302                                         formalType = formalTypes.begin();
    303                                         ++formal;
    304289                                }
    305 
    306290                                PRINT(
    307291                                        std::cerr << std::endl << "converting ";
    308                                         (*actualType)->print( std::cerr, 8 );
     292                                        (*actual)->print( std::cerr, 8 );
    309293                                        std::cerr << std::endl << " to ";
    310294                                        (*formal)->get_type()->print( std::cerr, 8 );
    311295                                )
    312                                 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
     296                                Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
    313297                                PRINT(
    314298                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    321305                                actualCost += newCost;
    322306
    323                                 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    324 
    325                                 formalType++;
     307                                convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
     308
     309                                formal++;
    326310                        }
    327311                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     
    372356        /// Adds type variables to the open variable set and marks their assertions
    373357        void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
    374                 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     358                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    375359                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    376360                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     
    381365        }
    382366
    383         /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,
    384         /// producing expression(s) in out and their total cost in cost.
    385         template< typename AltIterator, typename OutputIterator >
    386         bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) {
    387                 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    388                         // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    389                         TupleExpr * tupleExpr = new TupleExpr();
    390                         for ( Type * type : *tupleType ) {
    391                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
    392                                         delete tupleExpr;
    393                                         return false;
    394                                 }
    395                         }
    396                         tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
    397                         *out++ = tupleExpr;
    398                 } else if ( actualIt != actualEnd ) {
    399                         // both actualType and formalType are atomic (non-tuple) types - if they unify
    400                         // then accept actual as an argument, otherwise return false (fail to instantiate argument)
    401                         Expression * actual = actualIt->expr;
    402                         Type * actualType = actual->get_result();
    403                         PRINT(
    404                                 std::cerr << "formal type is ";
    405                                 formalType->print( std::cerr );
    406                                 std::cerr << std::endl << "actual type is ";
    407                                 actualType->print( std::cerr );
    408                                 std::cerr << std::endl;
    409                         )
    410                         if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    411                                 return false;
    412                         }
    413                         // move the expression from the alternative to the output iterator
    414                         *out++ = actual;
    415                         actualIt->expr = nullptr;
    416                         cost += actualIt->cost;
    417                         ++actualIt;
    418                 } else {
    419                         // End of actuals - Handle default values
    420                         if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {
    421                                 // so far, only constant expressions are accepted as default values
    422                                 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) {
    423                                         if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {
    424                                                 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    425                                                         // xxx - Don't know if this is right
    426                                                         *out++ = cnstexpr->clone();
    427                                                         return true;
    428                                                 } // if
    429                                         } // if
    430                                 } // if
    431                         } // if
    432                         return false;
    433                 } // if
    434                 return true;
    435         }
    436 
    437         bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) {
     367        bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
    438368                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    439369                // make sure we don't widen any existing bindings
     
    443373                resultEnv.extractOpenVars( openVars );
    444374
    445                 // flatten actuals so that each actual has an atomic (non-tuple) type
    446                 AltList exploded;
    447                 Tuples::explode( actuals, indexer, back_inserter( exploded ) );
    448 
    449                 AltList::iterator actualExpr = exploded.begin();
    450                 AltList::iterator actualEnd = exploded.end();
    451                 for ( DeclarationWithType * formal : formals ) {
    452                         // match flattened actuals with formal parameters - actuals will be grouped to match
    453                         // with formals as appropriate
    454                         Cost cost;
    455                         std::list< Expression * > newExprs;
    456                         ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
    457                         if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {
    458                                 deleteAll( newExprs );
    459                                 return false;
    460                         }
    461                         // success - produce argument as a new alternative
    462                         assert( newExprs.size() == 1 );
    463                         out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );
    464                 }
    465                 if ( actualExpr != actualEnd ) {
    466                         // there are still actuals remaining, but we've run out of formal parameters to match against
    467                         // this is okay only if the function is variadic
    468                         if ( ! isVarArgs ) {
    469                                 return false;
    470                         }
    471                         out.splice( out.end(), exploded, actualExpr, actualEnd );
     375                /*
     376                  Tuples::NameMatcher matcher( formals );
     377                  try {
     378                  matcher.match( actuals );
     379                  } catch ( Tuples::NoMatch &e ) {
     380                  std::cerr << "Alternative doesn't match: " << e.message << std::endl;
     381                  }
     382                */
     383                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     384                for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
     385                        for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
     386                                if ( formal == formals.end() ) {
     387                                        return isVarArgs;
     388                                }
     389                                PRINT(
     390                                        std::cerr << "formal type is ";
     391                                        (*formal)->get_type()->print( std::cerr );
     392                                        std::cerr << std::endl << "actual type is ";
     393                                        (*actual)->print( std::cerr );
     394                                        std::cerr << std::endl;
     395                                )
     396                                if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     397                                        return false;
     398                                }
     399                                formal++;
     400                        }
     401                }
     402                // Handling of default values
     403                while ( formal != formals.end() ) {
     404                        if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
     405                                if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
     406                                        // so far, only constant expressions are accepted as default values
     407                                        if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) )
     408                                                if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
     409                                                        if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     410                                                                // XXX Don't know if this is right
     411                                                                actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
     412                                                                formal++;
     413                                                                if ( formal == formals.end()) break;
     414                                                        }
     415                        return false;
    472416                }
    473417                return true;
     
    556500                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    557501                                Expression *varExpr = new VariableExpr( candDecl );
    558                                 delete varExpr->get_result();
    559                                 varExpr->set_result( adjType->clone() );
     502                                deleteAll( varExpr->get_results() );
     503                                varExpr->get_results().clear();
     504                                varExpr->get_results().push_front( adjType->clone() );
    560505                                PRINT(
    561506                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    600545
    601546        template< typename OutputIterator >
    602         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) {
     547        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
    603548                OpenVarSet openVars;
    604549                AssertionSet resultNeed, resultHave;
    605550                TypeEnvironment resultEnv;
    606551                makeUnifiableVars( funcType, openVars, resultNeed );
    607                 AltList instantiatedActuals; // filled by instantiate function
    608                 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) {
     552                if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
    609553                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    610                         Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
    611                         makeExprList( instantiatedActuals, appExpr->get_args() );
     554                        Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
     555                        makeExprList( actualAlt, appExpr->get_args() );
    612556                        PRINT(
    613557                                std::cerr << "need assertions:" << std::endl;
     
    630574                                PointerType pt( Type::Qualifiers(), v.clone() );
    631575                                UntypedExpr *vexpr = untypedExpr->clone();
    632                                 vexpr->set_result( pt.clone() );
     576                                vexpr->get_results().push_front( pt.clone() );
    633577                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    634578                                return;
     
    643587                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    644588
    645                 // take care of possible tuple assignments
    646                 // if not tuple assignment, assignment is taken care of as a normal function call
    647                 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
     589                Tuples::TupleAssignSpotter tassign( this );
     590                if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
     591                        // take care of possible tuple assignments, or discard expression
     592                        return;
     593                } // else ...
    648594
    649595                AltList candidates;
     
    658604                                // check if the type is pointer to function
    659605                                PointerType *pointer;
    660                                 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
     606                                if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
    661607                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    662608                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    694640                                                // check if the type is pointer to function
    695641                                                PointerType *pointer;
    696                                                 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
     642                                                if ( funcOp->expr->get_results().size() == 1
     643                                                        && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
    697644                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    698645                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    718665
    719666                        PRINT(
    720                                 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
    721                                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    722                                 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
     667                                ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
     668                                assert( appExpr );
     669                                PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     670                                assert( pointer );
     671                                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     672                                assert( function );
    723673                                std::cerr << "Case +++++++++++++" << std::endl;
    724674                                std::cerr << "formals are:" << std::endl;
     
    742692
    743693        bool isLvalue( Expression *expr ) {
    744                 // xxx - recurse into tuples?
    745                 return expr->has_result() && expr->get_result()->get_isLvalue();
     694                for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     695                        if ( !(*i)->get_isLvalue() ) return false;
     696                } // for
     697                return true;
    746698        }
    747699
     
    757709
    758710        void AlternativeFinder::visit( CastExpr *castExpr ) {
    759                 Type *& toType = castExpr->get_result();
    760                 toType = resolveTypeof( toType, indexer );
    761                 SymTab::validateType( toType, &indexer );
    762                 adjustExprType( toType, env, indexer );
     711                for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
     712                        *i = resolveTypeof( *i, indexer );
     713                        SymTab::validateType( *i, &indexer );
     714                        adjustExprType( *i, env, indexer );
     715                } // for
    763716
    764717                AlternativeFinder finder( indexer, env );
     
    774727                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    775728                        // to.
    776                         int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
     729                        int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
    777730                        if ( discardedValues < 0 ) continue;
    778                         // xxx - may need to go into tuple types and extract relavent types and use unifyList
     731                        std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
     732                        std::advance( candidate_end, castExpr->get_results().size() );
    779733                        // unification run for side-effects
    780                         unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    781                         Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
     734                        unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),
     735                                           (*i).expr->get_results().begin(), candidate_end,
     736                                   i->env, needAssertions, haveAssertions, openVars, indexer );
     737                        Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
     738                                                                                  castExpr->get_results().begin(), castExpr->get_results().end(),
     739                                                                                  indexer, i->env );
    782740                        if ( thisCost != Cost::infinity ) {
    783741                                // count one safe conversion for each value that is thrown away
     
    802760
    803761                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    804                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
    805                                 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    806                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
    807                                 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    808                         } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {
    809                                 addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     762                        if ( agg->expr->get_results().size() == 1 ) {
     763                                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
     764                                        addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     765                                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
     766                                        addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     767                                } // if
    810768                        } // if
    811769                } // for
     
    833791                        renameTypes( alternatives.back().expr );
    834792                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    835                                 NameExpr nameExpr( "" );
    836                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
     793                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    837794                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    838                                 NameExpr nameExpr( "" );
    839                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
     795                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    840796                        } // if
    841797                } // for
     
    938894                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    939895                        for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    940                                 alternatives.back().expr->set_result( (*i)->get_type()->clone() );
     896                                alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
    941897                        } // for
    942898                } // if
     
    961917                                                        finder.find( attrExpr->get_expr() );
    962918                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    963                                                                 if ( choice->expr->get_result()->size() == 1 ) {
    964                                                                         resolveAttr(*i, function, choice->expr->get_result(), choice->env );
     919                                                                if ( choice->expr->get_results().size() == 1 ) {
     920                                                                        resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
    965921                                                                } // fi
    966922                                                        } // for
     
    1004960                                        AssertionSet needAssertions, haveAssertions;
    1005961                                        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    1006                                         Type* commonType = nullptr;
    1007                                         if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     962                                        std::list< Type* > commonTypes;
     963                                        if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
    1008964                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    1009                                                 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
     965                                                std::list< Type* >::const_iterator original = second->expr->get_results().begin();
     966                                                std::list< Type* >::const_iterator commonType = commonTypes.begin();
     967                                                for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
     968                                                        if ( *commonType ) {
     969                                                                newExpr->get_results().push_back( *commonType );
     970                                                        } else {
     971                                                                newExpr->get_results().push_back( (*original)->clone() );
     972                                                        } // if
     973                                                } // for
    1010974                                                newAlt.expr = newExpr;
    1011975                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    1035999                        TupleExpr *newExpr = new TupleExpr;
    10361000                        makeExprList( *i, newExpr->get_exprs() );
    1037                         newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
     1001                        for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
     1002                                for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
     1003                                        newExpr->get_results().push_back( (*resultType)->clone() );
     1004                                } // for
     1005                        } // for
    10381006
    10391007                        TypeEnvironment compositeEnv;
     
    10561024                }
    10571025        }
    1058 
    1059         void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
    1060                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    1061         }
    1062 
    1063         void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
    1064                 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
    1065         }
    1066 
    1067         void AlternativeFinder::visit( UniqueExpr *unqExpr ) {
    1068                 AlternativeFinder finder( indexer, env );
    1069                 finder.findWithAdjustment( unqExpr->get_expr() );
    1070                 for ( Alternative & alt : finder.alternatives ) {
    1071                         // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked"
    1072                         UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
    1073                         alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) );
    1074                 }
    1075         }
    1076 
    10771026} // namespace ResolvExpr
    10781027
  • src/ResolvExpr/AlternativeFinder.h

    r1f44196 r3a2128f  
    6767                virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
    6868                virtual void visit( ConstructorExpr * ctorExpr );
    69                 virtual void visit( TupleIndexExpr *tupleExpr );
    70                 virtual void visit( TupleAssignExpr *tupleExpr );
    71                 virtual void visit( UniqueExpr *unqExpr );
    72                 /// Runs a new alternative finder on each element in [begin, end)
    73                 /// and writes each alternative finder to out.
     69          public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
    7470                template< typename InputIterator, typename OutputIterator >
    7571                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    7672
     73          private:
    7774                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    78                 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
    79                 /// Adds alternatives for member expressions where the left side has tuple type
    80                 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     75                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name );
    8176                /// Adds alternatives for offsetof expressions, given the base type and name of the member
    8277                template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
    83                 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out );
     78                bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
    8479                template< typename OutputIterator >
    85                 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out );
     80                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );
    8681                template< typename OutputIterator >
    8782                void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
     
    9489
    9590        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
    96 
    97         template< typename InputIterator, typename OutputIterator >
    98         void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
    99                 AltList alternatives;
    100 
    101                 // select the alternatives that have the minimum parameter cost
    102                 Cost minCost = Cost::infinity;
    103                 for ( InputIterator i = begin; i != end; ++i ) {
    104                         if ( i->cost < minCost ) {
    105                                 minCost = i->cost;
    106                                 i->cost = i->cvtCost;
    107                                 alternatives.clear();
    108                                 alternatives.push_back( *i );
    109                         } else if ( i->cost == minCost ) {
    110                                 i->cost = i->cvtCost;
    111                                 alternatives.push_back( *i );
    112                         }
    113                 }
    114                 std::copy( alternatives.begin(), alternatives.end(), out );
    115         }
    116 
    117         Cost sumCost( const AltList &in );
    118 
    119         template< typename InputIterator >
    120         void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
    121                 while ( begin != end ) {
    122                         result.simpleCombine( (*begin++).env );
    123                 }
    124         }
    12591} // namespace ResolvExpr
    12692
  • src/ResolvExpr/AlternativePrinter.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AlternativePrinter.cc --
     7// AlternativePrinter.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    3333                for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    3434                        os << "Alternative " << count++ << " ==============" << std::endl;
    35                         i->expr->get_result()->print( os );
     35                        printAll( i->expr->get_results(), os );
    3636                        //    i->print( os );
    3737                        os << std::endl;
  • src/ResolvExpr/ConversionCost.cc

    r1f44196 r3a2128f  
    240240                        std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
    241241                        std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
    242                         while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
     242                        while ( srcIt != tupleType->get_types().end() ) {
    243243                                Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
    244244                                if ( newCost == Cost::infinity ) {
  • src/ResolvExpr/FindOpenVars.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FindOpenVars.cc --
     7// FindOpenVars.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    4747        void FindOpenVars::common_action( Type *type ) {
    4848                if ( nextIsOpen ) {
    49                         for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     49                        for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    5050                                openVars[ (*i)->get_name() ] = (*i)->get_kind();
    5151                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     
    5656                        }
    5757                } else {
    58                         for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     58                        for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    5959                                closedVars[ (*i)->get_name() ] = (*i)->get_kind();
    6060                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
  • src/ResolvExpr/RenameVars.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // RenameVars.cc --
     7// RenameVars.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    125125                        mapStack.push_front( mapStack.front() );
    126126                        // renames all "forall" type names to `_${level}_${name}'
    127                         for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     127                        for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    128128                                std::ostringstream output;
    129129                                output << "_" << level << "_" << (*i)->get_name();
  • src/ResolvExpr/ResolveTypeof.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ResolveTypeof.cc --
     7// ResolveTypeof.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    5858                if ( typeofType->get_expr() ) {
    5959                        Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
    60                         assert( newExpr->has_result() && ! newExpr->get_result()->isVoid() );
    61                         Type *newType = newExpr->get_result();
     60                        assert( newExpr->get_results().size() > 0 );
     61                        Type *newType;
     62                        if ( newExpr->get_results().size() > 1 ) {
     63                                TupleType *tupleType = new TupleType( Type::Qualifiers() );
     64                                cloneAll( newExpr->get_results(), tupleType->get_types() );
     65                                newType = tupleType;
     66                        } else {
     67                                newType = newExpr->get_results().front()->clone();
     68                        } // if
    6269                        delete typeofType;
    6370                        return newType;
  • src/ResolvExpr/Resolver.cc

    r1f44196 r3a2128f  
    1919#include "RenameVars.h"
    2020#include "ResolveTypeof.h"
    21 #include "typeops.h"
    2221#include "SynTree/Statement.h"
    2322#include "SynTree/Type.h"
     
    6968          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    7069          void fallbackInit( ConstructorInit * ctorInit );
    71 
    72                 Type * functionReturn = nullptr;
    73                 Type *initContext = nullptr;
     70                std::list< Type * > functionReturn;
     71                Type *initContext;
    7472                bool inEnumDecl = false;
    7573        };
     
    159157                        const TypeEnvironment *newEnv = 0;
    160158                        for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    161                                 if ( i->expr->get_result()->size() == 1 && isIntegralType( i->expr->get_result() ) ) {
     159                                if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
    162160                                        if ( newExpr ) {
    163161                                                throw SemanticError( "Too many interpretations for case control expression", untyped );
     
    236234                Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
    237235                functionDecl->set_type( new_type );
    238                 ValueGuard< Type * > oldFunctionReturn( functionReturn );
    239                 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
     236                std::list< Type * > oldFunctionReturn = functionReturn;
     237                functionReturn.clear();
     238                for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
     239                        functionReturn.push_back( (*i)->get_type() );
     240                } // for
    240241                SymTab::Indexer::visit( functionDecl );
     242                functionReturn = oldFunctionReturn;
    241243        }
    242244
     
    336338        void Resolver::visit( ReturnStmt *returnStmt ) {
    337339                if ( returnStmt->get_expr() ) {
    338                         CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
     340                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
     341                        cloneAll( functionReturn, castExpr->get_results() );
    339342                        Expression *newExpr = findSingleExpression( castExpr, *this );
    340343                        delete castExpr;
     
    381384                                if ( isCharType( at->get_base() ) ) {
    382385                                        // check if the resolved type is char *
    383                                         if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
     386                                        if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) {
    384387                                                if ( isCharType( pt->get_base() ) ) {
    385388                                                        // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     
    443446                                (*iter)->accept( *this );
    444447                        } // for
    445                 } else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) {
    446                         for ( Type * t : *tt ) {
    447                                 if ( iter == end ) break;
    448                                 initContext = t;
    449                                 (*iter++)->accept( *this );
    450                         }
    451448                } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
    452449                        resolveAggrInit( st->get_baseStruct(), iter, end );
  • src/ResolvExpr/TypeEnvironment.cc

    r1f44196 r3a2128f  
    158158        }
    159159
    160         void TypeEnvironment::add( const Type::ForallList &tyDecls ) {
    161                 for ( Type::ForallList::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {
     160        void TypeEnvironment::add( const std::list< TypeDecl* > &tyDecls ) {
     161                for ( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {
    162162                        EqvClass newClass;
    163163                        newClass.vars.insert( (*i)->get_name() );
  • src/ResolvExpr/TypeEnvironment.h

    r1f44196 r3a2128f  
    5555                bool lookup( const std::string &var, EqvClass &eqvClass ) const;
    5656                void add( const EqvClass &eqvClass );
    57                 void add( const Type::ForallList &tyDecls );
     57                void add( const std::list< TypeDecl* > &tyDecls );
    5858                template< typename SynTreeClass > int apply( SynTreeClass *&type ) const;
    5959                template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const;
  • src/ResolvExpr/Unify.cc

    r1f44196 r3a2128f  
    597597        }
    598598
    599         // xxx - compute once and store in the FunctionType?
    600         Type * extractResultType( FunctionType * function ) {
    601                 if ( function->get_returnVals().size() == 0 ) {
    602                         return new VoidType( Type::Qualifiers() );
    603                 } else if ( function->get_returnVals().size() == 1 ) {
    604                         return function->get_returnVals().front()->get_type()->clone();
    605                 } else {
    606                         TupleType * tupleType = new TupleType( Type::Qualifiers() );
    607                         for ( DeclarationWithType * decl : function->get_returnVals() ) {
    608                                 tupleType->get_types().push_back( decl->get_type()->clone() );
    609                         } // for
    610                         return tupleType;
    611                 }
    612         }
    613599} // namespace ResolvExpr
    614600
  • src/ResolvExpr/typeops.h

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // typeops.h --
     7// typeops.h -- 
    88//
    99// Author           : Richard C. Bilson
     
    3030                typedef typename InputIterator::value_type SetType;
    3131                typedef typename std::list< typename SetType::value_type > ListType;
    32 
     32 
    3333                if ( begin == end )     {
    3434                        *out++ = ListType();
    3535                        return;
    3636                } // if
    37 
     37 
    3838                InputIterator current = begin;
    3939                begin++;
     
    4141                std::list< ListType > recursiveResult;
    4242                combos( begin, end, back_inserter( recursiveResult ) );
    43 
     43 
    4444                for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) {
    4545                        for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) {
     
    5252                } // for
    5353        }
    54 
     54 
    5555        // in AdjustExprType.cc
    5656        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
     
    144144        }
    145145
    146         /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
    147         Type * extractResultType( FunctionType * functionType );
    148 
    149146        // in CommonType.cc
    150147        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     
    155152        // in Occurs.cc
    156153        bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
    157 
    158         // flatten tuple type into list of types
    159         template< typename OutputIterator >
    160         void flatten( Type * type, OutputIterator out ) {
    161                 if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
    162                         for ( Type * t : tupleType->get_types() ) {
    163                                 flatten( t, out );
    164                         }
    165                 } else {
    166                         *out++ = type;
    167                 }
    168         }
    169154} // namespace ResolvExpr
    170155
  • src/SymTab/Autogen.cc

    r1f44196 r3a2128f  
    116116                // This happens before function pointer type conversion, so need to do it manually here
    117117                VariableExpr * assignVarExpr = new VariableExpr( assignDecl );
    118                 Type * assignVarExprType = assignVarExpr->get_result();
     118                Type *& assignVarExprType = assignVarExpr->get_results().front();
    119119                assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType );
    120                 assignVarExpr->set_result( assignVarExprType );
    121120                ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr );
    122121                assignExpr->get_args().push_back( new VariableExpr( dstParam ) );
  • src/SymTab/Indexer.cc

    r1f44196 r3a2128f  
    4040
    4141namespace SymTab {
    42         template< typename TreeType, typename VisitorType >
    43         inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
     42        template< typename Container, typename VisitorType >
     43        inline void acceptAllNewScope( Container &container, VisitorType &visitor ) {
    4444                visitor.enterScope();
    45                 maybeAccept( tree, visitor );
     45                acceptAll( container, visitor );
    4646                visitor.leaveScope();
    4747        }
     
    143143                for ( DeclarationWithType * decl : copy ) {
    144144                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {
    145                                 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
     145                                std::list< DeclarationWithType * > params = function->get_functionType()->get_parameters();
    146146                                assert( ! params.empty() );
    147147                                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     
    337337
    338338        void Indexer::visit( ApplicationExpr *applicationExpr ) {
    339                 acceptNewScope( applicationExpr->get_result(), *this );
     339                acceptAllNewScope( applicationExpr->get_results(), *this );
    340340                maybeAccept( applicationExpr->get_function(), *this );
    341341                acceptAll( applicationExpr->get_args(), *this );
     
    343343
    344344        void Indexer::visit( UntypedExpr *untypedExpr ) {
    345                 acceptNewScope( untypedExpr->get_result(), *this );
     345                acceptAllNewScope( untypedExpr->get_results(), *this );
    346346                acceptAll( untypedExpr->get_args(), *this );
    347347        }
    348348
    349349        void Indexer::visit( NameExpr *nameExpr ) {
    350                 acceptNewScope( nameExpr->get_result(), *this );
     350                acceptAllNewScope( nameExpr->get_results(), *this );
    351351        }
    352352
    353353        void Indexer::visit( AddressExpr *addressExpr ) {
    354                 acceptNewScope( addressExpr->get_result(), *this );
     354                acceptAllNewScope( addressExpr->get_results(), *this );
    355355                maybeAccept( addressExpr->get_arg(), *this );
    356356        }
    357357
    358358        void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
    359                 acceptNewScope( labAddressExpr->get_result(), *this );
     359                acceptAllNewScope( labAddressExpr->get_results(), *this );
    360360                maybeAccept( labAddressExpr->get_arg(), *this );
    361361        }
    362362
    363363        void Indexer::visit( CastExpr *castExpr ) {
    364                 acceptNewScope( castExpr->get_result(), *this );
     364                acceptAllNewScope( castExpr->get_results(), *this );
    365365                maybeAccept( castExpr->get_arg(), *this );
    366366        }
    367367
    368368        void Indexer::visit( UntypedMemberExpr *memberExpr ) {
    369                 acceptNewScope( memberExpr->get_result(), *this );
     369                acceptAllNewScope( memberExpr->get_results(), *this );
    370370                maybeAccept( memberExpr->get_aggregate(), *this );
    371371        }
    372372
    373373        void Indexer::visit( MemberExpr *memberExpr ) {
    374                 acceptNewScope( memberExpr->get_result(), *this );
     374                acceptAllNewScope( memberExpr->get_results(), *this );
    375375                maybeAccept( memberExpr->get_aggregate(), *this );
    376376        }
    377377
    378378        void Indexer::visit( VariableExpr *variableExpr ) {
    379                 acceptNewScope( variableExpr->get_result(), *this );
     379                acceptAllNewScope( variableExpr->get_results(), *this );
    380380        }
    381381
    382382        void Indexer::visit( ConstantExpr *constantExpr ) {
    383                 acceptNewScope( constantExpr->get_result(), *this );
     383                acceptAllNewScope( constantExpr->get_results(), *this );
    384384                maybeAccept( constantExpr->get_constant(), *this );
    385385        }
    386386
    387387        void Indexer::visit( SizeofExpr *sizeofExpr ) {
    388                 acceptNewScope( sizeofExpr->get_result(), *this );
     388                acceptAllNewScope( sizeofExpr->get_results(), *this );
    389389                if ( sizeofExpr->get_isType() ) {
    390390                        maybeAccept( sizeofExpr->get_type(), *this );
     
    395395
    396396        void Indexer::visit( AlignofExpr *alignofExpr ) {
    397                 acceptNewScope( alignofExpr->get_result(), *this );
     397                acceptAllNewScope( alignofExpr->get_results(), *this );
    398398                if ( alignofExpr->get_isType() ) {
    399399                        maybeAccept( alignofExpr->get_type(), *this );
     
    404404
    405405        void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
    406                 acceptNewScope( offsetofExpr->get_result(), *this );
     406                acceptAllNewScope( offsetofExpr->get_results(), *this );
    407407                maybeAccept( offsetofExpr->get_type(), *this );
    408408        }
    409409
    410410        void Indexer::visit( OffsetofExpr *offsetofExpr ) {
    411                 acceptNewScope( offsetofExpr->get_result(), *this );
     411                acceptAllNewScope( offsetofExpr->get_results(), *this );
    412412                maybeAccept( offsetofExpr->get_type(), *this );
    413413                maybeAccept( offsetofExpr->get_member(), *this );
     
    415415
    416416        void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {
    417                 acceptNewScope( offsetPackExpr->get_result(), *this );
     417                acceptAllNewScope( offsetPackExpr->get_results(), *this );
    418418                maybeAccept( offsetPackExpr->get_type(), *this );
    419419        }
    420420
    421421        void Indexer::visit( AttrExpr *attrExpr ) {
    422                 acceptNewScope( attrExpr->get_result(), *this );
     422                acceptAllNewScope( attrExpr->get_results(), *this );
    423423                if ( attrExpr->get_isType() ) {
    424424                        maybeAccept( attrExpr->get_type(), *this );
     
    429429
    430430        void Indexer::visit( LogicalExpr *logicalExpr ) {
    431                 acceptNewScope( logicalExpr->get_result(), *this );
     431                acceptAllNewScope( logicalExpr->get_results(), *this );
    432432                maybeAccept( logicalExpr->get_arg1(), *this );
    433433                maybeAccept( logicalExpr->get_arg2(), *this );
     
    435435
    436436        void Indexer::visit( ConditionalExpr *conditionalExpr ) {
    437                 acceptNewScope( conditionalExpr->get_result(), *this );
     437                acceptAllNewScope( conditionalExpr->get_results(), *this );
    438438                maybeAccept( conditionalExpr->get_arg1(), *this );
    439439                maybeAccept( conditionalExpr->get_arg2(), *this );
     
    442442
    443443        void Indexer::visit( CommaExpr *commaExpr ) {
    444                 acceptNewScope( commaExpr->get_result(), *this );
     444                acceptAllNewScope( commaExpr->get_results(), *this );
    445445                maybeAccept( commaExpr->get_arg1(), *this );
    446446                maybeAccept( commaExpr->get_arg2(), *this );
     
    448448
    449449        void Indexer::visit( TupleExpr *tupleExpr ) {
    450                 acceptNewScope( tupleExpr->get_result(), *this );
     450                acceptAllNewScope( tupleExpr->get_results(), *this );
    451451                acceptAll( tupleExpr->get_exprs(), *this );
    452452        }
    453453
    454         void Indexer::visit( TupleAssignExpr *tupleExpr ) {
    455                 acceptNewScope( tupleExpr->get_result(), *this );
    456                 enterScope();
    457                 acceptAll( tupleExpr->get_tempDecls(), *this );
    458                 acceptAll( tupleExpr->get_assigns(), *this );
    459                 leaveScope();
     454        void Indexer::visit( SolvedTupleExpr *tupleExpr ) {
     455                acceptAllNewScope( tupleExpr->get_results(), *this );
     456                acceptAll( tupleExpr->get_exprs(), *this );
    460457        }
    461458
    462459        void Indexer::visit( TypeExpr *typeExpr ) {
    463                 acceptNewScope( typeExpr->get_result(), *this );
     460                acceptAllNewScope( typeExpr->get_results(), *this );
    464461                maybeAccept( typeExpr->get_type(), *this );
    465462        }
     
    472469
    473470        void Indexer::visit( UntypedValofExpr *valofExpr ) {
    474                 acceptNewScope( valofExpr->get_result(), *this );
     471                acceptAllNewScope( valofExpr->get_results(), *this );
    475472                maybeAccept( valofExpr->get_body(), *this );
    476473        }
  • src/SymTab/Indexer.h

    r1f44196 r3a2128f  
    6464                virtual void visit( ConditionalExpr *conditionalExpr );
    6565                virtual void visit( CommaExpr *commaExpr );
     66                virtual void visit( TupleExpr *tupleExpr );
     67                virtual void visit( SolvedTupleExpr *tupleExpr );
    6668                virtual void visit( TypeExpr *typeExpr );
    6769                virtual void visit( AsmExpr *asmExpr );
    6870                virtual void visit( UntypedValofExpr *valofExpr );
    69                 virtual void visit( TupleExpr *tupleExpr );
    70                 virtual void visit( TupleAssignExpr *tupleExpr );
    7171
    7272                virtual void visit( TraitInstType *contextInst );
  • src/SymTab/Mangler.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Mangler.cc --
     7// Mangler.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    3535                return mangler.get_mangleName();
    3636        }
    37 
     37       
    3838        Mangler::Mangler( bool mangleOverridable, bool typeMode )
    3939                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {}
    40 
     40               
    4141        Mangler::Mangler( const Mangler &rhs ) : mangleName() {
    4242                varNums = rhs.varNums;
     
    115115                        "Ir",   // LongDoubleImaginary
    116116                };
    117 
     117 
    118118                printQualifiers( basicType );
    119119                mangleName << btLetter[ basicType->get_kind() ];
     
    253253                // skip if not including qualifiers
    254254                if ( typeMode ) return;
    255 
     255               
    256256                if ( ! type->get_forall().empty() ) {
    257257                        std::list< std::string > assertionNames;
    258258                        int tcount = 0, dcount = 0, fcount = 0;
    259259                        mangleName << "A";
    260                         for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     260                        for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    261261                                switch ( (*i)->get_kind() ) {
    262262                                  case TypeDecl::Any:
  • src/SymTab/Validate.cc

    r1f44196 r3a2128f  
    2323// - All enumeration constants have type EnumInstType.
    2424//
    25 // - The type "void" never occurs in lists of function parameter or return types.  A function
    26 //   taking no arguments has no argument types.
     25// - The type "void" never occurs in lists of function parameter or return types; neither do tuple types.  A function
     26//   taking no arguments has no argument types, and tuples are flattened.
    2727//
    2828// - No context instances exist; they are all replaced by the set of declarations signified by the context, instantiated
     
    243243                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
    244244        }
    245         // xxx - shouldn't this be declsToAddBefore?
     245
    246246        template< typename AggDecl >
    247247        void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
     
    431431        /// Fix up assertions
    432432        void forallFixer( Type *func ) {
    433                 for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
     433                for ( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
    434434                        std::list< DeclarationWithType * > toBeDone, nextRound;
    435435                        toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
  • src/SynTree/AddressExpr.cc

    r1f44196 r3a2128f  
    1919
    2020AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) {
    21         if ( arg->has_result() ) {
    22                 set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );
    23         }
     21        for ( std::list< Type* >::const_iterator i = arg->get_results().begin(); i != arg->get_results().end(); ++i ) {
     22                get_results().push_back( new PointerType( Type::Qualifiers(), (*i)->clone() ) );
     23        } // for
    2424}
    2525
     
    3535        if ( arg ) {
    3636                os << std::string( indent+2, ' ' );
    37                 arg->print( os, indent+2 );
     37    arg->print( os, indent+2 );
    3838        } // if
    3939}
  • src/SynTree/ApplicationExpr.cc

    r1f44196 r3a2128f  
    2121#include "TypeSubstitution.h"
    2222#include "Common/utility.h"
    23 #include "ResolvExpr/typeops.h"
     23
    2424
    2525ParamEntry::ParamEntry( const ParamEntry &other ) :
     
    4343
    4444ApplicationExpr::ApplicationExpr( Expression *funcExpr ) : function( funcExpr ) {
    45         PointerType *pointer = safe_dynamic_cast< PointerType* >( funcExpr->get_result() );
    46         FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
     45        PointerType *pointer = dynamic_cast< PointerType* >( funcExpr->get_results().front() );
     46        assert( pointer );
     47        FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     48        assert( function );
    4749
    48         set_result( ResolvExpr::extractResultType( function ) );
    49 
    50         assert( has_result() );
     50        for ( std::list< DeclarationWithType* >::const_iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
     51                get_results().push_back( (*i)->get_type()->clone() );
     52        } // for
    5153}
    5254
  • src/SynTree/CommaExpr.cc

    r1f44196 r3a2128f  
    2323        // to false on all result types. Actually doing this causes some strange things
    2424        // to happen in later passes (particularly, Specialize, Lvalue, and Box). This needs to be looked into.
    25         set_result( maybeClone( arg2->get_result() ) );
    26         // get_type->set_isLvalue( false );
     25        cloneAll( arg2->get_results(), get_results() );
     26        // for ( Type *& type : get_results() ) {
     27        //      type->set_isLvalue( false );
     28        // }
    2729}
    2830
  • src/SynTree/CompoundStmt.cc

    r1f44196 r3a2128f  
    2020#include "Expression.h"
    2121#include "Declaration.h"
    22 #include "SynTree/VarExprReplacer.h"
    2322
    2423using std::string;
    2524using std::endl;
     25
     26class VarExprReplacer : public Visitor {
     27public:
     28  typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
     29private:
     30  const DeclMap & declMap;
     31public:
     32  VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}
     33
     34  // replace variable with new node from decl map
     35  virtual void visit( VariableExpr * varExpr ) {
     36    if ( declMap.count( varExpr->get_var() ) ) {
     37      varExpr->set_var( declMap.at( varExpr->get_var() ) );
     38    }
     39  }
     40};
     41
    2642
    2743CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) {
     
    3147        cloneAll( other.kids, kids );
    3248
    33         // when cloning a compound statement, we may end up cloning declarations which
    34         // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
    35         // does a shallow copy, so the VariableExpr will end up pointing to the original
    36         // declaration. If the original declaration is deleted, e.g. because the original
    37         // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
    38         // find all DeclarationWithType nodes (since a VariableExpr must point to a
    39         // DeclarationWithType) in the original CompoundStmt and map them to the cloned
    40         // node in the new CompoundStmt ('this'), then replace the Declarations referred to
    41         // by each VariableExpr according to the constructed map. Note that only the declarations
    42         // in the current level are collected into the map, because child CompoundStmts will
    43         // recursively execute this routine. There may be more efficient ways of doing
    44         // this.
    45         VarExprReplacer::DeclMap declMap;
    46         std::list< Statement * >::const_iterator origit = other.kids.begin();
    47         for ( Statement * s : kids ) {
    48                 assert( origit != other.kids.end() );
    49                 Statement * origStmt = *origit++;
    50                 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) {
    51                         DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( origStmt );
    52                         assert( origDeclStmt );
    53                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) {
    54                                 DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
    55                                 assert( origdwt );
    56                                 assert( dwt->get_name() == origdwt->get_name() );
    57                                 declMap[ origdwt ] = dwt;
    58                         }
    59                 }
    60         }
    61         if ( ! declMap.empty() ) {
    62                 VarExprReplacer replacer( declMap );
    63                 accept( replacer );
    64         }
     49  // when cloning a compound statement, we may end up cloning declarations which
     50  // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
     51  // does a shallow copy, so the VariableExpr will end up pointing to the original
     52  // declaration. If the original declaration is deleted, e.g. because the original
     53  // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
     54  // find all DeclarationWithType nodes (since a VariableExpr must point to a
     55  // DeclarationWithType) in the original CompoundStmt and map them to the cloned
     56  // node in the new CompoundStmt ('this'), then replace the Declarations referred to
     57  // by each VariableExpr according to the constructed map. Note that only the declarations
     58  // in the current level are collected into the map, because child CompoundStmts will
     59  // recursively execute this routine. There may be more efficient ways of doing
     60  // this.
     61  VarExprReplacer::DeclMap declMap;
     62  std::list< Statement * >::const_iterator origit = other.kids.begin();
     63  for ( Statement * s : kids ) {
     64    assert( origit != other.kids.end() );
     65    if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) {
     66      DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( *origit );
     67      assert( origDeclStmt );
     68      if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) {
     69        DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
     70        assert( origdwt );
     71        declMap[ origdwt ] = dwt;
     72      }
     73    }
     74  }
     75  if ( ! declMap.empty() ) {
     76    VarExprReplacer replacer( declMap );
     77    accept( replacer );
     78  }
    6579}
    6680
  • src/SynTree/Expression.cc

    r1f44196 r3a2128f  
    3131
    3232
    33 Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname ) {}
    34 
    35 Expression::Expression( const Expression &other ) : result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
     33Expression::Expression( Expression *_aname ) : env( 0 ), argName( _aname ) {}
     34
     35Expression::Expression( const Expression &other ) : env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
     36        cloneAll( other.results, results );
    3637}
    3738
     
    3940        delete env;
    4041        delete argName; // xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix
    41         delete result;
     42        deleteAll( results );
     43}
     44
     45void Expression::add_result( Type *t ) {
     46        if ( TupleType *tuple = dynamic_cast< TupleType* >( t ) ) {
     47                std::copy( tuple->get_types().begin(), tuple->get_types().end(), back_inserter( results ) );
     48        } else {
     49                results.push_back(t);
     50        } // if
    4251}
    4352
     
    5968
    6069ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) {
    61         set_result( constant.get_type()->clone() );
     70        add_result( constant.get_type()->clone() );
    6271}
    6372
     
    7685        assert( var );
    7786        assert( var->get_type() );
    78         Type * type = var->get_type()->clone();
    79         type->set_isLvalue( true );
    80         set_result( type );
     87        add_result( var->get_type()->clone() );
     88        for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
     89                (*i)->set_isLvalue( true );
     90        } // for
    8191}
    8292
     
    100110SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) :
    101111                Expression( _aname ), expr(expr_), type(0), isType(false) {
    102         set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     112        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    103113}
    104114
    105115SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) :
    106116                Expression( _aname ), expr(0), type(type_), isType(true) {
    107         set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     117        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    108118}
    109119
     
    131141AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
    132142                Expression( _aname ), expr(expr_), type(0), isType(false) {
    133         set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     143        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    134144}
    135145
    136146AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
    137147                Expression( _aname ), expr(0), type(type_), isType(true) {
    138         set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     148        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    139149}
    140150
     
    162172UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) :
    163173                Expression( _aname ), type(type_), member(member_) {
    164         set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     174        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    165175}
    166176
     
    187197OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
    188198                Expression( _aname ), type(type_), member(member_) {
    189         set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     199        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    190200}
    191201
     
    219229
    220230OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) {
    221         set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
     231        add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
    222232}
    223233
     
    274284
    275285CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) {
    276         set_result(toType);
     286        add_result(toType);
    277287}
    278288
    279289CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) {
    280         set_result( new VoidType( Type::Qualifiers() ) );
    281290}
    282291
     
    294303        arg->print(os, indent+2);
    295304        os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl;
    296         os << std::string( indent+2, ' ' );
    297         if ( result->isVoid() ) {
    298                 os << "nothing";
     305        if ( results.empty() ) {
     306                os << std::string( indent+2, ' ' ) << "nothing" << std::endl;
    299307        } else {
    300                 result->print( os, indent+2 );
     308                printAll(results, os, indent+2);
    301309        } // if
    302         os << std::endl;
    303         Expression::print( os, indent );
    304 }
    305 
    306 UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) :
     310        Expression::print( os, indent );
     311}
     312
     313UntypedMemberExpr::UntypedMemberExpr( std::string _member, Expression *_aggregate, Expression *_aname ) :
    307314                Expression( _aname ), member(_member), aggregate(_aggregate) {}
    308315
    309316UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
    310                 Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
     317                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
    311318}
    312319
    313320UntypedMemberExpr::~UntypedMemberExpr() {
    314321        delete aggregate;
    315         delete member;
    316322}
    317323
    318324void UntypedMemberExpr::print( std::ostream &os, int indent ) const {
    319         os << "Untyped Member Expression, with field: " << std::endl;
    320         os << std::string( indent+2, ' ' );
    321         get_member()->print(os, indent+4);
    322         os << std::string( indent+2, ' ' );
     325        os << "Untyped Member Expression, with field: " << get_member();
    323326
    324327        Expression *agg = get_aggregate();
    325         os << "from aggregate: " << std::endl;
     328        os << ", from aggregate: ";
    326329        if (agg != 0) {
    327                 os << std::string( indent + 4, ' ' );
    328                 agg->print(os, indent + 4);
     330                os << std::string( indent + 2, ' ' );
     331                agg->print(os, indent + 2);
    329332        }
    330333        os << std::string( indent+2, ' ' );
     
    335338MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) :
    336339                Expression( _aname ), member(_member), aggregate(_aggregate) {
    337         set_result( member->get_type()->clone() );
    338         get_result()->set_isLvalue( true );
     340        add_result( member->get_type()->clone() );
     341        for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
     342                (*i)->set_isLvalue( true );
     343        } // for
    339344}
    340345
     
    367372}
    368373
    369 UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) :
    370                 Expression( _aname ), function(_function), args(_args) {}
     374
     375UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function ) {}
    371376
    372377UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
     
    375380}
    376381
     382UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) :
     383                Expression( _aname ), function(_function), args(_args) {}
     384
    377385UntypedExpr::~UntypedExpr() {
    378386        delete function;
    379387        deleteAll( args );
    380388}
    381 
    382 UntypedExpr * UntypedExpr::createDeref( Expression * expr ) {
    383         UntypedExpr * ret = new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ expr } );
    384         if ( Type * type = expr->get_result() ) {
    385                 Type * base = InitTweak::getPointerBase( type );
    386                 if ( ! base ) {
    387                         std::cerr << type << std::endl;
    388                 }
    389                 assertf( base, "expected pointer type in dereference\n" );
    390                 ret->set_result( maybeClone( base ) );
    391         }
    392         return ret;
    393 }
    394 
    395 UntypedExpr * UntypedExpr::createAssign( Expression * arg1, Expression * arg2 ) {
    396         assert( arg1 && arg2 );
    397         UntypedExpr * ret = new UntypedExpr( new NameExpr( "?=?" ), std::list< Expression * >{ arg1, arg2 } );
    398         if ( arg1->get_result() && arg2->get_result() ) {
    399                 // if both expressions are typed, assumes that this assignment is a C bitwise assignment,
    400                 // so the result is the type of the RHS
    401                 ret->set_result( arg2->get_result()->clone() );
    402         }
    403         return ret;
    404 }
    405 
    406389
    407390void UntypedExpr::print( std::ostream &os, int indent ) const {
     
    436419LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) :
    437420                Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp) {
    438         set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     421        add_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    439422}
    440423
     
    471454
    472455void ConditionalExpr::print( std::ostream &os, int indent ) const {
    473         os << "Conditional expression on: " << std::endl;
    474         os << std::string( indent+2, ' ' );
     456        os << std::string( indent, ' ' ) << "Conditional expression on: " << std::endl;
    475457        arg1->print( os, indent+2 );
    476458        os << std::string( indent, ' ' ) << "First alternative:" << std::endl;
    477         os << std::string( indent+2, ' ' );
    478459        arg2->print( os, indent+2 );
    479460        os << std::string( indent, ' ' ) << "Second alternative:" << std::endl;
    480         os << std::string( indent+2, ' ' );
    481461        arg3->print( os, indent+2 );
    482462        os << std::endl;
     
    497477ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
    498478        assert( callExpr );
    499         assert( callExpr->has_result() );
    500         set_result( callExpr->get_result()->clone() );
     479        cloneAll( callExpr->get_results(), results );
    501480}
    502481
     
    531510        Expression * arg = InitTweak::getCallArg( callExpr, 0 );
    532511        assert( arg );
    533         set_result( maybeClone( arg->get_result() ) );
     512        cloneAll( arg->get_results(), results );
    534513}
    535514
     
    551530
    552531CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) {
    553         assert( type && initializer );
    554         set_result( type->clone() );
    555 }
    556 
    557 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( other.type->clone() ), initializer( other.initializer->clone() ) {}
     532        add_result( type->clone() );
     533}
     534
     535CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {}
    558536
    559537CompoundLiteralExpr::~CompoundLiteralExpr() {
     
    564542void CompoundLiteralExpr::print( std::ostream &os, int indent ) const {
    565543        os << "Compound Literal Expression: " << std::endl;
    566         os << std::string( indent+2, ' ' );
    567         type->print( os, indent + 2 );
    568         os << std::string( indent+2, ' ' );
    569         initializer->print( os, indent + 2 );
     544        if ( type ) type->print( os, indent + 2 );
     545        if ( initializer ) initializer->print( os, indent + 2 );
    570546}
    571547
     
    581557
    582558RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    583 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
     559RangeExpr::RangeExpr( const RangeExpr &other ) : low( other.low->clone() ), high( other.high->clone() ) {}
    584560void RangeExpr::print( std::ostream &os, int indent ) const {
    585         os << "Range Expression: ";
     561        os << std::string( indent, ' ' ) << "Range Expression: ";
    586562        low->print( os, indent );
    587563        os << " ... ";
    588564        high->print( os, indent );
    589 }
    590 
    591 StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
    592         assert( statements );
    593         std::list< Statement * > & body = statements->get_kids();
    594         if ( ! body.empty() ) {
    595                 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
    596                         set_result( maybeClone( exprStmt->get_expr()->get_result() ) );
    597                 }
    598         }
    599 }
    600 StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {}
    601 StmtExpr::~StmtExpr() {
    602         delete statements;
    603 }
    604 void StmtExpr::print( std::ostream &os, int indent ) const {
    605         os << "Statement Expression: " << std::endl << std::string( indent, ' ' );
    606         statements->print( os, indent+2 );
    607 }
    608 
    609 
    610 long long UniqueExpr::count = 0;
    611 UniqueExpr::UniqueExpr( Expression *expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
    612         assert( expr );
    613         assert( count != -1 );
    614         if ( id == -1 ) id = count++;
    615         if ( expr->get_result() ) {
    616                 set_result( expr->get_result()->clone() );
    617         }
    618 }
    619 UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
    620 }
    621 UniqueExpr::~UniqueExpr() {
    622         delete expr;
    623         delete object;
    624         delete var;
    625 }
    626 void UniqueExpr::print( std::ostream &os, int indent ) const {
    627         os << "Unique Expression with id:" << id << std::endl << std::string( indent+2, ' ' );
    628         get_expr()->print( os, indent+2 );
    629         if ( get_object() ) {
    630                 os << " with decl: ";
    631                 get_object()->printShort( os, indent+2 );
    632         }
    633565}
    634566
  • src/SynTree/Expression.h

    r1f44196 r3a2128f  
    3232        virtual ~Expression();
    3333
    34         Type *& get_result() { return result; }
    35         void set_result( Type *newValue ) { result = newValue; }
    36         bool has_result() const { return result != nullptr; }
     34        std::list<Type *>& get_results() { return results; }
     35        void add_result( Type *t );
    3736
    3837        TypeSubstitution *get_env() const { return env; }
     
    4847        virtual void print( std::ostream &os, int indent = 0 ) const;
    4948  protected:
    50         Type * result;
     49        std::list<Type *> results;
    5150        TypeSubstitution *env;
    5251        Expression* argName; // if expression is used as an argument, it can be "designated" by this name
     
    9998class UntypedExpr : public Expression {
    10099  public:
    101         UntypedExpr( Expression *function, const std::list<Expression *> &args = std::list< Expression * >(), Expression *_aname = nullptr );
     100        UntypedExpr( Expression *function, Expression *_aname = nullptr );
    102101        UntypedExpr( const UntypedExpr &other );
     102        UntypedExpr( Expression *function, std::list<Expression *> &args, Expression *_aname = nullptr );
    103103        virtual ~UntypedExpr();
    104104
     
    111111        std::list<Expression*>& get_args() { return args; }
    112112
    113         static UntypedExpr * createDeref( Expression * arg );
    114         static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 );
    115 
    116113        virtual UntypedExpr *clone() const { return new UntypedExpr( *this ); }
    117114        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    203200class UntypedMemberExpr : public Expression {
    204201  public:
    205         UntypedMemberExpr( Expression *member, Expression *aggregate, Expression *_aname = nullptr );
     202        UntypedMemberExpr( std::string member, Expression *aggregate, Expression *_aname = nullptr );
    206203        UntypedMemberExpr( const UntypedMemberExpr &other );
    207204        virtual ~UntypedMemberExpr();
    208205
    209         Expression * get_member() const { return member; }
    210         void set_member( Expression * newValue ) { member = newValue; }
     206        std::string get_member() const { return member; }
     207        void set_member( const std::string &newValue ) { member = newValue; }
    211208        Expression *get_aggregate() const { return aggregate; }
    212209        void set_aggregate( Expression *newValue ) { aggregate = newValue; }
     
    217214        virtual void print( std::ostream &os, int indent = 0 ) const;
    218215  private:
    219         Expression *member;
     216        std::string member;
    220217        Expression *aggregate;
    221218};
     
    486483};
    487484
     485/// TupleExpr represents a tuple expression ( [a, b, c] )
     486class TupleExpr : public Expression {
     487  public:
     488        TupleExpr( Expression *_aname = nullptr );
     489        TupleExpr( const TupleExpr &other );
     490        virtual ~TupleExpr();
     491
     492        void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
     493        std::list<Expression*>& get_exprs() { return exprs; }
     494
     495        virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
     496        virtual void accept( Visitor &v ) { v.visit( this ); }
     497        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     498        virtual void print( std::ostream &os, int indent = 0 ) const;
     499  private:
     500        std::list<Expression*> exprs;
     501};
     502
     503/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
     504class SolvedTupleExpr : public Expression {
     505  public:
     506        SolvedTupleExpr( Expression *_aname = nullptr ) : Expression( _aname ) {}
     507        SolvedTupleExpr( std::list<Expression *> &, Expression *_aname = nullptr );
     508        SolvedTupleExpr( const SolvedTupleExpr &other );
     509        virtual ~SolvedTupleExpr() {}
     510
     511        std::list<Expression*> &get_exprs() { return exprs; }
     512
     513        virtual SolvedTupleExpr *clone() const { return new SolvedTupleExpr( *this ); }
     514        virtual void accept( Visitor &v ) { v.visit( this ); }
     515        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     516        virtual void print( std::ostream &os, int indent = 0 ) const;
     517  private:
     518        std::list<Expression*> exprs;
     519};
     520
    488521/// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
    489522class TypeExpr : public Expression {
     
    585618        CompoundLiteralExpr( Type * type, Initializer * initializer );
    586619        CompoundLiteralExpr( const CompoundLiteralExpr &other );
    587         virtual ~CompoundLiteralExpr();
     620        ~CompoundLiteralExpr();
    588621
    589622        Type * get_type() const { return type; }
     
    637670  private:
    638671        Expression *low, *high;
    639 };
    640 
    641 /// TupleExpr represents a tuple expression ( [a, b, c] )
    642 class TupleExpr : public Expression {
    643   public:
    644         TupleExpr( const std::list< Expression * > & exprs = std::list< Expression * >(), Expression *_aname = nullptr );
    645         TupleExpr( const TupleExpr &other );
    646         virtual ~TupleExpr();
    647 
    648         void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
    649         std::list<Expression*>& get_exprs() { return exprs; }
    650 
    651         virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
    652         virtual void accept( Visitor &v ) { v.visit( this ); }
    653         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    654         virtual void print( std::ostream &os, int indent = 0 ) const;
    655   private:
    656         std::list<Expression*> exprs;
    657 };
    658 
    659 /// TupleIndexExpr represents an element selection operation on a tuple value, e.g. t.3 after processing by the expression analyzer
    660 class TupleIndexExpr : public Expression {
    661   public:
    662         TupleIndexExpr( Expression * tuple, unsigned int index );
    663         TupleIndexExpr( const TupleIndexExpr &other );
    664         virtual ~TupleIndexExpr();
    665 
    666         Expression * get_tuple() const { return tuple; }
    667         int get_index() const { return index; }
    668         TupleIndexExpr * set_tuple( Expression *newValue ) { tuple = newValue; return this; }
    669         TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; }
    670 
    671         virtual TupleIndexExpr *clone() const { return new TupleIndexExpr( *this ); }
    672         virtual void accept( Visitor &v ) { v.visit( this ); }
    673         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    674         virtual void print( std::ostream &os, int indent = 0 ) const;
    675   private:
    676         Expression * tuple;
    677         unsigned int index;
    678 };
    679 
    680 /// MemberTupleExpr represents a tuple member selection operation on a struct type, e.g. s.[a, b, c] after processing by the expression analyzer
    681 class MemberTupleExpr : public Expression {
    682   public:
    683         MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname = nullptr );
    684         MemberTupleExpr( const MemberTupleExpr &other );
    685         virtual ~MemberTupleExpr();
    686 
    687         Expression * get_member() const { return member; }
    688         Expression * get_aggregate() const { return aggregate; }
    689         MemberTupleExpr * set_member( Expression *newValue ) { member = newValue; return this; }
    690         MemberTupleExpr * set_aggregate( Expression *newValue ) { aggregate = newValue; return this; }
    691 
    692         virtual MemberTupleExpr *clone() const { return new MemberTupleExpr( *this ); }
    693         virtual void accept( Visitor &v ) { v.visit( this ); }
    694         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    695         virtual void print( std::ostream &os, int indent = 0 ) const;
    696   private:
    697         Expression * member;
    698         Expression * aggregate;
    699 };
    700 
    701 /// TupleAssignExpr represents a multiple assignment operation, where both sides of the assignment have tuple type, e.g. [a, b, c] = [d, e, f];, a mass assignment operation, where the left hand side has tuple type and the right hand side does not, e.g. [a, b, c] = 5.0;, or a tuple ctor/dtor expression
    702 class TupleAssignExpr : public Expression {
    703   public:
    704         TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr );
    705         TupleAssignExpr( const TupleAssignExpr &other );
    706         virtual ~TupleAssignExpr();
    707 
    708         std::list< Expression * > & get_assigns() { return assigns; }
    709         std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
    710 
    711         virtual TupleAssignExpr *clone() const { return new TupleAssignExpr( *this ); }
    712         virtual void accept( Visitor &v ) { v.visit( this ); }
    713         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    714         virtual void print( std::ostream &os, int indent = 0 ) const;
    715   private:
    716         std::list< Expression * > assigns; // assignment expressions that use tempDecls
    717         std::list< ObjectDecl * > tempDecls; // temporaries for address of lhs exprs
    718 };
    719 
    720 /// StmtExpr represents a GCC 'statement expression', e.g. ({ int x = 5; x; })
    721 class StmtExpr : public Expression {
    722 public:
    723         StmtExpr( CompoundStmt *statements );
    724         StmtExpr( const StmtExpr & other );
    725         virtual ~StmtExpr();
    726 
    727         CompoundStmt * get_statements() const { return statements; }
    728         StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
    729 
    730         virtual StmtExpr *clone() const { return new StmtExpr( *this ); }
    731         virtual void accept( Visitor &v ) { v.visit( this ); }
    732         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    733         virtual void print( std::ostream &os, int indent = 0 ) const;
    734 private:
    735         CompoundStmt * statements;
    736 };
    737 
    738 class UniqueExpr : public Expression {
    739 public:
    740         UniqueExpr( Expression * expr, long long idVal = -1 );
    741         UniqueExpr( const UniqueExpr & other );
    742         ~UniqueExpr();
    743 
    744         Expression * get_expr() const { return expr; }
    745         UniqueExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
    746 
    747         ObjectDecl * get_object() const { return object; }
    748         UniqueExpr * set_object( ObjectDecl * newValue ) { object = newValue; return this; }
    749 
    750         VariableExpr * get_var() const { return var; }
    751         UniqueExpr * set_var( VariableExpr * newValue ) { var = newValue; return this; }
    752 
    753         int get_id() const { return id; }
    754 
    755         virtual UniqueExpr *clone() const { return new UniqueExpr( *this ); }
    756         virtual void accept( Visitor &v ) { v.visit( this ); }
    757         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    758         virtual void print( std::ostream &os, int indent = 0 ) const;
    759 private:
    760         Expression * expr;
    761         ObjectDecl * object;
    762         VariableExpr * var;
    763         int id;
    764         static long long count;
    765672};
    766673
  • src/SynTree/Initializer.h

    r1f44196 r3a2128f  
    2323
    2424#include <cassert>
    25 
    26 const std::list<Expression*> noDesignators;
    2725
    2826// Initializer: base class for object initializers (provide default values)
  • src/SynTree/Mutator.cc

    r1f44196 r3a2128f  
    178178
    179179Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
    180         applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) );
     180        mutateAll( applicationExpr->get_results(), *this );
    181181        applicationExpr->set_function( maybeMutate( applicationExpr->get_function(), *this ) );
    182182        mutateAll( applicationExpr->get_args(), *this );
     
    185185
    186186Expression *Mutator::mutate( UntypedExpr *untypedExpr ) {
    187         untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) );
     187        mutateAll( untypedExpr->get_results(), *this );
    188188        mutateAll( untypedExpr->get_args(), *this );
    189189        return untypedExpr;
     
    191191
    192192Expression *Mutator::mutate( NameExpr *nameExpr ) {
    193         nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) );
     193        mutateAll( nameExpr->get_results(), *this );
    194194        return nameExpr;
    195195}
    196196
    197197Expression *Mutator::mutate( AddressExpr *addressExpr ) {
    198         addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) );
     198        mutateAll( addressExpr->get_results(), *this );
    199199        addressExpr->set_arg( maybeMutate( addressExpr->get_arg(), *this ) );
    200200        return addressExpr;
     
    202202
    203203Expression *Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
    204         labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
     204        mutateAll( labelAddressExpr->get_results(), *this );
    205205        labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) );
    206206        return labelAddressExpr;
     
    208208
    209209Expression *Mutator::mutate( CastExpr *castExpr ) {
    210         castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
     210        mutateAll( castExpr->get_results(), *this );
    211211        castExpr->set_arg( maybeMutate( castExpr->get_arg(), *this ) );
    212212        return castExpr;
     
    214214
    215215Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) {
    216         memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
    217         memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
    218         memberExpr->set_member( maybeMutate( memberExpr->get_member(), *this ) );
    219         return memberExpr;
    220 }
    221 
    222 Expression *Mutator::mutate( MemberExpr *memberExpr ) {
    223         memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
     216        mutateAll( memberExpr->get_results(), *this );
    224217        memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
    225218        return memberExpr;
    226219}
    227220
     221Expression *Mutator::mutate( MemberExpr *memberExpr ) {
     222        mutateAll( memberExpr->get_results(), *this );
     223        memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
     224        return memberExpr;
     225}
     226
    228227Expression *Mutator::mutate( VariableExpr *variableExpr ) {
    229         variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) );
     228        mutateAll( variableExpr->get_results(), *this );
    230229        return variableExpr;
    231230}
    232231
    233232Expression *Mutator::mutate( ConstantExpr *constantExpr ) {
    234         constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) );
     233        mutateAll( constantExpr->get_results(), *this );
    235234//  maybeMutate( constantExpr->get_constant(), *this )
    236235        return constantExpr;
     
    238237
    239238Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) {
    240         sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) );
     239        mutateAll( sizeofExpr->get_results(), *this );
    241240        if ( sizeofExpr->get_isType() ) {
    242241                sizeofExpr->set_type( maybeMutate( sizeofExpr->get_type(), *this ) );
     
    248247
    249248Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
    250         alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) );
     249        mutateAll( alignofExpr->get_results(), *this );
    251250        if ( alignofExpr->get_isType() ) {
    252251                alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) );
     
    258257
    259258Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
    260         offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
     259        mutateAll( offsetofExpr->get_results(), *this );
    261260        offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
    262261        return offsetofExpr;
     
    264263
    265264Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
    266         offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
     265        mutateAll( offsetofExpr->get_results(), *this );
    267266        offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
    268267        offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) );
     
    271270
    272271Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
    273         offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) );
     272        mutateAll( offsetPackExpr->get_results(), *this );
    274273        offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) );
    275274        return offsetPackExpr;
     
    277276
    278277Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    279         attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) );
     278        mutateAll( attrExpr->get_results(), *this );
    280279        if ( attrExpr->get_isType() ) {
    281280                attrExpr->set_type( maybeMutate( attrExpr->get_type(), *this ) );
     
    287286
    288287Expression *Mutator::mutate( LogicalExpr *logicalExpr ) {
    289         logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) );
     288        mutateAll( logicalExpr->get_results(), *this );
    290289        logicalExpr->set_arg1( maybeMutate( logicalExpr->get_arg1(), *this ) );
    291290        logicalExpr->set_arg2( maybeMutate( logicalExpr->get_arg2(), *this ) );
     
    294293
    295294Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) {
    296         conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) );
     295        mutateAll( conditionalExpr->get_results(), *this );
    297296        conditionalExpr->set_arg1( maybeMutate( conditionalExpr->get_arg1(), *this ) );
    298297        conditionalExpr->set_arg2( maybeMutate( conditionalExpr->get_arg2(), *this ) );
     
    302301
    303302Expression *Mutator::mutate( CommaExpr *commaExpr ) {
    304         commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) );
     303        mutateAll( commaExpr->get_results(), *this );
    305304        commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
    306305        commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
     
    308307}
    309308
     309Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
     310        mutateAll( tupleExpr->get_results(), *this );
     311        mutateAll( tupleExpr->get_exprs(), *this );
     312        return tupleExpr;
     313}
     314
     315Expression *Mutator::mutate( SolvedTupleExpr *tupleExpr ) {
     316        mutateAll( tupleExpr->get_results(), *this );
     317        mutateAll( tupleExpr->get_exprs(), *this );
     318        return tupleExpr;
     319}
     320
    310321Expression *Mutator::mutate( TypeExpr *typeExpr ) {
    311         typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) );
     322        mutateAll( typeExpr->get_results(), *this );
    312323        typeExpr->set_type( maybeMutate( typeExpr->get_type(), *this ) );
    313324        return typeExpr;
     
    329340
    330341Expression* Mutator::mutate( ConstructorExpr *ctorExpr ) {
    331         ctorExpr->set_result( maybeMutate( ctorExpr->get_result(), *this ) );
     342        mutateAll( ctorExpr->get_results(), *this );
    332343        ctorExpr->set_callExpr( maybeMutate( ctorExpr->get_callExpr(), *this ) );
    333344        return ctorExpr;
     
    335346
    336347Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
    337         compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) );
     348        mutateAll( compLitExpr->get_results(), *this );
    338349        compLitExpr->set_type( maybeMutate( compLitExpr->get_type(), *this ) );
    339350        compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) );
     
    342353
    343354Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
    344         valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ) );
     355        mutateAll( valofExpr->get_results(), *this );
    345356        return valofExpr;
    346357}
     
    350361        rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) );
    351362        return rangeExpr;
    352 }
    353 
    354 Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
    355         tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
    356         mutateAll( tupleExpr->get_exprs(), *this );
    357         return tupleExpr;
    358 }
    359 
    360 Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
    361         tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
    362         tupleExpr->set_tuple( maybeMutate( tupleExpr->get_tuple(), *this ) );
    363         return tupleExpr;
    364 }
    365 
    366 Expression *Mutator::mutate( MemberTupleExpr *tupleExpr ) {
    367         tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
    368         tupleExpr->set_member( maybeMutate( tupleExpr->get_member(), *this ) );
    369         tupleExpr->set_aggregate( maybeMutate( tupleExpr->get_aggregate(), *this ) );
    370         return tupleExpr;
    371 }
    372 
    373 Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
    374         assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
    375         mutateAll( assignExpr->get_tempDecls(), *this );
    376         mutateAll( assignExpr->get_assigns(), *this );
    377         return assignExpr;
    378 }
    379 
    380 Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
    381         stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
    382         stmtExpr->set_statements( maybeMutate( stmtExpr->get_statements(), *this ) );
    383         return stmtExpr;
    384 }
    385 
    386 Expression *Mutator::mutate( UniqueExpr *uniqueExpr ) {
    387         uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) );
    388         uniqueExpr->set_expr( maybeMutate( uniqueExpr->get_expr(), *this ) );
    389         return uniqueExpr;
    390363}
    391364
  • src/SynTree/Mutator.h

    r1f44196 r3a2128f  
    7171        virtual Expression* mutate( ConditionalExpr *conditionalExpr );
    7272        virtual Expression* mutate( CommaExpr *commaExpr );
     73        virtual Expression* mutate( TupleExpr *tupleExpr );
     74        virtual Expression* mutate( SolvedTupleExpr *tupleExpr );
    7375        virtual Expression* mutate( TypeExpr *typeExpr );
    7476        virtual Expression* mutate( AsmExpr *asmExpr );
     
    7880        virtual Expression* mutate( UntypedValofExpr *valofExpr );
    7981        virtual Expression* mutate( RangeExpr *rangeExpr );
    80         virtual Expression* mutate( TupleExpr *tupleExpr );
    81         virtual Expression* mutate( TupleIndexExpr *tupleExpr );
    82         virtual Expression* mutate( MemberTupleExpr *tupleExpr );
    83         virtual Expression* mutate( TupleAssignExpr *assignExpr );
    84         virtual Expression* mutate( StmtExpr * stmtExpr );
    85         virtual Expression* mutate( UniqueExpr * uniqueExpr );
    8682
    8783        virtual Type* mutate( VoidType *basicType );
  • src/SynTree/ReferenceToType.cc

    r1f44196 r3a2128f  
    5656        }
    5757} // namespace
    58 
    59 StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct ) : Parent( tq, baseStruct->get_name() ), baseStruct( baseStruct ) {}
    6058
    6159std::string StructInstType::typeString() const { return "struct"; }
  • src/SynTree/SynTree.h

    r1f44196 r3a2128f  
    7676class ConditionalExpr;
    7777class CommaExpr;
     78class TupleExpr;
     79class SolvedTupleExpr;
    7880class TypeExpr;
    7981class AsmExpr;
     
    8385class UntypedValofExpr;
    8486class RangeExpr;
    85 class TupleExpr;
    86 class TupleIndexExpr;
    87 class MemberTupleExpr;
    88 class TupleAssignExpr;
    89 class StmtExpr;
    90 class UniqueExpr;
    9187
    9288class Type;
  • src/SynTree/TupleExpr.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TupleExpr.cc --
     7// TupleExpr.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    1616#include "Expression.h"
    1717#include "Common/utility.h"
    18 #include "Type.h"
    19 #include "Declaration.h"
    20 #include "Tuples/Tuples.h"
    21 #include "VarExprReplacer.h"
    2218
    23 TupleExpr::TupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
    24         if ( ! exprs.empty() ) {
    25                 if ( std::all_of( exprs.begin(), exprs.end(), [](Expression * expr) { return expr->get_result(); } ) ) {
    26                         set_result( Tuples::makeTupleType( exprs ) );
    27                 }
    28         }
     19TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) {
    2920}
    3021
     
    3829
    3930void TupleExpr::print( std::ostream &os, int indent ) const {
    40         os << "Tuple:" << std::endl;
     31        os << std::string( indent, ' ' ) << "Tuple:" << std::endl;
    4132        printAll( exprs, os, indent+2 );
    4233        Expression::print( os, indent );
    4334}
    4435
    45 TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) : tuple( tuple ), index( index )  {
    46         TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
    47         assert( type->size() > index );
    48         set_result( (*std::next( type->get_types().begin(), index ))->clone() );
    49         get_result()->set_isLvalue( type->get_isLvalue() );
     36SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname ) : Expression( _aname ) {
     37        std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs));
    5038}
    5139
    52 TupleIndexExpr::TupleIndexExpr( const TupleIndexExpr &other ) : Expression( other ), tuple( other.tuple->clone() ), index( other.index ) {
     40SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other ) : Expression( other ) {
     41        cloneAll( other.exprs, exprs );
    5342}
    5443
    55 TupleIndexExpr::~TupleIndexExpr() {
    56         delete tuple;
    57 }
    58 
    59 void TupleIndexExpr::print( std::ostream &os, int indent ) const {
    60         os << "Tuple Index Expression, with tuple:" << std::endl;
    61         os << std::string( indent+2, ' ' );
    62         tuple->print( os, indent+2 );
    63         os << std::string( indent+2, ' ' ) << "with index: " << index << std::endl;
     44void SolvedTupleExpr::print( std::ostream &os, int indent ) const {
     45        os << std::string( indent, ' ' ) << "Solved Tuple:" << std::endl;
     46        printAll( exprs, os, indent+2 );
    6447        Expression::print( os, indent );
    6548}
    66 
    67 MemberTupleExpr::MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname ) : Expression( _aname ) {
    68         set_result( maybeClone( member->get_result() ) ); // xxx - ???
    69 }
    70 
    71 MemberTupleExpr::MemberTupleExpr( const MemberTupleExpr &other ) : Expression( other ), member( other.member->clone() ), aggregate( other.aggregate->clone() ) {
    72 }
    73 
    74 MemberTupleExpr::~MemberTupleExpr() {
    75         delete member;
    76         delete aggregate;
    77 }
    78 
    79 void MemberTupleExpr::print( std::ostream &os, int indent ) const {
    80         os << "Member Tuple Expression, with aggregate:" << std::endl;
    81         os << std::string( indent+2, ' ' );
    82         aggregate->print( os, indent+2 );
    83         os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
    84         os << std::string( indent+2, ' ' );
    85         member->print( os, indent+2 );
    86         Expression::print( os, indent );
    87 }
    88 
    89 
    90 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ), assigns( assigns ), tempDecls( tempDecls ) {
    91         set_result( Tuples::makeTupleType( assigns ) );
    92 }
    93 
    94 TupleAssignExpr::TupleAssignExpr( const TupleAssignExpr &other ) : Expression( other ) {
    95         cloneAll( other.assigns, assigns );
    96         cloneAll( other.tempDecls, tempDecls );
    97 
    98         // clone needs to go into assigns and replace tempDecls
    99         VarExprReplacer::DeclMap declMap;
    100         std::list< ObjectDecl * >::const_iterator origit = other.tempDecls.begin();
    101         for ( ObjectDecl * temp : tempDecls ) {
    102                 assert( origit != other.tempDecls.end() );
    103                 ObjectDecl * origTemp = *origit++;
    104                 assert( origTemp );
    105                 assert( temp->get_name() == origTemp->get_name() );
    106                 declMap[ origTemp ] = temp;
    107         }
    108         if ( ! declMap.empty() ) {
    109                 VarExprReplacer replacer( declMap );
    110                 for ( Expression * assn : assigns ) {
    111                         assn->accept( replacer );
    112                 }
    113         }
    114 }
    115 
    116 TupleAssignExpr::~TupleAssignExpr() {
    117         deleteAll( assigns );
    118         // deleteAll( tempDecls );
    119 }
    120 
    121 void TupleAssignExpr::print( std::ostream &os, int indent ) const {
    122         os << "Tuple Assignment Expression, with temporaries:" << std::endl;
    123         printAll( tempDecls, os, indent+4 );
    124         os << std::string( indent+2, ' ' ) << "with assignments: " << std::endl;
    125         printAll( assigns, os, indent+4 );
    126         Expression::print( os, indent );
    127 }
    128 
    129 
    13049
    13150// Local Variables: //
  • src/SynTree/TupleType.cc

    r1f44196 r3a2128f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TupleType.cc --
     7// TupleType.cc -- 
    88//
    99// Author           : Richard C. Bilson
     
    1717#include "Common/utility.h"
    1818
    19 TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types ) : Type( tq ), types( types ) {
     19TupleType::TupleType( const Type::Qualifiers &tq ) : Type( tq ) {
    2020}
    2121
  • src/SynTree/Type.h

    r1f44196 r3a2128f  
    2020#include "Visitor.h"
    2121#include "Mutator.h"
    22 #include "Common/utility.h"
    2322
    2423class Type {
     
    2827                Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic, bool isAttribute ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ), isAttribute( isAttribute ) {}
    2928
    30                 Qualifiers &operator&=( const Qualifiers &other );
    3129                Qualifiers &operator+=( const Qualifiers &other );
    3230                Qualifiers &operator-=( const Qualifiers &other );
     
    6563        void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; }
    6664        void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; }
    67 
    68         typedef std::list<TypeDecl *> ForallList;
    69         ForallList& get_forall() { return forall; }
    70 
    71         /// How many elemental types are represented by this type
    72         virtual unsigned size() const { return 1; };
    73         virtual bool isVoid() const { return size() == 0; }
     65        std::list<TypeDecl*>& get_forall() { return forall; }
    7466
    7567        virtual Type *clone() const = 0;
     
    7971  private:
    8072        Qualifiers tq;
    81         ForallList forall;
     73        std::list<TypeDecl*> forall;
    8274};
    8375
     
    8577  public:
    8678        VoidType( const Type::Qualifiers &tq );
    87 
    88         virtual unsigned size() const { return 0; };
    8979
    9080        virtual VoidType *clone() const { return new VoidType( *this ); }
     
    244234  public:
    245235        StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {}
    246         StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct );
    247236        StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
    248237
     
    359348class TupleType : public Type {
    360349  public:
    361         TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types = std::list< Type * >() );
     350        TupleType( const Type::Qualifiers &tq );
    362351        TupleType( const TupleType& );
    363352        virtual ~TupleType();
    364353
    365         typedef std::list<Type*> value_type;
    366         typedef value_type::iterator iterator;
    367 
    368354        std::list<Type*>& get_types() { return types; }
    369         virtual unsigned size() const { return types.size(); };
    370 
    371         iterator begin() { return types.begin(); }
    372         iterator end() { return types.end(); }
    373355
    374356        virtual TupleType *clone() const { return new TupleType( *this ); }
     
    460442};
    461443
    462 inline Type::Qualifiers &Type::Qualifiers::operator&=( const Type::Qualifiers &other ) {
    463         isConst &= other.isConst;
    464         isVolatile &= other.isVolatile;
    465         isRestrict &= other.isRestrict;
    466         isLvalue &= other.isLvalue;
    467         isAtomic &= other.isAtomic;
    468         return *this;
    469 }
    470 
    471444inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) {
    472445        isConst |= other.isConst;
  • src/SynTree/TypeSubstitution.cc

    r1f44196 r3a2128f  
    7272Type *TypeSubstitution::lookup( std::string formalType ) const {
    7373        TypeEnvType::const_iterator i = typeEnv.find( formalType );
    74 
     74       
    7575        // break on not in substitution set
    7676        if ( i == typeEnv.end() ) return 0;
    77 
     77       
    7878        // attempt to transitively follow TypeInstType links.
    7979        while ( TypeInstType *actualType = dynamic_cast< TypeInstType* >( i->second ) ) {
    8080                const std::string& typeName = actualType->get_name();
    81 
     81               
    8282                // break cycles in the transitive follow
    8383                if ( formalType == typeName ) break;
    84 
     84               
    8585                // Look for the type this maps to, returning previous mapping if none-such
    8686                i = typeEnv.find( typeName );
    8787                if ( i == typeEnv.end() ) return actualType;
    8888        }
    89 
     89       
    9090        // return type from substitution set
    9191        return i->second;
    92 
     92       
    9393#if 0
    9494        if ( i == typeEnv.end() ) {
     
    149149        // bind type variables from forall-qualifiers
    150150        if ( freeOnly ) {
    151                 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     151                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    152152                        boundVars.insert( (*tyvar )->get_name() );
    153153                } // for
     
    163163        // bind type variables from forall-qualifiers
    164164        if ( freeOnly ) {
    165                 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     165                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    166166                        boundVars.insert( (*tyvar )->get_name() );
    167167                } // for
  • src/SynTree/Visitor.cc

    r1f44196 r3a2128f  
    150150
    151151void Visitor::visit( ApplicationExpr *applicationExpr ) {
    152         maybeAccept( applicationExpr->get_result(), *this );
     152        acceptAll( applicationExpr->get_results(), *this );
    153153        maybeAccept( applicationExpr->get_function(), *this );
    154154        acceptAll( applicationExpr->get_args(), *this );
     
    156156
    157157void Visitor::visit( UntypedExpr *untypedExpr ) {
    158         maybeAccept( untypedExpr->get_result(), *this );
     158        acceptAll( untypedExpr->get_results(), *this );
    159159        acceptAll( untypedExpr->get_args(), *this );
    160160}
    161161
    162162void Visitor::visit( NameExpr *nameExpr ) {
    163         maybeAccept( nameExpr->get_result(), *this );
     163        acceptAll( nameExpr->get_results(), *this );
    164164}
    165165
    166166void Visitor::visit( AddressExpr *addressExpr ) {
    167         maybeAccept( addressExpr->get_result(), *this );
     167        acceptAll( addressExpr->get_results(), *this );
    168168        maybeAccept( addressExpr->get_arg(), *this );
    169169}
    170170
    171171void Visitor::visit( LabelAddressExpr *labAddressExpr ) {
    172         maybeAccept( labAddressExpr->get_result(), *this );
     172        acceptAll( labAddressExpr->get_results(), *this );
    173173        maybeAccept( labAddressExpr->get_arg(), *this );
    174174}
    175175
    176176void Visitor::visit( CastExpr *castExpr ) {
    177         maybeAccept( castExpr->get_result(), *this );
     177        acceptAll( castExpr->get_results(), *this );
    178178        maybeAccept( castExpr->get_arg(), *this );
    179179}
    180180
    181181void Visitor::visit( UntypedMemberExpr *memberExpr ) {
    182         maybeAccept( memberExpr->get_result(), *this );
     182        acceptAll( memberExpr->get_results(), *this );
    183183        maybeAccept( memberExpr->get_aggregate(), *this );
    184         maybeAccept( memberExpr->get_member(), *this );
    185184}
    186185
    187186void Visitor::visit( MemberExpr *memberExpr ) {
    188         maybeAccept( memberExpr->get_result(), *this );
     187        acceptAll( memberExpr->get_results(), *this );
    189188        maybeAccept( memberExpr->get_aggregate(), *this );
    190189}
    191190
    192191void Visitor::visit( VariableExpr *variableExpr ) {
    193         maybeAccept( variableExpr->get_result(), *this );
     192        acceptAll( variableExpr->get_results(), *this );
    194193}
    195194
    196195void Visitor::visit( ConstantExpr *constantExpr ) {
    197         maybeAccept( constantExpr->get_result(), *this );
     196        acceptAll( constantExpr->get_results(), *this );
    198197        maybeAccept( constantExpr->get_constant(), *this );
    199198}
    200199
    201200void Visitor::visit( SizeofExpr *sizeofExpr ) {
    202         maybeAccept( sizeofExpr->get_result(), *this );
     201        acceptAll( sizeofExpr->get_results(), *this );
    203202        if ( sizeofExpr->get_isType() ) {
    204203                maybeAccept( sizeofExpr->get_type(), *this );
     
    209208
    210209void Visitor::visit( AlignofExpr *alignofExpr ) {
    211         maybeAccept( alignofExpr->get_result(), *this );
     210        acceptAll( alignofExpr->get_results(), *this );
    212211        if ( alignofExpr->get_isType() ) {
    213212                maybeAccept( alignofExpr->get_type(), *this );
     
    218217
    219218void Visitor::visit( UntypedOffsetofExpr *offsetofExpr ) {
    220         maybeAccept( offsetofExpr->get_result(), *this );
     219        acceptAll( offsetofExpr->get_results(), *this );
    221220        maybeAccept( offsetofExpr->get_type(), *this );
    222221}
    223222
    224223void Visitor::visit( OffsetofExpr *offsetofExpr ) {
    225         maybeAccept( offsetofExpr->get_result(), *this );
     224        acceptAll( offsetofExpr->get_results(), *this );
    226225        maybeAccept( offsetofExpr->get_type(), *this );
    227226        maybeAccept( offsetofExpr->get_member(), *this );
     
    229228
    230229void Visitor::visit( OffsetPackExpr *offsetPackExpr ) {
    231         maybeAccept( offsetPackExpr->get_result(), *this );
     230        acceptAll( offsetPackExpr->get_results(), *this );
    232231        maybeAccept( offsetPackExpr->get_type(), *this );
    233232}
    234233
    235234void Visitor::visit( AttrExpr *attrExpr ) {
    236         maybeAccept( attrExpr->get_result(), *this );
     235        acceptAll( attrExpr->get_results(), *this );
    237236        if ( attrExpr->get_isType() ) {
    238237                maybeAccept( attrExpr->get_type(), *this );
     
    243242
    244243void Visitor::visit( LogicalExpr *logicalExpr ) {
    245         maybeAccept( logicalExpr->get_result(), *this );
     244        acceptAll( logicalExpr->get_results(), *this );
    246245        maybeAccept( logicalExpr->get_arg1(), *this );
    247246        maybeAccept( logicalExpr->get_arg2(), *this );
     
    249248
    250249void Visitor::visit( ConditionalExpr *conditionalExpr ) {
    251         maybeAccept( conditionalExpr->get_result(), *this );
     250        acceptAll( conditionalExpr->get_results(), *this );
    252251        maybeAccept( conditionalExpr->get_arg1(), *this );
    253252        maybeAccept( conditionalExpr->get_arg2(), *this );
     
    256255
    257256void Visitor::visit( CommaExpr *commaExpr ) {
    258         maybeAccept( commaExpr->get_result(), *this );
     257        acceptAll( commaExpr->get_results(), *this );
    259258        maybeAccept( commaExpr->get_arg1(), *this );
    260259        maybeAccept( commaExpr->get_arg2(), *this );
    261260}
    262261
     262void Visitor::visit( TupleExpr *tupleExpr ) {
     263        acceptAll( tupleExpr->get_results(), *this );
     264        acceptAll( tupleExpr->get_exprs(), *this );
     265}
     266
     267void Visitor::visit( SolvedTupleExpr *tupleExpr ) {
     268        acceptAll( tupleExpr->get_results(), *this );
     269        acceptAll( tupleExpr->get_exprs(), *this );
     270}
     271
    263272void Visitor::visit( TypeExpr *typeExpr ) {
    264         maybeAccept( typeExpr->get_result(), *this );
     273        acceptAll( typeExpr->get_results(), *this );
    265274        maybeAccept( typeExpr->get_type(), *this );
    266275}
     
    279288
    280289void Visitor::visit( ConstructorExpr * ctorExpr ) {
    281         maybeAccept( ctorExpr->get_result(), *this );
     290        acceptAll( ctorExpr->get_results(), *this );
    282291        maybeAccept( ctorExpr->get_callExpr(), *this );
    283292}
    284293
    285294void Visitor::visit( CompoundLiteralExpr *compLitExpr ) {
    286         maybeAccept( compLitExpr->get_result(), *this );
     295        acceptAll( compLitExpr->get_results(), *this );
    287296        maybeAccept( compLitExpr->get_type(), *this );
    288297        maybeAccept( compLitExpr->get_initializer(), *this );
     
    290299
    291300void Visitor::visit( UntypedValofExpr *valofExpr ) {
    292         maybeAccept( valofExpr->get_result(), *this );
     301        acceptAll( valofExpr->get_results(), *this );
    293302        maybeAccept( valofExpr->get_body(), *this );
    294303}
     
    297306        maybeAccept( rangeExpr->get_low(), *this );
    298307        maybeAccept( rangeExpr->get_high(), *this );
    299 }
    300 
    301 void Visitor::visit( TupleExpr *tupleExpr ) {
    302         maybeAccept( tupleExpr->get_result(), *this );
    303         acceptAll( tupleExpr->get_exprs(), *this );
    304 }
    305 
    306 void Visitor::visit( TupleIndexExpr *tupleExpr ) {
    307         maybeAccept( tupleExpr->get_result(), *this );
    308         maybeAccept( tupleExpr->get_tuple(), *this );
    309 }
    310 
    311 void Visitor::visit( MemberTupleExpr *tupleExpr ) {
    312         maybeAccept( tupleExpr->get_result(), *this );
    313         maybeAccept( tupleExpr->get_member(), *this );
    314         maybeAccept( tupleExpr->get_aggregate(), *this );
    315 }
    316 
    317 void Visitor::visit( TupleAssignExpr *assignExpr ) {
    318         maybeAccept( assignExpr->get_result(), *this );
    319         acceptAll( assignExpr->get_tempDecls(), *this );
    320         acceptAll( assignExpr->get_assigns(), *this );
    321 }
    322 
    323 void Visitor::visit( StmtExpr *stmtExpr ) {
    324         maybeAccept( stmtExpr->get_result(), *this );
    325         maybeAccept( stmtExpr->get_statements(), *this );
    326 }
    327 
    328 void Visitor::visit( UniqueExpr *uniqueExpr ) {
    329         maybeAccept( uniqueExpr->get_result(), *this );
    330         maybeAccept( uniqueExpr->get_expr(), *this );
    331308}
    332309
  • src/SynTree/Visitor.h

    r1f44196 r3a2128f  
    7171        virtual void visit( ConditionalExpr *conditionalExpr );
    7272        virtual void visit( CommaExpr *commaExpr );
     73        virtual void visit( TupleExpr *tupleExpr );
     74        virtual void visit( SolvedTupleExpr *tupleExpr );
    7375        virtual void visit( TypeExpr *typeExpr );
    7476        virtual void visit( AsmExpr *asmExpr );
     
    7880        virtual void visit( UntypedValofExpr *valofExpr );
    7981        virtual void visit( RangeExpr *rangeExpr );
    80         virtual void visit( TupleExpr *tupleExpr );
    81         virtual void visit( TupleIndexExpr *tupleExpr );
    82         virtual void visit( MemberTupleExpr *tupleExpr );
    83         virtual void visit( TupleAssignExpr *assignExpr );
    84         virtual void visit( StmtExpr * stmtExpr );
    85         virtual void visit( UniqueExpr * uniqueExpr );
    8682
    8783        virtual void visit( VoidType *basicType );
  • src/SynTree/module.mk

    r1f44196 r3a2128f  
    4949       SynTree/AddStmtVisitor.cc \
    5050       SynTree/TypeSubstitution.cc \
    51        SynTree/Attribute.cc \
    52        SynTree/VarExprReplacer.cc
     51       SynTree/Attribute.cc
    5352
  • src/Tuples/TupleAssignment.cc

    r1f44196 r3a2128f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Nov 9 13:48:42 2016
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon May 18 15:02:53 2015
    1313// Update Count     : 2
    1414//
     
    1818#include "ResolvExpr/typeops.h"
    1919#include "SynTree/Expression.h"
    20 #include "SynTree/Initializer.h"
    21 #include "Tuples.h"
    22 #include "Explode.h"
     20#include "TupleAssignment.h"
    2321#include "Common/SemanticError.h"
    24 #include "InitTweak/InitTweak.h"
    2522
    2623#include <functional>
     
    3027#include <cassert>
    3128#include <set>
    32 #include <unordered_set>
    3329
    3430namespace Tuples {
    35         class TupleAssignSpotter {
    36           public:
    37                 // dispatcher for Tuple (multiple and mass) assignment operations
    38                 TupleAssignSpotter( ResolvExpr::AlternativeFinder & );
    39                 void spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities );
    40 
    41           private:
    42                 void match();
    43 
    44                 struct Matcher {
    45                   public:
    46                         Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts );
    47                         virtual ~Matcher() {}
    48                         virtual void match( std::list< Expression * > &out ) = 0;
    49                         ResolvExpr::AltList lhs, rhs;
    50                         TupleAssignSpotter &spotter;
    51                         std::list< ObjectDecl * > tmpDecls;
    52                 };
    53 
    54                 struct MassAssignMatcher : public Matcher {
    55                   public:
    56                         MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts );
    57                         virtual void match( std::list< Expression * > &out );
    58                 };
    59 
    60                 struct MultipleAssignMatcher : public Matcher {
    61                   public:
    62                         MultipleAssignMatcher( TupleAssignSpotter &spot, const ResolvExpr::AltList & alts );
    63                         virtual void match( std::list< Expression * > &out );
    64                 };
    65 
    66                 ResolvExpr::AlternativeFinder &currentFinder;
    67                 std::string fname;
    68                 std::unique_ptr< Matcher > matcher;
    69         };
    70 
    71         /// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function
    72         bool isTuple( Expression *expr ) {
     31        TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f )
     32                : currentFinder(f), matcher(0), hasMatched( false ) {}
     33
     34        bool TupleAssignSpotter::pointsToTuple( Expression *expr ) {
     35                // also check for function returning tuple of reference types
     36                if (AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) )
     37                        if ( isTuple(addr->get_arg() ) )
     38                                return true;
     39                return false;
     40        }
     41
     42        bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) {
     43                if ( dynamic_cast<TupleType *>(decl->get_type()) )
     44                        return true;
     45                return false;
     46        }
     47
     48        bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) {
     49                // true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function
    7350                if ( ! expr ) return false;
    74                 assert( expr->has_result() );
    75                 return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1;
    76         }
    77 
    78         template< typename AltIter >
    79         bool isMultAssign( AltIter begin, AltIter end ) {
    80                 // multiple assignment if more than one alternative in the range or if
    81                 // the alternative is a tuple
    82                 if ( begin == end ) return false;
    83                 if ( isTuple( begin->expr ) ) return true;
    84                 return ++begin != end;
    85         }
    86 
    87         bool pointsToTuple( Expression *expr ) {
    88                 // also check for function returning tuple of reference types
    89                 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    90                         return pointsToTuple( castExpr->get_arg() );
    91                 } else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
    92                         return isTuple( addr->get_arg() );
    93                 }
    94                 return false;
    95         }
    96 
    97         void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) {
    98                 TupleAssignSpotter spotter( currentFinder );
    99                 spotter.spot( expr, possibilities );
    100         }
    101 
    102         TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f )
    103                 : currentFinder(f) {}
    104 
    105         void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) {
    106                 if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
    107                         if ( InitTweak::isCtorDtorAssign( op->get_name() ) ) {
    108                                 fname = op->get_name();
    109                                 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
    110                                         if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal
    111                                         if ( ali->size() <= 1 && InitTweak::isAssignment( op->get_name() ) ) {
    112                                                 // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it
    113                                                 continue;
    114                                         }
    115 
    116                                         assert( ! ali->empty() );
    117                                         // grab args 2-N and group into a TupleExpr
    118                                         const ResolvExpr::Alternative & alt1 = ali->front();
    119                                         auto begin = std::next(ali->begin(), 1), end = ali->end();
    120                                         if ( pointsToTuple(alt1.expr) ) {
    121                                                 if ( isMultAssign( begin, end ) ) {
    122                                                         matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
    123                                                 } else {
     51
     52                if ( dynamic_cast<TupleExpr *>(expr) )
     53                        return true;
     54                else if ( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) {
     55                        if ( isTupleVar(var->get_var()) )
     56                                return true;
     57                }
     58
     59                return false;
     60        }
     61
     62        bool TupleAssignSpotter::match() {
     63                assert ( matcher != 0 );
     64
     65                std::list< Expression * > new_assigns;
     66                if ( ! matcher->match(new_assigns) )
     67                        return false;
     68
     69                if ( new_assigns.empty() ) return false;
     70                /*return */matcher->solve( new_assigns );
     71                if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
     72                        // now resolve new assignments
     73                        std::list< Expression * > solved_assigns;
     74                        ResolvExpr::AltList solved_alts;
     75                        assert( currentFinder != 0 );
     76
     77                        ResolvExpr::AltList current;
     78                        for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
     79                                //try {
     80                                ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
     81                                finder.findWithAdjustment(*i);
     82                                // prune expressions that don't coincide with
     83                                ResolvExpr::AltList alts = finder.get_alternatives();
     84                                assert( alts.size() == 1 );
     85                                assert(alts.front().expr != 0 );
     86                                current.push_back( finder.get_alternatives().front() );
     87                                solved_assigns.push_back( alts.front().expr->clone() );
     88                                //solved_assigns.back()->print(std::cerr);
     89                                /*} catch( ... ) {
     90                                  continue; // no reasonable alternative found
     91                                  }*/
     92                        }
     93                        options.add_option( current );
     94
     95                        return true;
     96                } else { // mass assignment
     97                        //if ( new_assigns.empty() ) return false;
     98                        std::list< Expression * > solved_assigns;
     99                        ResolvExpr::AltList solved_alts;
     100                        assert( currentFinder != 0 );
     101
     102                        ResolvExpr::AltList current;
     103                        if ( optMass.empty() ) {
     104                                for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
     105                                        optMass.push_back( ResolvExpr::AltList() );
     106                        }
     107                        int cnt = 0;
     108                        for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
     109
     110                                ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
     111                                finder.findWithAdjustment(*i);
     112                                ResolvExpr::AltList alts = finder.get_alternatives();
     113                                assert( alts.size() == 1 );
     114                                assert(alts.front().expr != 0 );
     115                                current.push_back( finder.get_alternatives().front() );
     116                                optMass[cnt].push_back( finder.get_alternatives().front() );
     117                                solved_assigns.push_back( alts.front().expr->clone() );
     118                        }
     119
     120                        return true;
     121                }
     122
     123                return false;
     124        }
     125
     126        bool TupleAssignSpotter::isMVR( Expression *expr ) {
     127                if ( expr->get_results().size() > 1 ) {
     128                        // MVR processing
     129                        return true;
     130                }
     131                return false;
     132        }
     133
     134        bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
     135                if (  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
     136
     137                        if ( assgnop->get_name() == std::string("?=?") ) {
     138
     139                                for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
     140                                        assert( ali->size() == 2 );
     141                                        ResolvExpr::AltList::iterator opit = ali->begin();
     142                                        ResolvExpr::Alternative op1 = *opit, op2 = *(++opit);
     143
     144                                        if ( pointsToTuple(op1.expr) ) { // also handles tuple vars
     145                                                if ( isTuple( op2.expr, true ) )
     146                                                        matcher = new MultipleAssignMatcher(op1.expr, op2.expr);
     147                                                else if ( isMVR( op2.expr ) ) {
     148                                                        // handle MVR differently
     149                                                } else
    124150                                                        // mass assignment
    125                                                         matcher.reset( new MassAssignMatcher( *this,  *ali ) );
     151                                                        matcher = new MassAssignMatcher(op1.expr, op2.expr);
     152
     153                                                std::list< ResolvExpr::AltList > options;
     154                                                if ( match() )
     155                                                        /*
     156                                                          if ( hasMatched ) {
     157                                                          // throw SemanticError("Ambiguous tuple assignment");
     158                                                          } else {*/
     159                                                        // Matched for the first time
     160                                                        hasMatched = true;
     161                                                /*} */
     162                                        } /* else if ( isTuple( op2 ) )
     163                                                 throw SemanticError("Inapplicable tuple assignment.");
     164                                          */
     165                                }
     166
     167                                if ( hasMatched ) {
     168                                        if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
     169                                                //options.print( std::cerr );
     170                                                std::list< ResolvExpr::AltList >best = options.get_best();
     171                                                if ( best.size() == 1 ) {
     172                                                        std::list<Expression *> solved_assigns;
     173                                                        for ( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ) {
     174                                                                solved_assigns.push_back( i->expr );
     175                                                        }
     176                                                        /* assigning cost zero? */
     177                                                        currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
    126178                                                }
    127                                                 match();
     179                                        } else {
     180                                                assert( ! optMass.empty() );
     181                                                ResolvExpr::AltList winners;
     182                                                for ( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i )
     183                                                        findMinCostAlt( i->begin(), i->end(), back_inserter(winners) );
     184
     185                                                std::list< Expression *> solved_assigns;
     186                                                for ( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i )
     187                                                        solved_assigns.push_back( i->expr );
     188                                                currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
    128189                                        }
    129190                                }
    130191                        }
    131192                }
    132         }
    133 
    134         void TupleAssignSpotter::match() {
    135                 assert ( matcher != 0 );
    136 
    137                 std::list< Expression * > new_assigns;
    138                 matcher->match( new_assigns );
    139 
    140                 if ( new_assigns.empty() ) return;
    141                 ResolvExpr::AltList current;
    142                 // now resolve new assignments
    143                 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
    144                         ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() );
    145                         try {
    146                                 finder.findWithAdjustment(*i);
    147                         } catch (...) {
    148                                 return; // xxx - no match should not mean failure, it just means this particular tuple assignment isn't valid
     193                return hasMatched;
     194        }
     195
     196        void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) {
     197                lhs.clear();
     198                if (AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) )
     199                        if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
     200                                std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) );
     201
     202                rhs.clear();
     203        }
     204
     205        TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{
     206                init(_lhs,_rhs);
     207        }
     208
     209        TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{
     210                init(_lhs,_rhs);
     211
     212                if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) )
     213                        std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) );
     214        }
     215
     216        UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) {
     217                if ( left && right ) {
     218                        std::list< Expression * > args;
     219                        args.push_back(new AddressExpr(left->clone()));  args.push_back(right->clone());
     220                        return new UntypedExpr(new NameExpr("?=?"), args);
     221                } else
     222                        throw 0; // xxx - diagnose the problem
     223        }
     224
     225        bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
     226                if ( lhs.empty() || (rhs.size() != 1) ) return false;
     227
     228                for ( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) {
     229                        std::list< Expression * > args;
     230                        args.push_back( new AddressExpr(*l) );
     231                        args.push_back( rhs.front() );
     232                        out.push_back( new UntypedExpr(new NameExpr("?=?"), args) );
     233                }
     234
     235                return true;
     236        }
     237
     238        bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) {
     239                /*
     240                  std::list< Expression * > solved_assigns;
     241                  ResolvExpr::AltList solved_alts;
     242                  assert( currentFinder != 0 );
     243
     244                  ResolvExpr::AltList current;
     245                  if ( optMass.empty() ) {
     246                  for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
     247                  optMass.push_back( ResolvExpr::AltList() );
     248                  }
     249                  int cnt = 0;
     250                  for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
     251
     252                  ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
     253                  finder.findWithAdjustment(*i);
     254                  ResolvExpr::AltList alts = finder.get_alternatives();
     255                  assert( alts.size() == 1 );
     256                  assert(alts.front().expr != 0 );
     257                  current.push_back( finder.get_alternatives().front() );
     258                  optMass[cnt].push_back( finder.get_alternatives().front() );
     259                  solved_assigns.push_back( alts.front().expr->clone() );
     260                  }
     261                */
     262                return true;
     263        }
     264
     265        bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
     266                // need more complicated matching
     267                if ( lhs.size() == rhs.size() ) {
     268                        zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn );
     269                        return true;
     270                } //else
     271                //std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/
     272                return false;
     273        }
     274
     275        bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) {
     276                /*
     277                  std::list< Expression * > solved_assigns;
     278                  ResolvExpr::AltList solved_alts;
     279                  assert( currentFinder != 0 );
     280
     281                  ResolvExpr::AltList current;
     282                  for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
     283                  //try {
     284                  ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
     285                  finder.findWithAdjustment(*i);
     286                  // prune expressions that don't coincide with
     287                  ResolvExpr::AltList alts = finder.get_alternatives();
     288                  assert( alts.size() == 1 );
     289                  assert(alts.front().expr != 0 );
     290                  current.push_back( finder.get_alternatives().front() );
     291                  solved_assigns.push_back( alts.front().expr->clone() );
     292                  //solved_assigns.back()->print(std::cerr);
     293                  //} catch( ... ) {
     294                  //continue; // no reasonable alternative found
     295                  //}
     296                  }
     297                  options.add_option( current );
     298                */
     299
     300                return true;
     301        }
     302
     303        void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) {
     304                using namespace std;
     305
     306                options.push_back( opt );
     307                /*
     308                  vector< Cost > costs;
     309                  costs.reserve( opt.size() );
     310                  transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) );
     311                */
     312                // transpose matrix
     313                if ( costMatrix.empty() )
     314                        for ( unsigned int i = 0; i< opt.size(); ++i)
     315                                costMatrix.push_back( vector<ResolvExpr::Cost>() );
     316
     317                int cnt = 0;
     318                for ( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ )
     319                        costMatrix[cnt].push_back( i->cost );
     320
     321                return;
     322        }
     323
     324        std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() {
     325                using namespace std;
     326                using namespace ResolvExpr;
     327                list< ResolvExpr::AltList > ret;
     328                list< multiset<int> > solns;
     329                for ( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
     330                        list<int> current;
     331                        findMinCost( i->begin(), i->end(), back_inserter(current) );
     332                        solns.push_back( multiset<int>(current.begin(), current.end()) );
     333                }
     334                // need to combine
     335                multiset<int> result;
     336                lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) );
     337                if ( result.size() != 1 )
     338                        throw SemanticError("Ambiguous tuple expression");
     339                ret.push_back(get_option( *(result.begin() )));
     340                return ret;
     341        }
     342
     343        void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
     344                using namespace std;
     345
     346                for ( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
     347                        for ( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j )
     348                                ostr << *j << " " ;
     349                        ostr << std::endl;
     350                } // for
     351                return;
     352        }
     353
     354        ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) {
     355                return alt.cost;
     356        }
     357
     358        template< typename InputIterator, typename OutputIterator >
     359        void TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
     360                using namespace ResolvExpr;
     361                std::list<int> alternatives;
     362
     363                // select the alternatives that have the minimum parameter cost
     364                Cost minCost = Cost::infinity;
     365                unsigned int index = 0;
     366                for ( InputIterator i = begin; i != end; ++i, index++ ) {
     367                        if ( *i < minCost ) {
     368                                minCost = *i;
     369                                alternatives.clear();
     370                                alternatives.push_back( index );
     371                        } else if ( *i == minCost ) {
     372                                alternatives.push_back( index );
    149373                        }
    150                         // prune expressions that don't coincide with
    151                         ResolvExpr::AltList alts = finder.get_alternatives();
    152                         assert( alts.size() == 1 );
    153                         assert( alts.front().expr != 0 );
    154                         current.push_back( alts.front() );
    155                 }
    156 
    157                 // extract expressions from the assignment alternatives to produce a list of assignments that
    158                 // together form a single alternative
    159                 std::list< Expression *> solved_assigns;
    160                 for ( ResolvExpr::Alternative & alt : current ) {
    161                         solved_assigns.push_back( alt.expr->clone() );
    162                 }
    163                 // xxx - need to do this??
    164                 ResolvExpr::TypeEnvironment compositeEnv;
    165                 simpleCombineEnvironments( current.begin(), current.end(), compositeEnv );
    166                 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), compositeEnv, ResolvExpr::sumCost( current ) ) );
    167         }
    168 
    169         TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter) {
    170                 assert( ! alts.empty() );
    171                 ResolvExpr::Alternative lhsAlt = alts.front();
    172                 // peel off the cast that exists on ctor/dtor expressions
    173                 bool isCast = false;
    174                 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( lhsAlt.expr ) ) {
    175                         lhsAlt.expr = castExpr->get_arg();
    176                         castExpr->set_arg( nullptr );
    177                         delete castExpr;
    178                         isCast = true;
    179                 }
    180 
    181                 // explode the lhs so that each field of the tuple-valued-expr is assigned.
    182                 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs) );
    183 
    184                 // and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed
    185                 if ( isCast ) {
    186                         for ( ResolvExpr::Alternative & alt : lhs ) {
    187                                 Expression *& expr = alt.expr;
    188                                 Type * castType = expr->get_result()->clone();
    189                                 Type * type = InitTweak::getPointerBase( castType );
    190                                 assert( type );
    191                                 type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
    192                                 type->set_isLvalue( true ); // xxx - might not need this
    193                                 expr = new CastExpr( expr, castType );
    194                         }
    195                 }
    196         }
    197 
    198         TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
    199                 assert( alts.size() == 1 || alts.size() == 2 );
    200                 if ( alts.size() == 2 ) {
    201                         rhs.push_back( alts.back() );
    202                 }
    203         }
    204 
    205         TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
    206                 // explode the rhs so that each field of the tuple-valued-expr is assigned.
    207                 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs) );
    208         }
    209 
    210         UntypedExpr * createFunc( const std::string &fname, ObjectDecl *left, ObjectDecl *right ) {
    211                 assert( left );
    212                 std::list< Expression * > args;
    213                 args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) );
    214                 // args.push_back( new AddressExpr( new VariableExpr( left ) ) );
    215                 if ( right ) args.push_back( new VariableExpr( right ) );
    216                 return new UntypedExpr( new NameExpr( fname ), args );
    217         }
    218 
    219         ObjectDecl * newObject( UniqueName & namer, Expression * expr ) {
    220                 assert( expr->has_result() && ! expr->get_result()->isVoid() );
    221                 return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
    222         }
    223 
    224         void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
    225                 static UniqueName lhsNamer( "__massassign_L" );
    226                 static UniqueName rhsNamer( "__massassign_R" );
    227                 assert ( ! lhs.empty() && rhs.size() <= 1);
    228 
    229                 ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr;
    230                 for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
    231                         ObjectDecl * ltmp = newObject( lhsNamer, lhsAlt.expr );
    232                         out.push_back( createFunc( spotter.fname, ltmp, rtmp ) );
    233                         tmpDecls.push_back( ltmp );
    234                 }
    235                 if ( rtmp ) tmpDecls.push_back( rtmp );
    236         }
    237 
    238         void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
    239                 static UniqueName lhsNamer( "__multassign_L" );
    240                 static UniqueName rhsNamer( "__multassign_R" );
    241 
    242                 // xxx - need more complicated matching?
    243                 if ( lhs.size() == rhs.size() ) {
    244                         std::list< ObjectDecl * > ltmp;
    245                         std::list< ObjectDecl * > rtmp;
    246                         std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( ResolvExpr::Alternative & alt ){
    247                                 return newObject( lhsNamer, alt.expr );
    248                         });
    249                         std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( ResolvExpr::Alternative & alt ){
    250                                 return newObject( rhsNamer, alt.expr );
    251                         });
    252                         zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), [&](ObjectDecl * obj1, ObjectDecl * obj2 ) { return createFunc(spotter.fname, obj1, obj2); } );
    253                         tmpDecls.splice( tmpDecls.end(), ltmp );
    254                         tmpDecls.splice( tmpDecls.end(), rtmp );
    255                 }
     374                }
     375                std::copy( alternatives.begin(), alternatives.end(), out );
     376        }
     377
     378        template< class InputIterator, class OutputIterator >
     379        void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ) {
     380                if ( begin == end ) return;
     381                InputIterator test = begin;
     382
     383                if (++test == end)
     384                        { copy(begin->begin(), begin->end(), out); return; }
     385
     386
     387                std::multiset<int> cur; // InputIterator::value_type::value_type
     388                copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) );
     389
     390                while ( test != end ) {
     391                        std::multiset<int> temp;
     392                        set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) );
     393                        cur.clear();
     394                        copy( temp.begin(), temp.end(), inserter(cur,cur.begin()));
     395                        ++test;
     396                }
     397
     398                copy( cur.begin(), cur.end(), out );
     399                return;
     400        }
     401
     402        ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) {
     403                if ( index >= options.size() )
     404                        throw 0; // XXX
     405                std::list< ResolvExpr::AltList >::iterator it = options.begin();
     406                for ( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it );
     407                return *it;
    256408        }
    257409} // namespace Tuples
  • src/Tuples/module.mk

    r1f44196 r3a2128f  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk --
     8## module.mk -- 
    99##
    1010## Author           : Richard C. Bilson
     
    1616
    1717SRC +=  Tuples/TupleAssignment.cc \
    18         Tuples/TupleExpansion.cc \
    19         Tuples/Explode.cc
     18        Tuples/NameMatcher.cc
  • src/driver/cfa.cc

    r1f44196 r3a2128f  
    244244                nargs += 1;
    245245        } // if
    246         args[nargs] = "-I" CFA_INCDIR "/concurrency";
    247         nargs += 1;
    248246        args[nargs] = "-I" CFA_INCDIR "/containers";
    249247        nargs += 1;
  • src/libcfa/Makefile.am

    r1f44196 r3a2128f  
    5656CC = ${abs_top_srcdir}/src/driver/cfa
    5757
    58 headers = limits stdlib math iostream fstream iterator rational assert containers/vector concurrency/threads
    59 runtimehdrs = concurrency
     58headers = limits stdlib math iostream fstream iterator rational containers/vector
    6059libobjs = ${headers:=.o}
    6160
  • src/libcfa/Makefile.in

    r1f44196 r3a2128f  
    9292am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) math.$(OBJEXT) \
    9393        iostream.$(OBJEXT) fstream.$(OBJEXT) iterator.$(OBJEXT) \
    94         rational.$(OBJEXT) assert.$(OBJEXT) \
    95         containers/vector.$(OBJEXT) concurrency/threads.$(OBJEXT)
     94        rational.$(OBJEXT) containers/vector.$(OBJEXT)
    9695am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1)
    9796libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
     
    235234cfalib_DATA = builtins.cf extras.cf prelude.cf
    236235MAINTAINERCLEANFILES = builtins.cf extras.cf ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
    237 headers = limits stdlib math iostream fstream iterator rational assert containers/vector concurrency/threads
    238 runtimehdrs = concurrency
     236headers = limits stdlib math iostream fstream iterator rational containers/vector
    239237libobjs = ${headers:=.o}
    240238libcfa_a_SOURCES = libcfa-prelude.c ${headers:=.c}
     
    314312containers/vector.$(OBJEXT): containers/$(am__dirstamp) \
    315313        containers/$(DEPDIR)/$(am__dirstamp)
    316 concurrency/$(am__dirstamp):
    317         @$(MKDIR_P) concurrency
    318         @: > concurrency/$(am__dirstamp)
    319 concurrency/$(DEPDIR)/$(am__dirstamp):
    320         @$(MKDIR_P) concurrency/$(DEPDIR)
    321         @: > concurrency/$(DEPDIR)/$(am__dirstamp)
    322 concurrency/threads.$(OBJEXT): concurrency/$(am__dirstamp) \
    323         concurrency/$(DEPDIR)/$(am__dirstamp)
    324314libcfa.a: $(libcfa_a_OBJECTS) $(libcfa_a_DEPENDENCIES) $(EXTRA_libcfa_a_DEPENDENCIES)
    325315        $(AM_V_at)-rm -f libcfa.a
     
    329319mostlyclean-compile:
    330320        -rm -f *.$(OBJEXT)
    331         -rm -f concurrency/threads.$(OBJEXT)
    332321        -rm -f containers/vector.$(OBJEXT)
    333322
     
    335324        -rm -f *.tab.c
    336325
    337 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Po@am__quote@
    338326@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstream.Po@am__quote@
    339327@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iostream.Po@am__quote@
     
    344332@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rational.Po@am__quote@
    345333@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@
    346 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/threads.Po@am__quote@
    347334@AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/vector.Po@am__quote@
    348335
     
    518505        -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
    519506        -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
    520         -rm -f concurrency/$(DEPDIR)/$(am__dirstamp)
    521         -rm -f concurrency/$(am__dirstamp)
    522507        -rm -f containers/$(DEPDIR)/$(am__dirstamp)
    523508        -rm -f containers/$(am__dirstamp)
     
    532517
    533518distclean: distclean-am
    534         -rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR)
     519        -rm -rf ./$(DEPDIR) containers/$(DEPDIR)
    535520        -rm -f Makefile
    536521distclean-am: clean-am distclean-compile distclean-generic \
     
    578563
    579564maintainer-clean: maintainer-clean-am
    580         -rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR)
     565        -rm -rf ./$(DEPDIR) containers/$(DEPDIR)
    581566        -rm -f Makefile
    582567maintainer-clean-am: distclean-am maintainer-clean-generic \
  • src/main.cc

    r1f44196 r3a2128f  
    4343#include "Common/UnimplementedError.h"
    4444#include "../config.h"
    45 #include "Tuples/Tuples.h"
    4645
    4746using namespace std;
     
    237236                OPTPRINT( "tweakInit" )
    238237                InitTweak::genInit( translationUnit );
    239                 OPTPRINT( "expandMemberTuples" );
    240                 Tuples::expandMemberTuples( translationUnit );
     238
    241239                if ( libcfap ) {
    242240                        // generate the bodies of cfa library functions
     
    263261                        return 0;
    264262                } // if
    265 
    266                 OPTPRINT( "expandUniqueExpr" ); // xxx - is this the right place for this? want to expand ASAP so that subsequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
    267                 Tuples::expandUniqueExpr( translationUnit );
    268263
    269264                OPTPRINT("instantiateGenerics")
     
    282277                OPTPRINT( "box" )
    283278                GenPoly::box( translationUnit );
    284                 OPTPRINT( "expandTuples" ); // xxx - is this the right place for this?
    285                 Tuples::expandTuples( translationUnit );
    286279
    287280                // print tree right before code generation
Note: See TracChangeset for help on using the changeset viewer.