Changeset 1f44196
- Timestamp:
- Nov 29, 2016, 3:30:59 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 8e5724e
- Parents:
- 3a2128f (diff), 9129a84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 22 added
- 5 deleted
- 70 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/concurrency/Makefile
r3a2128f r1f44196 9 9 SOURCES = ${addsuffix .tex, \ 10 10 concurrency \ 11 style \ 12 glossary \ 11 13 } 12 14 -
doc/proposals/concurrency/concurrency.tex
r3a2128f r1f44196 14 14 15 15 % Latex packages used in the document. 16 \usepackage[T1]{fontenc} 16 \usepackage[T1]{fontenc} % allow Latin1 (extended ASCII) characters 17 17 \usepackage{textcomp} 18 18 \usepackage[latin1]{inputenc} 19 19 \usepackage{fullpage,times,comment} 20 20 \usepackage{epic,eepic} 21 \usepackage{upquote} 21 \usepackage{upquote} % switch curled `'" to straight 22 22 \usepackage{calc} 23 23 \usepackage{xspace} … … 25 25 \usepackage{tabularx} 26 26 \usepackage[acronym]{glossaries} 27 \usepackage{varioref} 27 \usepackage{varioref} % extended references 28 28 \usepackage{inconsolata} 29 \usepackage{listings} 30 \usepackage[flushmargin]{footmisc} 31 \usepackage{latexsym} 32 \usepackage{mathptmx} 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" 33 33 \usepackage[usenames]{color} 34 34 \usepackage[pagewise]{lineno} 35 35 \usepackage{fancyhdr} 36 36 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 37 \input{ common}% bespoke macros used in the document37 \input{style} % bespoke macros used in the document 38 38 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 39 39 \usepackage{breakurl} … … 44 44 \renewcommand{\UrlFont}{\small\sf} 45 45 46 \setlength{\topmargin}{-0.45in} 46 \setlength{\topmargin}{-0.45in} % move running title into header 47 47 \setlength{\headsep}{0.25in} 48 48 … … 86 86 \title{Concurrency in \CFA} 87 87 \author{Thierry Delisle \\ 88 Dept.of Computer Science, University of Waterloo, \\ Waterloo, Ontario, Canada88 School of Computer Science, University of Waterloo, \\ Waterloo, Ontario, Canada 89 89 } 90 90 … … 100 100 101 101 \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 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. 103 Indeed, 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 105 There 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. 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. 106 105 107 106 % ##### ####### # # ##### # # ###### ###### ####### # # ##### # # … … 114 113 115 114 \section{Concurrency} 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 119 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\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 121 Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. 122 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. 123 \\ 124 125 Finally, 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. 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. 126 116 127 117 % # # ####### # # ### ####### ####### ###### ##### … … 134 124 135 125 \subsection{Monitors} 136 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 :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 : 137 127 \begin{lstlisting} 138 128 typedef /*some monitor type*/ monitor; … … 154 144 155 145 \subsubsection{Call semantics} \label{call} 156 The 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 159 Another 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 171 This 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 172 uses \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 175 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. 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 178 Regardless of which keyword is kept, it is important to establish when mutex/nomutex may be used depending on type parameters. 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: 179 165 \begin{lstlisting} 180 166 int f1(monitor & mutex m); … … 184 170 int f5(graph(monitor*) & mutex m); 185 171 \end{lstlisting} 186 187 The 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). 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. 188 173 189 174 % ###### # ####### # … … 196 181 197 182 \subsubsection{Data semantics} \label{data} 198 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 appr ipriate protection. For example here is a more fleshed-out version of the counter showed in \ref{call}: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}: 199 184 \begin{lstlisting} 200 185 mutex struct counter_t { … … 207 192 208 193 int ++?(counter_t & mutex this) { 209 return ++this->value; 210 } 211 194 return ++this.value; 195 } 196 197 //need for mutex is platform dependent here 212 198 void ?{}(int * this, counter_t & mutex cnt) { 213 199 *this = (int)cnt; 214 200 } 215 201 \end{lstlisting} 216 \begin{tabular}{ c c } 217 Thread 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 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++; 231 216 \end{lstlisting} 232 217 \end{tabular} 233 \\ 234 235 236 This 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 238 These simple mutual exclusion semantics also naturally expand to multi-monitor calls. 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. 239 221 \begin{lstlisting} 240 222 int f(MonitorA & mutex a, MonitorB & mutex b); … … 244 226 f(a,b); 245 227 \end{lstlisting} 246 247 This 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) { 250 //... 251 } 252 253 void bar(A & mutex a, B & nomutex a) 254 //... 255 foo(a, b); 256 //... 257 } 258 259 void baz(A & nomutex a, B & mutex a) 260 //... 261 foo(a, b); 262 //... 263 } 264 \end{lstlisting} 265 266 Recursive 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. 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 231 //... 232 } 233 234 void bar(A & mutex a, B & nomutex b) { //acquire a 235 //... 236 foo(a, b); //acquire b 237 //... 238 } 239 240 void baz(A & nomutex a, B & mutex b) { //acquire b 241 //... 242 foo(a, b); //acquire a 243 //... 244 } 245 \end{lstlisting} 246 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. 267 254 268 255 % ###### ####### ####### # ### # ##### … … 283 270 284 271 \subsubsection{Implementation Details: Interaction with polymorphism} 285 At 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 287 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. 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. 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 288 342 289 343 % ### # # ####### ##### ##### # # ####### ###### … … 296 350 297 351 \subsection{Internal scheduling} \label{insched} 298 Monitors 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 :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 : 299 353 300 354 \begin{lstlisting} … … 314 368 \end{lstlisting} 315 369 316 Here 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 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. 318 371 \begin{center} 319 372 \begin{tabular}{ c @{\hskip 0.65in} c } … … 321 374 \begin{lstlisting} 322 375 void foo(monitor & mutex a, 323 monitor & mutex b) {376 monitor & mutex b) { 324 377 //... 325 378 wait(a.e); … … 330 383 \end{lstlisting} &\begin{lstlisting} 331 384 void bar(monitor & mutex a, 332 monitor & mutex b) {385 monitor & mutex b) { 333 386 signal(a.e); 334 387 } … … 340 393 \end{tabular} 341 394 \end{center} 342 343 A 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): 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): 344 396 345 397 \begin{center} … … 350 402 condition e; 351 403 404 //acquire a & b 352 405 void foo(monitor & mutex a, 353 monitor & mutex b) { 354 wait(e); 406 monitor & mutex b) { 407 408 wait(e); //release a & b 355 409 } 356 410 … … 364 418 condition e; 365 419 420 //acquire a 366 421 void bar(monitor & mutex a, 367 monitor & nomutex b) {422 monitor & nomutex b) { 368 423 foo(a,b); 369 424 } 370 425 426 //acquire a & b 371 427 void foo(monitor & mutex a, 372 monitor & mutex b) {373 wait(e); 428 monitor & mutex b) { 429 wait(e); //release a & b 374 430 } 375 431 … … 378 434 condition e; 379 435 436 //acquire a 380 437 void bar(monitor & mutex a, 381 monitor & nomutex b) { 382 foo(a,b); 383 } 384 438 monitor & nomutex b) { 439 baz(a,b); 440 } 441 442 //acquire b 385 443 void baz(monitor & nomutex a, 386 monitor & mutex b) {387 wait(e); 444 monitor & mutex b) { 445 wait(e); //release b 388 446 } 389 447 … … 393 451 \end{center} 394 452 395 This 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} 402 While 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. : 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 403 455 404 456 \begin{center} 405 \begin{tabular}{c @{\hskip 0.35in} c @{\hskip 0.35in} c} 406 \begin{lstlisting} 407 enterMonitor(a); 408 enterMonitor(b); 409 // do stuff 410 leaveMonitor(b); 411 leaveMonitor(a); 412 \end{lstlisting} & != &\begin{lstlisting} 413 enterMonitor(a); 414 enterMonitor(a, b); 415 // do stuff 416 leaveMonitor(a, b); 417 leaveMonitor(a); 457 \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); 476 \end{lstlisting} &\begin{lstlisting} 477 condition e; 478 479 //acquire a & b 480 void 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); 494 \end{lstlisting} &\begin{lstlisting} 495 condition e; 496 497 //acquire a & b 498 void 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); 418 512 \end{lstlisting} 419 513 \end{tabular} 420 514 \end{center} 421 422 This 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 425 The following examples shows three alternatives of explicit wait semantics : 426 \\ 427 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 : 428 518 \begin{center} 429 \begin{tabular}{|c|c|c|} 430 Case 1 & Case 2 & Case 3 \\ 431 Branding on construction & Explicit release list & Explicit ignore list \\ 432 \hline 433 \begin{lstlisting} 434 void foo(monitor & mutex a, 435 monitor & mutex b, 436 condition & c) 437 { 438 // Releases monitors 439 // branded in ctor 440 wait(c); 441 } 442 443 monitor a; 444 monitor b; 445 condition1 c1 = {a}; 446 condition2 c2 = {a, b}; 447 448 //Will release only a 449 foo(a,b,c1); 450 451 //Will release a and b 452 foo(a,b,c2); 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); 453 538 \end{lstlisting} &\begin{lstlisting} 454 void foo(monitor & mutex a, 455 monitor & mutex b, 456 condition & c) 457 { 458 // Releases monitor a 459 // Holds monitor b 460 waitRelease(c, [a]); 461 } 462 463 monitor a; 464 monitor b; 465 condition c; 466 467 468 469 foo(a,b,c); 470 471 472 539 => 473 540 \end{lstlisting} &\begin{lstlisting} 474 void foo(monitor & mutex a, 475 monitor & mutex b, 476 condition & c) 477 { 478 // Releases monitor a 479 // Holds monitor b 480 waitHold(c, [b]); 481 } 482 483 monitor a; 484 monitor b; 485 condition c; 486 487 488 489 foo(a,b,c); 490 491 492 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); 493 551 \end{lstlisting} 494 552 \end{tabular} 495 553 \end{center} 496 (Note : Case 2 and 3 use tuple semantics to pass a variable length list of elements.) 497 \\ 498 499 All 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} 501 void wait(condition & cond) { 502 waitHold(cond, []); 503 } 504 \end{lstlisting} 505 This 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} 507 monitor global; 508 509 extern void doStuff(); //uses global 510 511 void foo(monitor & mutex m) { 512 //... 513 doStuff(); //warning can release monitor m 514 //... 515 } 516 517 foo(global); 518 \end{lstlisting} 519 520 Indeed, 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} 522 struct condition { /*...*/ }; 523 524 // Second argument is a variable length tuple. 525 void wait(condition & cond, [...] monitorsToRelease); 526 void signal(condition & cond); 527 528 struct conditionN { /*...*/ }; 529 530 void ?{}(conditionN* this, /*list of N monitors to release*/); 531 void wait(conditionN & cond); 532 void signal(conditionN & cond); 533 \end{lstlisting} 534 535 Regardless 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 537 Finally, 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. 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. 538 558 \\ 539 559 … … 545 565 % # # # # ### # # # # # # # # # 546 566 % ####### # # # ### ##### ##### # # ####### ###### 547 567 \newpage 548 568 \subsection{External scheduling} \label{extsched} 549 A s 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 whata simple use \code{accept} versus \code{wait}/\code{signal} and its advantages.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. 550 570 551 571 \begin{center} … … 565 585 566 586 public: 567 void f() ;587 void f() { /*...*/ } 568 588 void g() { _Accept(f); } 569 589 private: … … 573 593 \end{center} 574 594 575 In 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.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. 576 596 \\ 577 597 … … 756 776 % # # # # # # # ####### ####### ####### ####### ### ##### # # 757 777 \section{Parallelism} 758 Historically, computer performance was about processor speeds and instructions count. However, with heat dissipation being a n 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.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. 759 779 760 780 \subsection{User-level threads} 761 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 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 763 Examples of languages that support are Java\cite{Java}, Haskell\cite{Haskell} and \uC\cite{uC++book}. 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} 764 789 765 790 \subsection{Jobs and thread pools} 766 The 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. 767 The golden standard of this implementation is Intel's TBB library\cite{TBB}. 768 769 \subsection{Fibers : user-level threads without preemption} 770 Finally, 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. 771 An example of a language that uses fibers is Go\cite{Go} 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}. 772 794 773 795 \subsection{Paradigm performance} 774 While 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 belargely amorticised by the actual work done.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. 775 797 776 798 % ##### ####### # ####### ###### ###### … … 783 805 784 806 \section{\CFA 's Thread Building Blocks} 785 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, 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 800 As shown in section \ref{cfaparadigms} these different blocks being available in \CFA it is trivial to reproduce any of these paradigm. 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. 801 808 802 809 % ####### # # ###### ####### # ###### ##### … … 809 816 810 817 \subsection{Thread Interface} 811 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 comparatievely to \glspl{kthread}). A thread can be declared using a struct declaration prefix with the\code{thread} as follows :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 : 812 819 813 820 \begin{lstlisting} … … 815 822 \end{lstlisting} 816 823 817 Obviously, 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: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 : 818 825 \begin{lstlisting} 819 826 thread struct foo {}; 820 827 821 void ?main( threadfoo* this) {822 /*... Some useful code ...*/823 } 824 \end{lstlisting} 825 826 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 :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 : 827 834 \begin{lstlisting} 828 835 typedef void (*voidFunc)(void); … … 833 840 834 841 //ctor 835 void ?{}( threadFuncRunner* this, voidFunc inFunc) {842 void ?{}(FuncRunner* this, voidFunc inFunc) { 836 843 func = inFunc; 837 844 } 838 845 839 846 //main 840 void ?main( threadFuncRunner* this) {847 void ?main(FuncRunner* this) { 841 848 this->func(); 842 849 } 843 850 \end{lstlisting} 844 851 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 847 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 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} 849 thread struct FuncRunner; //FuncRunner declared above 850 851 void world() { 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) { 852 857 sout | "World!" | endl; 853 858 } 854 859 855 860 void main() { 856 FuncRunner run = {world};861 World w; 857 862 //Thread run forks here 858 863 … … 863 868 } 864 869 \end{lstlisting} 865 This 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 867 These semantics also naturally scale to multiple threads meaning basic synchronisation is very simple : 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 868 872 \begin{lstlisting} 869 873 thread struct MyThread { … … 872 876 873 877 //ctor 874 void ?{}(thread MyThread* this) {} 878 void ?{}(MyThread* this, 879 bool is_special = false) { 880 //... 881 } 875 882 876 883 //main 877 void ?main(thread MyThread* this) { 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) { 878 919 //... 879 920 } … … 889 930 \end{lstlisting} 890 931 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 891 990 \newpage 892 \ large{\textbf{WORK IN PROGRESS}}991 \bf{WORK IN PROGRESS} 893 992 \subsection{The \CFA Kernel : Processors, Clusters and Threads}\label{kernel} 894 993 -
doc/proposals/concurrency/glossary.tex
r3a2128f r1f44196 1 1 \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 2 22 \longnewglossaryentry{uthread} 3 23 {name={user-level thread}} … … 30 50 31 51 \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 : } 32 60 } 33 61 -
doc/proposals/concurrency/version
r3a2128f r1f44196 1 0. 4.991 0.7.48 -
doc/working/resolver_design.md
r3a2128f r1f44196 1382 1382 hypothesis needs to be empirically validated. 1383 1383 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 1384 1392 Both Baker and Cormack explicitly generate all possible interpretations of a 1385 1393 given expression; thinking of the set of interpretations of an expression as a -
src/CodeGen/CodeGenerator.cc
r3a2128f r1f44196 307 307 } else { 308 308 // 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. 309 312 UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 310 313 newExpr->get_args().push_back( *arg ); 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() ); 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() ); 315 317 *arg = newExpr; 316 318 } // if … … 527 529 extension( castExpr ); 528 530 output << "("; 529 if ( castExpr->get_result s().empty() ) {531 if ( castExpr->get_result()->isVoid() ) { 530 532 output << "(void)" ; 531 } else if ( ! castExpr->get_result s().front()->get_isLvalue() ) {533 } else if ( ! castExpr->get_result()->get_isLvalue() ) { 532 534 // at least one result type of cast, but not an lvalue 533 535 output << "("; 534 output << genType( castExpr->get_result s().front(), "" );536 output << genType( castExpr->get_result(), "" ); 535 537 output << ")"; 536 538 } else { … … 640 642 } 641 643 642 void CodeGenerator::visit( TupleExpr * tupleExpr ) { }644 void CodeGenerator::visit( TupleExpr * tupleExpr ) { assert( false ); } 643 645 644 646 void CodeGenerator::visit( TypeExpr * typeExpr ) {} … … 654 656 asmExpr->get_operand()->accept( *this ); 655 657 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 << "})"; 656 693 } 657 694 -
src/CodeGen/CodeGenerator.h
r3a2128f r1f44196 70 70 virtual void visit( ConditionalExpr *conditionalExpr ); 71 71 virtual void visit( CommaExpr *commaExpr ); 72 virtual void visit( CompoundLiteralExpr *compLitExpr ); 72 73 virtual void visit( TupleExpr *tupleExpr ); 73 74 virtual void visit( TypeExpr *typeExpr ); 74 75 virtual void visit( AsmExpr * ); 76 virtual void visit( StmtExpr * ); 75 77 76 78 //*** Statements -
src/CodeGen/GenType.cc
r3a2128f r1f44196 227 227 typeString = "_Atomic " + typeString; 228 228 } // if 229 if ( type->get_isAttribute() ) {230 typeString = "__attribute(( )) " + typeString;231 } // if232 229 } 233 230 } // namespace CodeGen -
src/Common/utility.h
r3a2128f r1f44196 148 148 } 149 149 150 // replace element of list with all elements of another list 150 151 template< typename T > 151 152 void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) { … … 158 159 159 160 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 ); 160 168 } 161 169 -
src/ControlStruct/Mutate.cc
r3a2128f r1f44196 23 23 #include "MLEMutator.h" 24 24 #include "ForExprMutator.h" 25 #include "LabelTypeChecker.h"26 25 //#include "ExceptMutator.h" 27 26 … … 41 40 42 41 //ExceptMutator exc; 43 // LabelTypeChecker lbl;44 42 45 43 mutateAll( translationUnit, formut ); 46 44 acceptAll( translationUnit, lfix ); 47 45 //mutateAll( translationUnit, exc ); 48 //acceptAll( translationUnit, lbl );49 46 } 50 47 } // namespace CodeGen -
src/ControlStruct/module.mk
r3a2128f r1f44196 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 19 19 ControlStruct/MLEMutator.cc \ 20 20 ControlStruct/Mutate.cc \ 21 ControlStruct/ForExprMutator.cc \ 22 ControlStruct/LabelTypeChecker.cc 21 ControlStruct/ForExprMutator.cc 23 22 -
src/GenPoly/Box.cc
r3a2128f r1f44196 113 113 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 114 114 /// Stores assignment operators from assertion list in local map of assignment operations 115 void findTypeOps( const std::list< TypeDecl *>&forall );115 void findTypeOps( const Type::ForallList &forall ); 116 116 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 117 117 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); … … 619 619 } 620 620 621 void Pass1::findTypeOps( const std::list< TypeDecl *>&forall ) {621 void Pass1::findTypeOps( const Type::ForallList &forall ) { 622 622 // what if a nested function uses an assignment operator? 623 623 // assignOps.clear(); 624 for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) {624 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 625 625 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 626 626 std::string typeName; … … 687 687 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 688 688 std::list< FunctionType *> functions; 689 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {689 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 690 690 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 691 691 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter ); … … 789 789 790 790 // add size/align for generic types to parameter list 791 if ( appExpr->get_function()->get_results().empty() ) return;792 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result s().front() );791 if ( ! appExpr->get_function()->has_result() ) return; 792 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 793 793 assert( funcType ); 794 794 … … 806 806 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 807 807 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 808 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;809 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_result s().front(), arg, exprTyVars, seenTypes );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 ); 810 810 } 811 811 } … … 897 897 Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 898 898 appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) ); 899 appExpr->set_function( new NameExpr( adapterName ) ); 899 appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr 900 900 901 901 return ret; … … 903 903 904 904 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 905 assert( ! arg->get_results().empty() );905 assert( arg->has_result() ); 906 906 if ( isPolyType( param, exprTyVars ) ) { 907 if ( isPolyType( arg->get_result s().front() ) ) {907 if ( isPolyType( arg->get_result() ) ) { 908 908 // if the argument's type is polymorphic, we don't need to box again! 909 909 return; 910 } else if ( arg->get_result s().front()->get_isLvalue() ) {910 } else if ( arg->get_result()->get_isLvalue() ) { 911 911 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 912 912 // xxx - need to test that this code is still reachable … … 953 953 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 954 954 std::list< Expression *>::iterator cur = arg; 955 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {955 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 956 956 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 957 957 InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() ); … … 994 994 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 995 995 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 996 deref-> get_results().push_back( arg->get_type()->clone() );996 deref->set_result( arg->get_type()->clone() ); 997 997 return deref; 998 998 } // if … … 1020 1020 Statement *bodyStmt; 1021 1021 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();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(); 1025 1025 for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) { 1026 1026 assert( tyArg != realType->get_forall().end() ); … … 1071 1071 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 1072 1072 std::list< FunctionType *> functions; 1073 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {1073 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 1074 1074 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 1075 1075 findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter ); … … 1131 1131 } // if 1132 1132 addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) ); 1133 addAssign-> get_results().front() = appExpr->get_results().front()->clone();1133 addAssign->set_result( appExpr->get_result()->clone() ); 1134 1134 if ( appExpr->get_env() ) { 1135 1135 addAssign->set_env( appExpr->get_env() ); … … 1145 1145 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 1146 1146 if ( varExpr->get_var()->get_name() == "?[?]" ) { 1147 assert( ! appExpr->get_results().empty() );1147 assert( appExpr->has_result() ); 1148 1148 assert( appExpr->get_args().size() == 2 ); 1149 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result s().front(), scopeTyVars, env );1150 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result s().front(), scopeTyVars, env );1149 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); 1150 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env ); 1151 1151 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers 1152 1152 UntypedExpr *ret = 0; … … 1168 1168 } // if 1169 1169 if ( baseType1 || baseType2 ) { 1170 ret-> get_results().push_front( appExpr->get_results().front()->clone() );1170 ret->set_result( appExpr->get_result()->clone() ); 1171 1171 if ( appExpr->get_env() ) { 1172 1172 ret->set_env( appExpr->get_env() ); … … 1178 1178 } // if 1179 1179 } else if ( varExpr->get_var()->get_name() == "*?" ) { 1180 assert( ! appExpr->get_results().empty() );1180 assert( appExpr->has_result() ); 1181 1181 assert( ! appExpr->get_args().empty() ); 1182 if ( isPolyType( appExpr->get_result s().front(), scopeTyVars, env ) ) {1182 if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) { 1183 1183 Expression *ret = appExpr->get_args().front(); 1184 delete ret->get_result s().front();1185 ret-> get_results().front() = appExpr->get_results().front()->clone();1184 delete ret->get_result(); 1185 ret->set_result( appExpr->get_result()->clone() ); 1186 1186 if ( appExpr->get_env() ) { 1187 1187 ret->set_env( appExpr->get_env() ); … … 1193 1193 } // if 1194 1194 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) { 1195 assert( ! appExpr->get_results().empty() );1195 assert( appExpr->has_result() ); 1196 1196 assert( appExpr->get_args().size() == 1 ); 1197 if ( Type *baseType = isPolyPtr( appExpr->get_result s().front(), scopeTyVars, env ) ) {1198 Type *tempType = appExpr->get_result s().front()->clone();1197 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { 1198 Type *tempType = appExpr->get_result()->clone(); 1199 1199 if ( env ) { 1200 1200 env->apply( tempType ); … … 1213 1213 } // if 1214 1214 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) { 1215 assert( ! appExpr->get_results().empty() );1215 assert( appExpr->has_result() ); 1216 1216 assert( appExpr->get_args().size() == 1 ); 1217 if ( Type *baseType = isPolyPtr( appExpr->get_result s().front(), scopeTyVars, env ) ) {1217 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { 1218 1218 return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" ); 1219 1219 } // if 1220 1220 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 1221 assert( ! appExpr->get_results().empty() );1221 assert( appExpr->has_result() ); 1222 1222 assert( appExpr->get_args().size() == 2 ); 1223 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result s().front(), scopeTyVars, env );1224 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result s().front(), scopeTyVars, env );1223 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); 1224 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env ); 1225 1225 if ( baseType1 && baseType2 ) { 1226 1226 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 1227 1227 divide->get_args().push_back( appExpr ); 1228 1228 divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) ); 1229 divide-> get_results().push_front( appExpr->get_results().front()->clone() );1229 divide->set_result( appExpr->get_result()->clone() ); 1230 1230 if ( appExpr->get_env() ) { 1231 1231 divide->set_env( appExpr->get_env() ); … … 1245 1245 } // if 1246 1246 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) { 1247 assert( ! appExpr->get_results().empty() );1247 assert( appExpr->has_result() ); 1248 1248 assert( appExpr->get_args().size() == 2 ); 1249 Type *baseType = isPolyPtr( appExpr->get_result s().front(), scopeTyVars, env );1249 Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ); 1250 1250 if ( baseType ) { 1251 1251 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); … … 1273 1273 useRetval = oldUseRetval; 1274 1274 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 ); 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() ); 1280 1278 1281 1279 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { … … 1315 1313 1316 1314 Expression *Pass1::mutate( UntypedExpr *expr ) { 1317 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {1315 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1318 1316 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1319 1317 if ( name->get_name() == "*?" ) { … … 1329 1327 1330 1328 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 1331 assert( ! addrExpr->get_arg()->get_results().empty() );1329 assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() ); 1332 1330 1333 1331 bool needs = false; 1334 1332 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 1335 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {1333 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1336 1334 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1337 1335 if ( name->get_name() == "*?" ) { 1338 1336 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 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 ); 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() ); 1344 1340 needs = needsAdapter( function, scopeTyVars ); 1345 1341 } // if … … 1350 1346 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1351 1347 // out of the if condition. 1352 bool polytype = isPolyType( addrExpr->get_arg()->get_result s().front(), scopeTyVars, env );1348 bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env ); 1353 1349 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1354 1350 if ( polytype || needs ) { 1355 1351 Expression *ret = addrExpr->get_arg(); 1356 delete ret->get_result s().front();1357 ret-> get_results().front() = addrExpr->get_results().front()->clone();1352 delete ret->get_result(); 1353 ret->set_result( addrExpr->get_result()->clone() ); 1358 1354 addrExpr->set_arg( 0 ); 1359 1355 delete addrExpr; … … 1393 1389 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1394 1390 if ( retval && returnStmt->get_expr() ) { 1395 assert( ! returnStmt->get_expr()->get_results().empty() );1391 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() ); 1396 1392 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 1397 1393 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { … … 1427 1423 // find each of its needed secondary assignment operators 1428 1424 std::list< Expression* > &tyParams = refType->get_parameters(); 1429 std::list< TypeDecl* >&forallParams = functionDecl->get_type()->get_forall();1425 Type::ForallList &forallParams = functionDecl->get_type()->get_forall(); 1430 1426 std::list< Expression* >::const_iterator tyIt = tyParams.begin(); 1431 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();1427 Type::ForallList::const_iterator forallIt = forallParams.begin(); 1432 1428 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1433 1429 // Add appropriate mapping to assignment expression environment … … 1473 1469 // replace return statement with appropriate assignment to out parameter 1474 1470 Expression *retParm = new NameExpr( retval->get_name() ); 1475 retParm-> get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );1471 retParm->set_result( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 1476 1472 assignExpr->get_args().push_back( retParm ); 1477 1473 assignExpr->get_args().push_back( returnStmt->get_expr() ); … … 1603 1599 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1604 1600 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1605 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {1601 for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1606 1602 ObjectDecl *sizeParm, *alignParm; 1607 1603 // add all size and alignment parameters to parameter list -
src/GenPoly/CopyParams.cc
r3a2128f r1f44196 54 54 std::map< std::string, DeclarationWithType* > assignOps; 55 55 // assume the assignment operator is the first assert param after any "type" parameter 56 for ( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) {56 for ( Type::ForallList::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) { 57 57 if ( (*tyVar)->get_kind() == TypeDecl::Any ) { 58 58 assert( !(*tyVar)->get_assertions().empty() ); -
src/GenPoly/FindFunction.cc
r3a2128f r1f44196 29 29 virtual Type *mutate( PointerType *pointerType ); 30 30 private: 31 void handleForall( const std::list< TypeDecl* >&forall );31 void handleForall( const Type::ForallList &forall ); 32 32 33 33 std::list< FunctionType* > &functions; … … 51 51 } 52 52 53 void FindFunction::handleForall( const std::list< TypeDecl* >&forall ) {54 for ( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {53 void FindFunction::handleForall( const Type::ForallList &forall ) { 54 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 55 55 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 56 56 if ( var != tyVars.end() ) { -
src/GenPoly/GenPoly.cc
r3a2128f r1f44196 110 110 ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) { 111 111 if ( function->get_returnVals().empty() ) return 0; 112 112 113 113 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes ); 114 114 } … … 127 127 // } // if 128 128 if ( isDynRet( adaptee, tyVars ) ) return true; 129 129 130 130 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) { 131 131 // if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) { … … 228 228 229 229 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { 230 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {230 for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { 231 231 assert( *tyVar ); 232 232 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind(); -
src/GenPoly/Lvalue.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Lvalue.cc -- 7 // Lvalue.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 41 41 public: 42 42 Pass1(); 43 43 44 44 virtual Expression *mutate( ApplicationExpr *appExpr ); 45 45 virtual Statement *mutate( ReturnStmt *appExpr ); … … 55 55 private: 56 56 }; 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 }; 57 66 } // namespace 58 67 … … 60 69 Pass1 p1; 61 70 Pass2 p2; 71 GeneralizedLvalue genLval; 62 72 mutateAll( translationUnit, p1 ); 63 73 acceptAll( translationUnit, p2 ); 74 mutateAll( translationUnit, genLval ); 64 75 } 65 76 … … 99 110 appExpr->get_function()->acceptMutator( *this ); 100 111 mutateAll( appExpr->get_args(), *this ); 101 102 assert( ! appExpr->get_function()->get_results().empty() );103 112 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 ); 113 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 114 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 108 115 109 116 Type *funType = isLvalueRet( function ); 110 117 if ( funType && ! isIntrinsicApp( appExpr ) ) { 111 118 Expression *expr = appExpr; 112 Type *appType = appExpr->get_result s().front();119 Type *appType = appExpr->get_result(); 113 120 if ( isPolyType( funType ) && ! isPolyType( appType ) ) { 114 121 // make sure cast for polymorphic type is inside dereference … … 116 123 } 117 124 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 118 deref-> get_results().push_back( appType->clone() );119 appExpr-> get_results().front() = new PointerType( Type::Qualifiers(), appType);125 deref->set_result( appType->clone() ); 126 appExpr->set_result( new PointerType( Type::Qualifiers(), appType ) ); 120 127 deref->get_args().push_back( expr ); 121 128 return deref; … … 127 134 Statement * Pass1::mutate(ReturnStmt *retStmt) { 128 135 if ( retval && retStmt->get_expr() ) { 129 assert( ! retStmt->get_expr()->get_results().empty() ); 130 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 136 if ( retStmt->get_expr()->get_result()->get_isLvalue() ) { 131 137 // ***** Code Removal ***** because casts may be stripped already 132 138 … … 155 161 retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) ); 156 162 } // if 157 163 158 164 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; 159 182 } 160 183 } // namespace -
src/GenPoly/Specialize.cc
r3a2128f r1f44196 148 148 149 149 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 150 assert ( ! actual->get_results().empty() ); // using front, should have this assert151 if ( needsSpecialization( formalType, actual->get_result s().front(), env ) ) {150 assertf( actual->has_result(), "attempting to specialize an untyped expression" ); 151 if ( needsSpecialization( formalType, actual->get_result(), env ) ) { 152 152 FunctionType *funType; 153 153 if ( ( funType = getFunctionType( formalType ) ) ) { … … 172 172 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 173 173 // create thunks for the explicit parameters 174 assert( ! appExpr->get_function()->get_results().empty() );175 FunctionType *function = getFunctionType( appExpr->get_function()->get_result s().front() );174 assert( appExpr->get_function()->has_result() ); 175 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 176 176 assert( function ); 177 177 std::list< DeclarationWithType* >::iterator formal; … … 201 201 Expression * Specialize::mutate( AddressExpr *addrExpr ) { 202 202 addrExpr->get_arg()->acceptMutator( *this ); 203 assert( ! addrExpr->get_results().empty() );204 addrExpr->set_arg( doSpecialization( addrExpr->get_result s().front(), addrExpr->get_arg() ) );203 assert( addrExpr->has_result() ); 204 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) ); 205 205 return addrExpr; 206 206 } … … 208 208 Expression * Specialize::mutate( CastExpr *castExpr ) { 209 209 castExpr->get_arg()->acceptMutator( *this ); 210 if ( castExpr->get_result s().empty() ) {210 if ( castExpr->get_result()->isVoid() ) { 211 211 // can't specialize if we don't have a return value 212 212 return castExpr; 213 213 } 214 Expression *specialized = doSpecialization( castExpr->get_result s().front(), castExpr->get_arg() );214 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() ); 215 215 if ( specialized != castExpr->get_arg() ) { 216 216 // assume here that the specialization incorporates the cast -
src/InitTweak/FixInit.cc
r3a2128f r1f44196 18 18 #include <iterator> 19 19 #include <algorithm> 20 #include <unordered_map> 21 #include <unordered_set> 20 22 #include "InitTweak.h" 21 23 #include "FixInit.h" … … 35 37 #include "GenPoly/DeclMutator.h" 36 38 #include "SynTree/AddStmtVisitor.h" 37 #include "CodeGen/GenType.h" // for warning s38 39 bool ctordtorp = false; 40 bool ctorp = false; 41 bool cpctorp = false; 42 bool dtorp = false; 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 43 45 #define PRINT( text ) if ( ctordtorp ) { text } 44 46 #define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text } … … 47 49 namespace InitTweak { 48 50 namespace { 49 const std::list<Label> noLabels;50 const std::list<Expression*> noDesignators;51 52 51 class InsertImplicitCalls final : public GenPoly::PolyMutator { 53 52 public: … … 67 66 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit ); 68 67 69 using SymTab::Indexer::visit; 68 typedef SymTab::Indexer Parent; 69 using Parent::visit; 70 70 71 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 72 virtual void visit( UniqueExpr * unqExpr ); 71 73 72 74 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) 73 ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 75 Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 76 Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL ); 74 77 /// true if type does not need to be copy constructed to ensure correctness 75 bool skipCopyConstruct( Type * ); 78 bool skipCopyConstruct( Type * type ); 79 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 80 void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 76 81 private: 77 82 TypeSubstitution * env; … … 183 188 using GenPoly::PolyMutator::mutate; 184 189 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 190 virtual Expression * mutate( UniqueExpr * unqExpr ) override; 185 191 }; 186 192 … … 368 374 } 369 375 370 ApplicationExpr* ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {376 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { 371 377 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 ); 372 383 UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) ); 373 untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ));384 untyped->get_args().push_back( thisArg ); 374 385 if (cpArg) untyped->get_args().push_back( cpArg->clone() ); 375 386 … … 378 389 // (VariableExpr and already resolved expression) 379 390 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 380 ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) ); 391 Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this ); 392 assert( resolved ); 381 393 if ( resolved->get_env() ) { 382 394 env->add( *resolved->get_env() ); 383 395 } // if 384 396 385 assert( resolved );386 397 delete untyped; 387 398 return resolved; 388 399 } 389 400 401 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) { 402 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 ) ) { 419 // if the chosen constructor is intrinsic, the copy is unnecessary, so 420 // don't create the temporary and don't call the copy constructor 421 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 422 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 390 436 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 391 static UniqueName tempNamer("_tmp_cp");392 static UniqueName retNamer("_tmp_cp_ret");393 394 437 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 395 Visitor::visit( impCpCtorExpr );438 Parent::visit( impCpCtorExpr ); 396 439 env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer... 397 440 … … 400 443 // take each argument and attempt to copy construct it. 401 444 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 417 // if the chosen constructor is intrinsic, the copy is unnecessary, so 418 // don't create the temporary and don't call the copy constructor 419 VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() ); 420 assert( function ); 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 445 copyConstructArg( arg, impCpCtorExpr ); 427 446 } // for 428 447 … … 434 453 // level. Trying to pass that environment along. 435 454 callExpr->set_env( impCpCtorExpr->get_env()->clone() ); 436 for ( Type * result : appExpr->get_results() ) { 455 Type * result = appExpr->get_result(); 456 if ( ! result->isVoid() ) { 457 static UniqueName retNamer("_tmp_cp_ret"); 437 458 result = result->clone(); 438 459 impCpCtorExpr->get_env()->apply( result ); … … 441 462 impCpCtorExpr->get_returnDecls().push_back( ret ); 442 463 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 443 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 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 } 444 468 } // for 445 469 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() ); 446 492 } 447 493 … … 490 536 // know the result type of the assignment is the type of the LHS (minus the pointer), so 491 537 // add that onto the assignment expression so that later steps have the necessary information 492 assign-> add_result( returnDecl->get_type()->clone() );538 assign->set_result( returnDecl->get_type()->clone() ); 493 539 494 540 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 495 if ( callExpr->get_result s().front()->get_isLvalue() ) {541 if ( callExpr->get_result()->get_isLvalue() ) { 496 542 // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning 497 543 // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the … … 500 546 // an AddressExpr. Effectively, this turns 501 547 // lvalue T f(); 502 // &*f() 548 // &*f(); 503 549 // into 550 // T * f(); 504 551 // T * tmp_cp_retN; 505 // tmp_cp_ret_N = &*(tmp_cp_ret_N = &*f(), tmp_cp_ret);552 // &*(tmp_cp_retN = &*f(), tmp_cp_retN); // the first * and second & are generated here 506 553 // which work out in terms of types, but is pretty messy. It would be nice to find a better way. 507 554 assign->get_args().back() = new AddressExpr( assign->get_args().back() ); 508 555 509 Type * resultType = returnDecl->get_type()->clone();510 556 returnDecl->set_type( new PointerType( Type::Qualifiers(), returnDecl->get_type() ) ); 511 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 512 deref->get_args().push_back( retExpr ); 513 deref->add_result( resultType ); 514 retExpr = deref; 557 retExpr->set_result( new PointerType( Type::Qualifiers(), retExpr->get_result() ) ); 558 retExpr = UntypedExpr::createDeref( retExpr ); 515 559 } // if 516 560 retExpr->set_env( env->clone() ); … … 519 563 return callExpr; 520 564 } // 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; 521 596 } 522 597 … … 950 1025 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) { 951 1026 static UniqueName tempNamer( "_tmp_ctor_expr" ); 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 ); 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 ); 954 1030 addDeclaration( tmp ); 955 1031 … … 963 1039 assign->get_args().push_back( new VariableExpr( tmp ) ); 964 1040 assign->get_args().push_back( firstArg ); 965 cloneAll( ctorExpr->get_results(), assign->get_results() );1041 assign->set_result( ctorExpr->get_result()->clone() ); 966 1042 firstArg = assign; 967 1043 -
src/InitTweak/GenInit.cc
r3a2128f r1f44196 29 29 #include "GenPoly/DeclMutator.h" 30 30 #include "GenPoly/ScopedSet.h" 31 #include "ResolvExpr/typeops.h" 31 32 32 33 namespace InitTweak { … … 50 51 51 52 protected: 52 std::list<DeclarationWithType*> returnVals;53 FunctionType * ftype; 53 54 UniqueName tempNamer; 54 55 std::string funcName; … … 86 87 87 88 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed 89 bool isManaged( Type * type ) const; // determine if type is managed 88 90 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor 89 91 GenPoly::ScopedSet< std::string > managedTypes; … … 136 138 137 139 Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) { 138 // update for multiple return values140 std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals(); 139 141 assert( returnVals.size() == 0 || returnVals.size() == 1 ); 140 142 // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address … … 158 160 159 161 DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) { 160 ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals ); 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 ); 161 172 ValueGuard< std::string > oldFuncName( funcName ); 162 173 163 FunctionType * type = functionDecl->get_functionType(); 164 returnVals = type->get_returnVals(); 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 } 165 182 funcName = functionDecl->get_name(); 166 183 DeclarationWithType * decl = Mutator::mutate( functionDecl ); … … 222 239 } 223 240 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 224 251 bool CtorDtor::isManaged( ObjectDecl * objDecl ) const { 225 252 Type * type = objDecl->get_type(); … … 227 254 type = at->get_base(); 228 255 } 229 return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end();256 return isManaged( type ); 230 257 } 231 258 … … 238 265 managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) ); 239 266 } 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; 240 299 } 241 300 … … 250 309 if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl ); 251 310 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 } 311 objDecl->set_init( genCtorInit( objDecl ) ); 280 312 } 281 313 return Parent::mutate( objDecl ); … … 290 322 managedTypes.beginScope(); 291 323 // go through assertions and recursively add seen ctor/dtors 292 for ( TypeDecl *tyDecl : functionDecl->get_functionType()->get_forall() ) {324 for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) { 293 325 for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) { 294 326 assertion = assertion->acceptMutator( *this ); -
src/InitTweak/GenInit.h
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // RemoveInit.h --7 // GenInit.h -- 8 8 // 9 9 // Author : Rodolfo G. Esteves … … 27 27 /// Adds return value temporaries and wraps Initializers in ConstructorInit nodes 28 28 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 ); 29 32 } // namespace 30 33 -
src/InitTweak/InitTweak.cc
r3a2128f r1f44196 340 340 return allofCtorDtor( stmt, []( Expression * callExpr ){ 341 341 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 342 assert( ! appExpr->get_function()->get_results().empty() ); 343 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() ); 342 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_result() ); 344 343 assert( funcType ); 345 344 return funcType->get_parameters().size() == 1; … … 388 387 return memberExpr->get_member()->get_name(); 389 388 } else if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * > ( func ) ) { 390 return memberExpr->get_member();389 return funcName( memberExpr->get_member() ); 391 390 } else { 392 391 assertf( false, "Unexpected expression type being called as a function in call expression" ); … … 451 450 // virtual void visit( LogicalExpr *logicalExpr ); 452 451 // virtual void visit( ConditionalExpr *conditionalExpr ); 453 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }454 virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }455 452 virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; } 456 453 virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; } 457 454 virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; } 458 455 virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; } 456 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; } 457 virtual void visit( TupleAssignExpr *tupleExpr ) { isConstExpr = false; } 459 458 460 459 bool isConstExpr; -
src/Makefile.in
r3a2128f r1f44196 105 105 ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \ 106 106 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \ 107 ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT) \108 107 GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \ 109 108 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \ … … 190 189 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \ 191 190 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \ 191 SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT) \ 192 192 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \ 193 Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT) 193 Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT) \ 194 Tuples/driver_cfa_cpp-Explode.$(OBJEXT) 194 195 am_driver_cfa_cpp_OBJECTS = $(am__objects_1) 195 196 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS) … … 364 365 ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \ 365 366 ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \ 366 ControlStruct/ForExprMutator.cc \ 367 ControlStruct/LabelTypeChecker.cc GenPoly/Box.cc \ 367 ControlStruct/ForExprMutator.cc GenPoly/Box.cc \ 368 368 GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \ 369 369 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ … … 404 404 SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \ 405 405 SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \ 406 SynTree/Attribute.cc Tuples/TupleAssignment.cc \ 407 Tuples/NameMatcher.cc 406 SynTree/Attribute.cc SynTree/VarExprReplacer.cc \ 407 Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \ 408 Tuples/Explode.cc 408 409 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \ 409 410 ${cfa_cpplib_PROGRAMS}} … … 541 542 ControlStruct/$(DEPDIR)/$(am__dirstamp) 542 543 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT): \ 543 ControlStruct/$(am__dirstamp) \544 ControlStruct/$(DEPDIR)/$(am__dirstamp)545 ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT): \546 544 ControlStruct/$(am__dirstamp) \ 547 545 ControlStruct/$(DEPDIR)/$(am__dirstamp) … … 769 767 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \ 770 768 SynTree/$(DEPDIR)/$(am__dirstamp) 769 SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT): \ 770 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 771 771 Tuples/$(am__dirstamp): 772 772 @$(MKDIR_P) Tuples … … 777 777 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT): \ 778 778 Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp) 779 Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT): Tuples/$(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) \ 780 782 Tuples/$(DEPDIR)/$(am__dirstamp) 781 783 driver/$(am__dirstamp): … … 800 802 -rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) 801 803 -rm -f ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) 802 -rm -f ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT)803 804 -rm -f ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT) 804 805 -rm -f ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) … … 884 885 -rm -f SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT) 885 886 -rm -f SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT) 887 -rm -f SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT) 886 888 -rm -f SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) 887 889 -rm -f SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) 888 890 -rm -f SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT) 889 -rm -f Tuples/driver_cfa_cpp- NameMatcher.$(OBJEXT)891 -rm -f Tuples/driver_cfa_cpp-Explode.$(OBJEXT) 890 892 -rm -f Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) 893 -rm -f Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT) 891 894 892 895 distclean-compile: … … 907 910 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@ 908 911 @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@910 912 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po@am__quote@ 911 913 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@ … … 991 993 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po@am__quote@ 992 994 @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@ 993 996 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@ 994 997 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@ 995 998 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@ 996 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp- NameMatcher.Po@am__quote@999 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po@am__quote@ 997 1000 @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@ 998 1002 999 1003 .cc.o: … … 1237 1241 @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` 1238 1242 1239 ControlStruct/driver_cfa_cpp-LabelTypeChecker.o: ControlStruct/LabelTypeChecker.cc1240 @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.cc1241 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po1242 @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.cc1245 1246 ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj: ControlStruct/LabelTypeChecker.cc1247 @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.Po1249 @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 1253 1243 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc 1254 1244 @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 … … 2427 2417 @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` 2428 2418 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 2429 2433 Tuples/driver_cfa_cpp-TupleAssignment.o: Tuples/TupleAssignment.cc 2430 2434 @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 … … 2441 2445 @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` 2442 2446 2443 Tuples/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 2450 Tuples/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` 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` 2456 2474 2457 2475 .ll.cc: -
src/Parser/ExpressionNode.cc
r3a2128f r1f44196 172 172 } // build_constantStr 173 173 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 174 217 NameExpr * build_varref( const string *name, bool labelp ) { 175 218 NameExpr *expr = new NameExpr( *name, nullptr ); … … 198 241 } 199 242 200 Expression *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 206 Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ) { 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 ) { 207 249 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 208 250 deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) ); 209 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref ); 210 delete member; 251 UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref ); 211 252 return ret; 212 253 } -
src/Parser/ParseNode.h
r3a2128f r1f44196 155 155 Expression * build_constantChar( const std::string &str ); 156 156 ConstantExpr * 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 ); 157 161 158 162 NameExpr * build_varref( const std::string * name, bool labelp = false ); … … 160 164 161 165 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ); 162 Expression * build_fieldSel( ExpressionNode * expr_node, NameExpr* member );163 Expression * build_pfieldSel( ExpressionNode * expr_node, NameExpr* member );166 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ); 167 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ); 164 168 Expression * build_addressOf( ExpressionNode * expr_node ); 165 169 Expression * build_sizeOfexpr( ExpressionNode * expr_node ); … … 383 387 //############################################################################## 384 388 385 template< typename SynTreeType, typename NodeType >386 void buildList( const NodeType * firstNode, std::list< SynTreeType *> &outputList ) {389 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args > 390 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) { 387 391 SemanticError errors; 388 std::back_insert_iterator< std::list< SynTreeType *> > out( outputList );392 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList ); 389 393 const NodeType * cur = firstNode; 390 394 -
src/Parser/TypeData.cc
r3a2128f r1f44196 385 385 } // TypeData::print 386 386 387 void buildForall( const DeclarationNode * firstNode, list< TypeDecl* > &outputList ) { 387 template< typename ForallList > 388 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { 388 389 buildList( firstNode, outputList ); 389 for ( list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) { 390 if ( (*i)->get_kind() == TypeDecl::Any ) { 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 ) { 391 393 // add assertion parameters to `type' tyvars in reverse order 392 394 // add dtor: void ^?{}(T *) 393 395 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), 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 ) );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 ) ); 396 398 397 399 // add copy ctor: void ?{}(T *, T) 398 400 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), 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 ) );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 ) ); 402 404 403 405 // add default ctor: void ?{}(T *) 404 406 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), 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 ) );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 ) ); 407 409 408 410 // add assignment operator: T * ?=?(T *, T) 409 411 FunctionType * assignType = new FunctionType( Type::Qualifiers(), 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 ) );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 ) ); 414 416 } // if 415 417 } // for … … 515 517 // character types. The implementation shall define char to have the same range, representation, and behavior as 516 518 // either signed char or unsigned char. 517 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; 519 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; 518 520 519 521 if ( td->length != DeclarationNode::NoLength ) { -
src/Parser/parser.cc
r3a2128f r1f44196 1030 1030 static const yytype_uint16 yyrline[] = 1031 1031 { 1032 0, 30 6, 306, 310, 317, 318, 319, 320, 321, 325,1033 32 6, 327, 331, 332, 336, 337, 341, 342, 346, 350,1034 35 1, 362, 364, 366, 367, 369, 374, 375, 381, 383,1035 38 5, 386, 387, 389, 390, 392, 394, 396, 405, 406,1036 41 2, 413, 417, 418, 422, 424, 426, 428, 430, 432,1037 43 4, 439, 441, 443, 447, 449, 453, 456, 458, 460,1038 4 65, 478, 480, 482, 484, 486, 488, 490, 492, 494,1039 496, 498, 505, 506, 512, 513, 514, 515, 519, 520,1040 5 27, 528, 530, 532, 537, 538, 540, 545, 546, 548,1041 55 3, 554, 556, 558, 560, 565, 566, 568, 573, 574,1042 5 79, 580, 585, 586, 591, 592, 597, 598, 603, 604,1043 6 07, 614, 619, 620, 628, 629, 633, 634, 635, 636,1044 6 37, 638, 639, 640, 641, 642, 643, 644, 654, 656,1045 66 1, 662, 667, 668, 674, 675, 681, 682, 683, 684,1046 6 85, 686, 687, 688, 689, 699, 706, 708, 718, 719,1047 7 24, 726, 732, 734, 738, 739, 744, 749, 752, 754,1048 7 56, 766, 768, 779, 780, 782, 786, 788, 792, 793,1049 798, 799, 803, 808, 809, 813, 815, 821, 822, 826,1050 8 28, 830, 832, 838, 839, 843, 845, 850, 852, 854,1051 8 59, 861, 866, 868, 872, 875, 879, 882, 886, 888,1052 89 0, 892, 897, 899, 901, 906, 908, 910, 912, 914,1053 9 19, 921, 923, 925, 930, 942, 943, 948, 950, 955,1054 9 59, 961, 963, 965, 967, 973, 974, 980, 981, 985,1055 9 86, 991, 993, 999, 1000, 1002, 1007, 1012, 1022, 1024,1056 10 28, 1029, 1034, 1036, 1040, 1041, 1045, 1047, 1051, 1052,1057 10 56, 1057, 1061, 1062, 1077, 1078, 1079, 1080, 1081, 1085,1058 109 0, 1097, 1107, 1112, 1117, 1125, 1130, 1135, 1140, 1145,1059 11 75, 1180, 1187, 1189, 1196, 1201, 1206, 1217, 1222, 1227,1060 123 2, 1237, 1246, 1251, 1259, 1260, 1261, 1262, 1268, 1273,1061 128 1, 1282, 1283, 1284, 1288, 1289, 1290, 1291, 1296, 1297,1062 13 06, 1307, 1312, 1313, 1318, 1320, 1322, 1324, 1326, 1329,1063 13 28, 1340, 1341, 1343, 1353, 1354, 1359, 1361, 1363, 1365,1064 13 67, 1370, 1372, 1375, 1380, 1382, 1384, 1386, 1388, 1390,1065 139 2, 1394, 1396, 1398, 1400, 1402, 1404, 1406, 1408, 1414,1066 14 15, 1417, 1419, 1421, 1426, 1427, 1433, 1434, 1436, 1438,1067 144 3, 1445, 1447, 1449, 1454, 1455, 1457, 1459, 1464, 1465,1068 14 67, 1472, 1473, 1475, 1477, 1482, 1484, 1486, 1491, 1492,1069 1 496, 1498, 1504, 1503, 1507, 1509, 1514, 1516, 1522, 1523,1070 15 28, 1529, 1531, 1532, 1541, 1542, 1544, 1546, 1551, 1553,1071 15 59, 1560, 1562, 1565, 1568, 1573, 1574, 1579, 1584, 1588,1072 159 0, 1596, 1595, 1602, 1604, 1610, 1611, 1619, 1620, 1624,1073 16 25, 1626, 1628, 1630, 1637, 1638, 1640, 1642, 1647, 1648,1074 16 54, 1655, 1659, 1660, 1665, 1666, 1667, 1669, 1677, 1678,1075 168 0, 1683, 1685, 1689, 1690, 1691, 1693, 1695, 1699, 1704,1076 171 2, 1713, 1722, 1724, 1729, 1730, 1731, 1735, 1736, 1737,1077 174 1, 1742, 1743, 1747, 1748, 1749, 1754, 1755, 1756, 1757,1078 176 3, 1764, 1766, 1771, 1772, 1777, 1778, 1779, 1780, 1781,1079 1 796, 1797, 1802, 1803, 1809, 1811, 1814, 1816, 1818, 1841,1080 184 2, 1844, 1846, 1851, 1852, 1854, 1859, 1864, 1865, 1871,1081 187 0, 1874, 1878, 1880, 1882, 1888, 1889, 1894, 1899, 1901,1082 19 06, 1908, 1909, 1911, 1916, 1918, 1920, 1925, 1927, 1932,1083 19 37, 1945, 1951, 1950, 1964, 1965, 1970, 1971, 1975, 1980,1084 19 85, 1993, 1998, 2009, 2010, 2015, 2016, 2022, 2023, 2027,1085 20 28, 2029, 2032, 2031, 2042, 2051, 2057, 2063, 2072, 2078,1086 20 84, 2090, 2096, 2104, 2110, 2118, 2124, 2133, 2134, 2135,1087 21 39, 2143, 2145, 2150, 2151, 2155, 2156, 2161, 2167, 2168,1088 217 1, 2173, 2174, 2178, 2179, 2180, 2181, 2215, 2217, 2218,1089 222 0, 2225, 2230, 2235, 2237, 2239, 2244, 2246, 2248, 2250,1090 22 55, 2257, 2266, 2268, 2269, 2274, 2276, 2278, 2283, 2285,1091 22 87, 2292, 2294, 2296, 2305, 2306, 2307, 2311, 2313, 2315,1092 232 0, 2322, 2324, 2329, 2331, 2333, 2348, 2350, 2351, 2353,1093 23 58, 2359, 2364, 2366, 2368, 2373, 2375, 2377, 2379, 2384,1094 23 86, 2388, 2398, 2400, 2401, 2403, 2408, 2410, 2412, 2417,1095 24 19, 2421, 2423, 2428, 2430, 2432, 2463, 2465, 2466, 2468,1096 247 3, 2478, 2486, 2488, 2490, 2495, 2497, 2502, 2504, 2518,1097 25 19, 2521, 2526, 2528, 2530, 2532, 2534, 2539, 2540, 2542,1098 25 44, 2549, 2551, 2553, 2559, 2561, 2563, 2567, 2569, 2571,1099 257 3, 2587, 2588, 2590, 2595, 2597, 2599, 2601, 2603, 2608,1100 26 09, 2611, 2613, 2618, 2620, 2622, 2628, 2629, 2631, 2640,1101 264 3, 2645, 2648, 2650, 2652, 2665, 2666, 2668, 2673, 2675,1102 26 77, 2679, 2681, 2686, 2687, 2689, 2691, 2696, 2698, 2706,1103 27 07, 2708, 2713, 2714, 2718, 2720, 2722, 2724, 2726, 2728,1104 27 35, 2737, 2739, 2741, 2743, 2746, 2748, 2750, 2752, 2754,1105 27 59, 2761, 2763, 2768, 2794, 2795, 2797, 2801, 2802, 2806,1106 28 08, 2810, 2812, 2814, 2816, 2823, 2825, 2827, 2829, 2831,1107 283 3, 2838, 2845, 2847, 2865, 2867, 2872, 28731032 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 1108 1108 }; 1109 1109 #endif … … 4928 4928 4929 4929 /* Line 1806 of yacc.c */ 4930 #line 30 6"parser.yy"4930 #line 305 "parser.yy" 4931 4931 { typedefTable.enterScope(); } 4932 4932 break; … … 4935 4935 4936 4936 /* Line 1806 of yacc.c */ 4937 #line 3 10"parser.yy"4937 #line 309 "parser.yy" 4938 4938 { typedefTable.leaveScope(); } 4939 4939 break; … … 4942 4942 4943 4943 /* Line 1806 of yacc.c */ 4944 #line 316 "parser.yy" 4945 { (yyval.en) = new ExpressionNode( build_constantInteger( *(yyvsp[(1) - (1)].tok) ) ); } 4946 break; 4947 4948 case 5: 4949 4950 /* Line 1806 of yacc.c */ 4944 4951 #line 317 "parser.yy" 4945 { (yyval.en) = new ExpressionNode( build_constant Integer( *(yyvsp[(1) - (1)].tok) ) ); }4946 break; 4947 4948 case 5:4952 { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); } 4953 break; 4954 4955 case 6: 4949 4956 4950 4957 /* Line 1806 of yacc.c */ … … 4953 4960 break; 4954 4961 4955 case 6:4962 case 7: 4956 4963 4957 4964 /* Line 1806 of yacc.c */ … … 4960 4967 break; 4961 4968 4962 case 7:4969 case 8: 4963 4970 4964 4971 /* Line 1806 of yacc.c */ 4965 4972 #line 320 "parser.yy" 4966 { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); }4967 break;4968 4969 case 8:4970 4971 /* Line 1806 of yacc.c */4972 #line 321 "parser.yy"4973 4973 { (yyval.en) = new ExpressionNode( build_constantChar( *(yyvsp[(1) - (1)].tok) ) ); } 4974 4974 break; … … 4977 4977 4978 4978 /* Line 1806 of yacc.c */ 4979 #line 34 6"parser.yy"4979 #line 345 "parser.yy" 4980 4980 { (yyval.constant) = build_constantStr( *(yyvsp[(1) - (1)].str) ); } 4981 4981 break; … … 4984 4984 4985 4985 /* Line 1806 of yacc.c */ 4986 #line 3 50"parser.yy"4986 #line 349 "parser.yy" 4987 4987 { (yyval.str) = (yyvsp[(1) - (1)].tok); } 4988 4988 break; … … 4991 4991 4992 4992 /* Line 1806 of yacc.c */ 4993 #line 35 2"parser.yy"4993 #line 351 "parser.yy" 4994 4994 { 4995 4995 appendStr( (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].tok) ); // append 2nd juxtaposed string to 1st … … 5002 5002 5003 5003 /* Line 1806 of yacc.c */ 5004 #line 36 3"parser.yy"5004 #line 362 "parser.yy" 5005 5005 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); } 5006 5006 break; … … 5009 5009 5010 5010 /* Line 1806 of yacc.c */ 5011 #line 36 5"parser.yy"5011 #line 364 "parser.yy" 5012 5012 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); } 5013 5013 break; … … 5016 5016 5017 5017 /* Line 1806 of yacc.c */ 5018 #line 36 8"parser.yy"5018 #line 367 "parser.yy" 5019 5019 { (yyval.en) = (yyvsp[(2) - (3)].en); } 5020 5020 break; … … 5023 5023 5024 5024 /* Line 1806 of yacc.c */ 5025 #line 3 70"parser.yy"5025 #line 369 "parser.yy" 5026 5026 { (yyval.en) = new ExpressionNode( build_valexpr( (yyvsp[(2) - (3)].sn) ) ); } 5027 5027 break; … … 5030 5030 5031 5031 /* Line 1806 of yacc.c */ 5032 #line 3 80"parser.yy"5032 #line 379 "parser.yy" 5033 5033 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Index, (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en) ) ); } 5034 5034 break; … … 5037 5037 5038 5038 /* Line 1806 of yacc.c */ 5039 #line 38 2"parser.yy"5039 #line 381 "parser.yy" 5040 5040 { (yyval.en) = new ExpressionNode( build_func( (yyvsp[(1) - (4)].en), (yyvsp[(3) - (4)].en) ) ); } 5041 5041 break; … … 5044 5044 5045 5045 /* Line 1806 of yacc.c */ 5046 #line 38 4"parser.yy"5046 #line 383 "parser.yy" 5047 5047 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); } 5048 5048 break; 5049 5049 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 5050 5064 case 32: 5051 5065 5052 5066 /* Line 1806 of yacc.c */ 5053 #line 38 8"parser.yy"5067 #line 389 "parser.yy" 5054 5068 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); } 5055 5069 break; 5056 5070 5071 case 33: 5072 5073 /* Line 1806 of yacc.c */ 5074 #line 391 "parser.yy" 5075 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); } 5076 break; 5077 5057 5078 case 34: 5058 5079 5059 5080 /* Line 1806 of yacc.c */ 5060 #line 39 1"parser.yy"5081 #line 393 "parser.yy" 5061 5082 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); } 5062 5083 break; … … 5065 5086 5066 5087 /* Line 1806 of yacc.c */ 5067 #line 39 3"parser.yy"5088 #line 395 "parser.yy" 5068 5089 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); } 5069 5090 break; … … 5072 5093 5073 5094 /* Line 1806 of yacc.c */ 5074 #line 39 5"parser.yy"5095 #line 397 "parser.yy" 5075 5096 { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); } 5076 5097 break; … … 5079 5100 5080 5101 /* Line 1806 of yacc.c */ 5081 #line 39 7"parser.yy"5102 #line 399 "parser.yy" 5082 5103 { 5083 5104 Token fn; … … 5090 5111 5091 5112 /* Line 1806 of yacc.c */ 5092 #line 40 7"parser.yy"5113 #line 409 "parser.yy" 5093 5114 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); } 5094 5115 break; … … 5097 5118 5098 5119 /* Line 1806 of yacc.c */ 5099 #line 41 2"parser.yy"5120 #line 414 "parser.yy" 5100 5121 { (yyval.en) = 0; } 5101 5122 break; … … 5104 5125 5105 5126 /* Line 1806 of yacc.c */ 5106 #line 4 18"parser.yy"5127 #line 420 "parser.yy" 5107 5128 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); } 5108 5129 break; 5109 5130 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 5117 5131 case 45: 5118 5132 5119 5133 /* Line 1806 of yacc.c */ 5120 #line 42 5"parser.yy"5121 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(2) - (2)].en), build_varref( (yyvsp[(1) - (2)].tok) ) ) ); }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) ) ) ); } 5122 5136 break; 5123 5137 … … 5125 5139 5126 5140 /* Line 1806 of yacc.c */ 5127 #line 42 7"parser.yy"5128 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(4) - (6)].en), build_varref( (yyvsp[(1) - (6)].tok) ) ) ); }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) ) ) ); } 5129 5143 break; 5130 5144 … … 5132 5146 5133 5147 /* Line 1806 of yacc.c */ 5134 #line 4 29"parser.yy"5135 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[( 3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }5148 #line 430 "parser.yy" 5149 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); } 5136 5150 break; 5137 5151 … … 5139 5153 5140 5154 /* Line 1806 of yacc.c */ 5141 #line 43 1"parser.yy"5142 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[( 5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }5155 #line 432 "parser.yy" 5156 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); } 5143 5157 break; 5144 5158 … … 5146 5160 5147 5161 /* Line 1806 of yacc.c */ 5148 #line 43 3"parser.yy"5149 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[( 3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }5162 #line 434 "parser.yy" 5163 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); } 5150 5164 break; 5151 5165 … … 5153 5167 5154 5168 /* Line 1806 of yacc.c */ 5155 #line 43 5"parser.yy"5156 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[( 5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }5169 #line 436 "parser.yy" 5170 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); } 5157 5171 break; 5158 5172 … … 5160 5174 5161 5175 /* Line 1806 of yacc.c */ 5162 #line 44 0"parser.yy"5163 { (yyval. tok) = (yyvsp[(1) - (2)].tok); }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) ) ); } 5164 5178 break; 5165 5179 … … 5167 5181 5168 5182 /* Line 1806 of yacc.c */ 5169 #line 44 2"parser.yy"5170 { (yyval. tok) = (yyvsp[(1) - (2)].tok); }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) ) ); } 5171 5185 break; 5172 5186 … … 5174 5188 5175 5189 /* Line 1806 of yacc.c */ 5176 #line 444 "parser.yy" 5177 { (yyval.tok) = (yyvsp[(1) - (2)].tok); } 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 } 5178 5209 break; 5179 5210 … … 5181 5212 5182 5213 /* Line 1806 of yacc.c */ 5183 #line 4 57"parser.yy"5214 #line 463 "parser.yy" 5184 5215 { (yyval.en) = (yyvsp[(1) - (1)].en); } 5185 5216 break; … … 5188 5219 5189 5220 /* Line 1806 of yacc.c */ 5190 #line 4 59"parser.yy"5221 #line 465 "parser.yy" 5191 5222 { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); } 5192 5223 break; … … 5195 5226 5196 5227 /* Line 1806 of yacc.c */ 5197 #line 46 1"parser.yy"5228 #line 467 "parser.yy" 5198 5229 { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); } 5199 5230 break; … … 5202 5233 5203 5234 /* Line 1806 of yacc.c */ 5204 #line 4 66"parser.yy"5235 #line 472 "parser.yy" 5205 5236 { 5206 5237 switch ( (yyvsp[(1) - (2)].op) ) { … … 5220 5251 5221 5252 /* Line 1806 of yacc.c */ 5222 #line 4 79"parser.yy"5253 #line 485 "parser.yy" 5223 5254 { (yyval.en) = new ExpressionNode( build_unary_val( (yyvsp[(1) - (2)].op), (yyvsp[(2) - (2)].en) ) ); } 5224 5255 break; … … 5227 5258 5228 5259 /* Line 1806 of yacc.c */ 5229 #line 48 1"parser.yy"5260 #line 487 "parser.yy" 5230 5261 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); } 5231 5262 break; … … 5234 5265 5235 5266 /* Line 1806 of yacc.c */ 5236 #line 48 3"parser.yy"5267 #line 489 "parser.yy" 5237 5268 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Decr, (yyvsp[(2) - (2)].en) ) ); } 5238 5269 break; … … 5241 5272 5242 5273 /* Line 1806 of yacc.c */ 5243 #line 4 85"parser.yy"5274 #line 491 "parser.yy" 5244 5275 { (yyval.en) = new ExpressionNode( build_sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); } 5245 5276 break; … … 5248 5279 5249 5280 /* Line 1806 of yacc.c */ 5250 #line 4 87"parser.yy"5281 #line 493 "parser.yy" 5251 5282 { (yyval.en) = new ExpressionNode( build_sizeOftype( (yyvsp[(3) - (4)].decl) ) ); } 5252 5283 break; … … 5255 5286 5256 5287 /* Line 1806 of yacc.c */ 5257 #line 4 89"parser.yy"5288 #line 495 "parser.yy" 5258 5289 { (yyval.en) = new ExpressionNode( build_alignOfexpr( (yyvsp[(2) - (2)].en) ) ); } 5259 5290 break; … … 5262 5293 5263 5294 /* Line 1806 of yacc.c */ 5264 #line 49 1"parser.yy"5295 #line 497 "parser.yy" 5265 5296 { (yyval.en) = new ExpressionNode( build_alignOftype( (yyvsp[(3) - (4)].decl) ) ); } 5266 5297 break; … … 5269 5300 5270 5301 /* Line 1806 of yacc.c */ 5271 #line 49 3"parser.yy"5302 #line 499 "parser.yy" 5272 5303 { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); } 5273 5304 break; … … 5276 5307 5277 5308 /* Line 1806 of yacc.c */ 5278 #line 495"parser.yy"5309 #line 501 "parser.yy" 5279 5310 { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); } 5280 5311 break; … … 5283 5314 5284 5315 /* Line 1806 of yacc.c */ 5285 #line 497"parser.yy"5316 #line 503 "parser.yy" 5286 5317 { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); } 5287 5318 break; … … 5290 5321 5291 5322 /* Line 1806 of yacc.c */ 5292 #line 499"parser.yy"5323 #line 505 "parser.yy" 5293 5324 { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); } 5294 5325 break; … … 5297 5328 5298 5329 /* Line 1806 of yacc.c */ 5299 #line 5 05"parser.yy"5330 #line 511 "parser.yy" 5300 5331 { (yyval.op) = OperKinds::PointTo; } 5301 5332 break; … … 5304 5335 5305 5336 /* Line 1806 of yacc.c */ 5306 #line 5 06"parser.yy"5337 #line 512 "parser.yy" 5307 5338 { (yyval.op) = OperKinds::AddressOf; } 5308 5339 break; … … 5311 5342 5312 5343 /* Line 1806 of yacc.c */ 5313 #line 51 2"parser.yy"5344 #line 518 "parser.yy" 5314 5345 { (yyval.op) = OperKinds::UnPlus; } 5315 5346 break; … … 5318 5349 5319 5350 /* Line 1806 of yacc.c */ 5320 #line 51 3"parser.yy"5351 #line 519 "parser.yy" 5321 5352 { (yyval.op) = OperKinds::UnMinus; } 5322 5353 break; … … 5325 5356 5326 5357 /* Line 1806 of yacc.c */ 5327 #line 5 14"parser.yy"5358 #line 520 "parser.yy" 5328 5359 { (yyval.op) = OperKinds::Neg; } 5329 5360 break; … … 5332 5363 5333 5364 /* Line 1806 of yacc.c */ 5334 #line 5 15"parser.yy"5365 #line 521 "parser.yy" 5335 5366 { (yyval.op) = OperKinds::BitNeg; } 5336 5367 break; … … 5339 5370 5340 5371 /* Line 1806 of yacc.c */ 5341 #line 52 1"parser.yy"5372 #line 527 "parser.yy" 5342 5373 { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); } 5343 5374 break; … … 5346 5377 5347 5378 /* Line 1806 of yacc.c */ 5348 #line 5 29"parser.yy"5379 #line 535 "parser.yy" 5349 5380 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mul, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5350 5381 break; … … 5353 5384 5354 5385 /* Line 1806 of yacc.c */ 5355 #line 53 1"parser.yy"5386 #line 537 "parser.yy" 5356 5387 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Div, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5357 5388 break; … … 5360 5391 5361 5392 /* Line 1806 of yacc.c */ 5362 #line 53 3"parser.yy"5393 #line 539 "parser.yy" 5363 5394 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5364 5395 break; … … 5367 5398 5368 5399 /* Line 1806 of yacc.c */ 5369 #line 5 39"parser.yy"5400 #line 545 "parser.yy" 5370 5401 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Plus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5371 5402 break; … … 5374 5405 5375 5406 /* Line 1806 of yacc.c */ 5376 #line 54 1"parser.yy"5407 #line 547 "parser.yy" 5377 5408 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5378 5409 break; … … 5381 5412 5382 5413 /* Line 1806 of yacc.c */ 5383 #line 5 47"parser.yy"5414 #line 553 "parser.yy" 5384 5415 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5385 5416 break; … … 5388 5419 5389 5420 /* Line 1806 of yacc.c */ 5390 #line 5 49"parser.yy"5421 #line 555 "parser.yy" 5391 5422 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5392 5423 break; … … 5395 5426 5396 5427 /* Line 1806 of yacc.c */ 5397 #line 5 55"parser.yy"5428 #line 561 "parser.yy" 5398 5429 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5399 5430 break; … … 5402 5433 5403 5434 /* Line 1806 of yacc.c */ 5404 #line 5 57"parser.yy"5435 #line 563 "parser.yy" 5405 5436 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5406 5437 break; … … 5409 5440 5410 5441 /* Line 1806 of yacc.c */ 5411 #line 5 59"parser.yy"5442 #line 565 "parser.yy" 5412 5443 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5413 5444 break; … … 5416 5447 5417 5448 /* Line 1806 of yacc.c */ 5418 #line 56 1"parser.yy"5449 #line 567 "parser.yy" 5419 5450 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5420 5451 break; … … 5423 5454 5424 5455 /* Line 1806 of yacc.c */ 5425 #line 5 67"parser.yy"5456 #line 573 "parser.yy" 5426 5457 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Eq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5427 5458 break; … … 5430 5461 5431 5462 /* Line 1806 of yacc.c */ 5432 #line 5 69"parser.yy"5463 #line 575 "parser.yy" 5433 5464 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5434 5465 break; … … 5437 5468 5438 5469 /* Line 1806 of yacc.c */ 5439 #line 5 75"parser.yy"5470 #line 581 "parser.yy" 5440 5471 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5441 5472 break; … … 5444 5475 5445 5476 /* Line 1806 of yacc.c */ 5446 #line 58 1"parser.yy"5477 #line 587 "parser.yy" 5447 5478 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5448 5479 break; … … 5451 5482 5452 5483 /* Line 1806 of yacc.c */ 5453 #line 5 87"parser.yy"5484 #line 593 "parser.yy" 5454 5485 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5455 5486 break; … … 5458 5489 5459 5490 /* Line 1806 of yacc.c */ 5460 #line 59 3"parser.yy"5491 #line 599 "parser.yy" 5461 5492 { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); } 5462 5493 break; … … 5465 5496 5466 5497 /* Line 1806 of yacc.c */ 5467 #line 599"parser.yy"5498 #line 605 "parser.yy" 5468 5499 { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); } 5469 5500 break; … … 5472 5503 5473 5504 /* Line 1806 of yacc.c */ 5474 #line 6 05"parser.yy"5505 #line 611 "parser.yy" 5475 5506 { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); } 5476 5507 break; … … 5479 5510 5480 5511 /* Line 1806 of yacc.c */ 5481 #line 6 08"parser.yy"5512 #line 614 "parser.yy" 5482 5513 { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (4)].en), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ) ); } 5483 5514 break; … … 5486 5517 5487 5518 /* Line 1806 of yacc.c */ 5488 #line 62 1"parser.yy"5519 #line 627 "parser.yy" 5489 5520 { (yyval.en) = new ExpressionNode( build_binary_ptr( (yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5490 5521 break; … … 5493 5524 5494 5525 /* Line 1806 of yacc.c */ 5495 #line 6 28"parser.yy"5526 #line 634 "parser.yy" 5496 5527 { (yyval.en) = nullptr; } 5497 5528 break; … … 5500 5531 5501 5532 /* Line 1806 of yacc.c */ 5502 #line 63 3"parser.yy"5533 #line 639 "parser.yy" 5503 5534 { (yyval.op) = OperKinds::Assign; } 5504 5535 break; … … 5507 5538 5508 5539 /* Line 1806 of yacc.c */ 5509 #line 6 34"parser.yy"5540 #line 640 "parser.yy" 5510 5541 { (yyval.op) = OperKinds::AtAssn; } 5511 5542 break; … … 5514 5545 5515 5546 /* Line 1806 of yacc.c */ 5516 #line 6 35"parser.yy"5547 #line 641 "parser.yy" 5517 5548 { (yyval.op) = OperKinds::MulAssn; } 5518 5549 break; … … 5521 5552 5522 5553 /* Line 1806 of yacc.c */ 5523 #line 6 36"parser.yy"5554 #line 642 "parser.yy" 5524 5555 { (yyval.op) = OperKinds::DivAssn; } 5525 5556 break; … … 5528 5559 5529 5560 /* Line 1806 of yacc.c */ 5530 #line 6 37"parser.yy"5561 #line 643 "parser.yy" 5531 5562 { (yyval.op) = OperKinds::ModAssn; } 5532 5563 break; … … 5535 5566 5536 5567 /* Line 1806 of yacc.c */ 5537 #line 6 38"parser.yy"5568 #line 644 "parser.yy" 5538 5569 { (yyval.op) = OperKinds::PlusAssn; } 5539 5570 break; … … 5542 5573 5543 5574 /* Line 1806 of yacc.c */ 5544 #line 6 39"parser.yy"5575 #line 645 "parser.yy" 5545 5576 { (yyval.op) = OperKinds::MinusAssn; } 5546 5577 break; … … 5549 5580 5550 5581 /* Line 1806 of yacc.c */ 5551 #line 64 0"parser.yy"5582 #line 646 "parser.yy" 5552 5583 { (yyval.op) = OperKinds::LSAssn; } 5553 5584 break; … … 5556 5587 5557 5588 /* Line 1806 of yacc.c */ 5558 #line 64 1"parser.yy"5589 #line 647 "parser.yy" 5559 5590 { (yyval.op) = OperKinds::RSAssn; } 5560 5591 break; … … 5563 5594 5564 5595 /* Line 1806 of yacc.c */ 5565 #line 64 2"parser.yy"5596 #line 648 "parser.yy" 5566 5597 { (yyval.op) = OperKinds::AndAssn; } 5567 5598 break; … … 5570 5601 5571 5602 /* Line 1806 of yacc.c */ 5572 #line 64 3"parser.yy"5603 #line 649 "parser.yy" 5573 5604 { (yyval.op) = OperKinds::ERAssn; } 5574 5605 break; … … 5577 5608 5578 5609 /* Line 1806 of yacc.c */ 5579 #line 6 44"parser.yy"5610 #line 650 "parser.yy" 5580 5611 { (yyval.op) = OperKinds::OrAssn; } 5581 5612 break; … … 5584 5615 5585 5616 /* Line 1806 of yacc.c */ 5586 #line 6 55"parser.yy"5617 #line 661 "parser.yy" 5587 5618 { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( (yyvsp[(4) - (6)].en) ) ) ); } 5588 5619 break; … … 5591 5622 5592 5623 /* Line 1806 of yacc.c */ 5593 #line 6 57"parser.yy"5624 #line 663 "parser.yy" 5594 5625 { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) ) ) ); } 5595 5626 break; … … 5598 5629 5599 5630 /* Line 1806 of yacc.c */ 5600 #line 66 3"parser.yy"5631 #line 669 "parser.yy" 5601 5632 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); } 5602 5633 break; … … 5605 5636 5606 5637 /* Line 1806 of yacc.c */ 5607 #line 6 69"parser.yy"5638 #line 675 "parser.yy" 5608 5639 { (yyval.en) = new ExpressionNode( build_comma( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5609 5640 break; … … 5612 5643 5613 5644 /* Line 1806 of yacc.c */ 5614 #line 6 74"parser.yy"5645 #line 680 "parser.yy" 5615 5646 { (yyval.en) = 0; } 5616 5647 break; … … 5619 5650 5620 5651 /* Line 1806 of yacc.c */ 5621 #line 68 3"parser.yy"5652 #line 689 "parser.yy" 5622 5653 { (yyval.sn) = (yyvsp[(1) - (1)].sn); } 5623 5654 break; … … 5626 5657 5627 5658 /* Line 1806 of yacc.c */ 5628 #line 69 0"parser.yy"5659 #line 696 "parser.yy" 5629 5660 { 5630 5661 Token fn; … … 5637 5668 5638 5669 /* Line 1806 of yacc.c */ 5639 #line 70 0"parser.yy"5670 #line 706 "parser.yy" 5640 5671 { 5641 5672 (yyval.sn) = (yyvsp[(4) - (4)].sn)->add_label( (yyvsp[(1) - (4)].tok) ); … … 5646 5677 5647 5678 /* Line 1806 of yacc.c */ 5648 #line 7 07"parser.yy"5679 #line 713 "parser.yy" 5649 5680 { (yyval.sn) = new StatementNode( build_compound( (StatementNode *)0 ) ); } 5650 5681 break; … … 5653 5684 5654 5685 /* Line 1806 of yacc.c */ 5655 #line 7 14"parser.yy"5686 #line 720 "parser.yy" 5656 5687 { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); } 5657 5688 break; … … 5660 5691 5661 5692 /* Line 1806 of yacc.c */ 5662 #line 72 0"parser.yy"5693 #line 726 "parser.yy" 5663 5694 { if ( (yyvsp[(1) - (3)].sn) != 0 ) { (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ); (yyval.sn) = (yyvsp[(1) - (3)].sn); } } 5664 5695 break; … … 5667 5698 5668 5699 /* Line 1806 of yacc.c */ 5669 #line 7 25"parser.yy"5700 #line 731 "parser.yy" 5670 5701 { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); } 5671 5702 break; … … 5674 5705 5675 5706 /* Line 1806 of yacc.c */ 5676 #line 7 27"parser.yy"5707 #line 733 "parser.yy" 5677 5708 { // mark all fields in list 5678 5709 for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) … … 5685 5716 5686 5717 /* Line 1806 of yacc.c */ 5687 #line 73 3"parser.yy"5718 #line 739 "parser.yy" 5688 5719 { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); } 5689 5720 break; … … 5692 5723 5693 5724 /* Line 1806 of yacc.c */ 5694 #line 74 0"parser.yy"5725 #line 746 "parser.yy" 5695 5726 { if ( (yyvsp[(1) - (2)].sn) != 0 ) { (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) ); (yyval.sn) = (yyvsp[(1) - (2)].sn); } } 5696 5727 break; … … 5699 5730 5700 5731 /* Line 1806 of yacc.c */ 5701 #line 7 45"parser.yy"5732 #line 751 "parser.yy" 5702 5733 { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); } 5703 5734 break; … … 5706 5737 5707 5738 /* Line 1806 of yacc.c */ 5708 #line 75 1"parser.yy"5739 #line 757 "parser.yy" 5709 5740 { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); } 5710 5741 break; … … 5713 5744 5714 5745 /* Line 1806 of yacc.c */ 5715 #line 75 3"parser.yy"5746 #line 759 "parser.yy" 5716 5747 { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); } 5717 5748 break; … … 5720 5751 5721 5752 /* Line 1806 of yacc.c */ 5722 #line 7 55"parser.yy"5753 #line 761 "parser.yy" 5723 5754 { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5724 5755 break; … … 5727 5758 5728 5759 /* Line 1806 of yacc.c */ 5729 #line 7 57"parser.yy"5760 #line 763 "parser.yy" 5730 5761 { 5731 5762 StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); … … 5742 5773 5743 5774 /* Line 1806 of yacc.c */ 5744 #line 7 67"parser.yy"5775 #line 773 "parser.yy" 5745 5776 { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5746 5777 break; … … 5749 5780 5750 5781 /* Line 1806 of yacc.c */ 5751 #line 7 69"parser.yy"5782 #line 775 "parser.yy" 5752 5783 { 5753 5784 StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); … … 5759 5790 5760 5791 /* Line 1806 of yacc.c */ 5761 #line 7 79"parser.yy"5792 #line 785 "parser.yy" 5762 5793 { (yyval.en) = (yyvsp[(1) - (1)].en); } 5763 5794 break; … … 5766 5797 5767 5798 /* Line 1806 of yacc.c */ 5768 #line 78 1"parser.yy"5799 #line 787 "parser.yy" 5769 5800 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5770 5801 break; … … 5773 5804 5774 5805 /* Line 1806 of yacc.c */ 5775 #line 7 86"parser.yy"5806 #line 792 "parser.yy" 5776 5807 { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); } 5777 5808 break; … … 5780 5811 5781 5812 /* Line 1806 of yacc.c */ 5782 #line 7 88"parser.yy"5813 #line 794 "parser.yy" 5783 5814 { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); } 5784 5815 break; … … 5787 5818 5788 5819 /* Line 1806 of yacc.c */ 5789 #line 79 2"parser.yy"5820 #line 798 "parser.yy" 5790 5821 { (yyval.sn) = (yyvsp[(2) - (3)].sn); } 5791 5822 break; … … 5794 5825 5795 5826 /* Line 1806 of yacc.c */ 5796 #line 79 3"parser.yy"5827 #line 799 "parser.yy" 5797 5828 { (yyval.sn) = new StatementNode( build_default() ); } 5798 5829 break; … … 5801 5832 5802 5833 /* Line 1806 of yacc.c */ 5803 #line 799"parser.yy"5834 #line 805 "parser.yy" 5804 5835 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) )); } 5805 5836 break; … … 5808 5839 5809 5840 /* Line 1806 of yacc.c */ 5810 #line 80 3"parser.yy"5841 #line 809 "parser.yy" 5811 5842 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); } 5812 5843 break; … … 5815 5846 5816 5847 /* Line 1806 of yacc.c */ 5817 #line 8 08"parser.yy"5848 #line 814 "parser.yy" 5818 5849 { (yyval.sn) = 0; } 5819 5850 break; … … 5822 5853 5823 5854 /* Line 1806 of yacc.c */ 5824 #line 8 14"parser.yy"5855 #line 820 "parser.yy" 5825 5856 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); } 5826 5857 break; … … 5829 5860 5830 5861 /* Line 1806 of yacc.c */ 5831 #line 8 16"parser.yy"5862 #line 822 "parser.yy" 5832 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) ) ) ) ) ); } 5833 5864 break; … … 5836 5867 5837 5868 /* Line 1806 of yacc.c */ 5838 #line 82 1"parser.yy"5869 #line 827 "parser.yy" 5839 5870 { (yyval.sn) = 0; } 5840 5871 break; … … 5843 5874 5844 5875 /* Line 1806 of yacc.c */ 5845 #line 8 27"parser.yy"5876 #line 833 "parser.yy" 5846 5877 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); } 5847 5878 break; … … 5850 5881 5851 5882 /* Line 1806 of yacc.c */ 5852 #line 8 29"parser.yy"5883 #line 835 "parser.yy" 5853 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) ) ) ) ); } 5854 5885 break; … … 5857 5888 5858 5889 /* Line 1806 of yacc.c */ 5859 #line 83 1"parser.yy"5890 #line 837 "parser.yy" 5860 5891 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); } 5861 5892 break; … … 5864 5895 5865 5896 /* Line 1806 of yacc.c */ 5866 #line 83 3"parser.yy"5897 #line 839 "parser.yy" 5867 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) ) ) ) ) ) ); } 5868 5899 break; … … 5871 5902 5872 5903 /* Line 1806 of yacc.c */ 5873 #line 8 38"parser.yy"5904 #line 844 "parser.yy" 5874 5905 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); } 5875 5906 break; … … 5878 5909 5879 5910 /* Line 1806 of yacc.c */ 5880 #line 8 44"parser.yy"5911 #line 850 "parser.yy" 5881 5912 { (yyval.sn) = 0; } 5882 5913 break; … … 5885 5916 5886 5917 /* Line 1806 of yacc.c */ 5887 #line 8 46"parser.yy"5918 #line 852 "parser.yy" 5888 5919 { (yyval.sn) = 0; } 5889 5920 break; … … 5892 5923 5893 5924 /* Line 1806 of yacc.c */ 5894 #line 85 1"parser.yy"5925 #line 857 "parser.yy" 5895 5926 { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5896 5927 break; … … 5899 5930 5900 5931 /* Line 1806 of yacc.c */ 5901 #line 85 3"parser.yy"5932 #line 859 "parser.yy" 5902 5933 { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); } 5903 5934 break; … … 5906 5937 5907 5938 /* Line 1806 of yacc.c */ 5908 #line 8 55"parser.yy"5939 #line 861 "parser.yy" 5909 5940 { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); } 5910 5941 break; … … 5913 5944 5914 5945 /* Line 1806 of yacc.c */ 5915 #line 86 0"parser.yy"5946 #line 866 "parser.yy" 5916 5947 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); } 5917 5948 break; … … 5920 5951 5921 5952 /* Line 1806 of yacc.c */ 5922 #line 86 2"parser.yy"5953 #line 868 "parser.yy" 5923 5954 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); } 5924 5955 break; … … 5927 5958 5928 5959 /* Line 1806 of yacc.c */ 5929 #line 8 67"parser.yy"5960 #line 873 "parser.yy" 5930 5961 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); } 5931 5962 break; … … 5934 5965 5935 5966 /* Line 1806 of yacc.c */ 5936 #line 87 1"parser.yy"5967 #line 877 "parser.yy" 5937 5968 { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); } 5938 5969 break; … … 5941 5972 5942 5973 /* Line 1806 of yacc.c */ 5943 #line 8 74"parser.yy"5974 #line 880 "parser.yy" 5944 5975 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); } 5945 5976 break; … … 5948 5979 5949 5980 /* Line 1806 of yacc.c */ 5950 #line 8 78"parser.yy"5981 #line 884 "parser.yy" 5951 5982 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); } 5952 5983 break; … … 5955 5986 5956 5987 /* Line 1806 of yacc.c */ 5957 #line 88 1"parser.yy"5988 #line 887 "parser.yy" 5958 5989 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); } 5959 5990 break; … … 5962 5993 5963 5994 /* Line 1806 of yacc.c */ 5964 #line 8 85"parser.yy"5995 #line 891 "parser.yy" 5965 5996 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); } 5966 5997 break; … … 5969 6000 5970 6001 /* Line 1806 of yacc.c */ 5971 #line 8 87"parser.yy"6002 #line 893 "parser.yy" 5972 6003 { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); } 5973 6004 break; … … 5976 6007 5977 6008 /* Line 1806 of yacc.c */ 5978 #line 8 89"parser.yy"6009 #line 895 "parser.yy" 5979 6010 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); } 5980 6011 break; … … 5983 6014 5984 6015 /* Line 1806 of yacc.c */ 5985 #line 89 1"parser.yy"6016 #line 897 "parser.yy" 5986 6017 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); } 5987 6018 break; … … 5990 6021 5991 6022 /* Line 1806 of yacc.c */ 5992 #line 89 3"parser.yy"6023 #line 899 "parser.yy" 5993 6024 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (5)].en) ) ); } 5994 6025 break; … … 5997 6028 5998 6029 /* Line 1806 of yacc.c */ 5999 #line 898"parser.yy"6030 #line 904 "parser.yy" 6000 6031 { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), (yyvsp[(3) - (3)].sn), 0 ) ); } 6001 6032 break; … … 6004 6035 6005 6036 /* Line 1806 of yacc.c */ 6006 #line 90 0"parser.yy"6037 #line 906 "parser.yy" 6007 6038 { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), 0, (yyvsp[(3) - (3)].sn) ) ); } 6008 6039 break; … … 6011 6042 6012 6043 /* Line 1806 of yacc.c */ 6013 #line 90 2"parser.yy"6044 #line 908 "parser.yy" 6014 6045 { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (4)].sn), (yyvsp[(3) - (4)].sn), (yyvsp[(4) - (4)].sn) ) ); } 6015 6046 break; … … 6018 6049 6019 6050 /* Line 1806 of yacc.c */ 6020 #line 9 09"parser.yy"6051 #line 915 "parser.yy" 6021 6052 { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); } 6022 6053 break; … … 6025 6056 6026 6057 /* Line 1806 of yacc.c */ 6027 #line 91 1"parser.yy"6058 #line 917 "parser.yy" 6028 6059 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); } 6029 6060 break; … … 6032 6063 6033 6064 /* Line 1806 of yacc.c */ 6034 #line 91 3"parser.yy"6065 #line 919 "parser.yy" 6035 6066 { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); } 6036 6067 break; … … 6039 6070 6040 6071 /* Line 1806 of yacc.c */ 6041 #line 9 15"parser.yy"6072 #line 921 "parser.yy" 6042 6073 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); } 6043 6074 break; … … 6046 6077 6047 6078 /* Line 1806 of yacc.c */ 6048 #line 92 0"parser.yy"6079 #line 926 "parser.yy" 6049 6080 { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); } 6050 6081 break; … … 6053 6084 6054 6085 /* Line 1806 of yacc.c */ 6055 #line 92 2"parser.yy"6086 #line 928 "parser.yy" 6056 6087 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); } 6057 6088 break; … … 6060 6091 6061 6092 /* Line 1806 of yacc.c */ 6062 #line 9 24"parser.yy"6093 #line 930 "parser.yy" 6063 6094 { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); } 6064 6095 break; … … 6067 6098 6068 6099 /* Line 1806 of yacc.c */ 6069 #line 9 26"parser.yy"6100 #line 932 "parser.yy" 6070 6101 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); } 6071 6102 break; … … 6074 6105 6075 6106 /* Line 1806 of yacc.c */ 6076 #line 93 1"parser.yy"6107 #line 937 "parser.yy" 6077 6108 { 6078 6109 (yyval.sn) = new StatementNode( build_finally( (yyvsp[(2) - (2)].sn) ) ); … … 6083 6114 6084 6115 /* Line 1806 of yacc.c */ 6085 #line 9 44"parser.yy"6116 #line 950 "parser.yy" 6086 6117 { 6087 6118 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6093 6124 6094 6125 /* Line 1806 of yacc.c */ 6095 #line 9 49"parser.yy"6126 #line 955 "parser.yy" 6096 6127 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 6097 6128 break; … … 6100 6131 6101 6132 /* Line 1806 of yacc.c */ 6102 #line 95 1"parser.yy"6133 #line 957 "parser.yy" 6103 6134 { 6104 6135 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6110 6141 6111 6142 /* Line 1806 of yacc.c */ 6112 #line 96 0"parser.yy"6143 #line 966 "parser.yy" 6113 6144 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ) ); } 6114 6145 break; … … 6117 6148 6118 6149 /* Line 1806 of yacc.c */ 6119 #line 96 2"parser.yy"6150 #line 968 "parser.yy" 6120 6151 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); } 6121 6152 break; … … 6124 6155 6125 6156 /* Line 1806 of yacc.c */ 6126 #line 9 64"parser.yy"6157 #line 970 "parser.yy" 6127 6158 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); } 6128 6159 break; … … 6131 6162 6132 6163 /* Line 1806 of yacc.c */ 6133 #line 9 66"parser.yy"6164 #line 972 "parser.yy" 6134 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) ) ); } 6135 6166 break; … … 6138 6169 6139 6170 /* Line 1806 of yacc.c */ 6140 #line 9 68"parser.yy"6171 #line 974 "parser.yy" 6141 6172 { (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) ) ); } 6142 6173 break; … … 6145 6176 6146 6177 /* Line 1806 of yacc.c */ 6147 #line 97 3"parser.yy"6178 #line 979 "parser.yy" 6148 6179 { (yyval.flag) = false; } 6149 6180 break; … … 6152 6183 6153 6184 /* Line 1806 of yacc.c */ 6154 #line 9 75"parser.yy"6185 #line 981 "parser.yy" 6155 6186 { (yyval.flag) = true; } 6156 6187 break; … … 6159 6190 6160 6191 /* Line 1806 of yacc.c */ 6161 #line 98 0"parser.yy"6192 #line 986 "parser.yy" 6162 6193 { (yyval.en) = 0; } 6163 6194 break; … … 6166 6197 6167 6198 /* Line 1806 of yacc.c */ 6168 #line 9 87"parser.yy"6199 #line 993 "parser.yy" 6169 6200 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); } 6170 6201 break; … … 6173 6204 6174 6205 /* Line 1806 of yacc.c */ 6175 #line 99 2"parser.yy"6206 #line 998 "parser.yy" 6176 6207 { (yyval.en) = new ExpressionNode( build_asmexpr( 0, (yyvsp[(1) - (4)].constant), (yyvsp[(3) - (4)].en) ) ); } 6177 6208 break; … … 6180 6211 6181 6212 /* Line 1806 of yacc.c */ 6182 #line 994"parser.yy"6213 #line 1000 "parser.yy" 6183 6214 { (yyval.en) = new ExpressionNode( build_asmexpr( (yyvsp[(2) - (7)].en), (yyvsp[(4) - (7)].constant), (yyvsp[(6) - (7)].en) ) ); } 6184 6215 break; … … 6187 6218 6188 6219 /* Line 1806 of yacc.c */ 6189 #line 999"parser.yy"6220 #line 1005 "parser.yy" 6190 6221 { (yyval.en) = 0; } 6191 6222 break; … … 6194 6225 6195 6226 /* Line 1806 of yacc.c */ 6196 #line 100 1"parser.yy"6227 #line 1007 "parser.yy" 6197 6228 { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); } 6198 6229 break; … … 6201 6232 6202 6233 /* Line 1806 of yacc.c */ 6203 #line 100 3"parser.yy"6234 #line 1009 "parser.yy" 6204 6235 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( (yyvsp[(3) - (3)].constant) ) ); } 6205 6236 break; … … 6208 6239 6209 6240 /* Line 1806 of yacc.c */ 6210 #line 10 08"parser.yy"6241 #line 1014 "parser.yy" 6211 6242 { 6212 6243 (yyval.label) = new LabelNode(); (yyval.label)->labels.push_back( *(yyvsp[(1) - (1)].tok) ); … … 6218 6249 6219 6250 /* Line 1806 of yacc.c */ 6220 #line 101 3"parser.yy"6251 #line 1019 "parser.yy" 6221 6252 { 6222 6253 (yyval.label) = (yyvsp[(1) - (3)].label); (yyvsp[(1) - (3)].label)->labels.push_back( *(yyvsp[(3) - (3)].tok) ); … … 6228 6259 6229 6260 /* Line 1806 of yacc.c */ 6230 #line 102 3"parser.yy"6261 #line 1029 "parser.yy" 6231 6262 { (yyval.decl) = 0; } 6232 6263 break; … … 6235 6266 6236 6267 /* Line 1806 of yacc.c */ 6237 #line 103 0"parser.yy"6268 #line 1036 "parser.yy" 6238 6269 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); } 6239 6270 break; … … 6242 6273 6243 6274 /* Line 1806 of yacc.c */ 6244 #line 10 35"parser.yy"6275 #line 1041 "parser.yy" 6245 6276 { (yyval.decl) = 0; } 6246 6277 break; … … 6249 6280 6250 6281 /* Line 1806 of yacc.c */ 6251 #line 104 2"parser.yy"6282 #line 1048 "parser.yy" 6252 6283 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); } 6253 6284 break; … … 6256 6287 6257 6288 /* Line 1806 of yacc.c */ 6258 #line 10 56"parser.yy"6289 #line 1062 "parser.yy" 6259 6290 {} 6260 6291 break; … … 6263 6294 6264 6295 /* Line 1806 of yacc.c */ 6265 #line 10 57"parser.yy"6296 #line 1063 "parser.yy" 6266 6297 {} 6267 6298 break; … … 6270 6301 6271 6302 /* Line 1806 of yacc.c */ 6272 #line 10 86"parser.yy"6303 #line 1092 "parser.yy" 6273 6304 { 6274 6305 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6280 6311 6281 6312 /* Line 1806 of yacc.c */ 6282 #line 109 3"parser.yy"6313 #line 1099 "parser.yy" 6283 6314 { 6284 6315 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6290 6321 6291 6322 /* Line 1806 of yacc.c */ 6292 #line 1 098"parser.yy"6323 #line 1104 "parser.yy" 6293 6324 { 6294 6325 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (6)].tok), TypedefTable::ID ); … … 6300 6331 6301 6332 /* Line 1806 of yacc.c */ 6302 #line 11 08"parser.yy"6333 #line 1114 "parser.yy" 6303 6334 { 6304 6335 typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) ); … … 6310 6341 6311 6342 /* Line 1806 of yacc.c */ 6312 #line 111 3"parser.yy"6343 #line 1119 "parser.yy" 6313 6344 { 6314 6345 typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) ); … … 6320 6351 6321 6352 /* Line 1806 of yacc.c */ 6322 #line 11 18"parser.yy"6353 #line 1124 "parser.yy" 6323 6354 { 6324 6355 typedefTable.setNextIdentifier( *(yyvsp[(3) - (4)].tok) ); … … 6330 6361 6331 6362 /* Line 1806 of yacc.c */ 6332 #line 11 26"parser.yy"6363 #line 1132 "parser.yy" 6333 6364 { 6334 6365 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6340 6371 6341 6372 /* Line 1806 of yacc.c */ 6342 #line 113 1"parser.yy"6373 #line 1137 "parser.yy" 6343 6374 { 6344 6375 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6350 6381 6351 6382 /* Line 1806 of yacc.c */ 6352 #line 11 36"parser.yy"6383 #line 1142 "parser.yy" 6353 6384 { 6354 6385 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6360 6391 6361 6392 /* Line 1806 of yacc.c */ 6362 #line 114 1"parser.yy"6393 #line 1147 "parser.yy" 6363 6394 { 6364 6395 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6370 6401 6371 6402 /* Line 1806 of yacc.c */ 6372 #line 11 46"parser.yy"6403 #line 1152 "parser.yy" 6373 6404 { 6374 6405 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::ID ); … … 6380 6411 6381 6412 /* Line 1806 of yacc.c */ 6382 #line 11 77"parser.yy"6413 #line 1183 "parser.yy" 6383 6414 { 6384 6415 (yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true ); … … 6389 6420 6390 6421 /* Line 1806 of yacc.c */ 6391 #line 118 1"parser.yy"6422 #line 1187 "parser.yy" 6392 6423 { 6393 6424 (yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true ); … … 6398 6429 6399 6430 /* Line 1806 of yacc.c */ 6400 #line 11 88"parser.yy"6431 #line 1194 "parser.yy" 6401 6432 { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); } 6402 6433 break; … … 6405 6436 6406 6437 /* Line 1806 of yacc.c */ 6407 #line 119 2"parser.yy"6438 #line 1198 "parser.yy" 6408 6439 { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (9)].decl)->appendList( (yyvsp[(7) - (9)].decl) ) ); } 6409 6440 break; … … 6412 6443 6413 6444 /* Line 1806 of yacc.c */ 6414 #line 1 197"parser.yy"6445 #line 1203 "parser.yy" 6415 6446 { 6416 6447 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6422 6453 6423 6454 /* Line 1806 of yacc.c */ 6424 #line 120 2"parser.yy"6455 #line 1208 "parser.yy" 6425 6456 { 6426 6457 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6432 6463 6433 6464 /* Line 1806 of yacc.c */ 6434 #line 12 07"parser.yy"6465 #line 1213 "parser.yy" 6435 6466 { 6436 6467 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::TD ); … … 6442 6473 6443 6474 /* Line 1806 of yacc.c */ 6444 #line 12 18"parser.yy"6475 #line 1224 "parser.yy" 6445 6476 { 6446 6477 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6452 6483 6453 6484 /* Line 1806 of yacc.c */ 6454 #line 122 3"parser.yy"6485 #line 1229 "parser.yy" 6455 6486 { 6456 6487 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6462 6493 6463 6494 /* Line 1806 of yacc.c */ 6464 #line 12 28"parser.yy"6495 #line 1234 "parser.yy" 6465 6496 { 6466 6497 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6472 6503 6473 6504 /* Line 1806 of yacc.c */ 6474 #line 123 3"parser.yy"6505 #line 1239 "parser.yy" 6475 6506 { 6476 6507 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6482 6513 6483 6514 /* Line 1806 of yacc.c */ 6484 #line 12 38"parser.yy"6515 #line 1244 "parser.yy" 6485 6516 { 6486 6517 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6492 6523 6493 6524 /* Line 1806 of yacc.c */ 6494 #line 12 47"parser.yy"6525 #line 1253 "parser.yy" 6495 6526 { 6496 6527 typedefTable.addToEnclosingScope( *(yyvsp[(2) - (4)].tok), TypedefTable::TD ); … … 6502 6533 6503 6534 /* Line 1806 of yacc.c */ 6504 #line 125 2"parser.yy"6535 #line 1258 "parser.yy" 6505 6536 { 6506 6537 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (7)].tok), TypedefTable::TD ); … … 6512 6543 6513 6544 /* Line 1806 of yacc.c */ 6514 #line 12 69"parser.yy"6545 #line 1275 "parser.yy" 6515 6546 { 6516 6547 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6522 6553 6523 6554 /* Line 1806 of yacc.c */ 6524 #line 12 74"parser.yy"6555 #line 1280 "parser.yy" 6525 6556 { 6526 6557 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6532 6563 6533 6564 /* Line 1806 of yacc.c */ 6534 #line 1 296"parser.yy"6565 #line 1302 "parser.yy" 6535 6566 { (yyval.decl) = 0; } 6536 6567 break; … … 6539 6570 6540 6571 /* Line 1806 of yacc.c */ 6541 #line 13 08"parser.yy"6572 #line 1314 "parser.yy" 6542 6573 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6543 6574 break; … … 6546 6577 6547 6578 /* Line 1806 of yacc.c */ 6548 #line 13 19"parser.yy"6579 #line 1325 "parser.yy" 6549 6580 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); } 6550 6581 break; … … 6553 6584 6554 6585 /* Line 1806 of yacc.c */ 6555 #line 132 1"parser.yy"6586 #line 1327 "parser.yy" 6556 6587 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); } 6557 6588 break; … … 6560 6591 6561 6592 /* Line 1806 of yacc.c */ 6562 #line 132 3"parser.yy"6593 #line 1329 "parser.yy" 6563 6594 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); } 6564 6595 break; … … 6567 6598 6568 6599 /* Line 1806 of yacc.c */ 6569 #line 13 25"parser.yy"6600 #line 1331 "parser.yy" 6570 6601 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); } 6571 6602 break; … … 6574 6605 6575 6606 /* Line 1806 of yacc.c */ 6576 #line 13 27"parser.yy"6607 #line 1333 "parser.yy" 6577 6608 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); } 6578 6609 break; … … 6581 6612 6582 6613 /* Line 1806 of yacc.c */ 6583 #line 13 29"parser.yy"6614 #line 1335 "parser.yy" 6584 6615 { 6585 6616 typedefTable.enterScope(); … … 6590 6621 6591 6622 /* Line 1806 of yacc.c */ 6592 #line 133 3"parser.yy"6623 #line 1339 "parser.yy" 6593 6624 { 6594 6625 typedefTable.leaveScope(); … … 6600 6631 6601 6632 /* Line 1806 of yacc.c */ 6602 #line 134 2"parser.yy"6633 #line 1348 "parser.yy" 6603 6634 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6604 6635 break; … … 6607 6638 6608 6639 /* Line 1806 of yacc.c */ 6609 #line 13 44"parser.yy"6640 #line 1350 "parser.yy" 6610 6641 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6611 6642 break; … … 6614 6645 6615 6646 /* Line 1806 of yacc.c */ 6616 #line 13 55"parser.yy"6647 #line 1361 "parser.yy" 6617 6648 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6618 6649 break; … … 6621 6652 6622 6653 /* Line 1806 of yacc.c */ 6623 #line 136 0"parser.yy"6654 #line 1366 "parser.yy" 6624 6655 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); } 6625 6656 break; … … 6628 6659 6629 6660 /* Line 1806 of yacc.c */ 6630 #line 136 2"parser.yy"6661 #line 1368 "parser.yy" 6631 6662 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); } 6632 6663 break; … … 6635 6666 6636 6667 /* Line 1806 of yacc.c */ 6637 #line 13 64"parser.yy"6668 #line 1370 "parser.yy" 6638 6669 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); } 6639 6670 break; … … 6642 6673 6643 6674 /* Line 1806 of yacc.c */ 6644 #line 13 66"parser.yy"6675 #line 1372 "parser.yy" 6645 6676 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Register ); } 6646 6677 break; … … 6649 6680 6650 6681 /* Line 1806 of yacc.c */ 6651 #line 13 69"parser.yy"6682 #line 1375 "parser.yy" 6652 6683 { (yyval.decl) = new DeclarationNode; (yyval.decl)->isInline = true; } 6653 6684 break; … … 6656 6687 6657 6688 /* Line 1806 of yacc.c */ 6658 #line 137 1"parser.yy"6689 #line 1377 "parser.yy" 6659 6690 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); } 6660 6691 break; … … 6663 6694 6664 6695 /* Line 1806 of yacc.c */ 6665 #line 13 74"parser.yy"6696 #line 1380 "parser.yy" 6666 6697 { (yyval.decl) = new DeclarationNode; (yyval.decl)->isNoreturn = true; } 6667 6698 break; … … 6670 6701 6671 6702 /* Line 1806 of yacc.c */ 6672 #line 13 76"parser.yy"6703 #line 1382 "parser.yy" 6673 6704 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Threadlocal ); } 6674 6705 break; … … 6677 6708 6678 6709 /* Line 1806 of yacc.c */ 6679 #line 138 1"parser.yy"6710 #line 1387 "parser.yy" 6680 6711 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); } 6681 6712 break; … … 6684 6715 6685 6716 /* Line 1806 of yacc.c */ 6686 #line 138 3"parser.yy"6717 #line 1389 "parser.yy" 6687 6718 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); } 6688 6719 break; … … 6691 6722 6692 6723 /* Line 1806 of yacc.c */ 6693 #line 13 85"parser.yy"6724 #line 1391 "parser.yy" 6694 6725 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); } 6695 6726 break; … … 6698 6729 6699 6730 /* Line 1806 of yacc.c */ 6700 #line 13 87"parser.yy"6731 #line 1393 "parser.yy" 6701 6732 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); } 6702 6733 break; … … 6705 6736 6706 6737 /* Line 1806 of yacc.c */ 6707 #line 13 89"parser.yy"6738 #line 1395 "parser.yy" 6708 6739 { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Long ); } 6709 6740 break; … … 6712 6743 6713 6744 /* Line 1806 of yacc.c */ 6714 #line 139 1"parser.yy"6745 #line 1397 "parser.yy" 6715 6746 { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Short ); } 6716 6747 break; … … 6719 6750 6720 6751 /* Line 1806 of yacc.c */ 6721 #line 139 3"parser.yy"6752 #line 1399 "parser.yy" 6722 6753 { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Signed ); } 6723 6754 break; … … 6726 6757 6727 6758 /* Line 1806 of yacc.c */ 6728 #line 1 395"parser.yy"6759 #line 1401 "parser.yy" 6729 6760 { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); } 6730 6761 break; … … 6733 6764 6734 6765 /* Line 1806 of yacc.c */ 6735 #line 1 397"parser.yy"6766 #line 1403 "parser.yy" 6736 6767 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); } 6737 6768 break; … … 6740 6771 6741 6772 /* Line 1806 of yacc.c */ 6742 #line 1 399"parser.yy"6773 #line 1405 "parser.yy" 6743 6774 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 6744 6775 break; … … 6747 6778 6748 6779 /* Line 1806 of yacc.c */ 6749 #line 140 1"parser.yy"6780 #line 1407 "parser.yy" 6750 6781 { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Complex ); } 6751 6782 break; … … 6754 6785 6755 6786 /* Line 1806 of yacc.c */ 6756 #line 140 3"parser.yy"6787 #line 1409 "parser.yy" 6757 6788 { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); } 6758 6789 break; … … 6761 6792 6762 6793 /* Line 1806 of yacc.c */ 6763 #line 14 05"parser.yy"6794 #line 1411 "parser.yy" 6764 6795 { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); } 6765 6796 break; … … 6768 6799 6769 6800 /* Line 1806 of yacc.c */ 6770 #line 14 07"parser.yy"6801 #line 1413 "parser.yy" 6771 6802 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); } 6772 6803 break; … … 6775 6806 6776 6807 /* Line 1806 of yacc.c */ 6777 #line 14 09"parser.yy"6808 #line 1415 "parser.yy" 6778 6809 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); } 6779 6810 break; … … 6782 6813 6783 6814 /* Line 1806 of yacc.c */ 6784 #line 14 16"parser.yy"6815 #line 1422 "parser.yy" 6785 6816 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6786 6817 break; … … 6789 6820 6790 6821 /* Line 1806 of yacc.c */ 6791 #line 14 18"parser.yy"6822 #line 1424 "parser.yy" 6792 6823 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6793 6824 break; … … 6796 6827 6797 6828 /* Line 1806 of yacc.c */ 6798 #line 142 0"parser.yy"6829 #line 1426 "parser.yy" 6799 6830 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6800 6831 break; … … 6803 6834 6804 6835 /* Line 1806 of yacc.c */ 6805 #line 142 2"parser.yy"6836 #line 1428 "parser.yy" 6806 6837 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); } 6807 6838 break; … … 6810 6841 6811 6842 /* Line 1806 of yacc.c */ 6812 #line 14 28"parser.yy"6843 #line 1434 "parser.yy" 6813 6844 { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6814 6845 break; … … 6817 6848 6818 6849 /* Line 1806 of yacc.c */ 6819 #line 14 35"parser.yy"6850 #line 1441 "parser.yy" 6820 6851 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6821 6852 break; … … 6824 6855 6825 6856 /* Line 1806 of yacc.c */ 6826 #line 14 37"parser.yy"6857 #line 1443 "parser.yy" 6827 6858 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6828 6859 break; … … 6831 6862 6832 6863 /* Line 1806 of yacc.c */ 6833 #line 14 39"parser.yy"6864 #line 1445 "parser.yy" 6834 6865 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); } 6835 6866 break; … … 6838 6869 6839 6870 /* Line 1806 of yacc.c */ 6840 #line 14 44"parser.yy"6871 #line 1450 "parser.yy" 6841 6872 { (yyval.decl) = (yyvsp[(3) - (4)].decl); } 6842 6873 break; … … 6845 6876 6846 6877 /* Line 1806 of yacc.c */ 6847 #line 14 46"parser.yy"6878 #line 1452 "parser.yy" 6848 6879 { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); } 6849 6880 break; … … 6852 6883 6853 6884 /* Line 1806 of yacc.c */ 6854 #line 14 48"parser.yy"6885 #line 1454 "parser.yy" 6855 6886 { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); } 6856 6887 break; … … 6859 6890 6860 6891 /* Line 1806 of yacc.c */ 6861 #line 145 0"parser.yy"6892 #line 1456 "parser.yy" 6862 6893 { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); } 6863 6894 break; … … 6866 6897 6867 6898 /* Line 1806 of yacc.c */ 6868 #line 14 56"parser.yy"6899 #line 1462 "parser.yy" 6869 6900 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6870 6901 break; … … 6873 6904 6874 6905 /* Line 1806 of yacc.c */ 6875 #line 14 58"parser.yy"6906 #line 1464 "parser.yy" 6876 6907 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6877 6908 break; … … 6880 6911 6881 6912 /* Line 1806 of yacc.c */ 6882 #line 146 0"parser.yy"6913 #line 1466 "parser.yy" 6883 6914 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6884 6915 break; … … 6887 6918 6888 6919 /* Line 1806 of yacc.c */ 6889 #line 14 66"parser.yy"6920 #line 1472 "parser.yy" 6890 6921 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6891 6922 break; … … 6894 6925 6895 6926 /* Line 1806 of yacc.c */ 6896 #line 14 68"parser.yy"6927 #line 1474 "parser.yy" 6897 6928 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6898 6929 break; … … 6901 6932 6902 6933 /* Line 1806 of yacc.c */ 6903 #line 14 74"parser.yy"6934 #line 1480 "parser.yy" 6904 6935 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6905 6936 break; … … 6908 6939 6909 6940 /* Line 1806 of yacc.c */ 6910 #line 14 76"parser.yy"6941 #line 1482 "parser.yy" 6911 6942 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6912 6943 break; … … 6915 6946 6916 6947 /* Line 1806 of yacc.c */ 6917 #line 14 78"parser.yy"6948 #line 1484 "parser.yy" 6918 6949 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6919 6950 break; … … 6922 6953 6923 6954 /* Line 1806 of yacc.c */ 6924 #line 148 3"parser.yy"6955 #line 1489 "parser.yy" 6925 6956 { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); } 6926 6957 break; … … 6929 6960 6930 6961 /* Line 1806 of yacc.c */ 6931 #line 14 85"parser.yy"6962 #line 1491 "parser.yy" 6932 6963 { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6933 6964 break; … … 6936 6967 6937 6968 /* Line 1806 of yacc.c */ 6938 #line 14 87"parser.yy"6969 #line 1493 "parser.yy" 6939 6970 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6940 6971 break; … … 6943 6974 6944 6975 /* Line 1806 of yacc.c */ 6945 #line 1 497"parser.yy"6976 #line 1503 "parser.yy" 6946 6977 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (4)].aggKey), nullptr, nullptr, (yyvsp[(3) - (4)].decl), true ); } 6947 6978 break; … … 6950 6981 6951 6982 /* Line 1806 of yacc.c */ 6952 #line 1 499"parser.yy"6983 #line 1505 "parser.yy" 6953 6984 { 6954 6985 typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); … … 6960 6991 6961 6992 /* Line 1806 of yacc.c */ 6962 #line 15 04"parser.yy"6993 #line 1510 "parser.yy" 6963 6994 { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); } 6964 6995 break; … … 6967 6998 6968 6999 /* Line 1806 of yacc.c */ 6969 #line 15 06"parser.yy"7000 #line 1512 "parser.yy" 6970 7001 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), nullptr, (yyvsp[(5) - (6)].decl), true ); } 6971 7002 break; … … 6974 7005 6975 7006 /* Line 1806 of yacc.c */ 6976 #line 15 08"parser.yy"7007 #line 1514 "parser.yy" 6977 7008 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), nullptr, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); } 6978 7009 break; … … 6981 7012 6982 7013 /* Line 1806 of yacc.c */ 6983 #line 151 0"parser.yy"7014 #line 1516 "parser.yy" 6984 7015 { (yyval.decl) = (yyvsp[(2) - (2)].decl); } 6985 7016 break; … … 6988 7019 6989 7020 /* Line 1806 of yacc.c */ 6990 #line 15 15"parser.yy"7021 #line 1521 "parser.yy" 6991 7022 { (yyval.aggKey) = DeclarationNode::Struct; } 6992 7023 break; … … 6995 7026 6996 7027 /* Line 1806 of yacc.c */ 6997 #line 15 17"parser.yy"7028 #line 1523 "parser.yy" 6998 7029 { (yyval.aggKey) = DeclarationNode::Union; } 6999 7030 break; … … 7002 7033 7003 7034 /* Line 1806 of yacc.c */ 7004 #line 152 2"parser.yy"7035 #line 1528 "parser.yy" 7005 7036 { (yyval.decl) = 0; } 7006 7037 break; … … 7009 7040 7010 7041 /* Line 1806 of yacc.c */ 7011 #line 15 24"parser.yy"7042 #line 1530 "parser.yy" 7012 7043 { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); } 7013 7044 break; … … 7016 7047 7017 7048 /* Line 1806 of yacc.c */ 7018 #line 153 0"parser.yy"7049 #line 1536 "parser.yy" 7019 7050 { (yyval.decl) = (yyvsp[(2) - (3)].decl)->set_extension( true ); } 7020 7051 break; … … 7023 7054 7024 7055 /* Line 1806 of yacc.c */ 7025 #line 153 3"parser.yy"7056 #line 1539 "parser.yy" 7026 7057 { // mark all fields in list 7027 7058 for ( DeclarationNode *iter = (yyvsp[(2) - (3)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) … … 7034 7065 7035 7066 /* Line 1806 of yacc.c */ 7036 #line 154 3"parser.yy"7067 #line 1549 "parser.yy" 7037 7068 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addName( (yyvsp[(2) - (2)].tok) ); } 7038 7069 break; … … 7041 7072 7042 7073 /* Line 1806 of yacc.c */ 7043 #line 15 45"parser.yy"7074 #line 1551 "parser.yy" 7044 7075 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(1) - (3)].decl)->cloneType( (yyvsp[(3) - (3)].tok) ) ); } 7045 7076 break; … … 7048 7079 7049 7080 /* Line 1806 of yacc.c */ 7050 #line 15 47"parser.yy"7081 #line 1553 "parser.yy" 7051 7082 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(1) - (2)].decl)->cloneType( 0 ) ); } 7052 7083 break; … … 7055 7086 7056 7087 /* Line 1806 of yacc.c */ 7057 #line 155 2"parser.yy"7088 #line 1558 "parser.yy" 7058 7089 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7059 7090 break; … … 7062 7093 7063 7094 /* Line 1806 of yacc.c */ 7064 #line 15 54"parser.yy"7095 #line 1560 "parser.yy" 7065 7096 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(1) - (4)].decl)->cloneBaseType( (yyvsp[(4) - (4)].decl) ) ); } 7066 7097 break; … … 7069 7100 7070 7101 /* Line 1806 of yacc.c */ 7071 #line 15 59"parser.yy"7102 #line 1565 "parser.yy" 7072 7103 { (yyval.decl) = DeclarationNode::newName( 0 ); /* XXX */ } 7073 7104 break; … … 7076 7107 7077 7108 /* Line 1806 of yacc.c */ 7078 #line 156 1"parser.yy"7109 #line 1567 "parser.yy" 7079 7110 { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); } 7080 7111 break; … … 7083 7114 7084 7115 /* Line 1806 of yacc.c */ 7085 #line 15 64"parser.yy"7116 #line 1570 "parser.yy" 7086 7117 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); } 7087 7118 break; … … 7090 7121 7091 7122 /* Line 1806 of yacc.c */ 7092 #line 15 67"parser.yy"7123 #line 1573 "parser.yy" 7093 7124 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); } 7094 7125 break; … … 7097 7128 7098 7129 /* Line 1806 of yacc.c */ 7099 #line 157 3"parser.yy"7130 #line 1579 "parser.yy" 7100 7131 { (yyval.en) = 0; } 7101 7132 break; … … 7104 7135 7105 7136 /* Line 1806 of yacc.c */ 7106 #line 15 75"parser.yy"7137 #line 1581 "parser.yy" 7107 7138 { (yyval.en) = (yyvsp[(1) - (1)].en); } 7108 7139 break; … … 7111 7142 7112 7143 /* Line 1806 of yacc.c */ 7113 #line 158 0"parser.yy"7144 #line 1586 "parser.yy" 7114 7145 { (yyval.en) = (yyvsp[(2) - (2)].en); } 7115 7146 break; … … 7118 7149 7119 7150 /* Line 1806 of yacc.c */ 7120 #line 15 89"parser.yy"7151 #line 1595 "parser.yy" 7121 7152 { (yyval.decl) = DeclarationNode::newEnum( nullptr, (yyvsp[(3) - (5)].decl) ); } 7122 7153 break; … … 7125 7156 7126 7157 /* Line 1806 of yacc.c */ 7127 #line 159 1"parser.yy"7158 #line 1597 "parser.yy" 7128 7159 { 7129 7160 typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); … … 7135 7166 7136 7167 /* Line 1806 of yacc.c */ 7137 #line 1 596"parser.yy"7168 #line 1602 "parser.yy" 7138 7169 { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); } 7139 7170 break; … … 7142 7173 7143 7174 /* Line 1806 of yacc.c */ 7144 #line 1 598"parser.yy"7175 #line 1604 "parser.yy" 7145 7176 { (yyval.decl) = DeclarationNode::newEnum( (yyvsp[(2) - (7)].tok), (yyvsp[(5) - (7)].decl) ); } 7146 7177 break; … … 7149 7180 7150 7181 /* Line 1806 of yacc.c */ 7151 #line 160 3"parser.yy"7182 #line 1609 "parser.yy" 7152 7183 { (yyval.decl) = DeclarationNode::newEnumConstant( (yyvsp[(1) - (2)].tok), (yyvsp[(2) - (2)].en) ); } 7153 7184 break; … … 7156 7187 7157 7188 /* Line 1806 of yacc.c */ 7158 #line 16 05"parser.yy"7189 #line 1611 "parser.yy" 7159 7190 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( DeclarationNode::newEnumConstant( (yyvsp[(3) - (4)].tok), (yyvsp[(4) - (4)].en) ) ); } 7160 7191 break; … … 7163 7194 7164 7195 /* Line 1806 of yacc.c */ 7165 #line 161 0"parser.yy"7196 #line 1616 "parser.yy" 7166 7197 { (yyval.en) = 0; } 7167 7198 break; … … 7170 7201 7171 7202 /* Line 1806 of yacc.c */ 7172 #line 161 2"parser.yy"7203 #line 1618 "parser.yy" 7173 7204 { (yyval.en) = (yyvsp[(2) - (2)].en); } 7174 7205 break; … … 7177 7208 7178 7209 /* Line 1806 of yacc.c */ 7179 #line 16 19"parser.yy"7210 #line 1625 "parser.yy" 7180 7211 { (yyval.decl) = 0; } 7181 7212 break; … … 7184 7215 7185 7216 /* Line 1806 of yacc.c */ 7186 #line 16 27"parser.yy"7217 #line 1633 "parser.yy" 7187 7218 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7188 7219 break; … … 7191 7222 7192 7223 /* Line 1806 of yacc.c */ 7193 #line 16 29"parser.yy"7224 #line 1635 "parser.yy" 7194 7225 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); } 7195 7226 break; … … 7198 7229 7199 7230 /* Line 1806 of yacc.c */ 7200 #line 163 1"parser.yy"7231 #line 1637 "parser.yy" 7201 7232 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); } 7202 7233 break; … … 7205 7236 7206 7237 /* Line 1806 of yacc.c */ 7207 #line 16 39"parser.yy"7238 #line 1645 "parser.yy" 7208 7239 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7209 7240 break; … … 7212 7243 7213 7244 /* Line 1806 of yacc.c */ 7214 #line 164 1"parser.yy"7245 #line 1647 "parser.yy" 7215 7246 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7216 7247 break; … … 7219 7250 7220 7251 /* Line 1806 of yacc.c */ 7221 #line 164 3"parser.yy"7252 #line 1649 "parser.yy" 7222 7253 { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); } 7223 7254 break; … … 7226 7257 7227 7258 /* Line 1806 of yacc.c */ 7228 #line 16 49"parser.yy"7259 #line 1655 "parser.yy" 7229 7260 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7230 7261 break; … … 7233 7264 7234 7265 /* Line 1806 of yacc.c */ 7235 #line 16 54"parser.yy"7266 #line 1660 "parser.yy" 7236 7267 { (yyval.decl) = 0; } 7237 7268 break; … … 7240 7271 7241 7272 /* Line 1806 of yacc.c */ 7242 #line 166 1"parser.yy"7273 #line 1667 "parser.yy" 7243 7274 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); } 7244 7275 break; … … 7247 7278 7248 7279 /* Line 1806 of yacc.c */ 7249 #line 16 68"parser.yy"7280 #line 1674 "parser.yy" 7250 7281 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7251 7282 break; … … 7254 7285 7255 7286 /* Line 1806 of yacc.c */ 7256 #line 167 0"parser.yy"7287 #line 1676 "parser.yy" 7257 7288 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7258 7289 break; … … 7261 7292 7262 7293 /* Line 1806 of yacc.c */ 7263 #line 16 79"parser.yy"7294 #line 1685 "parser.yy" 7264 7295 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); } 7265 7296 break; … … 7268 7299 7269 7300 /* Line 1806 of yacc.c */ 7270 #line 168 2"parser.yy"7301 #line 1688 "parser.yy" 7271 7302 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); } 7272 7303 break; … … 7275 7306 7276 7307 /* Line 1806 of yacc.c */ 7277 #line 16 84"parser.yy"7308 #line 1690 "parser.yy" 7278 7309 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addName( (yyvsp[(3) - (4)].tok) )->addQualifiers( (yyvsp[(1) - (4)].decl) ); } 7279 7310 break; … … 7282 7313 7283 7314 /* Line 1806 of yacc.c */ 7284 #line 1 694"parser.yy"7315 #line 1700 "parser.yy" 7285 7316 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7286 7317 break; … … 7289 7320 7290 7321 /* Line 1806 of yacc.c */ 7291 #line 170 0"parser.yy"7322 #line 1706 "parser.yy" 7292 7323 { 7293 7324 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7299 7330 7300 7331 /* Line 1806 of yacc.c */ 7301 #line 17 05"parser.yy"7332 #line 1711 "parser.yy" 7302 7333 { 7303 7334 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7309 7340 7310 7341 /* Line 1806 of yacc.c */ 7311 #line 17 14"parser.yy"7342 #line 1720 "parser.yy" 7312 7343 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7313 7344 break; … … 7316 7347 7317 7348 /* Line 1806 of yacc.c */ 7318 #line 172 3"parser.yy"7349 #line 1729 "parser.yy" 7319 7350 { (yyval.decl) = DeclarationNode::newName( (yyvsp[(1) - (1)].tok) ); } 7320 7351 break; … … 7323 7354 7324 7355 /* Line 1806 of yacc.c */ 7325 #line 17 25"parser.yy"7356 #line 1731 "parser.yy" 7326 7357 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( DeclarationNode::newName( (yyvsp[(3) - (3)].tok) ) ); } 7327 7358 break; … … 7330 7361 7331 7362 /* Line 1806 of yacc.c */ 7332 #line 175 0"parser.yy"7363 #line 1756 "parser.yy" 7333 7364 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7334 7365 break; … … 7337 7368 7338 7369 /* Line 1806 of yacc.c */ 7339 #line 17 58"parser.yy"7370 #line 1764 "parser.yy" 7340 7371 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7341 7372 break; … … 7344 7375 7345 7376 /* Line 1806 of yacc.c */ 7346 #line 176 3"parser.yy"7377 #line 1769 "parser.yy" 7347 7378 { (yyval.in) = 0; } 7348 7379 break; … … 7351 7382 7352 7383 /* Line 1806 of yacc.c */ 7353 #line 17 65"parser.yy"7384 #line 1771 "parser.yy" 7354 7385 { (yyval.in) = (yyvsp[(2) - (2)].in); } 7355 7386 break; … … 7358 7389 7359 7390 /* Line 1806 of yacc.c */ 7360 #line 17 67"parser.yy"7391 #line 1773 "parser.yy" 7361 7392 { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); } 7362 7393 break; … … 7365 7396 7366 7397 /* Line 1806 of yacc.c */ 7367 #line 177 1"parser.yy"7398 #line 1777 "parser.yy" 7368 7399 { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); } 7369 7400 break; … … 7372 7403 7373 7404 /* Line 1806 of yacc.c */ 7374 #line 177 2"parser.yy"7405 #line 1778 "parser.yy" 7375 7406 { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); } 7376 7407 break; … … 7379 7410 7380 7411 /* Line 1806 of yacc.c */ 7381 #line 17 77"parser.yy"7412 #line 1783 "parser.yy" 7382 7413 { (yyval.in) = 0; } 7383 7414 break; … … 7386 7417 7387 7418 /* Line 1806 of yacc.c */ 7388 #line 17 79"parser.yy"7419 #line 1785 "parser.yy" 7389 7420 { (yyval.in) = (yyvsp[(2) - (2)].in)->set_designators( (yyvsp[(1) - (2)].en) ); } 7390 7421 break; … … 7393 7424 7394 7425 /* Line 1806 of yacc.c */ 7395 #line 178 0"parser.yy"7426 #line 1786 "parser.yy" 7396 7427 { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (3)].in)->set_last( (yyvsp[(3) - (3)].in) ) ); } 7397 7428 break; … … 7400 7431 7401 7432 /* Line 1806 of yacc.c */ 7402 #line 178 2"parser.yy"7433 #line 1788 "parser.yy" 7403 7434 { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (4)].in)->set_last( (yyvsp[(4) - (4)].in)->set_designators( (yyvsp[(3) - (4)].en) ) ) ); } 7404 7435 break; … … 7407 7438 7408 7439 /* Line 1806 of yacc.c */ 7409 #line 1 798"parser.yy"7440 #line 1804 "parser.yy" 7410 7441 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); } 7411 7442 break; … … 7414 7445 7415 7446 /* Line 1806 of yacc.c */ 7416 #line 18 04"parser.yy"7447 #line 1810 "parser.yy" 7417 7448 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); } 7418 7449 break; … … 7421 7452 7422 7453 /* Line 1806 of yacc.c */ 7423 #line 181 0"parser.yy"7454 #line 1816 "parser.yy" 7424 7455 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(2) - (2)].tok) ) ); } 7425 7456 break; … … 7428 7459 7429 7460 /* Line 1806 of yacc.c */ 7430 #line 181 3"parser.yy"7461 #line 1819 "parser.yy" 7431 7462 { (yyval.en) = (yyvsp[(3) - (5)].en); } 7432 7463 break; … … 7435 7466 7436 7467 /* Line 1806 of yacc.c */ 7437 #line 18 15"parser.yy"7468 #line 1821 "parser.yy" 7438 7469 { (yyval.en) = (yyvsp[(3) - (5)].en); } 7439 7470 break; … … 7442 7473 7443 7474 /* Line 1806 of yacc.c */ 7444 #line 18 17"parser.yy"7475 #line 1823 "parser.yy" 7445 7476 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); } 7446 7477 break; … … 7449 7480 7450 7481 /* Line 1806 of yacc.c */ 7451 #line 18 19"parser.yy"7482 #line 1825 "parser.yy" 7452 7483 { (yyval.en) = (yyvsp[(4) - (6)].en); } 7453 7484 break; … … 7456 7487 7457 7488 /* Line 1806 of yacc.c */ 7458 #line 184 3"parser.yy"7489 #line 1849 "parser.yy" 7459 7490 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7460 7491 break; … … 7463 7494 7464 7495 /* Line 1806 of yacc.c */ 7465 #line 18 45"parser.yy"7496 #line 1851 "parser.yy" 7466 7497 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 7467 7498 break; … … 7470 7501 7471 7502 /* Line 1806 of yacc.c */ 7472 #line 18 47"parser.yy"7503 #line 1853 "parser.yy" 7473 7504 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 7474 7505 break; … … 7477 7508 7478 7509 /* Line 1806 of yacc.c */ 7479 #line 185 3"parser.yy"7510 #line 1859 "parser.yy" 7480 7511 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7481 7512 break; … … 7484 7515 7485 7516 /* Line 1806 of yacc.c */ 7486 #line 18 55"parser.yy"7517 #line 1861 "parser.yy" 7487 7518 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 7488 7519 break; … … 7491 7522 7492 7523 /* Line 1806 of yacc.c */ 7493 #line 186 0"parser.yy"7524 #line 1866 "parser.yy" 7494 7525 { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); } 7495 7526 break; … … 7498 7529 7499 7530 /* Line 1806 of yacc.c */ 7500 #line 18 66"parser.yy"7531 #line 1872 "parser.yy" 7501 7532 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(3) - (4)].decl) ); } 7502 7533 break; … … 7505 7536 7506 7537 /* Line 1806 of yacc.c */ 7507 #line 187 1"parser.yy"7538 #line 1877 "parser.yy" 7508 7539 { typedefTable.addToEnclosingScope( *(yyvsp[(2) - (2)].tok), TypedefTable::TD ); } 7509 7540 break; … … 7512 7543 7513 7544 /* Line 1806 of yacc.c */ 7514 #line 187 3"parser.yy"7545 #line 1879 "parser.yy" 7515 7546 { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); } 7516 7547 break; … … 7519 7550 7520 7551 /* Line 1806 of yacc.c */ 7521 #line 18 79"parser.yy"7552 #line 1885 "parser.yy" 7522 7553 { (yyval.tclass) = DeclarationNode::Otype; } 7523 7554 break; … … 7526 7557 7527 7558 /* Line 1806 of yacc.c */ 7528 #line 188 1"parser.yy"7559 #line 1887 "parser.yy" 7529 7560 { (yyval.tclass) = DeclarationNode::Ftype; } 7530 7561 break; … … 7533 7564 7534 7565 /* Line 1806 of yacc.c */ 7535 #line 188 3"parser.yy"7566 #line 1889 "parser.yy" 7536 7567 { (yyval.tclass) = DeclarationNode::Dtype; } 7537 7568 break; … … 7540 7571 7541 7572 /* Line 1806 of yacc.c */ 7542 #line 18 88"parser.yy"7573 #line 1894 "parser.yy" 7543 7574 { (yyval.decl) = 0; } 7544 7575 break; … … 7547 7578 7548 7579 /* Line 1806 of yacc.c */ 7549 #line 189 0"parser.yy"7580 #line 1896 "parser.yy" 7550 7581 { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); } 7551 7582 break; … … 7554 7585 7555 7586 /* Line 1806 of yacc.c */ 7556 #line 1 895"parser.yy"7587 #line 1901 "parser.yy" 7557 7588 { 7558 7589 typedefTable.openTrait( *(yyvsp[(2) - (5)].tok) ); … … 7564 7595 7565 7596 /* Line 1806 of yacc.c */ 7566 #line 190 0"parser.yy"7597 #line 1906 "parser.yy" 7567 7598 { (yyval.decl) = (yyvsp[(4) - (5)].decl); } 7568 7599 break; … … 7571 7602 7572 7603 /* Line 1806 of yacc.c */ 7573 #line 190 2"parser.yy"7604 #line 1908 "parser.yy" 7574 7605 { (yyval.decl) = 0; } 7575 7606 break; … … 7578 7609 7579 7610 /* Line 1806 of yacc.c */ 7580 #line 19 07"parser.yy"7611 #line 1913 "parser.yy" 7581 7612 { (yyval.en) = new ExpressionNode( build_typevalue( (yyvsp[(1) - (1)].decl) ) ); } 7582 7613 break; … … 7585 7616 7586 7617 /* Line 1806 of yacc.c */ 7587 #line 191 0"parser.yy"7618 #line 1916 "parser.yy" 7588 7619 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( build_typevalue( (yyvsp[(3) - (3)].decl) ) ) ) ); } 7589 7620 break; … … 7592 7623 7593 7624 /* Line 1806 of yacc.c */ 7594 #line 191 2"parser.yy"7625 #line 1918 "parser.yy" 7595 7626 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); } 7596 7627 break; … … 7599 7630 7600 7631 /* Line 1806 of yacc.c */ 7601 #line 19 17"parser.yy"7632 #line 1923 "parser.yy" 7602 7633 { (yyval.decl) = (yyvsp[(2) - (2)].decl); } 7603 7634 break; … … 7606 7637 7607 7638 /* Line 1806 of yacc.c */ 7608 #line 19 19"parser.yy"7639 #line 1925 "parser.yy" 7609 7640 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) ); } 7610 7641 break; … … 7613 7644 7614 7645 /* Line 1806 of yacc.c */ 7615 #line 192 1"parser.yy"7646 #line 1927 "parser.yy" 7616 7647 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl)->copyStorageClasses( (yyvsp[(1) - (3)].decl) ) ); } 7617 7648 break; … … 7620 7651 7621 7652 /* Line 1806 of yacc.c */ 7622 #line 19 26"parser.yy"7653 #line 1932 "parser.yy" 7623 7654 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addAssertions( (yyvsp[(2) - (2)].decl) ); } 7624 7655 break; … … 7627 7658 7628 7659 /* Line 1806 of yacc.c */ 7629 #line 19 28"parser.yy"7660 #line 1934 "parser.yy" 7630 7661 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addAssertions( (yyvsp[(2) - (4)].decl) )->addType( (yyvsp[(4) - (4)].decl) ); } 7631 7662 break; … … 7634 7665 7635 7666 /* Line 1806 of yacc.c */ 7636 #line 193 3"parser.yy"7667 #line 1939 "parser.yy" 7637 7668 { 7638 7669 typedefTable.addToEnclosingScope( *(yyvsp[(1) - (1)].tok), TypedefTable::TD ); … … 7644 7675 7645 7676 /* Line 1806 of yacc.c */ 7646 #line 19 38"parser.yy"7677 #line 1944 "parser.yy" 7647 7678 { 7648 7679 typedefTable.addToEnclosingScope( *(yyvsp[(1) - (6)].tok), TypedefTable::TG ); … … 7654 7685 7655 7686 /* Line 1806 of yacc.c */ 7656 #line 19 46"parser.yy"7687 #line 1952 "parser.yy" 7657 7688 { 7658 7689 typedefTable.addToEnclosingScope( *(yyvsp[(2) - (9)].tok), TypedefTable::ID ); … … 7664 7695 7665 7696 /* Line 1806 of yacc.c */ 7666 #line 195 1"parser.yy"7697 #line 1957 "parser.yy" 7667 7698 { 7668 7699 typedefTable.enterTrait( *(yyvsp[(2) - (8)].tok) ); … … 7674 7705 7675 7706 /* Line 1806 of yacc.c */ 7676 #line 19 56"parser.yy"7707 #line 1962 "parser.yy" 7677 7708 { 7678 7709 typedefTable.leaveTrait(); … … 7685 7716 7686 7717 /* Line 1806 of yacc.c */ 7687 #line 19 66"parser.yy"7718 #line 1972 "parser.yy" 7688 7719 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); } 7689 7720 break; … … 7692 7723 7693 7724 /* Line 1806 of yacc.c */ 7694 #line 19 76"parser.yy"7725 #line 1982 "parser.yy" 7695 7726 { 7696 7727 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7702 7733 7703 7734 /* Line 1806 of yacc.c */ 7704 #line 198 1"parser.yy"7735 #line 1987 "parser.yy" 7705 7736 { 7706 7737 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7712 7743 7713 7744 /* Line 1806 of yacc.c */ 7714 #line 19 86"parser.yy"7745 #line 1992 "parser.yy" 7715 7746 { 7716 7747 typedefTable.addToEnclosingScope2( *(yyvsp[(5) - (5)].tok), TypedefTable::ID ); … … 7722 7753 7723 7754 /* Line 1806 of yacc.c */ 7724 #line 1994"parser.yy"7755 #line 2000 "parser.yy" 7725 7756 { 7726 7757 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7732 7763 7733 7764 /* Line 1806 of yacc.c */ 7734 #line 1999"parser.yy"7765 #line 2005 "parser.yy" 7735 7766 { 7736 7767 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7742 7773 7743 7774 /* Line 1806 of yacc.c */ 7744 #line 20 09"parser.yy"7775 #line 2015 "parser.yy" 7745 7776 {} 7746 7777 break; … … 7749 7780 7750 7781 /* Line 1806 of yacc.c */ 7751 #line 201 1"parser.yy"7782 #line 2017 "parser.yy" 7752 7783 { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl); } 7753 7784 break; … … 7756 7787 7757 7788 /* Line 1806 of yacc.c */ 7758 #line 20 17"parser.yy"7789 #line 2023 "parser.yy" 7759 7790 { (yyval.decl) = (yyvsp[(1) - (3)].decl) != nullptr ? (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ) : (yyvsp[(3) - (3)].decl); } 7760 7791 break; … … 7763 7794 7764 7795 /* Line 1806 of yacc.c */ 7765 #line 202 2"parser.yy"7796 #line 2028 "parser.yy" 7766 7797 { (yyval.decl) = 0; } 7767 7798 break; … … 7770 7801 7771 7802 /* Line 1806 of yacc.c */ 7772 #line 203 0"parser.yy"7803 #line 2036 "parser.yy" 7773 7804 {} 7774 7805 break; … … 7777 7808 7778 7809 /* Line 1806 of yacc.c */ 7779 #line 203 2"parser.yy"7810 #line 2038 "parser.yy" 7780 7811 { 7781 7812 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" … … 7787 7818 7788 7819 /* Line 1806 of yacc.c */ 7789 #line 20 37"parser.yy"7820 #line 2043 "parser.yy" 7790 7821 { 7791 7822 linkage = linkageStack.top(); … … 7798 7829 7799 7830 /* Line 1806 of yacc.c */ 7800 #line 204 3"parser.yy"7831 #line 2049 "parser.yy" 7801 7832 { // mark all fields in list 7802 7833 for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) … … 7809 7840 7810 7841 /* Line 1806 of yacc.c */ 7811 #line 20 58"parser.yy"7842 #line 2064 "parser.yy" 7812 7843 { 7813 7844 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7820 7851 7821 7852 /* Line 1806 of yacc.c */ 7822 #line 20 64"parser.yy"7853 #line 2070 "parser.yy" 7823 7854 { 7824 7855 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7831 7862 7832 7863 /* Line 1806 of yacc.c */ 7833 #line 207 3"parser.yy"7864 #line 2079 "parser.yy" 7834 7865 { 7835 7866 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7842 7873 7843 7874 /* Line 1806 of yacc.c */ 7844 #line 20 79"parser.yy"7875 #line 2085 "parser.yy" 7845 7876 { 7846 7877 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7851 7882 7852 7883 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:7864 7884 7865 7885 /* Line 1806 of yacc.c */ … … 7872 7892 break; 7873 7893 7894 case 541: 7895 7896 /* Line 1806 of yacc.c */ 7897 #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 7874 7905 case 542: 7875 7906 7876 7907 /* Line 1806 of yacc.c */ 7877 #line 2 097"parser.yy"7908 #line 2103 "parser.yy" 7878 7909 { 7879 7910 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7886 7917 7887 7918 /* Line 1806 of yacc.c */ 7888 #line 21 05"parser.yy"7919 #line 2111 "parser.yy" 7889 7920 { 7890 7921 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7897 7928 7898 7929 /* Line 1806 of yacc.c */ 7899 #line 211 1"parser.yy"7930 #line 2117 "parser.yy" 7900 7931 { 7901 7932 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7908 7939 7909 7940 /* Line 1806 of yacc.c */ 7910 #line 21 19"parser.yy"7941 #line 2125 "parser.yy" 7911 7942 { 7912 7943 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7919 7950 7920 7951 /* Line 1806 of yacc.c */ 7921 #line 21 25"parser.yy"7952 #line 2131 "parser.yy" 7922 7953 { 7923 7954 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7930 7961 7931 7962 /* Line 1806 of yacc.c */ 7932 #line 214 0"parser.yy"7963 #line 2146 "parser.yy" 7933 7964 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 7934 7965 break; … … 7937 7968 7938 7969 /* Line 1806 of yacc.c */ 7939 #line 21 45"parser.yy"7970 #line 2151 "parser.yy" 7940 7971 { delete (yyvsp[(3) - (5)].str); } 7941 7972 break; … … 7944 7975 7945 7976 /* Line 1806 of yacc.c */ 7946 #line 215 0"parser.yy"7977 #line 2156 "parser.yy" 7947 7978 { (yyval.decl) = 0; } 7948 7979 break; … … 7951 7982 7952 7983 /* Line 1806 of yacc.c */ 7953 #line 21 57"parser.yy"7984 #line 2163 "parser.yy" 7954 7985 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7955 7986 break; … … 7958 7989 7959 7990 /* Line 1806 of yacc.c */ 7960 #line 216 3"parser.yy"7991 #line 2169 "parser.yy" 7961 7992 { (yyval.decl) = 0; } 7962 7993 break; … … 7965 7996 7966 7997 /* Line 1806 of yacc.c */ 7967 #line 21 74"parser.yy"7998 #line 2180 "parser.yy" 7968 7999 { delete (yyvsp[(3) - (4)].en); } 7969 8000 break; … … 7972 8003 7973 8004 /* Line 1806 of yacc.c */ 7974 #line 21 78"parser.yy"8005 #line 2184 "parser.yy" 7975 8006 { delete (yyvsp[(1) - (1)].tok); } 7976 8007 break; … … 7979 8010 7980 8011 /* Line 1806 of yacc.c */ 7981 #line 21 79"parser.yy"8012 #line 2185 "parser.yy" 7982 8013 { delete (yyvsp[(1) - (1)].decl); } 7983 8014 break; … … 7986 8017 7987 8018 /* Line 1806 of yacc.c */ 7988 #line 218 0"parser.yy"8019 #line 2186 "parser.yy" 7989 8020 { delete (yyvsp[(1) - (1)].decl); } 7990 8021 break; … … 7993 8024 7994 8025 /* Line 1806 of yacc.c */ 7995 #line 218 1"parser.yy"8026 #line 2187 "parser.yy" 7996 8027 { delete (yyvsp[(1) - (1)].decl); } 7997 8028 break; … … 8000 8031 8001 8032 /* Line 1806 of yacc.c */ 8002 #line 22 16"parser.yy"8033 #line 2222 "parser.yy" 8003 8034 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8004 8035 break; … … 8007 8038 8008 8039 /* Line 1806 of yacc.c */ 8009 #line 22 19"parser.yy"8040 #line 2225 "parser.yy" 8010 8041 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8011 8042 break; … … 8014 8045 8015 8046 /* Line 1806 of yacc.c */ 8016 #line 222 1"parser.yy"8047 #line 2227 "parser.yy" 8017 8048 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8018 8049 break; … … 8021 8052 8022 8053 /* Line 1806 of yacc.c */ 8023 #line 22 26"parser.yy"8054 #line 2232 "parser.yy" 8024 8055 { 8025 8056 typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) ); … … 8031 8062 8032 8063 /* Line 1806 of yacc.c */ 8033 #line 223 1"parser.yy"8064 #line 2237 "parser.yy" 8034 8065 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8035 8066 break; … … 8038 8069 8039 8070 /* Line 1806 of yacc.c */ 8040 #line 22 36"parser.yy"8071 #line 2242 "parser.yy" 8041 8072 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8042 8073 break; … … 8045 8076 8046 8077 /* Line 1806 of yacc.c */ 8047 #line 22 38"parser.yy"8078 #line 2244 "parser.yy" 8048 8079 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8049 8080 break; … … 8052 8083 8053 8084 /* Line 1806 of yacc.c */ 8054 #line 224 0"parser.yy"8085 #line 2246 "parser.yy" 8055 8086 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8056 8087 break; … … 8059 8090 8060 8091 /* Line 1806 of yacc.c */ 8061 #line 22 45"parser.yy"8092 #line 2251 "parser.yy" 8062 8093 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8063 8094 break; … … 8066 8097 8067 8098 /* Line 1806 of yacc.c */ 8068 #line 22 47"parser.yy"8099 #line 2253 "parser.yy" 8069 8100 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8070 8101 break; … … 8073 8104 8074 8105 /* Line 1806 of yacc.c */ 8075 #line 22 49"parser.yy"8106 #line 2255 "parser.yy" 8076 8107 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8077 8108 break; … … 8080 8111 8081 8112 /* Line 1806 of yacc.c */ 8082 #line 225 1"parser.yy"8113 #line 2257 "parser.yy" 8083 8114 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8084 8115 break; … … 8087 8118 8088 8119 /* Line 1806 of yacc.c */ 8089 #line 22 56"parser.yy"8120 #line 2262 "parser.yy" 8090 8121 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8091 8122 break; … … 8094 8125 8095 8126 /* Line 1806 of yacc.c */ 8096 #line 22 58"parser.yy"8127 #line 2264 "parser.yy" 8097 8128 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8098 8129 break; … … 8101 8132 8102 8133 /* Line 1806 of yacc.c */ 8103 #line 22 67"parser.yy"8134 #line 2273 "parser.yy" 8104 8135 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8105 8136 break; … … 8108 8139 8109 8140 /* Line 1806 of yacc.c */ 8110 #line 227 0"parser.yy"8141 #line 2276 "parser.yy" 8111 8142 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8112 8143 break; … … 8115 8146 8116 8147 /* Line 1806 of yacc.c */ 8117 #line 22 75"parser.yy"8148 #line 2281 "parser.yy" 8118 8149 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8119 8150 break; … … 8122 8153 8123 8154 /* Line 1806 of yacc.c */ 8124 #line 22 77"parser.yy"8155 #line 2283 "parser.yy" 8125 8156 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8126 8157 break; … … 8129 8160 8130 8161 /* Line 1806 of yacc.c */ 8131 #line 22 79"parser.yy"8162 #line 2285 "parser.yy" 8132 8163 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8133 8164 break; … … 8136 8167 8137 8168 /* Line 1806 of yacc.c */ 8138 #line 22 84"parser.yy"8169 #line 2290 "parser.yy" 8139 8170 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8140 8171 break; … … 8143 8174 8144 8175 /* Line 1806 of yacc.c */ 8145 #line 22 86"parser.yy"8176 #line 2292 "parser.yy" 8146 8177 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8147 8178 break; … … 8150 8181 8151 8182 /* Line 1806 of yacc.c */ 8152 #line 22 88"parser.yy"8183 #line 2294 "parser.yy" 8153 8184 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8154 8185 break; … … 8157 8188 8158 8189 /* Line 1806 of yacc.c */ 8159 #line 229 3"parser.yy"8190 #line 2299 "parser.yy" 8160 8191 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8161 8192 break; … … 8164 8195 8165 8196 /* Line 1806 of yacc.c */ 8166 #line 2 295"parser.yy"8197 #line 2301 "parser.yy" 8167 8198 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8168 8199 break; … … 8171 8202 8172 8203 /* Line 1806 of yacc.c */ 8173 #line 2 297"parser.yy"8204 #line 2303 "parser.yy" 8174 8205 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8175 8206 break; … … 8178 8209 8179 8210 /* Line 1806 of yacc.c */ 8180 #line 231 2"parser.yy"8211 #line 2318 "parser.yy" 8181 8212 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); } 8182 8213 break; … … 8185 8216 8186 8217 /* Line 1806 of yacc.c */ 8187 #line 23 14"parser.yy"8218 #line 2320 "parser.yy" 8188 8219 { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); } 8189 8220 break; … … 8192 8223 8193 8224 /* Line 1806 of yacc.c */ 8194 #line 23 16"parser.yy"8225 #line 2322 "parser.yy" 8195 8226 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8196 8227 break; … … 8199 8230 8200 8231 /* Line 1806 of yacc.c */ 8201 #line 232 1"parser.yy"8232 #line 2327 "parser.yy" 8202 8233 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8203 8234 break; … … 8206 8237 8207 8238 /* Line 1806 of yacc.c */ 8208 #line 232 3"parser.yy"8239 #line 2329 "parser.yy" 8209 8240 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8210 8241 break; … … 8213 8244 8214 8245 /* Line 1806 of yacc.c */ 8215 #line 23 25"parser.yy"8246 #line 2331 "parser.yy" 8216 8247 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8217 8248 break; … … 8220 8251 8221 8252 /* Line 1806 of yacc.c */ 8222 #line 233 0"parser.yy"8253 #line 2336 "parser.yy" 8223 8254 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8224 8255 break; … … 8227 8258 8228 8259 /* Line 1806 of yacc.c */ 8229 #line 233 2"parser.yy"8260 #line 2338 "parser.yy" 8230 8261 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8231 8262 break; … … 8234 8265 8235 8266 /* Line 1806 of yacc.c */ 8236 #line 23 34"parser.yy"8267 #line 2340 "parser.yy" 8237 8268 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8238 8269 break; … … 8241 8272 8242 8273 /* Line 1806 of yacc.c */ 8243 #line 23 49"parser.yy"8274 #line 2355 "parser.yy" 8244 8275 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8245 8276 break; … … 8248 8279 8249 8280 /* Line 1806 of yacc.c */ 8250 #line 235 2"parser.yy"8281 #line 2358 "parser.yy" 8251 8282 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8252 8283 break; … … 8255 8286 8256 8287 /* Line 1806 of yacc.c */ 8257 #line 23 54"parser.yy"8288 #line 2360 "parser.yy" 8258 8289 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8259 8290 break; … … 8262 8293 8263 8294 /* Line 1806 of yacc.c */ 8264 #line 236 0"parser.yy"8295 #line 2366 "parser.yy" 8265 8296 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8266 8297 break; … … 8269 8300 8270 8301 /* Line 1806 of yacc.c */ 8271 #line 23 65"parser.yy"8302 #line 2371 "parser.yy" 8272 8303 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8273 8304 break; … … 8276 8307 8277 8308 /* Line 1806 of yacc.c */ 8278 #line 23 67"parser.yy"8309 #line 2373 "parser.yy" 8279 8310 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8280 8311 break; … … 8283 8314 8284 8315 /* Line 1806 of yacc.c */ 8285 #line 23 69"parser.yy"8316 #line 2375 "parser.yy" 8286 8317 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8287 8318 break; … … 8290 8321 8291 8322 /* Line 1806 of yacc.c */ 8292 #line 23 74"parser.yy"8323 #line 2380 "parser.yy" 8293 8324 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8294 8325 break; … … 8297 8328 8298 8329 /* Line 1806 of yacc.c */ 8299 #line 23 76"parser.yy"8330 #line 2382 "parser.yy" 8300 8331 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8301 8332 break; … … 8304 8335 8305 8336 /* Line 1806 of yacc.c */ 8306 #line 23 78"parser.yy"8337 #line 2384 "parser.yy" 8307 8338 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8308 8339 break; … … 8311 8342 8312 8343 /* Line 1806 of yacc.c */ 8313 #line 238 0"parser.yy"8344 #line 2386 "parser.yy" 8314 8345 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8315 8346 break; … … 8318 8349 8319 8350 /* Line 1806 of yacc.c */ 8320 #line 23 85"parser.yy"8351 #line 2391 "parser.yy" 8321 8352 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8322 8353 break; … … 8325 8356 8326 8357 /* Line 1806 of yacc.c */ 8327 #line 23 87"parser.yy"8358 #line 2393 "parser.yy" 8328 8359 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8329 8360 break; … … 8332 8363 8333 8364 /* Line 1806 of yacc.c */ 8334 #line 23 89"parser.yy"8365 #line 2395 "parser.yy" 8335 8366 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8336 8367 break; … … 8339 8370 8340 8371 /* Line 1806 of yacc.c */ 8341 #line 2 399"parser.yy"8372 #line 2405 "parser.yy" 8342 8373 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8343 8374 break; … … 8346 8377 8347 8378 /* Line 1806 of yacc.c */ 8348 #line 240 2"parser.yy"8379 #line 2408 "parser.yy" 8349 8380 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8350 8381 break; … … 8353 8384 8354 8385 /* Line 1806 of yacc.c */ 8355 #line 24 04"parser.yy"8386 #line 2410 "parser.yy" 8356 8387 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8357 8388 break; … … 8360 8391 8361 8392 /* Line 1806 of yacc.c */ 8362 #line 24 09"parser.yy"8393 #line 2415 "parser.yy" 8363 8394 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8364 8395 break; … … 8367 8398 8368 8399 /* Line 1806 of yacc.c */ 8369 #line 241 1"parser.yy"8400 #line 2417 "parser.yy" 8370 8401 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8371 8402 break; … … 8374 8405 8375 8406 /* Line 1806 of yacc.c */ 8376 #line 241 3"parser.yy"8407 #line 2419 "parser.yy" 8377 8408 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8378 8409 break; … … 8381 8412 8382 8413 /* Line 1806 of yacc.c */ 8383 #line 24 18"parser.yy"8414 #line 2424 "parser.yy" 8384 8415 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8385 8416 break; … … 8388 8419 8389 8420 /* Line 1806 of yacc.c */ 8390 #line 242 0"parser.yy"8421 #line 2426 "parser.yy" 8391 8422 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8392 8423 break; … … 8395 8426 8396 8427 /* Line 1806 of yacc.c */ 8397 #line 242 2"parser.yy"8428 #line 2428 "parser.yy" 8398 8429 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8399 8430 break; … … 8402 8433 8403 8434 /* Line 1806 of yacc.c */ 8404 #line 24 24"parser.yy"8435 #line 2430 "parser.yy" 8405 8436 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8406 8437 break; … … 8409 8440 8410 8441 /* Line 1806 of yacc.c */ 8411 #line 24 29"parser.yy"8442 #line 2435 "parser.yy" 8412 8443 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8413 8444 break; … … 8416 8447 8417 8448 /* Line 1806 of yacc.c */ 8418 #line 243 1"parser.yy"8449 #line 2437 "parser.yy" 8419 8450 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8420 8451 break; … … 8423 8454 8424 8455 /* Line 1806 of yacc.c */ 8425 #line 243 3"parser.yy"8456 #line 2439 "parser.yy" 8426 8457 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8427 8458 break; … … 8430 8461 8431 8462 /* Line 1806 of yacc.c */ 8432 #line 24 64"parser.yy"8463 #line 2470 "parser.yy" 8433 8464 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8434 8465 break; … … 8437 8468 8438 8469 /* Line 1806 of yacc.c */ 8439 #line 24 67"parser.yy"8470 #line 2473 "parser.yy" 8440 8471 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8441 8472 break; … … 8444 8475 8445 8476 /* Line 1806 of yacc.c */ 8446 #line 24 69"parser.yy"8477 #line 2475 "parser.yy" 8447 8478 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8448 8479 break; … … 8451 8482 8452 8483 /* Line 1806 of yacc.c */ 8453 #line 24 74"parser.yy"8484 #line 2480 "parser.yy" 8454 8485 { 8455 8486 typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) ); … … 8461 8492 8462 8493 /* Line 1806 of yacc.c */ 8463 #line 24 79"parser.yy"8494 #line 2485 "parser.yy" 8464 8495 { 8465 8496 typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) ); … … 8471 8502 8472 8503 /* Line 1806 of yacc.c */ 8473 #line 24 87"parser.yy"8504 #line 2493 "parser.yy" 8474 8505 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8475 8506 break; … … 8478 8509 8479 8510 /* Line 1806 of yacc.c */ 8480 #line 24 89"parser.yy"8511 #line 2495 "parser.yy" 8481 8512 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8482 8513 break; … … 8485 8516 8486 8517 /* Line 1806 of yacc.c */ 8487 #line 249 1"parser.yy"8518 #line 2497 "parser.yy" 8488 8519 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8489 8520 break; … … 8492 8523 8493 8524 /* Line 1806 of yacc.c */ 8494 #line 2 496"parser.yy"8525 #line 2502 "parser.yy" 8495 8526 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8496 8527 break; … … 8499 8530 8500 8531 /* Line 1806 of yacc.c */ 8501 #line 2 498"parser.yy"8532 #line 2504 "parser.yy" 8502 8533 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8503 8534 break; … … 8506 8537 8507 8538 /* Line 1806 of yacc.c */ 8508 #line 250 3"parser.yy"8539 #line 2509 "parser.yy" 8509 8540 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8510 8541 break; … … 8513 8544 8514 8545 /* Line 1806 of yacc.c */ 8515 #line 25 05"parser.yy"8546 #line 2511 "parser.yy" 8516 8547 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8517 8548 break; … … 8520 8551 8521 8552 /* Line 1806 of yacc.c */ 8522 #line 252 0"parser.yy"8553 #line 2526 "parser.yy" 8523 8554 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8524 8555 break; … … 8527 8558 8528 8559 /* Line 1806 of yacc.c */ 8529 #line 252 2"parser.yy"8560 #line 2528 "parser.yy" 8530 8561 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8531 8562 break; … … 8534 8565 8535 8566 /* Line 1806 of yacc.c */ 8536 #line 25 27"parser.yy"8567 #line 2533 "parser.yy" 8537 8568 { (yyval.decl) = DeclarationNode::newPointer( 0 ); } 8538 8569 break; … … 8541 8572 8542 8573 /* Line 1806 of yacc.c */ 8543 #line 25 29"parser.yy"8574 #line 2535 "parser.yy" 8544 8575 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); } 8545 8576 break; … … 8548 8579 8549 8580 /* Line 1806 of yacc.c */ 8550 #line 253 1"parser.yy"8581 #line 2537 "parser.yy" 8551 8582 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8552 8583 break; … … 8555 8586 8556 8587 /* Line 1806 of yacc.c */ 8557 #line 253 3"parser.yy"8588 #line 2539 "parser.yy" 8558 8589 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8559 8590 break; … … 8562 8593 8563 8594 /* Line 1806 of yacc.c */ 8564 #line 25 35"parser.yy"8595 #line 2541 "parser.yy" 8565 8596 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8566 8597 break; … … 8569 8600 8570 8601 /* Line 1806 of yacc.c */ 8571 #line 254 1"parser.yy"8602 #line 2547 "parser.yy" 8572 8603 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8573 8604 break; … … 8576 8607 8577 8608 /* Line 1806 of yacc.c */ 8578 #line 254 3"parser.yy"8609 #line 2549 "parser.yy" 8579 8610 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8580 8611 break; … … 8583 8614 8584 8615 /* Line 1806 of yacc.c */ 8585 #line 25 45"parser.yy"8616 #line 2551 "parser.yy" 8586 8617 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8587 8618 break; … … 8590 8621 8591 8622 /* Line 1806 of yacc.c */ 8592 #line 255 0"parser.yy"8623 #line 2556 "parser.yy" 8593 8624 { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); } 8594 8625 break; … … 8597 8628 8598 8629 /* Line 1806 of yacc.c */ 8599 #line 255 2"parser.yy"8630 #line 2558 "parser.yy" 8600 8631 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8601 8632 break; … … 8604 8635 8605 8636 /* Line 1806 of yacc.c */ 8606 #line 25 54"parser.yy"8637 #line 2560 "parser.yy" 8607 8638 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8608 8639 break; … … 8611 8642 8612 8643 /* Line 1806 of yacc.c */ 8613 #line 256 0"parser.yy"8644 #line 2566 "parser.yy" 8614 8645 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); } 8615 8646 break; … … 8618 8649 8619 8650 /* Line 1806 of yacc.c */ 8620 #line 256 2"parser.yy"8651 #line 2568 "parser.yy" 8621 8652 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); } 8622 8653 break; … … 8625 8656 8626 8657 /* Line 1806 of yacc.c */ 8627 #line 25 68"parser.yy"8658 #line 2574 "parser.yy" 8628 8659 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); } 8629 8660 break; … … 8632 8663 8633 8664 /* Line 1806 of yacc.c */ 8634 #line 257 0"parser.yy"8665 #line 2576 "parser.yy" 8635 8666 { (yyval.decl) = DeclarationNode::newVarArray( 0 ); } 8636 8667 break; … … 8639 8670 8640 8671 /* Line 1806 of yacc.c */ 8641 #line 257 2"parser.yy"8672 #line 2578 "parser.yy" 8642 8673 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); } 8643 8674 break; … … 8646 8677 8647 8678 /* Line 1806 of yacc.c */ 8648 #line 25 74"parser.yy"8679 #line 2580 "parser.yy" 8649 8680 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); } 8650 8681 break; … … 8653 8684 8654 8685 /* Line 1806 of yacc.c */ 8655 #line 25 89"parser.yy"8686 #line 2595 "parser.yy" 8656 8687 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8657 8688 break; … … 8660 8691 8661 8692 /* Line 1806 of yacc.c */ 8662 #line 259 1"parser.yy"8693 #line 2597 "parser.yy" 8663 8694 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8664 8695 break; … … 8667 8698 8668 8699 /* Line 1806 of yacc.c */ 8669 #line 2 596"parser.yy"8700 #line 2602 "parser.yy" 8670 8701 { (yyval.decl) = DeclarationNode::newPointer( 0 ); } 8671 8702 break; … … 8674 8705 8675 8706 /* Line 1806 of yacc.c */ 8676 #line 2 598"parser.yy"8707 #line 2604 "parser.yy" 8677 8708 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); } 8678 8709 break; … … 8681 8712 8682 8713 /* Line 1806 of yacc.c */ 8683 #line 260 0"parser.yy"8714 #line 2606 "parser.yy" 8684 8715 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8685 8716 break; … … 8688 8719 8689 8720 /* Line 1806 of yacc.c */ 8690 #line 260 2"parser.yy"8721 #line 2608 "parser.yy" 8691 8722 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8692 8723 break; … … 8695 8726 8696 8727 /* Line 1806 of yacc.c */ 8697 #line 26 04"parser.yy"8728 #line 2610 "parser.yy" 8698 8729 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8699 8730 break; … … 8702 8733 8703 8734 /* Line 1806 of yacc.c */ 8704 #line 261 0"parser.yy"8735 #line 2616 "parser.yy" 8705 8736 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8706 8737 break; … … 8709 8740 8710 8741 /* Line 1806 of yacc.c */ 8711 #line 261 2"parser.yy"8742 #line 2618 "parser.yy" 8712 8743 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8713 8744 break; … … 8716 8747 8717 8748 /* Line 1806 of yacc.c */ 8718 #line 26 14"parser.yy"8749 #line 2620 "parser.yy" 8719 8750 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8720 8751 break; … … 8723 8754 8724 8755 /* Line 1806 of yacc.c */ 8725 #line 26 19"parser.yy"8756 #line 2625 "parser.yy" 8726 8757 { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); } 8727 8758 break; … … 8730 8761 8731 8762 /* Line 1806 of yacc.c */ 8732 #line 262 1"parser.yy"8763 #line 2627 "parser.yy" 8733 8764 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8734 8765 break; … … 8737 8768 8738 8769 /* Line 1806 of yacc.c */ 8739 #line 262 3"parser.yy"8770 #line 2629 "parser.yy" 8740 8771 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8741 8772 break; … … 8744 8775 8745 8776 /* Line 1806 of yacc.c */ 8746 #line 263 0"parser.yy"8777 #line 2636 "parser.yy" 8747 8778 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8748 8779 break; … … 8751 8782 8752 8783 /* Line 1806 of yacc.c */ 8753 #line 264 1"parser.yy"8784 #line 2647 "parser.yy" 8754 8785 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); } 8755 8786 break; … … 8758 8789 8759 8790 /* Line 1806 of yacc.c */ 8760 #line 26 44"parser.yy"8791 #line 2650 "parser.yy" 8761 8792 { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); } 8762 8793 break; … … 8765 8796 8766 8797 /* Line 1806 of yacc.c */ 8767 #line 26 46"parser.yy"8798 #line 2652 "parser.yy" 8768 8799 { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); } 8769 8800 break; … … 8772 8803 8773 8804 /* Line 1806 of yacc.c */ 8774 #line 26 49"parser.yy"8805 #line 2655 "parser.yy" 8775 8806 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); } 8776 8807 break; … … 8779 8810 8780 8811 /* Line 1806 of yacc.c */ 8781 #line 265 1"parser.yy"8812 #line 2657 "parser.yy" 8782 8813 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); } 8783 8814 break; … … 8786 8817 8787 8818 /* Line 1806 of yacc.c */ 8788 #line 265 3"parser.yy"8819 #line 2659 "parser.yy" 8789 8820 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); } 8790 8821 break; … … 8793 8824 8794 8825 /* Line 1806 of yacc.c */ 8795 #line 26 67"parser.yy"8826 #line 2673 "parser.yy" 8796 8827 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8797 8828 break; … … 8800 8831 8801 8832 /* Line 1806 of yacc.c */ 8802 #line 26 69"parser.yy"8833 #line 2675 "parser.yy" 8803 8834 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8804 8835 break; … … 8807 8838 8808 8839 /* Line 1806 of yacc.c */ 8809 #line 26 74"parser.yy"8840 #line 2680 "parser.yy" 8810 8841 { (yyval.decl) = DeclarationNode::newPointer( 0 ); } 8811 8842 break; … … 8814 8845 8815 8846 /* Line 1806 of yacc.c */ 8816 #line 26 76"parser.yy"8847 #line 2682 "parser.yy" 8817 8848 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); } 8818 8849 break; … … 8821 8852 8822 8853 /* Line 1806 of yacc.c */ 8823 #line 26 78"parser.yy"8854 #line 2684 "parser.yy" 8824 8855 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8825 8856 break; … … 8828 8859 8829 8860 /* Line 1806 of yacc.c */ 8830 #line 268 0"parser.yy"8861 #line 2686 "parser.yy" 8831 8862 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8832 8863 break; … … 8835 8866 8836 8867 /* Line 1806 of yacc.c */ 8837 #line 268 2"parser.yy"8868 #line 2688 "parser.yy" 8838 8869 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8839 8870 break; … … 8842 8873 8843 8874 /* Line 1806 of yacc.c */ 8844 #line 26 88"parser.yy"8875 #line 2694 "parser.yy" 8845 8876 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8846 8877 break; … … 8849 8880 8850 8881 /* Line 1806 of yacc.c */ 8851 #line 269 0"parser.yy"8882 #line 2696 "parser.yy" 8852 8883 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8853 8884 break; … … 8856 8887 8857 8888 /* Line 1806 of yacc.c */ 8858 #line 269 2"parser.yy"8889 #line 2698 "parser.yy" 8859 8890 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8860 8891 break; … … 8863 8894 8864 8895 /* Line 1806 of yacc.c */ 8865 #line 2 697"parser.yy"8896 #line 2703 "parser.yy" 8866 8897 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8867 8898 break; … … 8870 8901 8871 8902 /* Line 1806 of yacc.c */ 8872 #line 2 699"parser.yy"8903 #line 2705 "parser.yy" 8873 8904 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8874 8905 break; … … 8877 8908 8878 8909 /* Line 1806 of yacc.c */ 8879 #line 27 09"parser.yy"8910 #line 2715 "parser.yy" 8880 8911 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 8881 8912 break; … … 8884 8915 8885 8916 /* Line 1806 of yacc.c */ 8886 #line 27 19"parser.yy"8917 #line 2725 "parser.yy" 8887 8918 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 8888 8919 break; … … 8891 8922 8892 8923 /* Line 1806 of yacc.c */ 8893 #line 272 1"parser.yy"8924 #line 2727 "parser.yy" 8894 8925 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 8895 8926 break; … … 8898 8929 8899 8930 /* Line 1806 of yacc.c */ 8900 #line 272 3"parser.yy"8931 #line 2729 "parser.yy" 8901 8932 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 8902 8933 break; … … 8905 8936 8906 8937 /* Line 1806 of yacc.c */ 8907 #line 27 25"parser.yy"8938 #line 2731 "parser.yy" 8908 8939 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 8909 8940 break; … … 8912 8943 8913 8944 /* Line 1806 of yacc.c */ 8914 #line 27 27"parser.yy"8945 #line 2733 "parser.yy" 8915 8946 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 8916 8947 break; … … 8919 8950 8920 8951 /* Line 1806 of yacc.c */ 8921 #line 27 29"parser.yy"8952 #line 2735 "parser.yy" 8922 8953 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 8923 8954 break; … … 8926 8957 8927 8958 /* Line 1806 of yacc.c */ 8928 #line 27 36"parser.yy"8959 #line 2742 "parser.yy" 8929 8960 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8930 8961 break; 8931 8962 8932 8963 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 */8949 #line 2742 "parser.yy"8950 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }8951 break;8952 8953 case 724:8954 8964 8955 8965 /* Line 1806 of yacc.c */ … … 8958 8968 break; 8959 8969 8970 case 722: 8971 8972 /* Line 1806 of yacc.c */ 8973 #line 2746 "parser.yy" 8974 { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8975 break; 8976 8977 case 723: 8978 8979 /* Line 1806 of yacc.c */ 8980 #line 2748 "parser.yy" 8981 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); } 8982 break; 8983 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 8960 8991 case 725: 8961 8992 8962 8993 /* Line 1806 of yacc.c */ 8963 #line 27 47"parser.yy"8994 #line 2753 "parser.yy" 8964 8995 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8965 8996 break; 8966 8997 8967 8998 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"8978 { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }8979 break;8980 8981 case 728:8982 8983 /* Line 1806 of yacc.c */8984 #line 2753 "parser.yy"8985 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }8986 break;8987 8988 case 729:8989 8999 8990 9000 /* Line 1806 of yacc.c */ … … 8993 9003 break; 8994 9004 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" 9023 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); } 9024 break; 9025 8995 9026 case 730: 8996 9027 8997 9028 /* Line 1806 of yacc.c */ 8998 #line 276 0"parser.yy"9029 #line 2766 "parser.yy" 8999 9030 { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); } 9000 9031 break; … … 9003 9034 9004 9035 /* Line 1806 of yacc.c */ 9005 #line 276 2"parser.yy"9036 #line 2768 "parser.yy" 9006 9037 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); } 9007 9038 break; … … 9010 9041 9011 9042 /* Line 1806 of yacc.c */ 9012 #line 27 67"parser.yy"9043 #line 2773 "parser.yy" 9013 9044 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); } 9014 9045 break; … … 9017 9048 9018 9049 /* Line 1806 of yacc.c */ 9019 #line 27 69"parser.yy"9050 #line 2775 "parser.yy" 9020 9051 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); } 9021 9052 break; … … 9024 9055 9025 9056 /* Line 1806 of yacc.c */ 9026 #line 2 796"parser.yy"9057 #line 2802 "parser.yy" 9027 9058 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 9028 9059 break; … … 9031 9062 9032 9063 /* Line 1806 of yacc.c */ 9033 #line 28 07"parser.yy"9064 #line 2813 "parser.yy" 9034 9065 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9035 9066 break; … … 9038 9069 9039 9070 /* Line 1806 of yacc.c */ 9040 #line 28 09"parser.yy"9071 #line 2815 "parser.yy" 9041 9072 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9042 9073 break; … … 9045 9076 9046 9077 /* Line 1806 of yacc.c */ 9047 #line 281 1"parser.yy"9078 #line 2817 "parser.yy" 9048 9079 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9049 9080 break; … … 9052 9083 9053 9084 /* Line 1806 of yacc.c */ 9054 #line 281 3"parser.yy"9085 #line 2819 "parser.yy" 9055 9086 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9056 9087 break; … … 9059 9090 9060 9091 /* Line 1806 of yacc.c */ 9061 #line 28 15"parser.yy"9092 #line 2821 "parser.yy" 9062 9093 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9063 9094 break; … … 9066 9097 9067 9098 /* Line 1806 of yacc.c */ 9068 #line 28 17"parser.yy"9099 #line 2823 "parser.yy" 9069 9100 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9070 9101 break; 9071 9102 9072 9103 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"9090 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }9091 break;9092 9093 case 748:9094 9104 9095 9105 /* Line 1806 of yacc.c */ … … 9098 9108 break; 9099 9109 9100 case 74 9:9110 case 746: 9101 9111 9102 9112 /* Line 1806 of yacc.c */ … … 9105 9115 break; 9106 9116 9107 case 7 50:9117 case 747: 9108 9118 9109 9119 /* Line 1806 of yacc.c */ … … 9112 9122 break; 9113 9123 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 9114 9145 case 751: 9115 9146 9116 9147 /* Line 1806 of yacc.c */ 9117 #line 28 39"parser.yy"9148 #line 2845 "parser.yy" 9118 9149 { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); } 9119 9150 break; … … 9122 9153 9123 9154 /* Line 1806 of yacc.c */ 9124 #line 28 46"parser.yy"9155 #line 2852 "parser.yy" 9125 9156 { (yyval.decl) = DeclarationNode::newFunction( nullptr, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), nullptr ); } 9126 9157 break; … … 9129 9160 9130 9161 /* Line 1806 of yacc.c */ 9131 #line 28 48"parser.yy"9162 #line 2854 "parser.yy" 9132 9163 { (yyval.decl) = DeclarationNode::newFunction( nullptr, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), nullptr ); } 9133 9164 break; … … 9136 9167 9137 9168 /* Line 1806 of yacc.c */ 9138 #line 287 2"parser.yy"9169 #line 2878 "parser.yy" 9139 9170 { (yyval.en) = 0; } 9140 9171 break; … … 9143 9174 9144 9175 /* Line 1806 of yacc.c */ 9145 #line 28 74"parser.yy"9176 #line 2880 "parser.yy" 9146 9177 { (yyval.en) = (yyvsp[(2) - (2)].en); } 9147 9178 break; … … 9150 9181 9151 9182 /* Line 1806 of yacc.c */ 9152 #line 91 53"Parser/parser.cc"9183 #line 9184 "Parser/parser.cc" 9153 9184 default: break; 9154 9185 } … … 9381 9412 9382 9413 /* Line 2067 of yacc.c */ 9383 #line 28 77"parser.yy"9414 #line 2883 "parser.yy" 9384 9415 9385 9416 // ----end of grammar---- -
src/Parser/parser.yy
r3a2128f r1f44196 199 199 200 200 %type<decl> field_declaration field_declaration_list field_declarator field_declaring_list 201 %type<en> field field_list 202 %type<tok> field_name 201 %type<en> field field_list field_name fraction_constants 203 202 204 203 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 384 383 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 385 384 | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector 385 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); } 386 386 | postfix_expression REALFRACTIONconstant // CFA, tuple index 387 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_REALFRACTIONconstant( *$2 ) ) ); } 387 388 | postfix_expression ARROW no_attr_identifier 388 389 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 389 390 | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector 391 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); } 390 392 | postfix_expression ICR 391 393 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); } … … 421 423 field: // CFA, tuple field selector 422 424 field_name 423 { $$ = new ExpressionNode( build_varref( $1 ) ); }424 425 | REALDECIMALconstant field 425 { $$ = new ExpressionNode( build_fieldSel( $2, build_varref( $1) ) ); }426 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); } 426 427 | REALDECIMALconstant '[' push field_list pop ']' 427 { $$ = new ExpressionNode( build_fieldSel( $4, build_varref( $1) ) ); }428 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); } 428 429 | field_name '.' field 429 { $$ = new ExpressionNode( build_fieldSel( $ 3, build_varref( $1) ) ); }430 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 430 431 | field_name '.' '[' push field_list pop ']' 431 { $$ = new ExpressionNode( build_fieldSel( $ 5, build_varref( $1) ) ); }432 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); } 432 433 | field_name ARROW field 433 { $$ = new ExpressionNode( build_pfieldSel( $ 3, build_varref( $1) ) ); }434 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 434 435 | field_name ARROW '[' push field_list pop ']' 435 { $$ = new ExpressionNode( build_pfieldSel( $ 5, build_varref( $1) ) ); }436 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); } 436 437 ; 437 438 438 439 field_name: 439 440 INTEGERconstant fraction_constants 440 { $$ = $1; }441 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); } 441 442 | FLOATINGconstant fraction_constants 442 { $$ = $1; }443 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); } 443 444 | no_attr_identifier fraction_constants 444 { $$ = $1; }445 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); } 445 446 ; 446 447 447 448 fraction_constants: 448 449 // empty 450 { $$ = nullptr; } 449 451 | 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 } 450 456 ; 451 457 -
src/ResolvExpr/Alternative.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Alternative.cc -- 7 // Alternative.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 12 12 // Last Modified On : Sat May 16 23:54:23 2015 13 13 // Update Count : 2 14 // 14 // 15 15 16 16 #include "Alternative.h" … … 20 20 21 21 namespace ResolvExpr { 22 Alternative::Alternative() : expr( 0 ) {}22 Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( 0 ) {} 23 23 24 24 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost ) … … 35 35 if ( &other == this ) return *this; 36 36 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; 37 52 return *this; 38 53 } … … 54 69 expr->print( os, indent ); 55 70 os << "(types:" << std::endl; 56 printAll( expr->get_results(), os, indent + 4 ); 57 os << ")" << std::endl; 71 os << std::string( indent+4, ' ' ); 72 expr->get_result()->print( os, indent + 4 ); 73 os << std::endl << ")" << std::endl; 58 74 } else { 59 75 os << "Null expression!" << std::endl; -
src/ResolvExpr/Alternative.h
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Alternative.h -- 7 // Alternative.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 12 12 // Last Modified On : Sat May 16 23:54:39 2015 13 13 // Update Count : 2 14 // 14 // 15 15 16 16 #ifndef ALTERNATIVE_H … … 32 32 Alternative( const Alternative &other ); 33 33 Alternative &operator=( const Alternative &other ); 34 Alternative( Alternative && other ); 35 Alternative &operator=( Alternative && other ); 34 36 ~Alternative(); 35 37 36 38 void initialize( const Alternative &src, Alternative &dest ); 37 39 38 40 void print( std::ostream &os, int indent = 0 ) const; 39 41 40 42 Cost cost; 41 43 Cost cvtCost; -
src/ResolvExpr/AlternativeFinder.cc
r3a2128f r1f44196 38 38 #include "SynTree/TypeSubstitution.h" 39 39 #include "SymTab/Validate.h" 40 #include "Tuples/Tuple Assignment.h"41 #include "Tuples/ NameMatcher.h"40 #include "Tuples/Tuples.h" 41 #include "Tuples/Explode.h" 42 42 #include "Common/utility.h" 43 43 #include "InitTweak/InitTweak.h" 44 #include "InitTweak/GenInit.h" 44 45 #include "ResolveTypeof.h" 45 46 … … 64 65 } 65 66 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 66 75 namespace { 67 76 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) { … … 76 85 out.push_back( i->expr->clone() ); 77 86 } 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;86 87 } 87 88 … … 101 102 PruneStruct current( candidate ); 102 103 std::string mangleName; 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();104 { 105 Type * newType = candidate->expr->get_result()->clone(); 105 106 candidate->env.apply( newType ); 106 mangleName += SymTab::Mangler::mangle( newType );107 mangleName = SymTab::Mangler::mangle( newType ); 107 108 delete newType; 108 109 } … … 133 134 if ( ! target->second.isAmbiguous ) { 134 135 Alternative &alt = *target->second.candidate; 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 } 136 alt.env.applyFree( alt.expr->get_result() ); 138 137 *out++ = alt; 139 138 } 140 139 } 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 cost149 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 }169 140 } 170 141 171 142 void renameTypes( Expression *expr ) { 172 for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 173 (*i)->accept( global_renamer ); 174 } 143 expr->get_result()->accept( global_renamer ); 175 144 } 176 145 } … … 204 173 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) { 205 174 if ( adjust ) { 206 adjustExprType List( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );175 adjustExprType( i->expr->get_result(), i->env, indexer ); 207 176 } 208 177 } … … 240 209 } 241 210 211 // std::unordered_map< Expression *, UniqueExpr * > ; 212 242 213 template< typename StructOrUnionType > 243 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) { 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(); 244 218 std::list< Declaration* > members; 245 219 aggInst->lookup( name, members ); … … 254 228 } 255 229 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 256 254 void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) { 257 255 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); … … 259 257 260 258 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 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 ); 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() ); 267 262 268 263 Cost convCost( 0, 0, 0 ); … … 270 265 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 271 266 std::list< Expression* >& actuals = appExpr->get_args(); 267 268 std::list< Type * > formalTypes; 269 std::list< Type * >::iterator formalType = formalTypes.end(); 270 272 271 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 272 273 273 PRINT( 274 274 std::cerr << "actual expression:" << std::endl; 275 275 (*actualExpr)->print( std::cerr, 8 ); 276 276 std::cerr << "--- results are" << std::endl; 277 printAll( (*actualExpr)->get_results(),std::cerr, 8 );277 (*actualExpr)->get_result()->print( std::cerr, 8 ); 278 278 ) 279 279 std::list< DeclarationWithType* >::iterator startFormal = formal; 280 280 Cost actualCost; 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; 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 } 288 299 } 300 formalTypes.clear(); 301 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 302 formalType = formalTypes.begin(); 303 ++formal; 289 304 } 305 290 306 PRINT( 291 307 std::cerr << std::endl << "converting "; 292 (*actual )->print( std::cerr, 8 );308 (*actualType)->print( std::cerr, 8 ); 293 309 std::cerr << std::endl << " to "; 294 310 (*formal)->get_type()->print( std::cerr, 8 ); 295 311 ) 296 Cost newCost = conversionCost( *actual , (*formal)->get_type(), indexer, alt.env );312 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env ); 297 313 PRINT( 298 314 std::cerr << std::endl << "cost is" << newCost << std::endl; … … 305 321 actualCost += newCost; 306 322 307 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );308 309 formal ++;323 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 ); 324 325 formalType++; 310 326 } 311 327 if ( actualCost != Cost( 0, 0, 0 ) ) { … … 356 372 /// Adds type variables to the open variable set and marks their assertions 357 373 void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) { 358 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {374 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 359 375 unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind(); 360 376 for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { … … 365 381 } 366 382 367 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) { 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 ) { 368 438 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv ); 369 439 // make sure we don't widen any existing bindings … … 373 443 resultEnv.extractOpenVars( openVars ); 374 444 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; 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 ); 416 472 } 417 473 return true; … … 500 556 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 501 557 Expression *varExpr = new VariableExpr( candDecl ); 502 deleteAll( varExpr->get_results() ); 503 varExpr->get_results().clear(); 504 varExpr->get_results().push_front( adjType->clone() ); 558 delete varExpr->get_result(); 559 varExpr->set_result( adjType->clone() ); 505 560 PRINT( 506 561 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; … … 545 600 546 601 template< typename OutputIterator > 547 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {602 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) { 548 603 OpenVarSet openVars; 549 604 AssertionSet resultNeed, resultHave; 550 605 TypeEnvironment resultEnv; 551 606 makeUnifiableVars( funcType, openVars, resultNeed ); 552 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) { 607 AltList instantiatedActuals; // filled by instantiate function 608 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 553 609 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 554 Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt) );555 makeExprList( actualAlt, appExpr->get_args() );610 Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) ); 611 makeExprList( instantiatedActuals, appExpr->get_args() ); 556 612 PRINT( 557 613 std::cerr << "need assertions:" << std::endl; … … 574 630 PointerType pt( Type::Qualifiers(), v.clone() ); 575 631 UntypedExpr *vexpr = untypedExpr->clone(); 576 vexpr-> get_results().push_front( pt.clone() );632 vexpr->set_result( pt.clone() ); 577 633 alternatives.push_back( Alternative( vexpr, env, Cost()) ); 578 634 return; … … 587 643 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 588 644 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 ... 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 ); 594 648 595 649 AltList candidates; … … 604 658 // check if the type is pointer to function 605 659 PointerType *pointer; 606 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {660 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) { 607 661 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 608 662 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 640 694 // check if the type is pointer to function 641 695 PointerType *pointer; 642 if ( funcOp->expr->get_results().size() == 1 643 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) { 696 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) { 644 697 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 645 698 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 665 718 666 719 PRINT( 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 ); 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() ); 673 723 std::cerr << "Case +++++++++++++" << std::endl; 674 724 std::cerr << "formals are:" << std::endl; … … 692 742 693 743 bool isLvalue( Expression *expr ) { 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; 744 // xxx - recurse into tuples? 745 return expr->has_result() && expr->get_result()->get_isLvalue(); 698 746 } 699 747 … … 709 757 710 758 void AlternativeFinder::visit( CastExpr *castExpr ) { 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 759 Type *& toType = castExpr->get_result(); 760 toType = resolveTypeof( toType, indexer ); 761 SymTab::validateType( toType, &indexer ); 762 adjustExprType( toType, env, indexer ); 716 763 717 764 AlternativeFinder finder( indexer, env ); … … 727 774 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 728 775 // to. 729 int discardedValues = (*i).expr->get_result s().size() - castExpr->get_results().size();776 int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size(); 730 777 if ( discardedValues < 0 ) continue; 731 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 732 std::advance( candidate_end, castExpr->get_results().size() ); 778 // xxx - may need to go into tuple types and extract relavent types and use unifyList 733 779 // unification run for side-effects 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 ); 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 ); 740 782 if ( thisCost != Cost::infinity ) { 741 783 // count one safe conversion for each value that is thrown away … … 760 802 761 803 for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) { 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 } // if804 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() ); 768 810 } // if 769 811 } // for … … 791 833 renameTypes( alternatives.back().expr ); 792 834 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) { 793 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 835 NameExpr nameExpr( "" ); 836 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 794 837 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) { 795 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 838 NameExpr nameExpr( "" ); 839 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 796 840 } // if 797 841 } // for … … 894 938 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 895 939 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 896 alternatives.back().expr-> get_results().push_back( (*i)->get_type()->clone() );940 alternatives.back().expr->set_result( (*i)->get_type()->clone() ); 897 941 } // for 898 942 } // if … … 917 961 finder.find( attrExpr->get_expr() ); 918 962 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 919 if ( choice->expr->get_result s().size() == 1 ) {920 resolveAttr(*i, function, choice->expr->get_result s().front(), choice->env );963 if ( choice->expr->get_result()->size() == 1 ) { 964 resolveAttr(*i, function, choice->expr->get_result(), choice->env ); 921 965 } // fi 922 966 } // for … … 960 1004 AssertionSet needAssertions, haveAssertions; 961 1005 Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost ); 962 std::list< Type* > commonTypes;963 if ( unify List( 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) ) {1006 Type* commonType = nullptr; 1007 if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 964 1008 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->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 1009 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 974 1010 newAlt.expr = newExpr; 975 1011 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); … … 999 1035 TupleExpr *newExpr = new TupleExpr; 1000 1036 makeExprList( *i, 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 1037 newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) ); 1006 1038 1007 1039 TypeEnvironment compositeEnv; … … 1024 1056 } 1025 1057 } 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 1026 1077 } // namespace ResolvExpr 1027 1078 -
src/ResolvExpr/AlternativeFinder.h
r3a2128f r1f44196 67 67 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ); 68 68 virtual void visit( ConstructorExpr * ctorExpr ); 69 public: // xxx - temporary hack - should make Tuples::TupleAssignment a friend 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. 70 74 template< typename InputIterator, typename OutputIterator > 71 75 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 72 76 73 private:74 77 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 75 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ); 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 ); 76 81 /// Adds alternatives for offsetof expressions, given the base type and name of the member 77 82 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 78 bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave);83 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ); 79 84 template< typename OutputIterator > 80 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );85 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ); 81 86 template< typename OutputIterator > 82 87 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); … … 89 94 90 95 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 } 91 125 } // namespace ResolvExpr 92 126 -
src/ResolvExpr/AlternativePrinter.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AlternativePrinter.cc -- 7 // AlternativePrinter.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 33 33 for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 34 34 os << "Alternative " << count++ << " ==============" << std::endl; 35 printAll( i->expr->get_results(),os );35 i->expr->get_result()->print( os ); 36 36 // i->print( os ); 37 37 os << std::endl; -
src/ResolvExpr/ConversionCost.cc
r3a2128f r1f44196 240 240 std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin(); 241 241 std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin(); 242 while ( srcIt != tupleType->get_types().end() ) {242 while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) { 243 243 Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env ); 244 244 if ( newCost == Cost::infinity ) { -
src/ResolvExpr/FindOpenVars.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FindOpenVars.cc -- 7 // FindOpenVars.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 47 47 void FindOpenVars::common_action( Type *type ) { 48 48 if ( nextIsOpen ) { 49 for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {49 for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 50 50 openVars[ (*i)->get_name() ] = (*i)->get_kind(); 51 51 for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { … … 56 56 } 57 57 } else { 58 for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {58 for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 59 59 closedVars[ (*i)->get_name() ] = (*i)->get_kind(); 60 60 for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { -
src/ResolvExpr/RenameVars.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // RenameVars.cc -- 7 // RenameVars.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 125 125 mapStack.push_front( mapStack.front() ); 126 126 // renames all "forall" type names to `_${level}_${name}' 127 for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {127 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 128 128 std::ostringstream output; 129 129 output << "_" << level << "_" << (*i)->get_name(); -
src/ResolvExpr/ResolveTypeof.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ResolveTypeof.cc -- 7 // ResolveTypeof.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 58 58 if ( typeofType->get_expr() ) { 59 59 Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer ); 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 60 assert( newExpr->has_result() && ! newExpr->get_result()->isVoid() ); 61 Type *newType = newExpr->get_result(); 69 62 delete typeofType; 70 63 return newType; -
src/ResolvExpr/Resolver.cc
r3a2128f r1f44196 19 19 #include "RenameVars.h" 20 20 #include "ResolveTypeof.h" 21 #include "typeops.h" 21 22 #include "SynTree/Statement.h" 22 23 #include "SynTree/Type.h" … … 68 69 void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & ); 69 70 void fallbackInit( ConstructorInit * ctorInit ); 70 std::list< Type * > functionReturn; 71 Type *initContext; 71 72 Type * functionReturn = nullptr; 73 Type *initContext = nullptr; 72 74 bool inEnumDecl = false; 73 75 }; … … 157 159 const TypeEnvironment *newEnv = 0; 158 160 for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 159 if ( i->expr->get_result s().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {161 if ( i->expr->get_result()->size() == 1 && isIntegralType( i->expr->get_result() ) ) { 160 162 if ( newExpr ) { 161 163 throw SemanticError( "Too many interpretations for case control expression", untyped ); … … 234 236 Type *new_type = resolveTypeof( functionDecl->get_type(), *this ); 235 237 functionDecl->set_type( new_type ); 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 238 ValueGuard< Type * > oldFunctionReturn( functionReturn ); 239 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 241 240 SymTab::Indexer::visit( functionDecl ); 242 functionReturn = oldFunctionReturn;243 241 } 244 242 … … 338 336 void Resolver::visit( ReturnStmt *returnStmt ) { 339 337 if ( returnStmt->get_expr() ) { 340 CastExpr *castExpr = new CastExpr( returnStmt->get_expr() ); 341 cloneAll( functionReturn, castExpr->get_results() ); 338 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 342 339 Expression *newExpr = findSingleExpression( castExpr, *this ); 343 340 delete castExpr; … … 384 381 if ( isCharType( at->get_base() ) ) { 385 382 // check if the resolved type is char * 386 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result s().front() ) ) {383 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 387 384 if ( isCharType( pt->get_base() ) ) { 388 385 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; … … 446 443 (*iter)->accept( *this ); 447 444 } // 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 } 448 451 } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) { 449 452 resolveAggrInit( st->get_baseStruct(), iter, end ); -
src/ResolvExpr/TypeEnvironment.cc
r3a2128f r1f44196 158 158 } 159 159 160 void TypeEnvironment::add( const std::list< TypeDecl* >&tyDecls ) {161 for ( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {160 void TypeEnvironment::add( const Type::ForallList &tyDecls ) { 161 for ( Type::ForallList::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) { 162 162 EqvClass newClass; 163 163 newClass.vars.insert( (*i)->get_name() ); -
src/ResolvExpr/TypeEnvironment.h
r3a2128f r1f44196 55 55 bool lookup( const std::string &var, EqvClass &eqvClass ) const; 56 56 void add( const EqvClass &eqvClass ); 57 void add( const std::list< TypeDecl* >&tyDecls );57 void add( const Type::ForallList &tyDecls ); 58 58 template< typename SynTreeClass > int apply( SynTreeClass *&type ) const; 59 59 template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const; -
src/ResolvExpr/Unify.cc
r3a2128f r1f44196 597 597 } 598 598 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 } 599 613 } // namespace ResolvExpr 600 614 -
src/ResolvExpr/typeops.h
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // typeops.h -- 7 // typeops.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 30 30 typedef typename InputIterator::value_type SetType; 31 31 typedef typename std::list< typename SetType::value_type > ListType; 32 32 33 33 if ( begin == end ) { 34 34 *out++ = ListType(); 35 35 return; 36 36 } // if 37 37 38 38 InputIterator current = begin; 39 39 begin++; … … 41 41 std::list< ListType > recursiveResult; 42 42 combos( begin, end, back_inserter( recursiveResult ) ); 43 43 44 44 for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) { 45 45 for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) { … … 52 52 } // for 53 53 } 54 54 55 55 // in AdjustExprType.cc 56 56 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function … … 144 144 } 145 145 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 146 149 // in CommonType.cc 147 150 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); … … 152 155 // in Occurs.cc 153 156 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 } 154 169 } // namespace ResolvExpr 155 170 -
src/SymTab/Autogen.cc
r3a2128f r1f44196 116 116 // This happens before function pointer type conversion, so need to do it manually here 117 117 VariableExpr * assignVarExpr = new VariableExpr( assignDecl ); 118 Type * & assignVarExprType = assignVarExpr->get_results().front();118 Type * assignVarExprType = assignVarExpr->get_result(); 119 119 assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType ); 120 assignVarExpr->set_result( assignVarExprType ); 120 121 ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr ); 121 122 assignExpr->get_args().push_back( new VariableExpr( dstParam ) ); -
src/SymTab/Indexer.cc
r3a2128f r1f44196 40 40 41 41 namespace SymTab { 42 template< typename Container, typename VisitorType >43 inline void accept AllNewScope( Container &container, VisitorType &visitor ) {42 template< typename TreeType, typename VisitorType > 43 inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) { 44 44 visitor.enterScope(); 45 acceptAll( container, visitor );45 maybeAccept( tree, visitor ); 46 46 visitor.leaveScope(); 47 47 } … … 143 143 for ( DeclarationWithType * decl : copy ) { 144 144 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(); 146 146 assert( ! params.empty() ); 147 147 // use base type of pointer, so that qualifiers on the pointer type aren't considered. … … 337 337 338 338 void Indexer::visit( ApplicationExpr *applicationExpr ) { 339 accept AllNewScope( applicationExpr->get_results(), *this );339 acceptNewScope( applicationExpr->get_result(), *this ); 340 340 maybeAccept( applicationExpr->get_function(), *this ); 341 341 acceptAll( applicationExpr->get_args(), *this ); … … 343 343 344 344 void Indexer::visit( UntypedExpr *untypedExpr ) { 345 accept AllNewScope( untypedExpr->get_results(), *this );345 acceptNewScope( untypedExpr->get_result(), *this ); 346 346 acceptAll( untypedExpr->get_args(), *this ); 347 347 } 348 348 349 349 void Indexer::visit( NameExpr *nameExpr ) { 350 accept AllNewScope( nameExpr->get_results(), *this );350 acceptNewScope( nameExpr->get_result(), *this ); 351 351 } 352 352 353 353 void Indexer::visit( AddressExpr *addressExpr ) { 354 accept AllNewScope( addressExpr->get_results(), *this );354 acceptNewScope( addressExpr->get_result(), *this ); 355 355 maybeAccept( addressExpr->get_arg(), *this ); 356 356 } 357 357 358 358 void Indexer::visit( LabelAddressExpr *labAddressExpr ) { 359 accept AllNewScope( labAddressExpr->get_results(), *this );359 acceptNewScope( labAddressExpr->get_result(), *this ); 360 360 maybeAccept( labAddressExpr->get_arg(), *this ); 361 361 } 362 362 363 363 void Indexer::visit( CastExpr *castExpr ) { 364 accept AllNewScope( castExpr->get_results(), *this );364 acceptNewScope( castExpr->get_result(), *this ); 365 365 maybeAccept( castExpr->get_arg(), *this ); 366 366 } 367 367 368 368 void Indexer::visit( UntypedMemberExpr *memberExpr ) { 369 accept AllNewScope( memberExpr->get_results(), *this );369 acceptNewScope( memberExpr->get_result(), *this ); 370 370 maybeAccept( memberExpr->get_aggregate(), *this ); 371 371 } 372 372 373 373 void Indexer::visit( MemberExpr *memberExpr ) { 374 accept AllNewScope( memberExpr->get_results(), *this );374 acceptNewScope( memberExpr->get_result(), *this ); 375 375 maybeAccept( memberExpr->get_aggregate(), *this ); 376 376 } 377 377 378 378 void Indexer::visit( VariableExpr *variableExpr ) { 379 accept AllNewScope( variableExpr->get_results(), *this );379 acceptNewScope( variableExpr->get_result(), *this ); 380 380 } 381 381 382 382 void Indexer::visit( ConstantExpr *constantExpr ) { 383 accept AllNewScope( constantExpr->get_results(), *this );383 acceptNewScope( constantExpr->get_result(), *this ); 384 384 maybeAccept( constantExpr->get_constant(), *this ); 385 385 } 386 386 387 387 void Indexer::visit( SizeofExpr *sizeofExpr ) { 388 accept AllNewScope( sizeofExpr->get_results(), *this );388 acceptNewScope( sizeofExpr->get_result(), *this ); 389 389 if ( sizeofExpr->get_isType() ) { 390 390 maybeAccept( sizeofExpr->get_type(), *this ); … … 395 395 396 396 void Indexer::visit( AlignofExpr *alignofExpr ) { 397 accept AllNewScope( alignofExpr->get_results(), *this );397 acceptNewScope( alignofExpr->get_result(), *this ); 398 398 if ( alignofExpr->get_isType() ) { 399 399 maybeAccept( alignofExpr->get_type(), *this ); … … 404 404 405 405 void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) { 406 accept AllNewScope( offsetofExpr->get_results(), *this );406 acceptNewScope( offsetofExpr->get_result(), *this ); 407 407 maybeAccept( offsetofExpr->get_type(), *this ); 408 408 } 409 409 410 410 void Indexer::visit( OffsetofExpr *offsetofExpr ) { 411 accept AllNewScope( offsetofExpr->get_results(), *this );411 acceptNewScope( offsetofExpr->get_result(), *this ); 412 412 maybeAccept( offsetofExpr->get_type(), *this ); 413 413 maybeAccept( offsetofExpr->get_member(), *this ); … … 415 415 416 416 void Indexer::visit( OffsetPackExpr *offsetPackExpr ) { 417 accept AllNewScope( offsetPackExpr->get_results(), *this );417 acceptNewScope( offsetPackExpr->get_result(), *this ); 418 418 maybeAccept( offsetPackExpr->get_type(), *this ); 419 419 } 420 420 421 421 void Indexer::visit( AttrExpr *attrExpr ) { 422 accept AllNewScope( attrExpr->get_results(), *this );422 acceptNewScope( attrExpr->get_result(), *this ); 423 423 if ( attrExpr->get_isType() ) { 424 424 maybeAccept( attrExpr->get_type(), *this ); … … 429 429 430 430 void Indexer::visit( LogicalExpr *logicalExpr ) { 431 accept AllNewScope( logicalExpr->get_results(), *this );431 acceptNewScope( logicalExpr->get_result(), *this ); 432 432 maybeAccept( logicalExpr->get_arg1(), *this ); 433 433 maybeAccept( logicalExpr->get_arg2(), *this ); … … 435 435 436 436 void Indexer::visit( ConditionalExpr *conditionalExpr ) { 437 accept AllNewScope( conditionalExpr->get_results(), *this );437 acceptNewScope( conditionalExpr->get_result(), *this ); 438 438 maybeAccept( conditionalExpr->get_arg1(), *this ); 439 439 maybeAccept( conditionalExpr->get_arg2(), *this ); … … 442 442 443 443 void Indexer::visit( CommaExpr *commaExpr ) { 444 accept AllNewScope( commaExpr->get_results(), *this );444 acceptNewScope( commaExpr->get_result(), *this ); 445 445 maybeAccept( commaExpr->get_arg1(), *this ); 446 446 maybeAccept( commaExpr->get_arg2(), *this ); … … 448 448 449 449 void Indexer::visit( TupleExpr *tupleExpr ) { 450 accept AllNewScope( tupleExpr->get_results(), *this );450 acceptNewScope( tupleExpr->get_result(), *this ); 451 451 acceptAll( tupleExpr->get_exprs(), *this ); 452 452 } 453 453 454 void Indexer::visit( SolvedTupleExpr *tupleExpr ) { 455 acceptAllNewScope( tupleExpr->get_results(), *this ); 456 acceptAll( tupleExpr->get_exprs(), *this ); 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(); 457 460 } 458 461 459 462 void Indexer::visit( TypeExpr *typeExpr ) { 460 accept AllNewScope( typeExpr->get_results(), *this );463 acceptNewScope( typeExpr->get_result(), *this ); 461 464 maybeAccept( typeExpr->get_type(), *this ); 462 465 } … … 469 472 470 473 void Indexer::visit( UntypedValofExpr *valofExpr ) { 471 accept AllNewScope( valofExpr->get_results(), *this );474 acceptNewScope( valofExpr->get_result(), *this ); 472 475 maybeAccept( valofExpr->get_body(), *this ); 473 476 } -
src/SymTab/Indexer.h
r3a2128f r1f44196 64 64 virtual void visit( ConditionalExpr *conditionalExpr ); 65 65 virtual void visit( CommaExpr *commaExpr ); 66 virtual void visit( TupleExpr *tupleExpr );67 virtual void visit( SolvedTupleExpr *tupleExpr );68 66 virtual void visit( TypeExpr *typeExpr ); 69 67 virtual void visit( AsmExpr *asmExpr ); 70 68 virtual void visit( UntypedValofExpr *valofExpr ); 69 virtual void visit( TupleExpr *tupleExpr ); 70 virtual void visit( TupleAssignExpr *tupleExpr ); 71 71 72 72 virtual void visit( TraitInstType *contextInst ); -
src/SymTab/Mangler.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Mangler.cc -- 7 // Mangler.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 35 35 return mangler.get_mangleName(); 36 36 } 37 37 38 38 Mangler::Mangler( bool mangleOverridable, bool typeMode ) 39 39 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {} 40 40 41 41 Mangler::Mangler( const Mangler &rhs ) : mangleName() { 42 42 varNums = rhs.varNums; … … 115 115 "Ir", // LongDoubleImaginary 116 116 }; 117 117 118 118 printQualifiers( basicType ); 119 119 mangleName << btLetter[ basicType->get_kind() ]; … … 253 253 // skip if not including qualifiers 254 254 if ( typeMode ) return; 255 255 256 256 if ( ! type->get_forall().empty() ) { 257 257 std::list< std::string > assertionNames; 258 258 int tcount = 0, dcount = 0, fcount = 0; 259 259 mangleName << "A"; 260 for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {260 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 261 261 switch ( (*i)->get_kind() ) { 262 262 case TypeDecl::Any: -
src/SymTab/Validate.cc
r3a2128f r1f44196 23 23 // - All enumeration constants have type EnumInstType. 24 24 // 25 // - The type "void" never occurs in lists of function parameter or return types ; neither do tuple types. A function26 // taking no arguments has no argument types , and tuples are flattened.25 // - The type "void" never occurs in lists of function parameter or return types. A function 26 // taking no arguments has no argument types. 27 27 // 28 28 // - No context instances exist; they are all replaced by the set of declarations signified by the context, instantiated … … 243 243 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ); 244 244 } 245 245 // xxx - shouldn't this be declsToAddBefore? 246 246 template< typename AggDecl > 247 247 void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) { … … 431 431 /// Fix up assertions 432 432 void forallFixer( Type *func ) { 433 for ( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {433 for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) { 434 434 std::list< DeclarationWithType * > toBeDone, nextRound; 435 435 toBeDone.splice( toBeDone.end(), (*type )->get_assertions() ); -
src/SynTree/AddressExpr.cc
r3a2128f r1f44196 19 19 20 20 AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) { 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 } // for21 if ( arg->has_result() ) { 22 set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) ); 23 } 24 24 } 25 25 … … 35 35 if ( arg ) { 36 36 os << std::string( indent+2, ' ' ); 37 37 arg->print( os, indent+2 ); 38 38 } // if 39 39 } -
src/SynTree/ApplicationExpr.cc
r3a2128f r1f44196 21 21 #include "TypeSubstitution.h" 22 22 #include "Common/utility.h" 23 23 #include "ResolvExpr/typeops.h" 24 24 25 25 ParamEntry::ParamEntry( const ParamEntry &other ) : … … 43 43 44 44 ApplicationExpr::ApplicationExpr( Expression *funcExpr ) : function( funcExpr ) { 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 ); 45 PointerType *pointer = safe_dynamic_cast< PointerType* >( funcExpr->get_result() ); 46 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 49 47 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 } // for48 set_result( ResolvExpr::extractResultType( function ) ); 49 50 assert( has_result() ); 53 51 } 54 52 -
src/SynTree/CommaExpr.cc
r3a2128f r1f44196 23 23 // to false on all result types. Actually doing this causes some strange things 24 24 // to happen in later passes (particularly, Specialize, Lvalue, and Box). This needs to be looked into. 25 cloneAll( arg2->get_results(), get_results() ); 26 // for ( Type *& type : get_results() ) { 27 // type->set_isLvalue( false ); 28 // } 25 set_result( maybeClone( arg2->get_result() ) ); 26 // get_type->set_isLvalue( false ); 29 27 } 30 28 -
src/SynTree/CompoundStmt.cc
r3a2128f r1f44196 20 20 #include "Expression.h" 21 21 #include "Declaration.h" 22 #include "SynTree/VarExprReplacer.h" 22 23 23 24 using std::string; 24 25 using std::endl; 25 26 class VarExprReplacer : public Visitor {27 public:28 typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;29 private:30 const DeclMap & declMap;31 public:32 VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}33 34 // replace variable with new node from decl map35 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 42 26 43 27 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) { … … 47 31 cloneAll( other.kids, kids ); 48 32 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 } 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 } 79 65 } 80 66 -
src/SynTree/Expression.cc
r3a2128f r1f44196 31 31 32 32 33 Expression::Expression( Expression *_aname ) : env( 0 ), argName( _aname ) {} 34 35 Expression::Expression( const Expression &other ) : env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) { 36 cloneAll( other.results, results ); 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 ) { 37 36 } 38 37 … … 40 39 delete env; 41 40 delete argName; // xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix 42 deleteAll( results ); 43 } 44 45 void 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 41 delete result; 51 42 } 52 43 … … 68 59 69 60 ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) { 70 add_result( constant.get_type()->clone() );61 set_result( constant.get_type()->clone() ); 71 62 } 72 63 … … 85 76 assert( var ); 86 77 assert( var->get_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 78 Type * type = var->get_type()->clone(); 79 type->set_isLvalue( true ); 80 set_result( type ); 91 81 } 92 82 … … 110 100 SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) : 111 101 Expression( _aname ), expr(expr_), type(0), isType(false) { 112 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );102 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 113 103 } 114 104 115 105 SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) : 116 106 Expression( _aname ), expr(0), type(type_), isType(true) { 117 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );107 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 118 108 } 119 109 … … 141 131 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) : 142 132 Expression( _aname ), expr(expr_), type(0), isType(false) { 143 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );133 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 144 134 } 145 135 146 136 AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) : 147 137 Expression( _aname ), expr(0), type(type_), isType(true) { 148 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );138 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 149 139 } 150 140 … … 172 162 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) : 173 163 Expression( _aname ), type(type_), member(member_) { 174 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );164 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 175 165 } 176 166 … … 197 187 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) : 198 188 Expression( _aname ), type(type_), member(member_) { 199 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );189 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 200 190 } 201 191 … … 229 219 230 220 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) { 231 add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );221 set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 232 222 } 233 223 … … 284 274 285 275 CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) { 286 add_result(toType);276 set_result(toType); 287 277 } 288 278 289 279 CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) { 280 set_result( new VoidType( Type::Qualifiers() ) ); 290 281 } 291 282 … … 303 294 arg->print(os, indent+2); 304 295 os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl; 305 if ( results.empty() ) { 306 os << std::string( indent+2, ' ' ) << "nothing" << std::endl; 296 os << std::string( indent+2, ' ' ); 297 if ( result->isVoid() ) { 298 os << "nothing"; 307 299 } else { 308 printAll(results, os, indent+2);300 result->print( os, indent+2 ); 309 301 } // if 310 Expression::print( os, indent ); 311 } 312 313 UntypedMemberExpr::UntypedMemberExpr( std::string _member, Expression *_aggregate, Expression *_aname ) : 302 os << std::endl; 303 Expression::print( os, indent ); 304 } 305 306 UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) : 314 307 Expression( _aname ), member(_member), aggregate(_aggregate) {} 315 308 316 309 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) : 317 Expression( other ), member( other.member), aggregate( maybeClone( other.aggregate ) ) {310 Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) { 318 311 } 319 312 320 313 UntypedMemberExpr::~UntypedMemberExpr() { 321 314 delete aggregate; 315 delete member; 322 316 } 323 317 324 318 void UntypedMemberExpr::print( std::ostream &os, int indent ) const { 325 os << "Untyped Member Expression, with field: " << get_member(); 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, ' ' ); 326 323 327 324 Expression *agg = get_aggregate(); 328 os << " , from aggregate: ";325 os << "from aggregate: " << std::endl; 329 326 if (agg != 0) { 330 os << std::string( indent + 2, ' ' );331 agg->print(os, indent + 2);327 os << std::string( indent + 4, ' ' ); 328 agg->print(os, indent + 4); 332 329 } 333 330 os << std::string( indent+2, ' ' ); … … 338 335 MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) : 339 336 Expression( _aname ), member(_member), aggregate(_aggregate) { 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 337 set_result( member->get_type()->clone() ); 338 get_result()->set_isLvalue( true ); 344 339 } 345 340 … … 372 367 } 373 368 374 375 UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function) {}369 UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) : 370 Expression( _aname ), function(_function), args(_args) {} 376 371 377 372 UntypedExpr::UntypedExpr( const UntypedExpr &other ) : … … 380 375 } 381 376 382 UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) :383 Expression( _aname ), function(_function), args(_args) {}384 385 377 UntypedExpr::~UntypedExpr() { 386 378 delete function; 387 379 deleteAll( args ); 388 380 } 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 389 406 390 407 void UntypedExpr::print( std::ostream &os, int indent ) const { … … 419 436 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) : 420 437 Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp) { 421 add_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );438 set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 422 439 } 423 440 … … 454 471 455 472 void ConditionalExpr::print( std::ostream &os, int indent ) const { 456 os << std::string( indent, ' ' ) << "Conditional expression on: " << std::endl; 473 os << "Conditional expression on: " << std::endl; 474 os << std::string( indent+2, ' ' ); 457 475 arg1->print( os, indent+2 ); 458 476 os << std::string( indent, ' ' ) << "First alternative:" << std::endl; 477 os << std::string( indent+2, ' ' ); 459 478 arg2->print( os, indent+2 ); 460 479 os << std::string( indent, ' ' ) << "Second alternative:" << std::endl; 480 os << std::string( indent+2, ' ' ); 461 481 arg3->print( os, indent+2 ); 462 482 os << std::endl; … … 477 497 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) { 478 498 assert( callExpr ); 479 cloneAll( callExpr->get_results(), results ); 499 assert( callExpr->has_result() ); 500 set_result( callExpr->get_result()->clone() ); 480 501 } 481 502 … … 510 531 Expression * arg = InitTweak::getCallArg( callExpr, 0 ); 511 532 assert( arg ); 512 cloneAll( arg->get_results(), results);533 set_result( maybeClone( arg->get_result() ) ); 513 534 } 514 535 … … 530 551 531 552 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) { 532 add_result( type->clone() ); 533 } 534 535 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.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() ) {} 536 558 537 559 CompoundLiteralExpr::~CompoundLiteralExpr() { … … 542 564 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const { 543 565 os << "Compound Literal Expression: " << std::endl; 544 if ( type ) type->print( os, indent + 2 ); 545 if ( initializer ) initializer->print( os, indent + 2 ); 566 os << std::string( indent+2, ' ' ); 567 type->print( os, indent + 2 ); 568 os << std::string( indent+2, ' ' ); 569 initializer->print( os, indent + 2 ); 546 570 } 547 571 … … 557 581 558 582 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {} 559 RangeExpr::RangeExpr( const RangeExpr &other ) : low( other.low->clone() ), high( other.high->clone() ) {}583 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {} 560 584 void RangeExpr::print( std::ostream &os, int indent ) const { 561 os << std::string( indent, ' ' ) <<"Range Expression: ";585 os << "Range Expression: "; 562 586 low->print( os, indent ); 563 587 os << " ... "; 564 588 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 } 565 633 } 566 634 -
src/SynTree/Expression.h
r3a2128f r1f44196 32 32 virtual ~Expression(); 33 33 34 std::list<Type *>& get_results() { return results; } 35 void add_result( Type *t ); 34 Type *& get_result() { return result; } 35 void set_result( Type *newValue ) { result = newValue; } 36 bool has_result() const { return result != nullptr; } 36 37 37 38 TypeSubstitution *get_env() const { return env; } … … 47 48 virtual void print( std::ostream &os, int indent = 0 ) const; 48 49 protected: 49 std::list<Type *> results;50 Type * result; 50 51 TypeSubstitution *env; 51 52 Expression* argName; // if expression is used as an argument, it can be "designated" by this name … … 98 99 class UntypedExpr : public Expression { 99 100 public: 100 UntypedExpr( Expression *function, Expression *_aname = nullptr );101 UntypedExpr( Expression *function, const std::list<Expression *> &args = std::list< Expression * >(), Expression *_aname = nullptr ); 101 102 UntypedExpr( const UntypedExpr &other ); 102 UntypedExpr( Expression *function, std::list<Expression *> &args, Expression *_aname = nullptr );103 103 virtual ~UntypedExpr(); 104 104 … … 111 111 std::list<Expression*>& get_args() { return args; } 112 112 113 static UntypedExpr * createDeref( Expression * arg ); 114 static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 ); 115 113 116 virtual UntypedExpr *clone() const { return new UntypedExpr( *this ); } 114 117 virtual void accept( Visitor &v ) { v.visit( this ); } … … 200 203 class UntypedMemberExpr : public Expression { 201 204 public: 202 UntypedMemberExpr( std::stringmember, Expression *aggregate, Expression *_aname = nullptr );205 UntypedMemberExpr( Expression *member, Expression *aggregate, Expression *_aname = nullptr ); 203 206 UntypedMemberExpr( const UntypedMemberExpr &other ); 204 207 virtual ~UntypedMemberExpr(); 205 208 206 std::stringget_member() const { return member; }207 void set_member( const std::string &newValue ) { member = newValue; }209 Expression * get_member() const { return member; } 210 void set_member( Expression * newValue ) { member = newValue; } 208 211 Expression *get_aggregate() const { return aggregate; } 209 212 void set_aggregate( Expression *newValue ) { aggregate = newValue; } … … 214 217 virtual void print( std::ostream &os, int indent = 0 ) const; 215 218 private: 216 std::stringmember;219 Expression *member; 217 220 Expression *aggregate; 218 221 }; … … 483 486 }; 484 487 485 /// TupleExpr represents a tuple expression ( [a, b, c] )486 class 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 on504 class 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 521 488 /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter) 522 489 class TypeExpr : public Expression { … … 618 585 CompoundLiteralExpr( Type * type, Initializer * initializer ); 619 586 CompoundLiteralExpr( const CompoundLiteralExpr &other ); 620 ~CompoundLiteralExpr();587 virtual ~CompoundLiteralExpr(); 621 588 622 589 Type * get_type() const { return type; } … … 670 637 private: 671 638 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; 672 765 }; 673 766 -
src/SynTree/Initializer.h
r3a2128f r1f44196 23 23 24 24 #include <cassert> 25 26 const std::list<Expression*> noDesignators; 25 27 26 28 // Initializer: base class for object initializers (provide default values) -
src/SynTree/Mutator.cc
r3a2128f r1f44196 178 178 179 179 Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) { 180 mutateAll( applicationExpr->get_results(), *this);180 applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) ); 181 181 applicationExpr->set_function( maybeMutate( applicationExpr->get_function(), *this ) ); 182 182 mutateAll( applicationExpr->get_args(), *this ); … … 185 185 186 186 Expression *Mutator::mutate( UntypedExpr *untypedExpr ) { 187 mutateAll( untypedExpr->get_results(), *this);187 untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) ); 188 188 mutateAll( untypedExpr->get_args(), *this ); 189 189 return untypedExpr; … … 191 191 192 192 Expression *Mutator::mutate( NameExpr *nameExpr ) { 193 mutateAll( nameExpr->get_results(), *this);193 nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) ); 194 194 return nameExpr; 195 195 } 196 196 197 197 Expression *Mutator::mutate( AddressExpr *addressExpr ) { 198 mutateAll( addressExpr->get_results(), *this);198 addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) ); 199 199 addressExpr->set_arg( maybeMutate( addressExpr->get_arg(), *this ) ); 200 200 return addressExpr; … … 202 202 203 203 Expression *Mutator::mutate( LabelAddressExpr *labelAddressExpr ) { 204 mutateAll( labelAddressExpr->get_results(), *this);204 labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) ); 205 205 labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) ); 206 206 return labelAddressExpr; … … 208 208 209 209 Expression *Mutator::mutate( CastExpr *castExpr ) { 210 mutateAll( castExpr->get_results(), *this);210 castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) ); 211 211 castExpr->set_arg( maybeMutate( castExpr->get_arg(), *this ) ); 212 212 return castExpr; … … 214 214 215 215 Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) { 216 mutateAll( memberExpr->get_results(), *this ); 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 ) ); 217 224 memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) ); 218 225 return memberExpr; 219 226 } 220 227 221 Expression *Mutator::mutate( MemberExpr *memberExpr ) {222 mutateAll( memberExpr->get_results(), *this );223 memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );224 return memberExpr;225 }226 227 228 Expression *Mutator::mutate( VariableExpr *variableExpr ) { 228 mutateAll( variableExpr->get_results(), *this);229 variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) ); 229 230 return variableExpr; 230 231 } 231 232 232 233 Expression *Mutator::mutate( ConstantExpr *constantExpr ) { 233 mutateAll( constantExpr->get_results(), *this);234 constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) ); 234 235 // maybeMutate( constantExpr->get_constant(), *this ) 235 236 return constantExpr; … … 237 238 238 239 Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) { 239 mutateAll( sizeofExpr->get_results(), *this);240 sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) ); 240 241 if ( sizeofExpr->get_isType() ) { 241 242 sizeofExpr->set_type( maybeMutate( sizeofExpr->get_type(), *this ) ); … … 247 248 248 249 Expression *Mutator::mutate( AlignofExpr *alignofExpr ) { 249 mutateAll( alignofExpr->get_results(), *this);250 alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) ); 250 251 if ( alignofExpr->get_isType() ) { 251 252 alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) ); … … 257 258 258 259 Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) { 259 mutateAll( offsetofExpr->get_results(), *this);260 offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) ); 260 261 offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) ); 261 262 return offsetofExpr; … … 263 264 264 265 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) { 265 mutateAll( offsetofExpr->get_results(), *this);266 offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) ); 266 267 offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) ); 267 268 offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) ); … … 270 271 271 272 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) { 272 mutateAll( offsetPackExpr->get_results(), *this);273 offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) ); 273 274 offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) ); 274 275 return offsetPackExpr; … … 276 277 277 278 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 278 mutateAll( attrExpr->get_results(), *this);279 attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) ); 279 280 if ( attrExpr->get_isType() ) { 280 281 attrExpr->set_type( maybeMutate( attrExpr->get_type(), *this ) ); … … 286 287 287 288 Expression *Mutator::mutate( LogicalExpr *logicalExpr ) { 288 mutateAll( logicalExpr->get_results(), *this);289 logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) ); 289 290 logicalExpr->set_arg1( maybeMutate( logicalExpr->get_arg1(), *this ) ); 290 291 logicalExpr->set_arg2( maybeMutate( logicalExpr->get_arg2(), *this ) ); … … 293 294 294 295 Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) { 295 mutateAll( conditionalExpr->get_results(), *this);296 conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) ); 296 297 conditionalExpr->set_arg1( maybeMutate( conditionalExpr->get_arg1(), *this ) ); 297 298 conditionalExpr->set_arg2( maybeMutate( conditionalExpr->get_arg2(), *this ) ); … … 301 302 302 303 Expression *Mutator::mutate( CommaExpr *commaExpr ) { 303 mutateAll( commaExpr->get_results(), *this);304 commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) ); 304 305 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) ); 305 306 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) ); … … 307 308 } 308 309 309 Expression *Mutator::mutate( TupleExpr *tupleExpr ) {310 mutateAll( tupleExpr->get_results(), *this );311 mutateAll( tupleExpr->get_exprs(), *this );312 return tupleExpr;313 }314 315 Expression *Mutator::mutate( SolvedTupleExpr *tupleExpr ) {316 mutateAll( tupleExpr->get_results(), *this );317 mutateAll( tupleExpr->get_exprs(), *this );318 return tupleExpr;319 }320 321 310 Expression *Mutator::mutate( TypeExpr *typeExpr ) { 322 mutateAll( typeExpr->get_results(), *this);311 typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) ); 323 312 typeExpr->set_type( maybeMutate( typeExpr->get_type(), *this ) ); 324 313 return typeExpr; … … 340 329 341 330 Expression* Mutator::mutate( ConstructorExpr *ctorExpr ) { 342 mutateAll( ctorExpr->get_results(), *this);331 ctorExpr->set_result( maybeMutate( ctorExpr->get_result(), *this ) ); 343 332 ctorExpr->set_callExpr( maybeMutate( ctorExpr->get_callExpr(), *this ) ); 344 333 return ctorExpr; … … 346 335 347 336 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) { 348 mutateAll( compLitExpr->get_results(), *this);337 compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) ); 349 338 compLitExpr->set_type( maybeMutate( compLitExpr->get_type(), *this ) ); 350 339 compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) ); … … 353 342 354 343 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) { 355 mutateAll( valofExpr->get_results(), *this);344 valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ) ); 356 345 return valofExpr; 357 346 } … … 361 350 rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) ); 362 351 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; 363 390 } 364 391 -
src/SynTree/Mutator.h
r3a2128f r1f44196 71 71 virtual Expression* mutate( ConditionalExpr *conditionalExpr ); 72 72 virtual Expression* mutate( CommaExpr *commaExpr ); 73 virtual Expression* mutate( TupleExpr *tupleExpr );74 virtual Expression* mutate( SolvedTupleExpr *tupleExpr );75 73 virtual Expression* mutate( TypeExpr *typeExpr ); 76 74 virtual Expression* mutate( AsmExpr *asmExpr ); … … 80 78 virtual Expression* mutate( UntypedValofExpr *valofExpr ); 81 79 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 ); 82 86 83 87 virtual Type* mutate( VoidType *basicType ); -
src/SynTree/ReferenceToType.cc
r3a2128f r1f44196 56 56 } 57 57 } // namespace 58 59 StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct ) : Parent( tq, baseStruct->get_name() ), baseStruct( baseStruct ) {} 58 60 59 61 std::string StructInstType::typeString() const { return "struct"; } -
src/SynTree/SynTree.h
r3a2128f r1f44196 76 76 class ConditionalExpr; 77 77 class CommaExpr; 78 class TupleExpr;79 class SolvedTupleExpr;80 78 class TypeExpr; 81 79 class AsmExpr; … … 85 83 class UntypedValofExpr; 86 84 class RangeExpr; 85 class TupleExpr; 86 class TupleIndexExpr; 87 class MemberTupleExpr; 88 class TupleAssignExpr; 89 class StmtExpr; 90 class UniqueExpr; 87 91 88 92 class Type; -
src/SynTree/TupleExpr.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TupleExpr.cc -- 7 // TupleExpr.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 16 16 #include "Expression.h" 17 17 #include "Common/utility.h" 18 #include "Type.h" 19 #include "Declaration.h" 20 #include "Tuples/Tuples.h" 21 #include "VarExprReplacer.h" 18 22 19 TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) { 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 } 20 29 } 21 30 … … 29 38 30 39 void TupleExpr::print( std::ostream &os, int indent ) const { 31 os << std::string( indent, ' ' ) <<"Tuple:" << std::endl;40 os << "Tuple:" << std::endl; 32 41 printAll( exprs, os, indent+2 ); 33 42 Expression::print( os, indent ); 34 43 } 35 44 36 SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname ) : Expression( _aname ) { 37 std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs)); 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() ); 38 50 } 39 51 40 SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other ) : Expression( other ) { 41 cloneAll( other.exprs, exprs ); 52 TupleIndexExpr::TupleIndexExpr( const TupleIndexExpr &other ) : Expression( other ), tuple( other.tuple->clone() ), index( other.index ) { 42 53 } 43 54 44 void SolvedTupleExpr::print( std::ostream &os, int indent ) const { 45 os << std::string( indent, ' ' ) << "Solved Tuple:" << std::endl; 46 printAll( exprs, os, indent+2 ); 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; 47 64 Expression::print( os, indent ); 48 65 } 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 49 130 50 131 // Local Variables: // -
src/SynTree/TupleType.cc
r3a2128f r1f44196 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TupleType.cc -- 7 // TupleType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 17 17 #include "Common/utility.h" 18 18 19 TupleType::TupleType( const Type::Qualifiers &tq ) : Type( tq) {19 TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types ) : Type( tq ), types( types ) { 20 20 } 21 21 -
src/SynTree/Type.h
r3a2128f r1f44196 20 20 #include "Visitor.h" 21 21 #include "Mutator.h" 22 #include "Common/utility.h" 22 23 23 24 class Type { … … 27 28 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 ) {} 28 29 30 Qualifiers &operator&=( const Qualifiers &other ); 29 31 Qualifiers &operator+=( const Qualifiers &other ); 30 32 Qualifiers &operator-=( const Qualifiers &other ); … … 63 65 void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; } 64 66 void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; } 65 std::list<TypeDecl*>& get_forall() { return forall; } 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; } 66 74 67 75 virtual Type *clone() const = 0; … … 71 79 private: 72 80 Qualifiers tq; 73 std::list<TypeDecl*>forall;81 ForallList forall; 74 82 }; 75 83 … … 77 85 public: 78 86 VoidType( const Type::Qualifiers &tq ); 87 88 virtual unsigned size() const { return 0; }; 79 89 80 90 virtual VoidType *clone() const { return new VoidType( *this ); } … … 234 244 public: 235 245 StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {} 246 StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct ); 236 247 StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {} 237 248 … … 348 359 class TupleType : public Type { 349 360 public: 350 TupleType( const Type::Qualifiers &tq );361 TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types = std::list< Type * >() ); 351 362 TupleType( const TupleType& ); 352 363 virtual ~TupleType(); 353 364 365 typedef std::list<Type*> value_type; 366 typedef value_type::iterator iterator; 367 354 368 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(); } 355 373 356 374 virtual TupleType *clone() const { return new TupleType( *this ); } … … 442 460 }; 443 461 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 444 471 inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) { 445 472 isConst |= other.isConst; -
src/SynTree/TypeSubstitution.cc
r3a2128f r1f44196 72 72 Type *TypeSubstitution::lookup( std::string formalType ) const { 73 73 TypeEnvType::const_iterator i = typeEnv.find( formalType ); 74 74 75 75 // break on not in substitution set 76 76 if ( i == typeEnv.end() ) return 0; 77 77 78 78 // attempt to transitively follow TypeInstType links. 79 79 while ( TypeInstType *actualType = dynamic_cast< TypeInstType* >( i->second ) ) { 80 80 const std::string& typeName = actualType->get_name(); 81 81 82 82 // break cycles in the transitive follow 83 83 if ( formalType == typeName ) break; 84 84 85 85 // Look for the type this maps to, returning previous mapping if none-such 86 86 i = typeEnv.find( typeName ); 87 87 if ( i == typeEnv.end() ) return actualType; 88 88 } 89 89 90 90 // return type from substitution set 91 91 return i->second; 92 92 93 93 #if 0 94 94 if ( i == typeEnv.end() ) { … … 149 149 // bind type variables from forall-qualifiers 150 150 if ( freeOnly ) { 151 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {151 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 152 152 boundVars.insert( (*tyvar )->get_name() ); 153 153 } // for … … 163 163 // bind type variables from forall-qualifiers 164 164 if ( freeOnly ) { 165 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {165 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 166 166 boundVars.insert( (*tyvar )->get_name() ); 167 167 } // for -
src/SynTree/Visitor.cc
r3a2128f r1f44196 150 150 151 151 void Visitor::visit( ApplicationExpr *applicationExpr ) { 152 acceptAll( applicationExpr->get_results(), *this );152 maybeAccept( applicationExpr->get_result(), *this ); 153 153 maybeAccept( applicationExpr->get_function(), *this ); 154 154 acceptAll( applicationExpr->get_args(), *this ); … … 156 156 157 157 void Visitor::visit( UntypedExpr *untypedExpr ) { 158 acceptAll( untypedExpr->get_results(), *this );158 maybeAccept( untypedExpr->get_result(), *this ); 159 159 acceptAll( untypedExpr->get_args(), *this ); 160 160 } 161 161 162 162 void Visitor::visit( NameExpr *nameExpr ) { 163 acceptAll( nameExpr->get_results(), *this );163 maybeAccept( nameExpr->get_result(), *this ); 164 164 } 165 165 166 166 void Visitor::visit( AddressExpr *addressExpr ) { 167 acceptAll( addressExpr->get_results(), *this );167 maybeAccept( addressExpr->get_result(), *this ); 168 168 maybeAccept( addressExpr->get_arg(), *this ); 169 169 } 170 170 171 171 void Visitor::visit( LabelAddressExpr *labAddressExpr ) { 172 acceptAll( labAddressExpr->get_results(), *this );172 maybeAccept( labAddressExpr->get_result(), *this ); 173 173 maybeAccept( labAddressExpr->get_arg(), *this ); 174 174 } 175 175 176 176 void Visitor::visit( CastExpr *castExpr ) { 177 acceptAll( castExpr->get_results(), *this );177 maybeAccept( castExpr->get_result(), *this ); 178 178 maybeAccept( castExpr->get_arg(), *this ); 179 179 } 180 180 181 181 void Visitor::visit( UntypedMemberExpr *memberExpr ) { 182 acceptAll( memberExpr->get_results(), *this );182 maybeAccept( memberExpr->get_result(), *this ); 183 183 maybeAccept( memberExpr->get_aggregate(), *this ); 184 maybeAccept( memberExpr->get_member(), *this ); 184 185 } 185 186 186 187 void Visitor::visit( MemberExpr *memberExpr ) { 187 acceptAll( memberExpr->get_results(), *this );188 maybeAccept( memberExpr->get_result(), *this ); 188 189 maybeAccept( memberExpr->get_aggregate(), *this ); 189 190 } 190 191 191 192 void Visitor::visit( VariableExpr *variableExpr ) { 192 acceptAll( variableExpr->get_results(), *this );193 maybeAccept( variableExpr->get_result(), *this ); 193 194 } 194 195 195 196 void Visitor::visit( ConstantExpr *constantExpr ) { 196 acceptAll( constantExpr->get_results(), *this );197 maybeAccept( constantExpr->get_result(), *this ); 197 198 maybeAccept( constantExpr->get_constant(), *this ); 198 199 } 199 200 200 201 void Visitor::visit( SizeofExpr *sizeofExpr ) { 201 acceptAll( sizeofExpr->get_results(), *this );202 maybeAccept( sizeofExpr->get_result(), *this ); 202 203 if ( sizeofExpr->get_isType() ) { 203 204 maybeAccept( sizeofExpr->get_type(), *this ); … … 208 209 209 210 void Visitor::visit( AlignofExpr *alignofExpr ) { 210 acceptAll( alignofExpr->get_results(), *this );211 maybeAccept( alignofExpr->get_result(), *this ); 211 212 if ( alignofExpr->get_isType() ) { 212 213 maybeAccept( alignofExpr->get_type(), *this ); … … 217 218 218 219 void Visitor::visit( UntypedOffsetofExpr *offsetofExpr ) { 219 acceptAll( offsetofExpr->get_results(), *this );220 maybeAccept( offsetofExpr->get_result(), *this ); 220 221 maybeAccept( offsetofExpr->get_type(), *this ); 221 222 } 222 223 223 224 void Visitor::visit( OffsetofExpr *offsetofExpr ) { 224 acceptAll( offsetofExpr->get_results(), *this );225 maybeAccept( offsetofExpr->get_result(), *this ); 225 226 maybeAccept( offsetofExpr->get_type(), *this ); 226 227 maybeAccept( offsetofExpr->get_member(), *this ); … … 228 229 229 230 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) { 230 acceptAll( offsetPackExpr->get_results(), *this );231 maybeAccept( offsetPackExpr->get_result(), *this ); 231 232 maybeAccept( offsetPackExpr->get_type(), *this ); 232 233 } 233 234 234 235 void Visitor::visit( AttrExpr *attrExpr ) { 235 acceptAll( attrExpr->get_results(), *this );236 maybeAccept( attrExpr->get_result(), *this ); 236 237 if ( attrExpr->get_isType() ) { 237 238 maybeAccept( attrExpr->get_type(), *this ); … … 242 243 243 244 void Visitor::visit( LogicalExpr *logicalExpr ) { 244 acceptAll( logicalExpr->get_results(), *this );245 maybeAccept( logicalExpr->get_result(), *this ); 245 246 maybeAccept( logicalExpr->get_arg1(), *this ); 246 247 maybeAccept( logicalExpr->get_arg2(), *this ); … … 248 249 249 250 void Visitor::visit( ConditionalExpr *conditionalExpr ) { 250 acceptAll( conditionalExpr->get_results(), *this );251 maybeAccept( conditionalExpr->get_result(), *this ); 251 252 maybeAccept( conditionalExpr->get_arg1(), *this ); 252 253 maybeAccept( conditionalExpr->get_arg2(), *this ); … … 255 256 256 257 void Visitor::visit( CommaExpr *commaExpr ) { 257 acceptAll( commaExpr->get_results(), *this );258 maybeAccept( commaExpr->get_result(), *this ); 258 259 maybeAccept( commaExpr->get_arg1(), *this ); 259 260 maybeAccept( commaExpr->get_arg2(), *this ); 260 261 } 261 262 262 void Visitor::visit( TupleExpr *tupleExpr ) {263 acceptAll( tupleExpr->get_results(), *this );264 acceptAll( tupleExpr->get_exprs(), *this );265 }266 267 void Visitor::visit( SolvedTupleExpr *tupleExpr ) {268 acceptAll( tupleExpr->get_results(), *this );269 acceptAll( tupleExpr->get_exprs(), *this );270 }271 272 263 void Visitor::visit( TypeExpr *typeExpr ) { 273 acceptAll( typeExpr->get_results(), *this );264 maybeAccept( typeExpr->get_result(), *this ); 274 265 maybeAccept( typeExpr->get_type(), *this ); 275 266 } … … 288 279 289 280 void Visitor::visit( ConstructorExpr * ctorExpr ) { 290 acceptAll( ctorExpr->get_results(), *this );281 maybeAccept( ctorExpr->get_result(), *this ); 291 282 maybeAccept( ctorExpr->get_callExpr(), *this ); 292 283 } 293 284 294 285 void Visitor::visit( CompoundLiteralExpr *compLitExpr ) { 295 acceptAll( compLitExpr->get_results(), *this );286 maybeAccept( compLitExpr->get_result(), *this ); 296 287 maybeAccept( compLitExpr->get_type(), *this ); 297 288 maybeAccept( compLitExpr->get_initializer(), *this ); … … 299 290 300 291 void Visitor::visit( UntypedValofExpr *valofExpr ) { 301 acceptAll( valofExpr->get_results(), *this );292 maybeAccept( valofExpr->get_result(), *this ); 302 293 maybeAccept( valofExpr->get_body(), *this ); 303 294 } … … 306 297 maybeAccept( rangeExpr->get_low(), *this ); 307 298 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 ); 308 331 } 309 332 -
src/SynTree/Visitor.h
r3a2128f r1f44196 71 71 virtual void visit( ConditionalExpr *conditionalExpr ); 72 72 virtual void visit( CommaExpr *commaExpr ); 73 virtual void visit( TupleExpr *tupleExpr );74 virtual void visit( SolvedTupleExpr *tupleExpr );75 73 virtual void visit( TypeExpr *typeExpr ); 76 74 virtual void visit( AsmExpr *asmExpr ); … … 80 78 virtual void visit( UntypedValofExpr *valofExpr ); 81 79 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 ); 82 86 83 87 virtual void visit( VoidType *basicType ); -
src/SynTree/module.mk
r3a2128f r1f44196 49 49 SynTree/AddStmtVisitor.cc \ 50 50 SynTree/TypeSubstitution.cc \ 51 SynTree/Attribute.cc 51 SynTree/Attribute.cc \ 52 SynTree/VarExprReplacer.cc 52 53 -
src/Tuples/TupleAssignment.cc
r3a2128f r1f44196 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon May 18 15:02:53 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Nov 9 13:48:42 2016 13 13 // Update Count : 2 14 14 // … … 18 18 #include "ResolvExpr/typeops.h" 19 19 #include "SynTree/Expression.h" 20 #include "TupleAssignment.h" 20 #include "SynTree/Initializer.h" 21 #include "Tuples.h" 22 #include "Explode.h" 21 23 #include "Common/SemanticError.h" 24 #include "InitTweak/InitTweak.h" 22 25 23 26 #include <functional> … … 27 30 #include <cassert> 28 31 #include <set> 32 #include <unordered_set> 29 33 30 34 namespace Tuples { 31 TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f ) 32 : currentFinder(f), matcher(0), hasMatched( false ) {} 33 34 bool TupleAssignSpotter::pointsToTuple( Expression *expr ) { 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 ¤tFinder; 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 ) { 73 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 ) { 35 88 // 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; 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 } 39 94 return false; 40 95 } 41 96 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 50 if ( ! expr ) return false; 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 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 { 150 124 // mass assignment 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() ) ); 125 matcher.reset( new MassAssignMatcher( *this, *ali ) ); 178 126 } 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() ) ); 127 match(); 189 128 } 190 129 } 191 130 } 192 131 } 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 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 149 } 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? 267 243 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 ); 373 } 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; 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 } 408 256 } 409 257 } // namespace Tuples -
src/Tuples/module.mk
r3a2128f r1f44196 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 16 16 17 17 SRC += Tuples/TupleAssignment.cc \ 18 Tuples/NameMatcher.cc 18 Tuples/TupleExpansion.cc \ 19 Tuples/Explode.cc -
src/driver/cfa.cc
r3a2128f r1f44196 244 244 nargs += 1; 245 245 } // if 246 args[nargs] = "-I" CFA_INCDIR "/concurrency"; 247 nargs += 1; 246 248 args[nargs] = "-I" CFA_INCDIR "/containers"; 247 249 nargs += 1; -
src/libcfa/Makefile.am
r3a2128f r1f44196 56 56 CC = ${abs_top_srcdir}/src/driver/cfa 57 57 58 headers = limits stdlib math iostream fstream iterator rational containers/vector 58 headers = limits stdlib math iostream fstream iterator rational assert containers/vector concurrency/threads 59 runtimehdrs = concurrency 59 60 libobjs = ${headers:=.o} 60 61 -
src/libcfa/Makefile.in
r3a2128f r1f44196 92 92 am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) math.$(OBJEXT) \ 93 93 iostream.$(OBJEXT) fstream.$(OBJEXT) iterator.$(OBJEXT) \ 94 rational.$(OBJEXT) containers/vector.$(OBJEXT) 94 rational.$(OBJEXT) assert.$(OBJEXT) \ 95 containers/vector.$(OBJEXT) concurrency/threads.$(OBJEXT) 95 96 am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1) 96 97 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) … … 234 235 cfalib_DATA = builtins.cf extras.cf prelude.cf 235 236 MAINTAINERCLEANFILES = builtins.cf extras.cf ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}} 236 headers = limits stdlib math iostream fstream iterator rational containers/vector 237 headers = limits stdlib math iostream fstream iterator rational assert containers/vector concurrency/threads 238 runtimehdrs = concurrency 237 239 libobjs = ${headers:=.o} 238 240 libcfa_a_SOURCES = libcfa-prelude.c ${headers:=.c} … … 312 314 containers/vector.$(OBJEXT): containers/$(am__dirstamp) \ 313 315 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) 314 324 libcfa.a: $(libcfa_a_OBJECTS) $(libcfa_a_DEPENDENCIES) $(EXTRA_libcfa_a_DEPENDENCIES) 315 325 $(AM_V_at)-rm -f libcfa.a … … 319 329 mostlyclean-compile: 320 330 -rm -f *.$(OBJEXT) 331 -rm -f concurrency/threads.$(OBJEXT) 321 332 -rm -f containers/vector.$(OBJEXT) 322 333 … … 324 335 -rm -f *.tab.c 325 336 337 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Po@am__quote@ 326 338 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstream.Po@am__quote@ 327 339 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iostream.Po@am__quote@ … … 332 344 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rational.Po@am__quote@ 333 345 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@ 346 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/threads.Po@am__quote@ 334 347 @AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/vector.Po@am__quote@ 335 348 … … 505 518 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 506 519 -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) 507 522 -rm -f containers/$(DEPDIR)/$(am__dirstamp) 508 523 -rm -f containers/$(am__dirstamp) … … 517 532 518 533 distclean: distclean-am 519 -rm -rf ./$(DEPDIR) con tainers/$(DEPDIR)534 -rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) 520 535 -rm -f Makefile 521 536 distclean-am: clean-am distclean-compile distclean-generic \ … … 563 578 564 579 maintainer-clean: maintainer-clean-am 565 -rm -rf ./$(DEPDIR) con tainers/$(DEPDIR)580 -rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) 566 581 -rm -f Makefile 567 582 maintainer-clean-am: distclean-am maintainer-clean-generic \ -
src/main.cc
r3a2128f r1f44196 43 43 #include "Common/UnimplementedError.h" 44 44 #include "../config.h" 45 #include "Tuples/Tuples.h" 45 46 46 47 using namespace std; … … 236 237 OPTPRINT( "tweakInit" ) 237 238 InitTweak::genInit( translationUnit ); 238 239 OPTPRINT( "expandMemberTuples" ); 240 Tuples::expandMemberTuples( translationUnit ); 239 241 if ( libcfap ) { 240 242 // generate the bodies of cfa library functions … … 261 263 return 0; 262 264 } // 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 ); 263 268 264 269 OPTPRINT("instantiateGenerics") … … 277 282 OPTPRINT( "box" ) 278 283 GenPoly::box( translationUnit ); 284 OPTPRINT( "expandTuples" ); // xxx - is this the right place for this? 285 Tuples::expandTuples( translationUnit ); 279 286 280 287 // print tree right before code generation
Note:
See TracChangeset
for help on using the changeset viewer.