Changes in / [1f44196:3a2128f]
- Files:
-
- 5 added
- 22 deleted
- 70 edited
-
doc/proposals/concurrency/Makefile (modified) (1 diff)
-
doc/proposals/concurrency/concurrency.tex (modified) (33 diffs)
-
doc/proposals/concurrency/glossary.tex (modified) (2 diffs)
-
doc/proposals/concurrency/style.tex (deleted)
-
doc/proposals/concurrency/version (modified) (1 diff)
-
doc/proposals/virtual.txt (deleted)
-
doc/working/.gitignore (deleted)
-
doc/working/declarative_resolver.tex (deleted)
-
doc/working/resolver_design.md (modified) (1 diff)
-
src/CodeGen/CodeGenerator.cc (modified) (4 diffs)
-
src/CodeGen/CodeGenerator.h (modified) (1 diff)
-
src/CodeGen/GenType.cc (modified) (1 diff)
-
src/Common/utility.h (modified) (2 diffs)
-
src/ControlStruct/LabelTypeChecker.cc (added)
-
src/ControlStruct/LabelTypeChecker.h (added)
-
src/ControlStruct/Mutate.cc (modified) (2 diffs)
-
src/ControlStruct/module.mk (modified) (2 diffs)
-
src/GenPoly/Box.cc (modified) (26 diffs)
-
src/GenPoly/CopyParams.cc (modified) (1 diff)
-
src/GenPoly/FindFunction.cc (modified) (2 diffs)
-
src/GenPoly/GenPoly.cc (modified) (3 diffs)
-
src/GenPoly/Lvalue.cc (modified) (8 diffs)
-
src/GenPoly/Specialize.cc (modified) (4 diffs)
-
src/InitTweak/FixInit.cc (modified) (14 diffs)
-
src/InitTweak/GenInit.cc (modified) (10 diffs)
-
src/InitTweak/GenInit.h (modified) (2 diffs)
-
src/InitTweak/InitTweak.cc (modified) (3 diffs)
-
src/Makefile.in (modified) (14 diffs)
-
src/Parser/ExpressionNode.cc (modified) (2 diffs)
-
src/Parser/ParseNode.h (modified) (3 diffs)
-
src/Parser/TypeData.cc (modified) (2 diffs)
-
src/Parser/parser.cc (modified) (269 diffs)
-
src/Parser/parser.yy (modified) (3 diffs)
-
src/ResolvExpr/Alternative.cc (modified) (5 diffs)
-
src/ResolvExpr/Alternative.h (modified) (3 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (31 diffs)
-
src/ResolvExpr/AlternativeFinder.h (modified) (2 diffs)
-
src/ResolvExpr/AlternativePrinter.cc (modified) (2 diffs)
-
src/ResolvExpr/ConversionCost.cc (modified) (1 diff)
-
src/ResolvExpr/FindOpenVars.cc (modified) (3 diffs)
-
src/ResolvExpr/RenameVars.cc (modified) (2 diffs)
-
src/ResolvExpr/ResolveTypeof.cc (modified) (2 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (7 diffs)
-
src/ResolvExpr/TypeEnvironment.cc (modified) (1 diff)
-
src/ResolvExpr/TypeEnvironment.h (modified) (1 diff)
-
src/ResolvExpr/Unify.cc (modified) (1 diff)
-
src/ResolvExpr/typeops.h (modified) (6 diffs)
-
src/SymTab/Autogen.cc (modified) (1 diff)
-
src/SymTab/Indexer.cc (modified) (12 diffs)
-
src/SymTab/Indexer.h (modified) (1 diff)
-
src/SymTab/Mangler.cc (modified) (4 diffs)
-
src/SymTab/Validate.cc (modified) (3 diffs)
-
src/SynTree/AddressExpr.cc (modified) (2 diffs)
-
src/SynTree/ApplicationExpr.cc (modified) (2 diffs)
-
src/SynTree/CommaExpr.cc (modified) (1 diff)
-
src/SynTree/CompoundStmt.cc (modified) (2 diffs)
-
src/SynTree/Expression.cc (modified) (21 diffs)
-
src/SynTree/Expression.h (modified) (9 diffs)
-
src/SynTree/Initializer.h (modified) (1 diff)
-
src/SynTree/Mutator.cc (modified) (20 diffs)
-
src/SynTree/Mutator.h (modified) (2 diffs)
-
src/SynTree/ReferenceToType.cc (modified) (1 diff)
-
src/SynTree/SynTree.h (modified) (2 diffs)
-
src/SynTree/TupleExpr.cc (modified) (3 diffs)
-
src/SynTree/TupleType.cc (modified) (2 diffs)
-
src/SynTree/Type.h (modified) (8 diffs)
-
src/SynTree/TypeSubstitution.cc (modified) (3 diffs)
-
src/SynTree/VarExprReplacer.cc (deleted)
-
src/SynTree/VarExprReplacer.h (deleted)
-
src/SynTree/Visitor.cc (modified) (11 diffs)
-
src/SynTree/Visitor.h (modified) (2 diffs)
-
src/SynTree/module.mk (modified) (1 diff)
-
src/Tuples/Explode.cc (deleted)
-
src/Tuples/Explode.h (deleted)
-
src/Tuples/NameMatcher.cc (added)
-
src/Tuples/NameMatcher.h (added)
-
src/Tuples/TupleAssignment.cc (modified) (3 diffs)
-
src/Tuples/TupleAssignment.h (added)
-
src/Tuples/TupleExpansion.cc (deleted)
-
src/Tuples/Tuples.h (deleted)
-
src/Tuples/module.mk (modified) (2 diffs)
-
src/driver/cfa.cc (modified) (1 diff)
-
src/examples/ArrayN.c (deleted)
-
src/examples/coroutine.c (deleted)
-
src/libcfa/Makefile.am (modified) (1 diff)
-
src/libcfa/Makefile.in (modified) (9 diffs)
-
src/libcfa/assert (deleted)
-
src/libcfa/assert.c (deleted)
-
src/libcfa/concurrency/threads (deleted)
-
src/libcfa/concurrency/threads.c (deleted)
-
src/main.cc (modified) (4 diffs)
-
src/tests/.expect/tupleAssign.txt (deleted)
-
src/tests/.expect/tupleFunction.txt (deleted)
-
src/tests/.expect/tupleMember.txt (deleted)
-
src/tests/tupleAssign.c (deleted)
-
src/tests/tupleFunction.c (deleted)
-
src/tests/tupleMember.c (deleted)
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/concurrency/Makefile
r1f44196 r3a2128f 9 9 SOURCES = ${addsuffix .tex, \ 10 10 concurrency \ 11 style \12 glossary \13 11 } 14 12 -
doc/proposals/concurrency/concurrency.tex
r1f44196 r3a2128f 14 14 15 15 % Latex packages used in the document. 16 \usepackage[T1]{fontenc} % allow Latin1 (extended ASCII) characters16 \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} % switch curled `'" to straight21 \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} % extended references27 \usepackage{varioref} % extended references 28 28 \usepackage{inconsolata} 29 \usepackage{listings} % format program code30 \usepackage[flushmargin]{footmisc} % support label/reference in footnote31 \usepackage{latexsym} % \Box glyph32 \usepackage{mathptmx} % better math font with "times"29 \usepackage{listings} % format program code 30 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 31 \usepackage{latexsym} % \Box glyph 32 \usepackage{mathptmx} % better math font with "times" 33 33 \usepackage[usenames]{color} 34 34 \usepackage[pagewise]{lineno} 35 35 \usepackage{fancyhdr} 36 36 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 37 \input{ style}% bespoke macros used in the document37 \input{common} % 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} % move running title into header46 \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 Schoolof Computer Science, University of Waterloo, \\ Waterloo, Ontario, Canada88 Dept. 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 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. 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. 105 106 106 107 % ##### ####### # # ##### # # ###### ###### ####### # # ##### # # … … 113 114 114 115 \section{Concurrency} 115 Several tool can be used to solve concurrency challenges. Since these challenges always appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms that closely relate to networking concepts (channels\cit for example). However, in languages that use routine calls as their core abstraction mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine call). Which in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. This distinction can be hidden away in library code, but effective use of the librairy still has to take both paradigms into account. Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and objects. At a lower level these can be implemented as locks and atomic operations. Many such mechanisms have been proposed, including semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}. However, for productivity reasons it is desireable to have a higher-level construct be the core concurrency paradigm~\cite{HPP:Study}. An approach that is worth mentionning because it is gaining in popularity is transactionnal memory~\cite{Dice10}[Check citation]. While this approach is even pursued by system languages like \CC\cit, the performance and feature set is currently too restrictive to add such a paradigm to a language like C or \CC\cit, which is why it was rejected as the core paradigm for concurrency in \CFA. One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared memory systems, is the \emph{monitor}. Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. Many programming languages---e.g., Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs. In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors. For these reasons, this project proposes monitors as the core concurrency construct. 116 % Several tool can be used to solve concurrency challenges. Since these challenges always appear with the use of mutable shared state, some languages and libraries simply disallow mutable shared-state (Erlang\cite{Erlang}, Haskell\cite{Haskell}, Akka (Scala)\cite{Akka}). In these paradigms, interaction among concurrent objects rely on message passing or other paradigms that often closely relate to networking concepts. However, in imperative or OO languages, these approaches entail a clear distinction between concurrent and non-concurrent paradigms (i.e. message passing versus routine call). Which in turns mean that programmers need to learn two sets of designs patterns in order to be effective. Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on non-concurrent constructs like routine calls and objects. At a lower level these can be implemented as locks and atomic operations. However, for productivity reasons it is desireable to have a higher-level construct to be the core concurrency paradigm\cite{HPP:Study}. This project proposes Monitors\cite{Hoare74} as the core concurrency construct. 117 % \\ 118 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. 116 126 117 127 % # # ####### # # ### ####### ####### ###### ##### … … 124 134 125 135 \subsection{Monitors} 126 A monitor is a set of routines that ensure mutual exclusion when accessing shared state. This concept is generally associated with Object-Oriented Languages like Java ~\cite{Java} or \uC~\cite{uC++book} but does not strictly require OOP semantics. The only requirements is the ability to declare a handle to a shared object and a set of routines that act on it :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 : 127 137 \begin{lstlisting} 128 138 typedef /*some monitor type*/ monitor; … … 144 154 145 155 \subsubsection{Call semantics} \label{call} 146 The above monitor example displays some of the intrinsic characteristics. Indeed, it is necessary to use pass-by-reference over pass-by-value for monitor routines. This semantics is important because at their core, monitors are implicit mutual-exclusion objects (locks), and these objects cannot be copied. Therefore, monitors are implicitly non-copyable. 147 148 Another aspect to consider is when a monitor acquires its mutual exclusion. For example, a monitor may need to be passed through multiple helper routines that do not acquire the monitor mutual-exclusion on entry. Pass through can be both generic helper routines (\code{swap}, \code{sort}, etc.) or specific helper routines like the following to implement an atomic counter : 149 150 \begin{lstlisting} 151 mutex struct counter_t { /*...see section §\ref{data}§...*/ }; 152 153 void ?{}(counter_t & nomutex this); //constructor 154 size_t ++?(counter_t & mutex this); //increment 155 156 //need for mutex is platform dependent here 157 void ?{}(size_t * this, counter_t & mutex cnt); //conversion 158 \end{lstlisting} 159 160 Here, the constructor(\code{?\{\}}) uses the \code{nomutex} keyword to signify that it does not acquire the monitor mutual exclusion when constructing. This semantics is because an object not yet constructed should never be shared and therefore does not require mutual exclusion. The prefix increment operator uses \code{mutex} to protect the incrementing process from race conditions. Finally, there is a conversion operator from \code{counter_t} to \code{size_t}. This conversion may or may not require the \code{mutex} key word depending on whether or not reading an \code{size_t} is an atomic operation or not. 161 162 Having both \code{mutex} and \code{nomutex} keywords could be argued to be redundant based on the meaning of a routine having neither of these keywords. For example, given a routine without wualifiers \code{void foo(counter_t & this)} then one could argue that it should default to the safest option \code{mutex}. On the other hand, the option of having routine \code{void foo(counter_t & this)} mean \code{nomutex} is unsafe by default and may easily cause subtle errors. It can be argued that \code{nomutex} is the more "normal" behaviour, the \code{nomutex} keyword effectively stating explicitly that "this routine has nothing special". Another alternative is to make having exactly one of these keywords mandatory, which would provide the same semantics but without the ambiguity of supporting routine \code{void foo(counter_t & this)}. Mandatory keywords would also have the added benefice of being self-documented but at the cost of extra typing. In the end, which solution should be picked is still up for debate. For the reminder of this proposal, the explicit approach is used for clarity. 163 164 The next semantic decision is to establish when mutex/nomutex may be used as a type qualifier. Consider the following declarations: 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. 165 179 \begin{lstlisting} 166 180 int f1(monitor & mutex m); … … 170 184 int f5(graph(monitor*) & mutex m); 171 185 \end{lstlisting} 172 The problem is to indentify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to indentify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C and even then making sure we only acquire objects once becomes also none trivial. This can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To keep everyone as sane as possible~\cite{Chicken}, this projects imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter (ignoring potential qualifiers and indirections). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is be acquired, passing an array to this routine would be type safe and yet result in undefined behavior because only the first element of the array is acquired. However, this ambiguity is part of the C type system with respects to arrays. For this reason, it would also be reasonnable to disallow mutex in the context where arrays may be passed. 186 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). 173 188 174 189 % ###### # ####### # … … 181 196 182 197 \subsubsection{Data semantics} \label{data} 183 Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contian shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appr opriate protection. For example, here is a complete version of the counter showed in section \ref{call}: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 appripriate protection. For example here is a more fleshed-out version of the counter showed in \ref{call}: 184 199 \begin{lstlisting} 185 200 mutex struct counter_t { … … 192 207 193 208 int ++?(counter_t & mutex this) { 194 return ++this.value; 195 } 196 197 //need for mutex is platform dependent here 209 return ++this->value; 210 } 211 198 212 void ?{}(int * this, counter_t & mutex cnt) { 199 213 *this = (int)cnt; 200 214 } 201 215 \end{lstlisting} 202 203 This simple counter is used as follows: 204 \begin{center} 205 \begin{tabular}{c @{\hskip 0.35in} c @{\hskip 0.35in} c} 206 \begin{lstlisting} 207 //shared counter 208 counter_t cnt; 209 210 //multiple threads access counter 211 thread 1 : cnt++; 212 thread 2 : cnt++; 213 thread 3 : cnt++; 214 ... 215 thread N : cnt++; 216 \begin{tabular}{ c c } 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 216 231 \end{lstlisting} 217 232 \end{tabular} 218 \end{center} 219 220 Notice how the counter is used without any explicit synchronisation and yet supports thread-safe semantics for both reading and writting. Unlike object-oriented monitors, where calling a mutex member \emph{implicitly} acquires mutual-exclusion, \CFA uses an explicit mechanism to acquire mutual-exclusion. A consequence of this approach is that it extends to multi-monitor calls. 233 \\ 234 235 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. 221 239 \begin{lstlisting} 222 240 int f(MonitorA & mutex a, MonitorB & mutex b); … … 226 244 f(a,b); 227 245 \end{lstlisting} 228 This code acquires both locks before entering the critical section, called \emph{\gls{group-acquire}}. In practice, writing multi-locking routines that do not lead to deadlocks is tricky. Having language support for such a feature is therefore a significant asset for \CFA. In the case presented above, \CFA guarantees that the order of aquisition is consistent across calls to routines using the same monitors as arguments. However, since \CFA monitors use multi-acquisition locks, users can effectively force the acquiring order. For example, notice which routines use \code{mutex}/\code{nomutex} and how this affects aquiring order : 229 \begin{lstlisting} 230 void foo(A & mutex a, B & mutex b) { //acquire a & b 246 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) { 231 250 //... 232 251 } 233 252 234 void bar(A & mutex a, B & nomutex b) { //acquire a253 void bar(A & mutex a, B & nomutex a) 235 254 //... 236 foo(a, b); //acquire b255 foo(a, b); 237 256 //... 238 257 } 239 258 240 void baz(A & nomutex a, B & mutex b) { //acquire b259 void baz(A & nomutex a, B & mutex a) 241 260 //... 242 foo(a, b); //acquire a261 foo(a, b); 243 262 //... 244 263 } 245 264 \end{lstlisting} 246 265 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. 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. 254 267 255 268 % ###### ####### ####### # ### # ##### … … 270 283 271 284 \subsubsection{Implementation Details: Interaction with polymorphism} 272 At first glance, interaction between monitors and \CFA's concept of polymorphism seems complex to support. However, it is shown that entry-point locking can solve most of the issues. 273 274 Before looking into complex control flow, it is important to present the difference between the two acquiring options : \gls{callsite-locking} and \gls{entry-point-locking}, i.e. acquiring the monitors before making a mutex call or as the first instruction of the mutex call. For example: 275 276 \begin{center} 277 \begin{tabular}{|c|c|c|} 278 Code & \gls{callsite-locking} & \gls{entry-point-locking} \\ 279 \CFA & pseudo-code & pseudo-code \\ 280 \hline 281 \begin{lstlisting} 282 void foo(monitor & mutex a) { 283 284 285 286 //Do Work 287 //... 288 289 } 290 291 void main() { 292 monitor a; 293 294 295 296 foo(a); 297 298 } 299 \end{lstlisting} &\begin{lstlisting} 300 foo(& a) { 301 302 303 304 //Do Work 305 //... 306 307 } 308 309 main() { 310 monitor a; 311 //calling routine 312 //handles concurrency 313 acquire(a); 314 foo(a); 315 release(a); 316 } 317 \end{lstlisting} &\begin{lstlisting} 318 foo(& a) { 319 //called routine 320 //handles concurrency 321 acquire(a); 322 //Do Work 323 //... 324 release(a); 325 } 326 327 main() { 328 monitor a; 329 330 331 332 foo(a); 333 334 } 335 \end{lstlisting} 336 \end{tabular} 337 \end{center} 338 339 First of all, interaction between \code{otype} polymorphism and monitors is impossible since monitors do not support copying. Therefore, the main question is how to support \code{dtype} polymorphism. Since a monitor's main purpose is to ensure mutual exclusion when accessing shared data, this implies that mutual exclusion is only required for routines that do in fact access shared data. However, since \code{dtype} polymorphism always handles incomplete types (by definition), no \code{dtype} polymorphic routine can access shared data since the data requires knowledge about the type. Therefore, the only concern when combining \code{dtype} polymorphism and monitors is to protect access to routines. \Gls{callsite-locking} would require a significant amount of work, since any \code{dtype} routine may have to obtain some lock before calling a routine, depending on whether or not the type passed is a monitor. However, with \gls{entry-point-locking} calling a monitor routine becomes exactly the same as calling it from anywhere else. 340 341 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. 342 288 343 289 % ### # # ####### ##### ##### # # ####### ###### … … 350 296 351 297 \subsection{Internal scheduling} \label{insched} 352 Monitors also need to schedule waiting threads internally as a mean of synchronization. Internal scheduling is one of the simple examples of such a feature. It allows users to declare condition variables and have threads wait and signaled from them. Here is a simple example of such a technique :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 : 353 299 354 300 \begin{lstlisting} … … 368 314 \end{lstlisting} 369 315 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. 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 371 318 \begin{center} 372 319 \begin{tabular}{ c @{\hskip 0.65in} c } … … 374 321 \begin{lstlisting} 375 322 void foo(monitor & mutex a, 376 monitor & mutex b) {323 monitor & mutex b) { 377 324 //... 378 325 wait(a.e); … … 383 330 \end{lstlisting} &\begin{lstlisting} 384 331 void bar(monitor & mutex a, 385 monitor & mutex b) {332 monitor & mutex b) { 386 333 signal(a.e); 387 334 } … … 393 340 \end{tabular} 394 341 \end{center} 395 A direct extension of the single monitor semantics is to release all locks when waiting and transferring ownership of all locks when signalling. However, for the purpose of synchronization it may be usefull to only release some of the locks but keep others. It is possible to support internal scheduling and \gls{group-acquire} without any extra syntax by relying on order of acquisition. Here is an example of the different contexts in which internal scheduling can be used. (Note that here the use of helper routines is irrelevant, only routines acquire mutual exclusion have an impact on internal scheduling): 342 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): 396 344 397 345 \begin{center} … … 402 350 condition e; 403 351 404 //acquire a & b405 352 void foo(monitor & mutex a, 406 monitor & mutex b) { 407 408 wait(e); //release a & b 353 monitor & mutex b) { 354 wait(e); 409 355 } 410 356 … … 418 364 condition e; 419 365 420 //acquire a421 366 void bar(monitor & mutex a, 422 monitor & nomutex b) {367 monitor & nomutex b) { 423 368 foo(a,b); 424 369 } 425 370 426 //acquire a & b427 371 void foo(monitor & mutex a, 428 monitor & mutex b) {429 wait(e); //release a & b372 monitor & mutex b) { 373 wait(e); 430 374 } 431 375 … … 434 378 condition e; 435 379 436 //acquire a437 380 void bar(monitor & mutex a, 438 monitor & nomutex b) { 439 baz(a,b); 440 } 441 442 //acquire b 381 monitor & nomutex b) { 382 foo(a,b); 383 } 384 443 385 void baz(monitor & nomutex a, 444 monitor & mutex b) {445 wait(e); //release b386 monitor & mutex b) { 387 wait(e); 446 388 } 447 389 … … 451 393 \end{center} 452 394 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 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. : 403 404 \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); 418 \end{lstlisting} 419 \end{tabular} 420 \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 \\ 455 427 456 428 \begin{center} 457 429 \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); 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); 476 453 \end{lstlisting} &\begin{lstlisting} 477 condition e;478 479 //acquire a & b480 454 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); 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 494 473 \end{lstlisting} &\begin{lstlisting} 495 condition e;496 497 //acquire a & b498 474 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); 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 512 493 \end{lstlisting} 513 494 \end{tabular} 514 495 \end{center} 515 Note the right-most example is actually a trick pulled on the reader. Monitor state information is stored in thread local storage rather then in the routine context, which means that helper routines and other \code{nomutex} routines are invisible to the runtime system in regards to concurrency. This means that in the right-most example, the routine parameters are completly unnecessary. However, calling this routine from outside a valid monitor context is undefined. 516 517 These semantics imply that in order to release of subset of the monitors currently held, users must write (and name) a routine that only acquires the desired subset and simply calls wait. While users can use this method, \CFA offers the \code{wait_release}\footnote{Not sure if an overload of \code{wait} would work...} which will release only the specified monitors. In the center previous examples, the code in the center uses the \code{bar} routine to only release monitor \code{b}. Using the \code{wait_release} helper, this can be rewritten without having the name two routines : 518 \begin{center} 519 \begin{tabular}{ c c c } 520 \begin{lstlisting} 521 condition e; 522 523 //acquire a & b 524 void foo(monitor & mutex a, 525 monitor & mutex b) { 526 bar(a,b); 527 } 528 529 //acquire b 530 void bar(monitor & mutex a, 531 monitor & nomutex b) { 532 533 wait(e); //release b 534 //keep a 535 } 536 537 foo(a, b); 538 \end{lstlisting} &\begin{lstlisting} 539 => 540 \end{lstlisting} &\begin{lstlisting} 541 condition e; 542 543 //acquire a & b 544 void foo(monitor & mutex a, 545 monitor & mutex b) { 546 wait_release(e,b); //release b 547 //keep a 548 } 549 550 foo(a, b); 551 \end{lstlisting} 552 \end{tabular} 553 \end{center} 554 555 Regardless of the context in which the \code{wait} statement is used, \code{signal} must be called holding the same set of monitors. In all cases, signal only needs a single parameter, the condition variable that needs to be signalled. But \code{signal} needs to be called from the same monitor(s) that call to \code{wait}. Otherwise, mutual exclusion cannot be properly transferred back to the waiting monitor. 556 557 Finally, an additional semantic which can be very usefull is the \code{signal_block} routine. This routine behaves like signal for all of the semantics discussed above, but with the subtelty that mutual exclusion is transferred to the waiting task immediately rather than wating for the end of the critical section. 496 (Note : Case 2 and 3 use tuple semantics to pass a variable length list of elements.) 497 \\ 498 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. 558 538 \\ 559 539 … … 565 545 % # # # # ### # # # # # # # # # 566 546 % ####### # # # ### ##### ##### # # ####### ###### 567 \newpage 547 568 548 \subsection{External scheduling} \label{extsched} 569 A n 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 showsa simple use \code{accept} versus \code{wait}/\code{signal} and its advantages.549 As one might expect, the alternative to Internal scheduling is to use External scheduling instead. This method is somewhat more robust to deadlocks since one of the threads keeps a relatively tight control on scheduling. Indeed, as the following examples will demonstrate, external scheduling allows users to wait for events from other threads without the concern of unrelated events occuring. External scheduling can generally be done either in terms of control flow (ex: \uC) or in terms of data (ex: Go). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control flow semantics where chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multi-monitor routines. The following example shows what a simple use \code{accept} versus \code{wait}/\code{signal} and its advantages. 570 550 571 551 \begin{center} … … 585 565 586 566 public: 587 void f() { /*...*/ }567 void f(); 588 568 void g() { _Accept(f); } 589 569 private: … … 593 573 \end{center} 594 574 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.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. 596 576 \\ 597 577 … … 776 756 % # # # # # # # ####### ####### ####### ####### ### ##### # # 777 757 \section{Parallelism} 778 Historically, computer performance was about processor speeds and instructions count. However, with heat dissipation being a direct consequence of speed increase, parallelism has become the new source for increased performance~\cite{Sutter05, Sutter05b}. In this decade, it is not longer reasonnable to create a high-performance application without caring about parallelism. Indeed, parallelism is an important aspect of performance and more specifically throughput and hardware utilization. The lowest-level approach of parallelism is to use \glspl{kthread} in combination with semantics like \code{fork}, \code{join}, etc. However, since these have significant costs and limitations, \glspl{kthread} are now mostly used as an implementation tool rather than a user oriented one. There are several alternatives to solve these issues that all have strengths and weaknesses. While there are many variations of the presented paradigms, most of these variations do not actually change the guarantees or the semantics, they simply move costs in order to achieve better performance for certain workloads.758 Historically, computer performance was about processor speeds and instructions count. However, with heat dissipation being an ever growing challenge, parallelism has become the new source of greatest performance \cite{Sutter05, Sutter05b}. In this decade, it is not longer reasonnable to create high-performance application without caring about parallelism. Indeed, parallelism is an important aspect of performance and more specifically throughput and hardware utilization. The lowest level approach of parallelism is to use \glspl{kthread}. However since these have significant costs and limitations \glspl{kthread} are now mostly used as an implementation tool rather than a user oriented one. There are several alternatives to solve these issues which all have strengths and weaknesses. 779 759 780 760 \subsection{User-level threads} 781 A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provide but can be used on a much larger scale. This approach is the most powerfull solution as it allows all the features of multi-threading, while removing several of the more expensives costs of using kernel threads. The down side is that almost none of the low-level threading problems are hidden, users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong garantees but the parallelism toolkit offers very little to reduce complexity in itself. 782 783 Examples of languages that support \glspl{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}. 784 785 \subsubsection{Fibers : user-level threads without preemption} 786 A popular varient of \glspl{uthread} is what is often reffered to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantical differences with \glspl{uthread}. Advocates of \glspl{fiber} list their high performance and ease of implementation as majors strenghts of \glspl{fiber} but the performance difference between \glspl{uthread} and \glspl{fiber} is controversial and the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignore fibers. 787 788 An example of a language that uses fibers is Go~\cite{Go} 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}. 789 764 790 765 \subsection{Jobs and thread pools} 791 The approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly limits the interaction that can occur among jobs. Indeed, any \gls{job} that blocks also blocks the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant amount of blocked jobs always results in idles cores. 792 793 The gold standard of this implementation is Intel's TBB library~\cite{TBB}. 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} 794 772 795 773 \subsection{Paradigm performance} 796 While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pin down 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 islargely amorticised by the actual work done.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 be largely amorticised by the actual work done. 797 775 798 776 % ##### ####### # ####### ###### ###### … … 805 783 806 784 \section{\CFA 's Thread Building Blocks} 807 As a system-level language, \CFA should offer both performance and flexibilty as its primary goals, simplicity and user-friendliness being a secondary concern. Therefore, the core of parallelism in \CFA should prioritize power and efficiency. With this said, deconstructing popular paradigms in order to get simple building blocks yields \glspl{uthread} as the core parallelism block. \Glspl{pool} and other parallelism paradigms can then be built on top of the underlying threading model. 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. 808 801 809 802 % ####### # # ###### ####### # ###### ##### … … 816 809 817 810 \subsection{Thread Interface} 818 The basic building blocks of \CFA are \glspl{cfathread}. By default these are implemented as \glspl{uthread} , and as such, offer a flexible and lightweight threading interface (lightweight compared to \glspl{kthread}). A thread can be declared using a struct declaration with prefix\code{thread} as follows :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 : 819 812 820 813 \begin{lstlisting} … … 822 815 \end{lstlisting} 823 816 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: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 : 825 818 \begin{lstlisting} 826 819 thread struct foo {}; 827 820 828 void ?main( foo* this) {829 sout | "Hello World!" | endl;830 } 831 \end{lstlisting} 832 833 In this example, threads of type \code{foo} will start there execution in the \code{void ?main(foo*)} routine which in this case prints \code{"Hello World!"}. While this proposoal encourages this approach which is enforces strongly type programming. Users may prefer to use the routine based thread semantics for the sake of simplicity.With these semantics it is trivial to write a thread type that takes a function pointer as parameter and executes it on its stack asynchronously :821 void ?main(thread foo* this) { 822 /*... Some useful code ...*/ 823 } 824 \end{lstlisting} 825 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 : 834 827 \begin{lstlisting} 835 828 typedef void (*voidFunc)(void); … … 840 833 841 834 //ctor 842 void ?{}( FuncRunner* this, voidFunc inFunc) {835 void ?{}(thread FuncRunner* this, voidFunc inFunc) { 843 836 func = inFunc; 844 837 } 845 838 846 839 //main 847 void ?main( FuncRunner* this) {840 void ?main(thread FuncRunner* this) { 848 841 this->func(); 849 842 } 850 843 \end{lstlisting} 851 844 852 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} once the constructor has completed and \code{join} before the destructor runs. 853 \begin{lstlisting} 854 thread struct World; //FuncRunner declared above 855 856 void ?main(thread World* this) { 845 % In this example \code{func} is a function pointer stored in \acrfull{tls}, which is \CFA is both easy to use and completly typesafe. 846 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() { 857 852 sout | "World!" | endl; 858 853 } 859 854 860 855 void main() { 861 World w;856 FuncRunner run = {world}; 862 857 //Thread run forks here 863 858 … … 868 863 } 869 864 \end{lstlisting} 870 This semantic has several advantages over explicit semantics : typesafety is guaranteed, a thread is always started and stopped exaclty once and users cannot make any progamming errors. However, one of the apparent drawbacks of this system is that threads now always form a lattice, that is they are always destroyed in opposite order of construction. While this seems like a significant limitation, existing \CFA semantics can solve this problem. Indeed, by using dynamic allocation to create threads will naturally let threads outlive the scope in which the thread was created much like dynamically allocating memory will let objects outlive the scope in which thy were created : 871 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 : 872 868 \begin{lstlisting} 873 869 thread struct MyThread { … … 876 872 877 873 //ctor 878 void ?{}(MyThread* this, 879 bool is_special = false) { 880 //... 881 } 874 void ?{}(thread MyThread* this) {} 882 875 883 876 //main 884 void ?main(MyThread* this) { 885 //... 886 } 887 888 void foo() { 889 MyThread* special_thread; 890 { 891 MyThread thrds = {false}; 892 //Start a thread at the beginning of the scope 893 894 DoStuff(); 895 896 //create a other thread that will outlive the thread in this scope 897 special_thread = new MyThread{true}; 898 899 //Wait for the thread to finish 900 } 901 DoMoreStuff(); 902 903 //Now wait for the special 904 } 905 \end{lstlisting} 906 907 Another advantage of this semantic is that it naturally scale to multiple threads meaning basic synchronisation is very simple : 908 909 \begin{lstlisting} 910 thread struct MyThread { 911 //... 912 }; 913 914 //ctor 915 void ?{}(MyThread* this) {} 916 917 //main 918 void ?main(MyThread* this) { 877 void ?main(thread MyThread* this) { 919 878 //... 920 879 } … … 930 889 \end{lstlisting} 931 890 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 //ctor942 void ?{}(MyCoroutine* this) {943 944 }945 946 //main947 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 communication956 };957 958 void ?main(Fibonacci* this) {959 int fn1, fn2; // retained between resumes960 this->fn = 0;961 fn1 = this->fn;962 suspend(this); // return to last resume963 964 this->fn = 1;965 fn2 = fn1;966 fn1 = this->fn;967 suspend(this); // return to last resume968 969 for ( ;; ) {970 this->fn = fn1 + fn2;971 fn2 = fn1;972 fn1 = this->fn;973 suspend(this); // return to last resume974 }975 }976 977 int next(Fibonacci& this) {978 resume(&this); // transfer to last suspend979 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 990 891 \newpage 991 \ bf{WORK IN PROGRESS}892 \large{\textbf{WORK IN PROGRESS}} 992 893 \subsection{The \CFA Kernel : Processors, Clusters and Threads}\label{kernel} 993 894 -
doc/proposals/concurrency/glossary.tex
r1f44196 r3a2128f 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 22 2 \longnewglossaryentry{uthread} 23 3 {name={user-level thread}} … … 50 30 51 31 \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 : }60 32 } 61 33 -
doc/proposals/concurrency/version
r1f44196 r3a2128f 1 0. 7.481 0.4.99 -
doc/working/resolver_design.md
r1f44196 r3a2128f 1382 1382 hypothesis needs to be empirically validated. 1383 1383 1384 Another approach would be to abandon expression-tree ordering for1385 subexpression matching, and order by "most constrained symbol"; symbols would1386 be more constrained if there were fewer matching declarations, fewer1387 subexpressions yet to resolve, or possibly fewer possible types the expression1388 could resolve to. Ordering the expressions in a priority-queue by this metric1389 would not necessarily produce a top-down or a bottom-up order, but would add1390 opportunities for pruning based on memoized upper and lower bounds.1391 1392 1384 Both Baker and Cormack explicitly generate all possible interpretations of a 1393 1385 given expression; thinking of the set of interpretations of an expression as a -
src/CodeGen/CodeGenerator.cc
r1f44196 r3a2128f 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 application311 // is visited multiple times.312 309 UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 313 310 newExpr->get_args().push_back( *arg ); 314 Type * type = InitTweak::getPointerBase( (*arg)->get_result() ); 315 assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." ); 316 newExpr->set_result( type->clone() ); 311 assert( (*arg)->get_results().size() == 1 ); 312 Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() ); 313 assert( type ); 314 newExpr->get_results().push_back( type->clone() ); 317 315 *arg = newExpr; 318 316 } // if … … 529 527 extension( castExpr ); 530 528 output << "("; 531 if ( castExpr->get_result ()->isVoid() ) {529 if ( castExpr->get_results().empty() ) { 532 530 output << "(void)" ; 533 } else if ( ! castExpr->get_result ()->get_isLvalue() ) {531 } else if ( ! castExpr->get_results().front()->get_isLvalue() ) { 534 532 // at least one result type of cast, but not an lvalue 535 533 output << "("; 536 output << genType( castExpr->get_result (), "" );534 output << genType( castExpr->get_results().front(), "" ); 537 535 output << ")"; 538 536 } else { … … 642 640 } 643 641 644 void CodeGenerator::visit( TupleExpr * tupleExpr ) { assert( false );}642 void CodeGenerator::visit( TupleExpr * tupleExpr ) {} 645 643 646 644 void CodeGenerator::visit( TypeExpr * typeExpr ) {} … … 656 654 asmExpr->get_operand()->accept( *this ); 657 655 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 value677 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 } // if689 ++i;690 }691 cur_indent -= CodeGenerator::tabsize;692 output << indent << "})";693 656 } 694 657 -
src/CodeGen/CodeGenerator.h
r1f44196 r3a2128f 70 70 virtual void visit( ConditionalExpr *conditionalExpr ); 71 71 virtual void visit( CommaExpr *commaExpr ); 72 virtual void visit( CompoundLiteralExpr *compLitExpr );73 72 virtual void visit( TupleExpr *tupleExpr ); 74 73 virtual void visit( TypeExpr *typeExpr ); 75 74 virtual void visit( AsmExpr * ); 76 virtual void visit( StmtExpr * );77 75 78 76 //*** Statements -
src/CodeGen/GenType.cc
r1f44196 r3a2128f 227 227 typeString = "_Atomic " + typeString; 228 228 } // if 229 if ( type->get_isAttribute() ) { 230 typeString = "__attribute(( )) " + typeString; 231 } // if 229 232 } 230 233 } // namespace CodeGen -
src/Common/utility.h
r1f44196 r3a2128f 148 148 } 149 149 150 // replace element of list with all elements of another list151 150 template< typename T > 152 151 void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) { … … 159 158 160 159 return; 161 }162 163 // replace range of a list with a single element164 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 );168 160 } 169 161 -
src/ControlStruct/Mutate.cc
r1f44196 r3a2128f 23 23 #include "MLEMutator.h" 24 24 #include "ForExprMutator.h" 25 #include "LabelTypeChecker.h" 25 26 //#include "ExceptMutator.h" 26 27 … … 40 41 41 42 //ExceptMutator exc; 43 // LabelTypeChecker lbl; 42 44 43 45 mutateAll( translationUnit, formut ); 44 46 acceptAll( translationUnit, lfix ); 45 47 //mutateAll( translationUnit, exc ); 48 //acceptAll( translationUnit, lbl ); 46 49 } 47 50 } // namespace CodeGen -
src/ControlStruct/module.mk
r1f44196 r3a2128f 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 21 ControlStruct/ForExprMutator.cc \ 22 ControlStruct/LabelTypeChecker.cc 22 23 -
src/GenPoly/Box.cc
r1f44196 r3a2128f 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 Type::ForallList&forall );115 void findTypeOps( const std::list< TypeDecl *> &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 Type::ForallList&forall ) {621 void Pass1::findTypeOps( const std::list< TypeDecl *> &forall ) { 622 622 // what if a nested function uses an assignment operator? 623 623 // assignOps.clear(); 624 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) {624 for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 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 ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {689 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 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()->has_result() ) return;792 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result () );791 if ( appExpr->get_function()->get_results().empty() ) return; 792 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); 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 ) continue; // xxx - previously had check for non-empty fnArgBase results809 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_result (), arg, exprTyVars, seenTypes );808 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue; 809 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes ); 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 ) ); // xxx - result is never set on NameExpr899 appExpr->set_function( new NameExpr( adapterName ) ); 900 900 901 901 return ret; … … 903 903 904 904 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 905 assert( arg->has_result() );905 assert( ! arg->get_results().empty() ); 906 906 if ( isPolyType( param, exprTyVars ) ) { 907 if ( isPolyType( arg->get_result () ) ) {907 if ( isPolyType( arg->get_results().front() ) ) { 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 ()->get_isLvalue() ) {910 } else if ( arg->get_results().front()->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 ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {955 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 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-> set_result( arg->get_type()->clone() );996 deref->get_results().push_back( arg->get_type()->clone() ); 997 997 return deref; 998 998 } // if … … 1020 1020 Statement *bodyStmt; 1021 1021 1022 Type::ForallList::iterator tyArg = realType->get_forall().begin();1023 Type::ForallList::iterator tyParam = adapterType->get_forall().begin();1024 Type::ForallList::iterator realTyParam = adaptee->get_forall().begin();1022 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin(); 1023 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin(); 1024 std::list< TypeDecl *>::iterator realTyParam = adaptee->get_forall().begin(); 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 ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {1073 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 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-> set_result( appExpr->get_result()->clone());1133 addAssign->get_results().front() = appExpr->get_results().front()->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->has_result() );1147 assert( ! appExpr->get_results().empty() ); 1148 1148 assert( appExpr->get_args().size() == 2 ); 1149 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result (), scopeTyVars, env );1150 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result (), scopeTyVars, env );1149 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 1150 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 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-> set_result( appExpr->get_result()->clone() );1170 ret->get_results().push_front( appExpr->get_results().front()->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->has_result() );1180 assert( ! appExpr->get_results().empty() ); 1181 1181 assert( ! appExpr->get_args().empty() ); 1182 if ( isPolyType( appExpr->get_result (), scopeTyVars, env ) ) {1182 if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) { 1183 1183 Expression *ret = appExpr->get_args().front(); 1184 delete ret->get_result ();1185 ret-> set_result( appExpr->get_result()->clone());1184 delete ret->get_results().front(); 1185 ret->get_results().front() = appExpr->get_results().front()->clone(); 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->has_result() );1195 assert( ! appExpr->get_results().empty() ); 1196 1196 assert( appExpr->get_args().size() == 1 ); 1197 if ( Type *baseType = isPolyPtr( appExpr->get_result (), scopeTyVars, env ) ) {1198 Type *tempType = appExpr->get_result ()->clone();1197 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 1198 Type *tempType = appExpr->get_results().front()->clone(); 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->has_result() );1215 assert( ! appExpr->get_results().empty() ); 1216 1216 assert( appExpr->get_args().size() == 1 ); 1217 if ( Type *baseType = isPolyPtr( appExpr->get_result (), scopeTyVars, env ) ) {1217 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 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->has_result() );1221 assert( ! appExpr->get_results().empty() ); 1222 1222 assert( appExpr->get_args().size() == 2 ); 1223 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result (), scopeTyVars, env );1224 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result (), scopeTyVars, env );1223 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 1224 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 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-> set_result( appExpr->get_result()->clone() );1229 divide->get_results().push_front( appExpr->get_results().front()->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->has_result() );1247 assert( ! appExpr->get_results().empty() ); 1248 1248 assert( appExpr->get_args().size() == 2 ); 1249 Type *baseType = isPolyPtr( appExpr->get_result (), scopeTyVars, env );1249 Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ); 1250 1250 if ( baseType ) { 1251 1251 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); … … 1273 1273 useRetval = oldUseRetval; 1274 1274 1275 assert( appExpr->get_function()->has_result() ); 1276 PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() ); 1277 FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() ); 1275 assert( ! appExpr->get_function()->get_results().empty() ); 1276 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 1277 assert( pointer ); 1278 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 1279 assert( function ); 1278 1280 1279 1281 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { … … 1313 1315 1314 1316 Expression *Pass1::mutate( UntypedExpr *expr ) { 1315 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {1317 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 1316 1318 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1317 1319 if ( name->get_name() == "*?" ) { … … 1327 1329 1328 1330 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 1329 assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );1331 assert( ! addrExpr->get_arg()->get_results().empty() ); 1330 1332 1331 1333 bool needs = false; 1332 1334 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 1333 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {1335 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 1334 1336 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1335 1337 if ( name->get_name() == "*?" ) { 1336 1338 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 1337 assert( appExpr->get_function()->has_result() ); 1338 PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() ); 1339 FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() ); 1339 assert( ! appExpr->get_function()->get_results().empty() ); 1340 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 1341 assert( pointer ); 1342 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 1343 assert( function ); 1340 1344 needs = needsAdapter( function, scopeTyVars ); 1341 1345 } // if … … 1346 1350 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1347 1351 // out of the if condition. 1348 bool polytype = isPolyType( addrExpr->get_arg()->get_result (), scopeTyVars, env );1352 bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ); 1349 1353 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1350 1354 if ( polytype || needs ) { 1351 1355 Expression *ret = addrExpr->get_arg(); 1352 delete ret->get_result ();1353 ret-> set_result( addrExpr->get_result()->clone());1356 delete ret->get_results().front(); 1357 ret->get_results().front() = addrExpr->get_results().front()->clone(); 1354 1358 addrExpr->set_arg( 0 ); 1355 1359 delete addrExpr; … … 1389 1393 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1390 1394 if ( retval && returnStmt->get_expr() ) { 1391 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );1395 assert( ! returnStmt->get_expr()->get_results().empty() ); 1392 1396 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 1393 1397 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { … … 1423 1427 // find each of its needed secondary assignment operators 1424 1428 std::list< Expression* > &tyParams = refType->get_parameters(); 1425 Type::ForallList&forallParams = functionDecl->get_type()->get_forall();1429 std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall(); 1426 1430 std::list< Expression* >::const_iterator tyIt = tyParams.begin(); 1427 Type::ForallList::const_iterator forallIt = forallParams.begin();1431 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1428 1432 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1429 1433 // Add appropriate mapping to assignment expression environment … … 1469 1473 // replace return statement with appropriate assignment to out parameter 1470 1474 Expression *retParm = new NameExpr( retval->get_name() ); 1471 retParm-> set_result( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );1475 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 1472 1476 assignExpr->get_args().push_back( retParm ); 1473 1477 assignExpr->get_args().push_back( returnStmt->get_expr() ); … … 1599 1603 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1600 1604 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1601 for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {1605 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1602 1606 ObjectDecl *sizeParm, *alignParm; 1603 1607 // add all size and alignment parameters to parameter list -
src/GenPoly/CopyParams.cc
r1f44196 r3a2128f 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 ( Type::ForallList::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) {56 for ( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) { 57 57 if ( (*tyVar)->get_kind() == TypeDecl::Any ) { 58 58 assert( !(*tyVar)->get_assertions().empty() ); -
src/GenPoly/FindFunction.cc
r1f44196 r3a2128f 29 29 virtual Type *mutate( PointerType *pointerType ); 30 30 private: 31 void handleForall( const Type::ForallList&forall );31 void handleForall( const std::list< TypeDecl* > &forall ); 32 32 33 33 std::list< FunctionType* > &functions; … … 51 51 } 52 52 53 void FindFunction::handleForall( const Type::ForallList&forall ) {54 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) {53 void FindFunction::handleForall( const std::list< TypeDecl* > &forall ) { 54 for ( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 55 55 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 56 56 if ( var != tyVars.end() ) { -
src/GenPoly/GenPoly.cc
r1f44196 r3a2128f 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 ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {230 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { 231 231 assert( *tyVar ); 232 232 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind(); -
src/GenPoly/Lvalue.cc
r1f44196 r3a2128f 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#Lvalues60 /// 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 };66 57 } // namespace 67 58 … … 69 60 Pass1 p1; 70 61 Pass2 p2; 71 GeneralizedLvalue genLval;72 62 mutateAll( translationUnit, p1 ); 73 63 acceptAll( translationUnit, p2 ); 74 mutateAll( translationUnit, genLval );75 64 } 76 65 … … 110 99 appExpr->get_function()->acceptMutator( *this ); 111 100 mutateAll( appExpr->get_args(), *this ); 101 102 assert( ! appExpr->get_function()->get_results().empty() ); 112 103 113 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 114 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 104 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 105 assert( pointer ); 106 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 107 assert( function ); 115 108 116 109 Type *funType = isLvalueRet( function ); 117 110 if ( funType && ! isIntrinsicApp( appExpr ) ) { 118 111 Expression *expr = appExpr; 119 Type *appType = appExpr->get_result ();112 Type *appType = appExpr->get_results().front(); 120 113 if ( isPolyType( funType ) && ! isPolyType( appType ) ) { 121 114 // make sure cast for polymorphic type is inside dereference … … 123 116 } 124 117 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 125 deref-> set_result( appType->clone() );126 appExpr-> set_result( new PointerType( Type::Qualifiers(), appType ));118 deref->get_results().push_back( appType->clone() ); 119 appExpr->get_results().front() = new PointerType( Type::Qualifiers(), appType ); 127 120 deref->get_args().push_back( expr ); 128 121 return deref; … … 134 127 Statement * Pass1::mutate(ReturnStmt *retStmt) { 135 128 if ( retval && retStmt->get_expr() ) { 136 if ( retStmt->get_expr()->get_result()->get_isLvalue() ) { 129 assert( ! retStmt->get_expr()->get_results().empty() ); 130 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 137 131 // ***** Code Removal ***** because casts may be stripped already 138 132 … … 161 155 retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) ); 162 156 } // if 163 157 164 158 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;182 159 } 183 160 } // namespace -
src/GenPoly/Specialize.cc
r1f44196 r3a2128f 148 148 149 149 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 150 assert f( actual->has_result(), "attempting to specialize an untyped expression" );151 if ( needsSpecialization( formalType, actual->get_result (), env ) ) {150 assert( ! actual->get_results().empty() ); // using front, should have this assert 151 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 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()->has_result() );175 FunctionType *function = getFunctionType( appExpr->get_function()->get_result () );174 assert( ! appExpr->get_function()->get_results().empty() ); 175 FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() ); 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->has_result() );204 addrExpr->set_arg( doSpecialization( addrExpr->get_result (), addrExpr->get_arg() ) );203 assert( ! addrExpr->get_results().empty() ); 204 addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) ); 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 ()->isVoid() ) {210 if ( castExpr->get_results().empty() ) { 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 (), castExpr->get_arg() );214 Expression *specialized = doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ); 215 215 if ( specialized != castExpr->get_arg() ) { 216 216 // assume here that the specialization incorporates the cast -
src/InitTweak/FixInit.cc
r1f44196 r3a2128f 18 18 #include <iterator> 19 19 #include <algorithm> 20 #include <unordered_map>21 #include <unordered_set>22 20 #include "InitTweak.h" 23 21 #include "FixInit.h" … … 37 35 #include "GenPoly/DeclMutator.h" 38 36 #include "SynTree/AddStmtVisitor.h" 39 #include "CodeGen/GenType.h" // for warning /error messages40 41 bool ctordtorp = false; // print all debug42 bool ctorp = false; // print ctor debug43 bool cpctorp = false; // print copy ctor debug44 bool dtorp = false; // print dtor debug37 #include "CodeGen/GenType.h" // for warnings 38 39 bool ctordtorp = false; 40 bool ctorp = false; 41 bool cpctorp = false; 42 bool dtorp = false; 45 43 #define PRINT( text ) if ( ctordtorp ) { text } 46 44 #define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text } … … 49 47 namespace InitTweak { 50 48 namespace { 49 const std::list<Label> noLabels; 50 const std::list<Expression*> noDesignators; 51 51 52 class InsertImplicitCalls final : public GenPoly::PolyMutator { 52 53 public: … … 66 67 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit ); 67 68 68 typedef SymTab::Indexer Parent; 69 using Parent::visit; 70 69 using SymTab::Indexer::visit; 71 70 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 72 virtual void visit( UniqueExpr * unqExpr );73 71 74 72 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) 75 Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 76 Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL ); 73 ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 77 74 /// true if type does not need to be copy constructed to ensure correctness 78 bool skipCopyConstruct( Type * type ); 79 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 80 void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 75 bool skipCopyConstruct( Type * ); 81 76 private: 82 77 TypeSubstitution * env; … … 188 183 using GenPoly::PolyMutator::mutate; 189 184 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 190 virtual Expression * mutate( UniqueExpr * unqExpr ) override;191 185 }; 192 186 … … 374 368 } 375 369 376 Expression* ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {370 ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { 377 371 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 );383 372 UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) ); 384 untyped->get_args().push_back( thisArg);373 untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) ); 385 374 if (cpArg) untyped->get_args().push_back( cpArg->clone() ); 386 375 … … 389 378 // (VariableExpr and already resolved expression) 390 379 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 391 Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this ); 392 assert( resolved ); 380 ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) ); 393 381 if ( resolved->get_env() ) { 394 382 env->add( *resolved->get_env() ); 395 383 } // if 396 384 385 assert( resolved ); 397 386 delete untyped; 398 387 return resolved; 399 388 } 400 389 401 void ResolveCopyCtors:: copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr *impCpCtorExpr ) {390 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 402 391 static UniqueName tempNamer("_tmp_cp"); 403 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 404 assert( arg->has_result() ); 405 Type * result = arg->get_result(); 406 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 407 408 // type may involve type variables, so apply type substitution to get temporary variable's actual type 409 result = result->clone(); 410 impCpCtorExpr->get_env()->apply( result ); 411 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 412 tmp->get_type()->set_isConst( false ); 413 414 // create and resolve copy constructor 415 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; ) 416 Expression * cpCtor = makeCtorDtor( "?{}", tmp, arg ); 417 418 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( cpCtor ) ) { 392 static UniqueName retNamer("_tmp_cp_ret"); 393 394 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 395 Visitor::visit( impCpCtorExpr ); 396 env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer... 397 398 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); 399 400 // take each argument and attempt to copy construct it. 401 for ( Expression * & arg : appExpr->get_args() ) { 402 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 403 // xxx - need to handle tuple arguments 404 assert( ! arg->get_results().empty() ); 405 Type * result = arg->get_results().front(); 406 if ( skipCopyConstruct( result ) ) continue; // skip certain non-copyable types 407 // type may involve type variables, so apply type substitution to get temporary variable's actual type 408 result = result->clone(); 409 impCpCtorExpr->get_env()->apply( result ); 410 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 411 tmp->get_type()->set_isConst( false ); 412 413 // create and resolve copy constructor 414 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; ) 415 ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg ); 416 419 417 // if the chosen constructor is intrinsic, the copy is unnecessary, so 420 418 // don't create the temporary and don't call the copy constructor 421 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );419 VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() ); 422 420 assert( function ); 423 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 424 } 425 426 // replace argument to function call with temporary 427 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 428 impCpCtorExpr->get_tempDecls().push_back( tmp ); 429 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) ); 430 } 431 432 void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) { 433 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) ); 434 } 435 436 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 437 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 438 Parent::visit( impCpCtorExpr ); 439 env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer... 440 441 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); 442 443 // take each argument and attempt to copy construct it. 444 for ( Expression * & arg : appExpr->get_args() ) { 445 copyConstructArg( arg, impCpCtorExpr ); 421 if ( function->get_var()->get_linkage() != LinkageSpec::Intrinsic ) { 422 // replace argument to function call with temporary 423 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 424 impCpCtorExpr->get_tempDecls().push_back( tmp ); 425 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) ); 426 } // if 446 427 } // for 447 428 … … 453 434 // level. Trying to pass that environment along. 454 435 callExpr->set_env( impCpCtorExpr->get_env()->clone() ); 455 Type * result = appExpr->get_result(); 456 if ( ! result->isVoid() ) { 457 static UniqueName retNamer("_tmp_cp_ret"); 436 for ( Type * result : appExpr->get_results() ) { 458 437 result = result->clone(); 459 438 impCpCtorExpr->get_env()->apply( result ); … … 462 441 impCpCtorExpr->get_returnDecls().push_back( ret ); 463 442 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 464 if ( ! result->get_isLvalue() ) { 465 // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary 466 destructRet( new VariableExpr( ret ), impCpCtorExpr ); 467 } 443 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 468 444 } // for 469 445 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 generated476 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 rethought481 assert( unqExpr->get_result() );482 if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->get_expr() ) ) {483 // note the variable used as the result from the call484 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 expression488 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() );492 446 } 493 447 … … 536 490 // know the result type of the assignment is the type of the LHS (minus the pointer), so 537 491 // add that onto the assignment expression so that later steps have the necessary information 538 assign-> set_result( returnDecl->get_type()->clone() );492 assign->add_result( returnDecl->get_type()->clone() ); 539 493 540 494 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 541 if ( callExpr->get_result ()->get_isLvalue() ) {495 if ( callExpr->get_results().front()->get_isLvalue() ) { 542 496 // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning 543 497 // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the … … 546 500 // an AddressExpr. Effectively, this turns 547 501 // lvalue T f(); 548 // &*f() ;502 // &*f() 549 503 // into 550 // T * f();551 504 // T * tmp_cp_retN; 552 // &*(tmp_cp_retN = &*f(), tmp_cp_retN); // the first * and second & are generated here505 // tmp_cp_ret_N = &*(tmp_cp_ret_N = &*f(), tmp_cp_ret); 553 506 // which work out in terms of types, but is pretty messy. It would be nice to find a better way. 554 507 assign->get_args().back() = new AddressExpr( assign->get_args().back() ); 555 508 509 Type * resultType = returnDecl->get_type()->clone(); 556 510 returnDecl->set_type( new PointerType( Type::Qualifiers(), returnDecl->get_type() ) ); 557 retExpr->set_result( new PointerType( Type::Qualifiers(), retExpr->get_result() ) ); 558 retExpr = UntypedExpr::createDeref( retExpr ); 511 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 512 deref->get_args().push_back( retExpr ); 513 deref->add_result( resultType ); 514 retExpr = deref; 559 515 } // if 560 516 retExpr->set_env( env->clone() ); … … 563 519 return callExpr; 564 520 } // 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 passes571 unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) );572 if ( unqMap.count( unqExpr->get_id() ) ) {573 // take data from other UniqueExpr to ensure consistency574 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 too580 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 expression588 // (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;596 521 } 597 522 … … 1025 950 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) { 1026 951 static UniqueName tempNamer( "_tmp_ctor_expr" ); 1027 // xxx - is the size check necessary? 1028 assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 ); 1029 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr ); 952 assert( ctorExpr->get_results().size() == 1 ); 953 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_results().front()->clone(), nullptr ); 1030 954 addDeclaration( tmp ); 1031 955 … … 1039 963 assign->get_args().push_back( new VariableExpr( tmp ) ); 1040 964 assign->get_args().push_back( firstArg ); 1041 assign->set_result( ctorExpr->get_result()->clone() );965 cloneAll( ctorExpr->get_results(), assign->get_results() ); 1042 966 firstArg = assign; 1043 967 -
src/InitTweak/GenInit.cc
r1f44196 r3a2128f 29 29 #include "GenPoly/DeclMutator.h" 30 30 #include "GenPoly/ScopedSet.h" 31 #include "ResolvExpr/typeops.h"32 31 33 32 namespace InitTweak { … … 51 50 52 51 protected: 53 FunctionType * ftype;52 std::list<DeclarationWithType*> returnVals; 54 53 UniqueName tempNamer; 55 54 std::string funcName; … … 87 86 88 87 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed 89 bool isManaged( Type * type ) const; // determine if type is managed90 88 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor 91 89 GenPoly::ScopedSet< std::string > managedTypes; … … 138 136 139 137 Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) { 140 std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();138 // update for multiple return values 141 139 assert( returnVals.size() == 0 || returnVals.size() == 1 ); 142 140 // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address … … 160 158 161 159 DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) { 162 // xxx - need to handle named return values - this pass may need to happen 163 // after resolution? the ordering is tricky because return statements must be 164 // constructed - the simplest way to do that (while also handling multiple 165 // returns) is to structure the returnVals into a tuple, as done here. 166 // however, if the tuple return value is structured before resolution, 167 // it's difficult to resolve named return values, since the name is lost 168 // in conversion to a tuple. this might be easiest to deal with 169 // after reference types are added, as it may then be possible to 170 // uniformly move named return values to the parameter list directly 171 ValueGuard< FunctionType * > oldFtype( ftype ); 160 ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals ); 172 161 ValueGuard< std::string > oldFuncName( funcName ); 173 162 174 ftype = functionDecl->get_functionType(); 175 std::list< DeclarationWithType * > & retVals = ftype->get_returnVals(); 176 if ( retVals.size() > 1 ) { 177 TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 178 ObjectDecl * newRet = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) ); 179 retVals.clear(); 180 retVals.push_back( newRet ); 181 } 163 FunctionType * type = functionDecl->get_functionType(); 164 returnVals = type->get_returnVals(); 182 165 funcName = functionDecl->get_name(); 183 166 DeclarationWithType * decl = Mutator::mutate( functionDecl ); … … 239 222 } 240 223 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 managed244 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 251 224 bool CtorDtor::isManaged( ObjectDecl * objDecl ) const { 252 225 Type * type = objDecl->get_type(); … … 254 227 type = at->get_base(); 255 228 } 256 return isManaged( type);229 return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end(); 257 230 } 258 231 … … 265 238 managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) ); 266 239 } 267 }268 269 ConstructorInit * genCtorInit( ObjectDecl * objDecl ) {270 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor271 // for each constructable object272 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 CompoundStmt281 // which wraps everything that needs to happen. As such, it's technically282 // possible to use a Statement ** in the above calls, but this is inherently283 // unsafe, so instead we take the slightly less efficient route, but will be284 // 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 genImplicitCall287 // itself. It is possible that genImplicitCall produces no statements (e.g. if288 // an array type does not have a dimension). In this case, it's fine to ignore289 // 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 exist293 // if ctor does exist, want to use ctor expression instead of init294 // push this decision to the resolver295 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;299 240 } 300 241 … … 309 250 if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl ); 310 251 311 objDecl->set_init( genCtorInit( objDecl ) ); 252 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor 253 // for each constructable object 254 std::list< Statement * > ctor; 255 std::list< Statement * > dtor; 256 257 InitExpander srcParam( objDecl->get_init() ); 258 InitExpander nullParam( (Initializer *)NULL ); 259 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 260 SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 261 262 // Currently genImplicitCall produces a single Statement - a CompoundStmt 263 // which wraps everything that needs to happen. As such, it's technically 264 // possible to use a Statement ** in the above calls, but this is inherently 265 // unsafe, so instead we take the slightly less efficient route, but will be 266 // immediately informed if somehow the above assumption is broken. In this case, 267 // we could always wrap the list of statements at this point with a CompoundStmt, 268 // but it seems reasonable at the moment for this to be done by genImplicitCall 269 // itself. It is possible that genImplicitCall produces no statements (e.g. if 270 // an array type does not have a dimension). In this case, it's fine to ignore 271 // the object for the purposes of construction. 272 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 273 if ( ctor.size() == 1 ) { 274 // need to remember init expression, in case no ctors exist 275 // if ctor does exist, want to use ctor expression instead of init 276 // push this decision to the resolver 277 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 278 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 279 } 312 280 } 313 281 return Parent::mutate( objDecl ); … … 322 290 managedTypes.beginScope(); 323 291 // go through assertions and recursively add seen ctor/dtors 324 for ( auto &tyDecl : functionDecl->get_functionType()->get_forall() ) {292 for ( TypeDecl * tyDecl : functionDecl->get_functionType()->get_forall() ) { 325 293 for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) { 326 294 assertion = assertion->acceptMutator( *this ); -
src/InitTweak/GenInit.h
r1f44196 r3a2128f 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // GenInit.h --7 // RemoveInit.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-initializer31 ConstructorInit * genCtorInit( ObjectDecl * objDecl );32 29 } // namespace 33 30 -
src/InitTweak/InitTweak.cc
r1f44196 r3a2128f 340 340 return allofCtorDtor( stmt, []( Expression * callExpr ){ 341 341 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 342 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_result() ); 342 assert( ! appExpr->get_function()->get_results().empty() ); 343 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() ); 343 344 assert( funcType ); 344 345 return funcType->get_parameters().size() == 1; … … 387 388 return memberExpr->get_member()->get_name(); 388 389 } else if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * > ( func ) ) { 389 return funcName( memberExpr->get_member());390 return memberExpr->get_member(); 390 391 } else { 391 392 assertf( false, "Unexpected expression type being called as a function in call expression" ); … … 450 451 // virtual void visit( LogicalExpr *logicalExpr ); 451 452 // virtual void visit( ConditionalExpr *conditionalExpr ); 453 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; } 454 virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; } 452 455 virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; } 453 456 virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; } 454 457 virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; } 455 458 virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; } 456 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }457 virtual void visit( TupleAssignExpr *tupleExpr ) { isConstExpr = false; }458 459 459 460 bool isConstExpr; -
src/Makefile.in
r1f44196 r3a2128f 105 105 ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \ 106 106 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \ 107 ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT) \ 107 108 GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \ 108 109 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \ … … 189 190 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \ 190 191 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-TupleExpansion.$(OBJEXT) \ 194 Tuples/driver_cfa_cpp-Explode.$(OBJEXT) 193 Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT) 195 194 am_driver_cfa_cpp_OBJECTS = $(am__objects_1) 196 195 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS) … … 365 364 ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \ 366 365 ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \ 367 ControlStruct/ForExprMutator.cc GenPoly/Box.cc \ 366 ControlStruct/ForExprMutator.cc \ 367 ControlStruct/LabelTypeChecker.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 SynTree/VarExprReplacer.cc \ 407 Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \ 408 Tuples/Explode.cc 406 SynTree/Attribute.cc Tuples/TupleAssignment.cc \ 407 Tuples/NameMatcher.cc 409 408 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \ 410 409 ${cfa_cpplib_PROGRAMS}} … … 542 541 ControlStruct/$(DEPDIR)/$(am__dirstamp) 543 542 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT): \ 543 ControlStruct/$(am__dirstamp) \ 544 ControlStruct/$(DEPDIR)/$(am__dirstamp) 545 ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT): \ 544 546 ControlStruct/$(am__dirstamp) \ 545 547 ControlStruct/$(DEPDIR)/$(am__dirstamp) … … 767 769 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \ 768 770 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-TupleExpansion.$(OBJEXT): \ 780 Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp) 781 Tuples/driver_cfa_cpp-Explode.$(OBJEXT): Tuples/$(am__dirstamp) \ 779 Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT): Tuples/$(am__dirstamp) \ 782 780 Tuples/$(DEPDIR)/$(am__dirstamp) 783 781 driver/$(am__dirstamp): … … 802 800 -rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) 803 801 -rm -f ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) 802 -rm -f ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT) 804 803 -rm -f ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT) 805 804 -rm -f ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) … … 885 884 -rm -f SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT) 886 885 -rm -f SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT) 887 -rm -f SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT)888 886 -rm -f SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) 889 887 -rm -f SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) 890 888 -rm -f SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT) 891 -rm -f Tuples/driver_cfa_cpp- Explode.$(OBJEXT)889 -rm -f Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT) 892 890 -rm -f Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) 893 -rm -f Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT)894 891 895 892 distclean-compile: … … 910 907 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@ 911 908 @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@ 912 910 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po@am__quote@ 913 911 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@ … … 993 991 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po@am__quote@ 994 992 @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@996 993 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@ 997 994 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@ 998 995 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@ 999 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp- Explode.Po@am__quote@996 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po@am__quote@ 1000 997 @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@1002 998 1003 999 .cc.o: … … 1241 1237 @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` 1242 1238 1239 ControlStruct/driver_cfa_cpp-LabelTypeChecker.o: ControlStruct/LabelTypeChecker.cc 1240 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelTypeChecker.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.o `test -f 'ControlStruct/LabelTypeChecker.cc' || echo '$(srcdir)/'`ControlStruct/LabelTypeChecker.cc 1241 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po 1242 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/LabelTypeChecker.cc' object='ControlStruct/driver_cfa_cpp-LabelTypeChecker.o' libtool=no @AMDEPBACKSLASH@ 1243 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1244 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.o `test -f 'ControlStruct/LabelTypeChecker.cc' || echo '$(srcdir)/'`ControlStruct/LabelTypeChecker.cc 1245 1246 ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj: ControlStruct/LabelTypeChecker.cc 1247 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj `if test -f 'ControlStruct/LabelTypeChecker.cc'; then $(CYGPATH_W) 'ControlStruct/LabelTypeChecker.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelTypeChecker.cc'; fi` 1248 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po 1249 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/LabelTypeChecker.cc' object='ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj' libtool=no @AMDEPBACKSLASH@ 1250 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1251 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj `if test -f 'ControlStruct/LabelTypeChecker.cc'; then $(CYGPATH_W) 'ControlStruct/LabelTypeChecker.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelTypeChecker.cc'; fi` 1252 1243 1253 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc 1244 1254 @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 … … 2417 2427 @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` 2418 2428 2419 SynTree/driver_cfa_cpp-VarExprReplacer.o: SynTree/VarExprReplacer.cc2420 @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.cc2421 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Po2422 @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.cc2425 2426 SynTree/driver_cfa_cpp-VarExprReplacer.obj: SynTree/VarExprReplacer.cc2427 @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.Po2429 @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 2433 2429 Tuples/driver_cfa_cpp-TupleAssignment.o: Tuples/TupleAssignment.cc 2434 2430 @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 … … 2445 2441 @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` 2446 2442 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` 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` 2474 2456 2475 2457 .ll.cc: -
src/Parser/ExpressionNode.cc
r1f44196 r3a2128f 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 expression176 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_FLOATINGconstant186 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_constants198 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_constants202 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_REALFRACTIONconstant209 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_REALDECIMALconstant216 217 174 NameExpr * build_varref( const string *name, bool labelp ) { 218 175 NameExpr *expr = new NameExpr( *name, nullptr ); … … 241 198 } 242 199 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 ) { 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 ) { 249 207 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 250 208 deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) ); 251 UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref ); 209 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref ); 210 delete member; 252 211 return ret; 253 212 } -
src/Parser/ParseNode.h
r1f44196 r3a2128f 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 );161 157 162 158 NameExpr * build_varref( const std::string * name, bool labelp = false ); … … 164 160 165 161 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ); 166 Expression * build_fieldSel( ExpressionNode * expr_node, Expression* member );167 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression* member );162 Expression * build_fieldSel( ExpressionNode * expr_node, NameExpr * member ); 163 Expression * build_pfieldSel( ExpressionNode * expr_node, NameExpr * member ); 168 164 Expression * build_addressOf( ExpressionNode * expr_node ); 169 165 Expression * build_sizeOfexpr( ExpressionNode * expr_node ); … … 387 383 //############################################################################## 388 384 389 template< typename SynTreeType, typename NodeType , template< typename, typename...> class Container, typename... Args>390 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args...> &outputList ) {385 template< typename SynTreeType, typename NodeType > 386 void buildList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) { 391 387 SemanticError errors; 392 std::back_insert_iterator< Container< SynTreeType *, Args...> > out( outputList );388 std::back_insert_iterator< std::list< SynTreeType * > > out( outputList ); 393 389 const NodeType * cur = firstNode; 394 390 -
src/Parser/TypeData.cc
r1f44196 r3a2128f 385 385 } // TypeData::print 386 386 387 template< typename ForallList > 388 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { 387 void buildForall( const DeclarationNode * firstNode, list< TypeDecl* > &outputList ) { 389 388 buildList( firstNode, outputList ); 390 for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i ) { 391 TypeDecl * td = static_cast<TypeDecl*>(*i); 392 if ( td->get_kind() == TypeDecl::Any ) { 389 for ( list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) { 390 if ( (*i)->get_kind() == TypeDecl::Any ) { 393 391 // add assertion parameters to `type' tyvars in reverse order 394 392 // add dtor: void ^?{}(T *) 395 393 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false ); 396 dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );397 td->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, nullptr, false, false ) );394 dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) ); 395 (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, nullptr, false, false ) ); 398 396 399 397 // add copy ctor: void ?{}(T *, T) 400 398 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false ); 401 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );402 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );403 td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, nullptr, false, false ) );399 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) ); 400 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), nullptr ) ); 401 (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, nullptr, false, false ) ); 404 402 405 403 // add default ctor: void ?{}(T *) 406 404 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false ); 407 ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );408 td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, nullptr, false, false ) );405 ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) ); 406 (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, nullptr, false, false ) ); 409 407 410 408 // add assignment operator: T * ?=?(T *, T) 411 409 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false ); 412 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );413 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );414 assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );415 td->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, nullptr, false, false ) );410 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), nullptr ) ); 411 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), nullptr ) ); 412 assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), nullptr ) ); 413 (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, nullptr, false, false ) ); 416 414 } // if 417 415 } // for … … 517 515 // character types. The implementation shall define char to have the same range, representation, and behavior as 518 516 // either signed char or unsigned char. 519 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; 517 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; 520 518 521 519 if ( td->length != DeclarationNode::NoLength ) { -
src/Parser/parser.cc
r1f44196 r3a2128f 1030 1030 static const yytype_uint16 yyrline[] = 1031 1031 { 1032 0, 30 5, 305, 309, 316, 317, 318, 319, 320, 324,1033 32 5, 326, 330, 331, 335, 336, 340, 341, 345, 349,1034 35 0, 361, 363, 365, 366, 368, 373, 374, 380, 382,1035 38 4, 386, 388, 390, 392, 394, 396, 398, 407, 408,1036 41 4, 415, 419, 420, 424, 425, 427, 429, 431, 433,1037 43 5, 440, 442, 444, 450, 451, 459, 462, 464, 466,1038 4 71, 484, 486, 488, 490, 492, 494, 496, 498, 500,1039 502, 504, 511, 512, 518, 519, 520, 521, 525, 526,1040 5 33, 534, 536, 538, 543, 544, 546, 551, 552, 554,1041 55 9, 560, 562, 564, 566, 571, 572, 574, 579, 580,1042 5 85, 586, 591, 592, 597, 598, 603, 604, 609, 610,1043 6 13, 620, 625, 626, 634, 635, 639, 640, 641, 642,1044 6 43, 644, 645, 646, 647, 648, 649, 650, 660, 662,1045 66 7, 668, 673, 674, 680, 681, 687, 688, 689, 690,1046 6 91, 692, 693, 694, 695, 705, 712, 714, 724, 725,1047 7 30, 732, 738, 740, 744, 745, 750, 755, 758, 760,1048 7 62, 772, 774, 785, 786, 788, 792, 794, 798, 799,1049 804, 805, 809, 814, 815, 819, 821, 827, 828, 832,1050 8 34, 836, 838, 844, 845, 849, 851, 856, 858, 860,1051 8 65, 867, 872, 874, 878, 881, 885, 888, 892, 894,1052 89 6, 898, 903, 905, 907, 912, 914, 916, 918, 920,1053 9 25, 927, 929, 931, 936, 948, 949, 954, 956, 961,1054 9 65, 967, 969, 971, 973, 979, 980, 986, 987, 991,1055 9 92, 997, 999, 1005, 1006, 1008, 1013, 1018, 1028, 1030,1056 10 34, 1035, 1040, 1042, 1046, 1047, 1051, 1053, 1057, 1058,1057 10 62, 1063, 1067, 1068, 1083, 1084, 1085, 1086, 1087, 1091,1058 109 6, 1103, 1113, 1118, 1123, 1131, 1136, 1141, 1146, 1151,1059 11 81, 1186, 1193, 1195, 1202, 1207, 1212, 1223, 1228, 1233,1060 123 8, 1243, 1252, 1257, 1265, 1266, 1267, 1268, 1274, 1279,1061 128 7, 1288, 1289, 1290, 1294, 1295, 1296, 1297, 1302, 1303,1062 13 12, 1313, 1318, 1319, 1324, 1326, 1328, 1330, 1332, 1335,1063 13 34, 1346, 1347, 1349, 1359, 1360, 1365, 1367, 1369, 1371,1064 13 73, 1376, 1378, 1381, 1386, 1388, 1390, 1392, 1394, 1396,1065 139 8, 1400, 1402, 1404, 1406, 1408, 1410, 1412, 1414, 1420,1066 14 21, 1423, 1425, 1427, 1432, 1433, 1439, 1440, 1442, 1444,1067 144 9, 1451, 1453, 1455, 1460, 1461, 1463, 1465, 1470, 1471,1068 14 73, 1478, 1479, 1481, 1483, 1488, 1490, 1492, 1497, 1498,1069 1 502, 1504, 1510, 1509, 1513, 1515, 1520, 1522, 1528, 1529,1070 15 34, 1535, 1537, 1538, 1547, 1548, 1550, 1552, 1557, 1559,1071 15 65, 1566, 1568, 1571, 1574, 1579, 1580, 1585, 1590, 1594,1072 159 6, 1602, 1601, 1608, 1610, 1616, 1617, 1625, 1626, 1630,1073 16 31, 1632, 1634, 1636, 1643, 1644, 1646, 1648, 1653, 1654,1074 16 60, 1661, 1665, 1666, 1671, 1672, 1673, 1675, 1683, 1684,1075 168 6, 1689, 1691, 1695, 1696, 1697, 1699, 1701, 1705, 1710,1076 171 8, 1719, 1728, 1730, 1735, 1736, 1737, 1741, 1742, 1743,1077 174 7, 1748, 1749, 1753, 1754, 1755, 1760, 1761, 1762, 1763,1078 176 9, 1770, 1772, 1777, 1778, 1783, 1784, 1785, 1786, 1787,1079 1 802, 1803, 1808, 1809, 1815, 1817, 1820, 1822, 1824, 1847,1080 184 8, 1850, 1852, 1857, 1858, 1860, 1865, 1870, 1871, 1877,1081 187 6, 1880, 1884, 1886, 1888, 1894, 1895, 1900, 1905, 1907,1082 19 12, 1914, 1915, 1917, 1922, 1924, 1926, 1931, 1933, 1938,1083 19 43, 1951, 1957, 1956, 1970, 1971, 1976, 1977, 1981, 1986,1084 19 91, 1999, 2004, 2015, 2016, 2021, 2022, 2028, 2029, 2033,1085 20 34, 2035, 2038, 2037, 2048, 2057, 2063, 2069, 2078, 2084,1086 20 90, 2096, 2102, 2110, 2116, 2124, 2130, 2139, 2140, 2141,1087 21 45, 2149, 2151, 2156, 2157, 2161, 2162, 2167, 2173, 2174,1088 217 7, 2179, 2180, 2184, 2185, 2186, 2187, 2221, 2223, 2224,1089 222 6, 2231, 2236, 2241, 2243, 2245, 2250, 2252, 2254, 2256,1090 22 61, 2263, 2272, 2274, 2275, 2280, 2282, 2284, 2289, 2291,1091 22 93, 2298, 2300, 2302, 2311, 2312, 2313, 2317, 2319, 2321,1092 232 6, 2328, 2330, 2335, 2337, 2339, 2354, 2356, 2357, 2359,1093 23 64, 2365, 2370, 2372, 2374, 2379, 2381, 2383, 2385, 2390,1094 23 92, 2394, 2404, 2406, 2407, 2409, 2414, 2416, 2418, 2423,1095 24 25, 2427, 2429, 2434, 2436, 2438, 2469, 2471, 2472, 2474,1096 247 9, 2484, 2492, 2494, 2496, 2501, 2503, 2508, 2510, 2524,1097 25 25, 2527, 2532, 2534, 2536, 2538, 2540, 2545, 2546, 2548,1098 25 50, 2555, 2557, 2559, 2565, 2567, 2569, 2573, 2575, 2577,1099 257 9, 2593, 2594, 2596, 2601, 2603, 2605, 2607, 2609, 2614,1100 26 15, 2617, 2619, 2624, 2626, 2628, 2634, 2635, 2637, 2646,1101 264 9, 2651, 2654, 2656, 2658, 2671, 2672, 2674, 2679, 2681,1102 26 83, 2685, 2687, 2692, 2693, 2695, 2697, 2702, 2704, 2712,1103 27 13, 2714, 2719, 2720, 2724, 2726, 2728, 2730, 2732, 2734,1104 27 41, 2743, 2745, 2747, 2749, 2752, 2754, 2756, 2758, 2760,1105 27 65, 2767, 2769, 2774, 2800, 2801, 2803, 2807, 2808, 2812,1106 28 14, 2816, 2818, 2820, 2822, 2829, 2831, 2833, 2835, 2837,1107 283 9, 2844, 2851, 2853, 2871, 2873, 2878, 28791032 0, 306, 306, 310, 317, 318, 319, 320, 321, 325, 1033 326, 327, 331, 332, 336, 337, 341, 342, 346, 350, 1034 351, 362, 364, 366, 367, 369, 374, 375, 381, 383, 1035 385, 386, 387, 389, 390, 392, 394, 396, 405, 406, 1036 412, 413, 417, 418, 422, 424, 426, 428, 430, 432, 1037 434, 439, 441, 443, 447, 449, 453, 456, 458, 460, 1038 465, 478, 480, 482, 484, 486, 488, 490, 492, 494, 1039 496, 498, 505, 506, 512, 513, 514, 515, 519, 520, 1040 527, 528, 530, 532, 537, 538, 540, 545, 546, 548, 1041 553, 554, 556, 558, 560, 565, 566, 568, 573, 574, 1042 579, 580, 585, 586, 591, 592, 597, 598, 603, 604, 1043 607, 614, 619, 620, 628, 629, 633, 634, 635, 636, 1044 637, 638, 639, 640, 641, 642, 643, 644, 654, 656, 1045 661, 662, 667, 668, 674, 675, 681, 682, 683, 684, 1046 685, 686, 687, 688, 689, 699, 706, 708, 718, 719, 1047 724, 726, 732, 734, 738, 739, 744, 749, 752, 754, 1048 756, 766, 768, 779, 780, 782, 786, 788, 792, 793, 1049 798, 799, 803, 808, 809, 813, 815, 821, 822, 826, 1050 828, 830, 832, 838, 839, 843, 845, 850, 852, 854, 1051 859, 861, 866, 868, 872, 875, 879, 882, 886, 888, 1052 890, 892, 897, 899, 901, 906, 908, 910, 912, 914, 1053 919, 921, 923, 925, 930, 942, 943, 948, 950, 955, 1054 959, 961, 963, 965, 967, 973, 974, 980, 981, 985, 1055 986, 991, 993, 999, 1000, 1002, 1007, 1012, 1022, 1024, 1056 1028, 1029, 1034, 1036, 1040, 1041, 1045, 1047, 1051, 1052, 1057 1056, 1057, 1061, 1062, 1077, 1078, 1079, 1080, 1081, 1085, 1058 1090, 1097, 1107, 1112, 1117, 1125, 1130, 1135, 1140, 1145, 1059 1175, 1180, 1187, 1189, 1196, 1201, 1206, 1217, 1222, 1227, 1060 1232, 1237, 1246, 1251, 1259, 1260, 1261, 1262, 1268, 1273, 1061 1281, 1282, 1283, 1284, 1288, 1289, 1290, 1291, 1296, 1297, 1062 1306, 1307, 1312, 1313, 1318, 1320, 1322, 1324, 1326, 1329, 1063 1328, 1340, 1341, 1343, 1353, 1354, 1359, 1361, 1363, 1365, 1064 1367, 1370, 1372, 1375, 1380, 1382, 1384, 1386, 1388, 1390, 1065 1392, 1394, 1396, 1398, 1400, 1402, 1404, 1406, 1408, 1414, 1066 1415, 1417, 1419, 1421, 1426, 1427, 1433, 1434, 1436, 1438, 1067 1443, 1445, 1447, 1449, 1454, 1455, 1457, 1459, 1464, 1465, 1068 1467, 1472, 1473, 1475, 1477, 1482, 1484, 1486, 1491, 1492, 1069 1496, 1498, 1504, 1503, 1507, 1509, 1514, 1516, 1522, 1523, 1070 1528, 1529, 1531, 1532, 1541, 1542, 1544, 1546, 1551, 1553, 1071 1559, 1560, 1562, 1565, 1568, 1573, 1574, 1579, 1584, 1588, 1072 1590, 1596, 1595, 1602, 1604, 1610, 1611, 1619, 1620, 1624, 1073 1625, 1626, 1628, 1630, 1637, 1638, 1640, 1642, 1647, 1648, 1074 1654, 1655, 1659, 1660, 1665, 1666, 1667, 1669, 1677, 1678, 1075 1680, 1683, 1685, 1689, 1690, 1691, 1693, 1695, 1699, 1704, 1076 1712, 1713, 1722, 1724, 1729, 1730, 1731, 1735, 1736, 1737, 1077 1741, 1742, 1743, 1747, 1748, 1749, 1754, 1755, 1756, 1757, 1078 1763, 1764, 1766, 1771, 1772, 1777, 1778, 1779, 1780, 1781, 1079 1796, 1797, 1802, 1803, 1809, 1811, 1814, 1816, 1818, 1841, 1080 1842, 1844, 1846, 1851, 1852, 1854, 1859, 1864, 1865, 1871, 1081 1870, 1874, 1878, 1880, 1882, 1888, 1889, 1894, 1899, 1901, 1082 1906, 1908, 1909, 1911, 1916, 1918, 1920, 1925, 1927, 1932, 1083 1937, 1945, 1951, 1950, 1964, 1965, 1970, 1971, 1975, 1980, 1084 1985, 1993, 1998, 2009, 2010, 2015, 2016, 2022, 2023, 2027, 1085 2028, 2029, 2032, 2031, 2042, 2051, 2057, 2063, 2072, 2078, 1086 2084, 2090, 2096, 2104, 2110, 2118, 2124, 2133, 2134, 2135, 1087 2139, 2143, 2145, 2150, 2151, 2155, 2156, 2161, 2167, 2168, 1088 2171, 2173, 2174, 2178, 2179, 2180, 2181, 2215, 2217, 2218, 1089 2220, 2225, 2230, 2235, 2237, 2239, 2244, 2246, 2248, 2250, 1090 2255, 2257, 2266, 2268, 2269, 2274, 2276, 2278, 2283, 2285, 1091 2287, 2292, 2294, 2296, 2305, 2306, 2307, 2311, 2313, 2315, 1092 2320, 2322, 2324, 2329, 2331, 2333, 2348, 2350, 2351, 2353, 1093 2358, 2359, 2364, 2366, 2368, 2373, 2375, 2377, 2379, 2384, 1094 2386, 2388, 2398, 2400, 2401, 2403, 2408, 2410, 2412, 2417, 1095 2419, 2421, 2423, 2428, 2430, 2432, 2463, 2465, 2466, 2468, 1096 2473, 2478, 2486, 2488, 2490, 2495, 2497, 2502, 2504, 2518, 1097 2519, 2521, 2526, 2528, 2530, 2532, 2534, 2539, 2540, 2542, 1098 2544, 2549, 2551, 2553, 2559, 2561, 2563, 2567, 2569, 2571, 1099 2573, 2587, 2588, 2590, 2595, 2597, 2599, 2601, 2603, 2608, 1100 2609, 2611, 2613, 2618, 2620, 2622, 2628, 2629, 2631, 2640, 1101 2643, 2645, 2648, 2650, 2652, 2665, 2666, 2668, 2673, 2675, 1102 2677, 2679, 2681, 2686, 2687, 2689, 2691, 2696, 2698, 2706, 1103 2707, 2708, 2713, 2714, 2718, 2720, 2722, 2724, 2726, 2728, 1104 2735, 2737, 2739, 2741, 2743, 2746, 2748, 2750, 2752, 2754, 1105 2759, 2761, 2763, 2768, 2794, 2795, 2797, 2801, 2802, 2806, 1106 2808, 2810, 2812, 2814, 2816, 2823, 2825, 2827, 2829, 2831, 1107 2833, 2838, 2845, 2847, 2865, 2867, 2872, 2873 1108 1108 }; 1109 1109 #endif … … 4928 4928 4929 4929 /* Line 1806 of yacc.c */ 4930 #line 30 5"parser.yy"4930 #line 306 "parser.yy" 4931 4931 { typedefTable.enterScope(); } 4932 4932 break; … … 4935 4935 4936 4936 /* Line 1806 of yacc.c */ 4937 #line 3 09"parser.yy"4937 #line 310 "parser.yy" 4938 4938 { typedefTable.leaveScope(); } 4939 4939 break; … … 4942 4942 4943 4943 /* Line 1806 of yacc.c */ 4944 #line 31 6"parser.yy"4944 #line 317 "parser.yy" 4945 4945 { (yyval.en) = new ExpressionNode( build_constantInteger( *(yyvsp[(1) - (1)].tok) ) ); } 4946 4946 break; 4947 4947 4948 4948 case 5: 4949 4950 /* Line 1806 of yacc.c */4951 #line 317 "parser.yy"4952 { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); }4953 break;4954 4955 case 6:4956 4949 4957 4950 /* Line 1806 of yacc.c */ … … 4960 4953 break; 4961 4954 4962 case 7:4955 case 6: 4963 4956 4964 4957 /* Line 1806 of yacc.c */ … … 4967 4960 break; 4968 4961 4962 case 7: 4963 4964 /* Line 1806 of yacc.c */ 4965 #line 320 "parser.yy" 4966 { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); } 4967 break; 4968 4969 4969 case 8: 4970 4970 4971 4971 /* Line 1806 of yacc.c */ 4972 #line 32 0"parser.yy"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 5"parser.yy"4979 #line 346 "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 49"parser.yy"4986 #line 350 "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 1"parser.yy"4993 #line 352 "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 2"parser.yy"5004 #line 363 "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 4"parser.yy"5011 #line 365 "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 7"parser.yy"5018 #line 368 "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 69"parser.yy"5025 #line 370 "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 79"parser.yy"5032 #line 380 "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 1"parser.yy"5039 #line 382 "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 3"parser.yy"5046 #line 384 "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 5064 5050 case 32: 5065 5051 5066 5052 /* Line 1806 of yacc.c */ 5067 #line 38 9"parser.yy"5053 #line 388 "parser.yy" 5068 5054 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); } 5069 5055 break; 5070 5056 5071 case 3 3:5057 case 34: 5072 5058 5073 5059 /* Line 1806 of yacc.c */ 5074 5060 #line 391 "parser.yy" 5075 { (yyval.en) = new ExpressionNode( build_ pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en)) ) ); }5076 break; 5077 5078 case 3 4:5061 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); } 5062 break; 5063 5064 case 35: 5079 5065 5080 5066 /* Line 1806 of yacc.c */ 5081 5067 #line 393 "parser.yy" 5082 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds:: IncrPost, (yyvsp[(1) - (2)].en) ) ); }5083 break; 5084 5085 case 3 5:5068 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); } 5069 break; 5070 5071 case 36: 5086 5072 5087 5073 /* Line 1806 of yacc.c */ 5088 5074 #line 395 "parser.yy" 5089 { (yyval.en) = new ExpressionNode( build_ unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); }5090 break; 5091 5092 case 3 6:5075 { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); } 5076 break; 5077 5078 case 37: 5093 5079 5094 5080 /* Line 1806 of yacc.c */ 5095 5081 #line 397 "parser.yy" 5096 { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); }5097 break;5098 5099 case 37:5100 5101 /* Line 1806 of yacc.c */5102 #line 399 "parser.yy"5103 5082 { 5104 5083 Token fn; … … 5111 5090 5112 5091 /* Line 1806 of yacc.c */ 5113 #line 40 9"parser.yy"5092 #line 407 "parser.yy" 5114 5093 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); } 5115 5094 break; … … 5118 5097 5119 5098 /* Line 1806 of yacc.c */ 5120 #line 41 4"parser.yy"5099 #line 412 "parser.yy" 5121 5100 { (yyval.en) = 0; } 5122 5101 break; … … 5125 5104 5126 5105 /* Line 1806 of yacc.c */ 5127 #line 4 20"parser.yy"5106 #line 418 "parser.yy" 5128 5107 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); } 5129 5108 break; 5130 5109 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 5131 5117 case 45: 5132 5118 5133 5119 /* Line 1806 of yacc.c */ 5134 #line 42 6"parser.yy"5135 { (yyval.en) = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *(yyvsp[(1) - (2)].tok) ) ), maybeMoveBuild<Expression>( (yyvsp[(2) - (2)].en) ) ) ); }5120 #line 425 "parser.yy" 5121 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(2) - (2)].en), build_varref( (yyvsp[(1) - (2)].tok) ) ) ); } 5136 5122 break; 5137 5123 … … 5139 5125 5140 5126 /* Line 1806 of yacc.c */ 5141 #line 42 8"parser.yy"5142 { (yyval.en) = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *(yyvsp[(1) - (6)].tok) ) ), build_tuple( (yyvsp[(4) - (6)].en) ) ) ); }5127 #line 427 "parser.yy" 5128 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(4) - (6)].en), build_varref( (yyvsp[(1) - (6)].tok) ) ) ); } 5143 5129 break; 5144 5130 … … 5146 5132 5147 5133 /* Line 1806 of yacc.c */ 5148 #line 4 30"parser.yy"5149 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[( 1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); }5134 #line 429 "parser.yy" 5135 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); } 5150 5136 break; 5151 5137 … … 5153 5139 5154 5140 /* Line 1806 of yacc.c */ 5155 #line 43 2"parser.yy"5156 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[( 1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }5141 #line 431 "parser.yy" 5142 { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); } 5157 5143 break; 5158 5144 … … 5160 5146 5161 5147 /* Line 1806 of yacc.c */ 5162 #line 43 4"parser.yy"5163 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[( 1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); }5148 #line 433 "parser.yy" 5149 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); } 5164 5150 break; 5165 5151 … … 5167 5153 5168 5154 /* Line 1806 of yacc.c */ 5169 #line 43 6"parser.yy"5170 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[( 1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }5155 #line 435 "parser.yy" 5156 { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); } 5171 5157 break; 5172 5158 … … 5174 5160 5175 5161 /* Line 1806 of yacc.c */ 5176 #line 44 1"parser.yy"5177 { (yyval. en) = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *(yyvsp[(1) - (2)].tok) ), (yyvsp[(2) - (2)].en) )); }5162 #line 440 "parser.yy" 5163 { (yyval.tok) = (yyvsp[(1) - (2)].tok); } 5178 5164 break; 5179 5165 … … 5181 5167 5182 5168 /* Line 1806 of yacc.c */ 5183 #line 44 3"parser.yy"5184 { (yyval. en) = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *(yyvsp[(1) - (2)].tok) ), (yyvsp[(2) - (2)].en) )); }5169 #line 442 "parser.yy" 5170 { (yyval.tok) = (yyvsp[(1) - (2)].tok); } 5185 5171 break; 5186 5172 … … 5188 5174 5189 5175 /* Line 1806 of yacc.c */ 5190 #line 445 "parser.yy" 5191 { (yyval.en) = new ExpressionNode( build_field_name_fraction_constants( build_varref( (yyvsp[(1) - (2)].tok) ), (yyvsp[(2) - (2)].en) ) ); } 5192 break; 5193 5194 case 54: 5195 5196 /* Line 1806 of yacc.c */ 5197 #line 450 "parser.yy" 5198 { (yyval.en) = nullptr; } 5199 break; 5200 5201 case 55: 5202 5203 /* Line 1806 of yacc.c */ 5204 #line 452 "parser.yy" 5205 { 5206 Expression * constant = build_field_name_REALFRACTIONconstant( *(yyvsp[(2) - (2)].tok) ); 5207 (yyval.en) = (yyvsp[(1) - (2)].en) != nullptr ? new ExpressionNode( build_fieldSel( (yyvsp[(1) - (2)].en), constant ) ) : new ExpressionNode( constant ); 5208 } 5176 #line 444 "parser.yy" 5177 { (yyval.tok) = (yyvsp[(1) - (2)].tok); } 5209 5178 break; 5210 5179 … … 5212 5181 5213 5182 /* Line 1806 of yacc.c */ 5214 #line 4 63"parser.yy"5183 #line 457 "parser.yy" 5215 5184 { (yyval.en) = (yyvsp[(1) - (1)].en); } 5216 5185 break; … … 5219 5188 5220 5189 /* Line 1806 of yacc.c */ 5221 #line 4 65"parser.yy"5190 #line 459 "parser.yy" 5222 5191 { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); } 5223 5192 break; … … 5226 5195 5227 5196 /* Line 1806 of yacc.c */ 5228 #line 46 7"parser.yy"5197 #line 461 "parser.yy" 5229 5198 { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); } 5230 5199 break; … … 5233 5202 5234 5203 /* Line 1806 of yacc.c */ 5235 #line 4 72"parser.yy"5204 #line 466 "parser.yy" 5236 5205 { 5237 5206 switch ( (yyvsp[(1) - (2)].op) ) { … … 5251 5220 5252 5221 /* Line 1806 of yacc.c */ 5222 #line 479 "parser.yy" 5223 { (yyval.en) = new ExpressionNode( build_unary_val( (yyvsp[(1) - (2)].op), (yyvsp[(2) - (2)].en) ) ); } 5224 break; 5225 5226 case 62: 5227 5228 /* Line 1806 of yacc.c */ 5229 #line 481 "parser.yy" 5230 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); } 5231 break; 5232 5233 case 63: 5234 5235 /* Line 1806 of yacc.c */ 5236 #line 483 "parser.yy" 5237 { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Decr, (yyvsp[(2) - (2)].en) ) ); } 5238 break; 5239 5240 case 64: 5241 5242 /* Line 1806 of yacc.c */ 5253 5243 #line 485 "parser.yy" 5254 { (yyval.en) = new ExpressionNode( build_ unary_val( (yyvsp[(1) - (2)].op),(yyvsp[(2) - (2)].en) ) ); }5255 break; 5256 5257 case 6 2:5244 { (yyval.en) = new ExpressionNode( build_sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); } 5245 break; 5246 5247 case 65: 5258 5248 5259 5249 /* Line 1806 of yacc.c */ 5260 5250 #line 487 "parser.yy" 5261 { (yyval.en) = new ExpressionNode( build_ unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); }5262 break; 5263 5264 case 6 3:5251 { (yyval.en) = new ExpressionNode( build_sizeOftype( (yyvsp[(3) - (4)].decl) ) ); } 5252 break; 5253 5254 case 66: 5265 5255 5266 5256 /* Line 1806 of yacc.c */ 5267 5257 #line 489 "parser.yy" 5268 { (yyval.en) = new ExpressionNode( build_ unary_ptr( OperKinds::Decr,(yyvsp[(2) - (2)].en) ) ); }5269 break; 5270 5271 case 6 4:5258 { (yyval.en) = new ExpressionNode( build_alignOfexpr( (yyvsp[(2) - (2)].en) ) ); } 5259 break; 5260 5261 case 67: 5272 5262 5273 5263 /* Line 1806 of yacc.c */ 5274 5264 #line 491 "parser.yy" 5275 { (yyval.en) = new ExpressionNode( build_ sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); }5276 break; 5277 5278 case 6 5:5265 { (yyval.en) = new ExpressionNode( build_alignOftype( (yyvsp[(3) - (4)].decl) ) ); } 5266 break; 5267 5268 case 68: 5279 5269 5280 5270 /* Line 1806 of yacc.c */ 5281 5271 #line 493 "parser.yy" 5282 { (yyval.en) = new ExpressionNode( build_ sizeOftype( (yyvsp[(3) - (4)].decl) ) ); }5283 break; 5284 5285 case 6 6:5272 { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); } 5273 break; 5274 5275 case 69: 5286 5276 5287 5277 /* Line 1806 of yacc.c */ 5288 5278 #line 495 "parser.yy" 5289 { (yyval.en) = new ExpressionNode( build_a lignOfexpr( (yyvsp[(2) - (2)].en)) ); }5290 break; 5291 5292 case 67:5279 { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); } 5280 break; 5281 5282 case 70: 5293 5283 5294 5284 /* Line 1806 of yacc.c */ 5295 5285 #line 497 "parser.yy" 5296 { (yyval.en) = new ExpressionNode( build_a lignOftype( (yyvsp[(3) - (4)].decl) ) ); }5297 break; 5298 5299 case 68:5286 { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); } 5287 break; 5288 5289 case 71: 5300 5290 5301 5291 /* Line 1806 of yacc.c */ 5302 5292 #line 499 "parser.yy" 5303 { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); } 5304 break; 5305 5306 case 69: 5307 5308 /* Line 1806 of yacc.c */ 5309 #line 501 "parser.yy" 5310 { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); } 5311 break; 5312 5313 case 70: 5314 5315 /* Line 1806 of yacc.c */ 5316 #line 503 "parser.yy" 5317 { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); } 5318 break; 5319 5320 case 71: 5293 { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); } 5294 break; 5295 5296 case 72: 5321 5297 5322 5298 /* Line 1806 of yacc.c */ 5323 5299 #line 505 "parser.yy" 5324 { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); }5325 break;5326 5327 case 72:5328 5329 /* Line 1806 of yacc.c */5330 #line 511 "parser.yy"5331 5300 { (yyval.op) = OperKinds::PointTo; } 5332 5301 break; … … 5335 5304 5336 5305 /* Line 1806 of yacc.c */ 5306 #line 506 "parser.yy" 5307 { (yyval.op) = OperKinds::AddressOf; } 5308 break; 5309 5310 case 74: 5311 5312 /* Line 1806 of yacc.c */ 5337 5313 #line 512 "parser.yy" 5338 { (yyval.op) = OperKinds::AddressOf; }5339 break;5340 5341 case 74:5342 5343 /* Line 1806 of yacc.c */5344 #line 518 "parser.yy"5345 5314 { (yyval.op) = OperKinds::UnPlus; } 5346 5315 break; … … 5349 5318 5350 5319 /* Line 1806 of yacc.c */ 5351 #line 51 9"parser.yy"5320 #line 513 "parser.yy" 5352 5321 { (yyval.op) = OperKinds::UnMinus; } 5353 5322 break; … … 5356 5325 5357 5326 /* Line 1806 of yacc.c */ 5358 #line 5 20"parser.yy"5327 #line 514 "parser.yy" 5359 5328 { (yyval.op) = OperKinds::Neg; } 5360 5329 break; … … 5363 5332 5364 5333 /* Line 1806 of yacc.c */ 5334 #line 515 "parser.yy" 5335 { (yyval.op) = OperKinds::BitNeg; } 5336 break; 5337 5338 case 79: 5339 5340 /* Line 1806 of yacc.c */ 5365 5341 #line 521 "parser.yy" 5366 { (yyval.op) = OperKinds::BitNeg; }5367 break;5368 5369 case 79:5370 5371 /* Line 1806 of yacc.c */5372 #line 527 "parser.yy"5373 5342 { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); } 5374 5343 break; … … 5377 5346 5378 5347 /* Line 1806 of yacc.c */ 5379 #line 5 35"parser.yy"5348 #line 529 "parser.yy" 5380 5349 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mul, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5381 5350 break; … … 5384 5353 5385 5354 /* Line 1806 of yacc.c */ 5386 #line 53 7"parser.yy"5355 #line 531 "parser.yy" 5387 5356 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Div, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5388 5357 break; … … 5391 5360 5392 5361 /* Line 1806 of yacc.c */ 5362 #line 533 "parser.yy" 5363 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5364 break; 5365 5366 case 85: 5367 5368 /* Line 1806 of yacc.c */ 5393 5369 #line 539 "parser.yy" 5394 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }5395 break;5396 5397 case 85:5398 5399 /* Line 1806 of yacc.c */5400 #line 545 "parser.yy"5401 5370 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Plus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5402 5371 break; … … 5405 5374 5406 5375 /* Line 1806 of yacc.c */ 5376 #line 541 "parser.yy" 5377 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5378 break; 5379 5380 case 88: 5381 5382 /* Line 1806 of yacc.c */ 5407 5383 #line 547 "parser.yy" 5408 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }5409 break;5410 5411 case 88:5412 5413 /* Line 1806 of yacc.c */5414 #line 553 "parser.yy"5415 5384 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5416 5385 break; … … 5419 5388 5420 5389 /* Line 1806 of yacc.c */ 5390 #line 549 "parser.yy" 5391 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5392 break; 5393 5394 case 91: 5395 5396 /* Line 1806 of yacc.c */ 5421 5397 #line 555 "parser.yy" 5422 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5423 break; 5424 5425 case 91: 5398 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5399 break; 5400 5401 case 92: 5402 5403 /* Line 1806 of yacc.c */ 5404 #line 557 "parser.yy" 5405 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5406 break; 5407 5408 case 93: 5409 5410 /* Line 1806 of yacc.c */ 5411 #line 559 "parser.yy" 5412 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5413 break; 5414 5415 case 94: 5426 5416 5427 5417 /* Line 1806 of yacc.c */ 5428 5418 #line 561 "parser.yy" 5429 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5430 break; 5431 5432 case 92: 5433 5434 /* Line 1806 of yacc.c */ 5435 #line 563 "parser.yy" 5436 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5437 break; 5438 5439 case 93: 5440 5441 /* Line 1806 of yacc.c */ 5442 #line 565 "parser.yy" 5443 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5444 break; 5445 5446 case 94: 5419 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5420 break; 5421 5422 case 96: 5447 5423 5448 5424 /* Line 1806 of yacc.c */ 5449 5425 #line 567 "parser.yy" 5450 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }5451 break;5452 5453 case 96:5454 5455 /* Line 1806 of yacc.c */5456 #line 573 "parser.yy"5457 5426 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Eq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5458 5427 break; … … 5461 5430 5462 5431 /* Line 1806 of yacc.c */ 5432 #line 569 "parser.yy" 5433 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5434 break; 5435 5436 case 99: 5437 5438 /* Line 1806 of yacc.c */ 5463 5439 #line 575 "parser.yy" 5464 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds:: Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }5465 break; 5466 5467 case 99:5440 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5441 break; 5442 5443 case 101: 5468 5444 5469 5445 /* Line 1806 of yacc.c */ 5470 5446 #line 581 "parser.yy" 5471 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds:: BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }5472 break; 5473 5474 case 10 1:5447 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5448 break; 5449 5450 case 103: 5475 5451 5476 5452 /* Line 1806 of yacc.c */ 5477 5453 #line 587 "parser.yy" 5478 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds:: Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }5479 break; 5480 5481 case 10 3:5454 { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5455 break; 5456 5457 case 105: 5482 5458 5483 5459 /* Line 1806 of yacc.c */ 5484 5460 #line 593 "parser.yy" 5485 { (yyval.en) = new ExpressionNode( build_ binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en)) ); }5486 break; 5487 5488 case 10 5:5461 { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); } 5462 break; 5463 5464 case 107: 5489 5465 5490 5466 /* Line 1806 of yacc.c */ 5491 5467 #line 599 "parser.yy" 5492 { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); }5493 break; 5494 5495 case 10 7:5468 { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); } 5469 break; 5470 5471 case 109: 5496 5472 5497 5473 /* Line 1806 of yacc.c */ 5498 5474 #line 605 "parser.yy" 5499 { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); }5500 break;5501 5502 case 109:5503 5504 /* Line 1806 of yacc.c */5505 #line 611 "parser.yy"5506 5475 { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); } 5507 5476 break; … … 5510 5479 5511 5480 /* Line 1806 of yacc.c */ 5512 #line 6 14"parser.yy"5481 #line 608 "parser.yy" 5513 5482 { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (4)].en), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ) ); } 5514 5483 break; … … 5517 5486 5518 5487 /* Line 1806 of yacc.c */ 5519 #line 62 7"parser.yy"5488 #line 621 "parser.yy" 5520 5489 { (yyval.en) = new ExpressionNode( build_binary_ptr( (yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5521 5490 break; … … 5524 5493 5525 5494 /* Line 1806 of yacc.c */ 5495 #line 628 "parser.yy" 5496 { (yyval.en) = nullptr; } 5497 break; 5498 5499 case 116: 5500 5501 /* Line 1806 of yacc.c */ 5502 #line 633 "parser.yy" 5503 { (yyval.op) = OperKinds::Assign; } 5504 break; 5505 5506 case 117: 5507 5508 /* Line 1806 of yacc.c */ 5526 5509 #line 634 "parser.yy" 5527 { (yyval.en) = nullptr; } 5528 break; 5529 5530 case 116: 5510 { (yyval.op) = OperKinds::AtAssn; } 5511 break; 5512 5513 case 118: 5514 5515 /* Line 1806 of yacc.c */ 5516 #line 635 "parser.yy" 5517 { (yyval.op) = OperKinds::MulAssn; } 5518 break; 5519 5520 case 119: 5521 5522 /* Line 1806 of yacc.c */ 5523 #line 636 "parser.yy" 5524 { (yyval.op) = OperKinds::DivAssn; } 5525 break; 5526 5527 case 120: 5528 5529 /* Line 1806 of yacc.c */ 5530 #line 637 "parser.yy" 5531 { (yyval.op) = OperKinds::ModAssn; } 5532 break; 5533 5534 case 121: 5535 5536 /* Line 1806 of yacc.c */ 5537 #line 638 "parser.yy" 5538 { (yyval.op) = OperKinds::PlusAssn; } 5539 break; 5540 5541 case 122: 5531 5542 5532 5543 /* Line 1806 of yacc.c */ 5533 5544 #line 639 "parser.yy" 5534 { (yyval.op) = OperKinds:: Assign; }5535 break; 5536 5537 case 1 17:5545 { (yyval.op) = OperKinds::MinusAssn; } 5546 break; 5547 5548 case 123: 5538 5549 5539 5550 /* Line 1806 of yacc.c */ 5540 5551 #line 640 "parser.yy" 5541 { (yyval.op) = OperKinds:: AtAssn; }5542 break; 5543 5544 case 1 18:5552 { (yyval.op) = OperKinds::LSAssn; } 5553 break; 5554 5555 case 124: 5545 5556 5546 5557 /* Line 1806 of yacc.c */ 5547 5558 #line 641 "parser.yy" 5548 { (yyval.op) = OperKinds:: MulAssn; }5549 break; 5550 5551 case 1 19:5559 { (yyval.op) = OperKinds::RSAssn; } 5560 break; 5561 5562 case 125: 5552 5563 5553 5564 /* Line 1806 of yacc.c */ 5554 5565 #line 642 "parser.yy" 5555 { (yyval.op) = OperKinds:: DivAssn; }5556 break; 5557 5558 case 12 0:5566 { (yyval.op) = OperKinds::AndAssn; } 5567 break; 5568 5569 case 126: 5559 5570 5560 5571 /* Line 1806 of yacc.c */ 5561 5572 #line 643 "parser.yy" 5562 { (yyval.op) = OperKinds:: ModAssn; }5563 break; 5564 5565 case 12 1:5573 { (yyval.op) = OperKinds::ERAssn; } 5574 break; 5575 5576 case 127: 5566 5577 5567 5578 /* Line 1806 of yacc.c */ 5568 5579 #line 644 "parser.yy" 5569 { (yyval.op) = OperKinds::PlusAssn; }5570 break;5571 5572 case 122:5573 5574 /* Line 1806 of yacc.c */5575 #line 645 "parser.yy"5576 { (yyval.op) = OperKinds::MinusAssn; }5577 break;5578 5579 case 123:5580 5581 /* Line 1806 of yacc.c */5582 #line 646 "parser.yy"5583 { (yyval.op) = OperKinds::LSAssn; }5584 break;5585 5586 case 124:5587 5588 /* Line 1806 of yacc.c */5589 #line 647 "parser.yy"5590 { (yyval.op) = OperKinds::RSAssn; }5591 break;5592 5593 case 125:5594 5595 /* Line 1806 of yacc.c */5596 #line 648 "parser.yy"5597 { (yyval.op) = OperKinds::AndAssn; }5598 break;5599 5600 case 126:5601 5602 /* Line 1806 of yacc.c */5603 #line 649 "parser.yy"5604 { (yyval.op) = OperKinds::ERAssn; }5605 break;5606 5607 case 127:5608 5609 /* Line 1806 of yacc.c */5610 #line 650 "parser.yy"5611 5580 { (yyval.op) = OperKinds::OrAssn; } 5612 5581 break; … … 5615 5584 5616 5585 /* Line 1806 of yacc.c */ 5617 #line 6 61"parser.yy"5586 #line 655 "parser.yy" 5618 5587 { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( (yyvsp[(4) - (6)].en) ) ) ); } 5619 5588 break; … … 5622 5591 5623 5592 /* Line 1806 of yacc.c */ 5593 #line 657 "parser.yy" 5594 { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) ) ) ); } 5595 break; 5596 5597 case 131: 5598 5599 /* Line 1806 of yacc.c */ 5624 5600 #line 663 "parser.yy" 5625 { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) )) ); }5626 break; 5627 5628 case 13 1:5601 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); } 5602 break; 5603 5604 case 133: 5629 5605 5630 5606 /* Line 1806 of yacc.c */ 5631 5607 #line 669 "parser.yy" 5632 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }5633 break;5634 5635 case 133:5636 5637 /* Line 1806 of yacc.c */5638 #line 675 "parser.yy"5639 5608 { (yyval.en) = new ExpressionNode( build_comma( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5640 5609 break; … … 5643 5612 5644 5613 /* Line 1806 of yacc.c */ 5645 #line 6 80"parser.yy"5614 #line 674 "parser.yy" 5646 5615 { (yyval.en) = 0; } 5647 5616 break; … … 5650 5619 5651 5620 /* Line 1806 of yacc.c */ 5652 #line 68 9"parser.yy"5621 #line 683 "parser.yy" 5653 5622 { (yyval.sn) = (yyvsp[(1) - (1)].sn); } 5654 5623 break; … … 5657 5626 5658 5627 /* Line 1806 of yacc.c */ 5659 #line 69 6"parser.yy"5628 #line 690 "parser.yy" 5660 5629 { 5661 5630 Token fn; … … 5668 5637 5669 5638 /* Line 1806 of yacc.c */ 5670 #line 70 6"parser.yy"5639 #line 700 "parser.yy" 5671 5640 { 5672 5641 (yyval.sn) = (yyvsp[(4) - (4)].sn)->add_label( (yyvsp[(1) - (4)].tok) ); … … 5677 5646 5678 5647 /* Line 1806 of yacc.c */ 5679 #line 7 13"parser.yy"5648 #line 707 "parser.yy" 5680 5649 { (yyval.sn) = new StatementNode( build_compound( (StatementNode *)0 ) ); } 5681 5650 break; … … 5684 5653 5685 5654 /* Line 1806 of yacc.c */ 5655 #line 714 "parser.yy" 5656 { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); } 5657 break; 5658 5659 case 149: 5660 5661 /* Line 1806 of yacc.c */ 5686 5662 #line 720 "parser.yy" 5687 { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); }5688 break;5689 5690 case 149:5691 5692 /* Line 1806 of yacc.c */5693 #line 726 "parser.yy"5694 5663 { if ( (yyvsp[(1) - (3)].sn) != 0 ) { (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ); (yyval.sn) = (yyvsp[(1) - (3)].sn); } } 5695 5664 break; … … 5698 5667 5699 5668 /* Line 1806 of yacc.c */ 5700 #line 7 31"parser.yy"5669 #line 725 "parser.yy" 5701 5670 { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); } 5702 5671 break; … … 5705 5674 5706 5675 /* Line 1806 of yacc.c */ 5707 #line 7 33"parser.yy"5676 #line 727 "parser.yy" 5708 5677 { // mark all fields in list 5709 5678 for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) … … 5716 5685 5717 5686 /* Line 1806 of yacc.c */ 5718 #line 73 9"parser.yy"5687 #line 733 "parser.yy" 5719 5688 { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); } 5720 5689 break; … … 5723 5692 5724 5693 /* Line 1806 of yacc.c */ 5725 #line 74 6"parser.yy"5694 #line 740 "parser.yy" 5726 5695 { if ( (yyvsp[(1) - (2)].sn) != 0 ) { (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) ); (yyval.sn) = (yyvsp[(1) - (2)].sn); } } 5727 5696 break; … … 5730 5699 5731 5700 /* Line 1806 of yacc.c */ 5701 #line 745 "parser.yy" 5702 { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); } 5703 break; 5704 5705 case 157: 5706 5707 /* Line 1806 of yacc.c */ 5732 5708 #line 751 "parser.yy" 5733 { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); } 5734 break; 5735 5736 case 157: 5709 { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); } 5710 break; 5711 5712 case 158: 5713 5714 /* Line 1806 of yacc.c */ 5715 #line 753 "parser.yy" 5716 { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); } 5717 break; 5718 5719 case 159: 5720 5721 /* Line 1806 of yacc.c */ 5722 #line 755 "parser.yy" 5723 { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5724 break; 5725 5726 case 160: 5737 5727 5738 5728 /* Line 1806 of yacc.c */ 5739 5729 #line 757 "parser.yy" 5740 { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); }5741 break;5742 5743 case 158:5744 5745 /* Line 1806 of yacc.c */5746 #line 759 "parser.yy"5747 { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }5748 break;5749 5750 case 159:5751 5752 /* Line 1806 of yacc.c */5753 #line 761 "parser.yy"5754 { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }5755 break;5756 5757 case 160:5758 5759 /* Line 1806 of yacc.c */5760 #line 763 "parser.yy"5761 5730 { 5762 5731 StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); … … 5773 5742 5774 5743 /* Line 1806 of yacc.c */ 5775 #line 7 73"parser.yy"5744 #line 767 "parser.yy" 5776 5745 { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5777 5746 break; … … 5780 5749 5781 5750 /* Line 1806 of yacc.c */ 5782 #line 7 75"parser.yy"5751 #line 769 "parser.yy" 5783 5752 { 5784 5753 StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); … … 5790 5759 5791 5760 /* Line 1806 of yacc.c */ 5792 #line 7 85"parser.yy"5761 #line 779 "parser.yy" 5793 5762 { (yyval.en) = (yyvsp[(1) - (1)].en); } 5794 5763 break; … … 5797 5766 5798 5767 /* Line 1806 of yacc.c */ 5799 #line 78 7"parser.yy"5768 #line 781 "parser.yy" 5800 5769 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5801 5770 break; … … 5804 5773 5805 5774 /* Line 1806 of yacc.c */ 5775 #line 786 "parser.yy" 5776 { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); } 5777 break; 5778 5779 case 167: 5780 5781 /* Line 1806 of yacc.c */ 5782 #line 788 "parser.yy" 5783 { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); } 5784 break; 5785 5786 case 168: 5787 5788 /* Line 1806 of yacc.c */ 5806 5789 #line 792 "parser.yy" 5807 { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); }5808 break;5809 5810 case 167:5811 5812 /* Line 1806 of yacc.c */5813 #line 794 "parser.yy"5814 { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); }5815 break;5816 5817 case 168:5818 5819 /* Line 1806 of yacc.c */5820 #line 798 "parser.yy"5821 5790 { (yyval.sn) = (yyvsp[(2) - (3)].sn); } 5822 5791 break; … … 5825 5794 5826 5795 /* Line 1806 of yacc.c */ 5796 #line 793 "parser.yy" 5797 { (yyval.sn) = new StatementNode( build_default() ); } 5798 break; 5799 5800 case 171: 5801 5802 /* Line 1806 of yacc.c */ 5827 5803 #line 799 "parser.yy" 5828 { (yyval.sn) = new StatementNode( build_default() ); }5829 break;5830 5831 case 171:5832 5833 /* Line 1806 of yacc.c */5834 #line 805 "parser.yy"5835 5804 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) )); } 5836 5805 break; … … 5839 5808 5840 5809 /* Line 1806 of yacc.c */ 5841 #line 80 9"parser.yy"5810 #line 803 "parser.yy" 5842 5811 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); } 5843 5812 break; … … 5846 5815 5847 5816 /* Line 1806 of yacc.c */ 5817 #line 808 "parser.yy" 5818 { (yyval.sn) = 0; } 5819 break; 5820 5821 case 175: 5822 5823 /* Line 1806 of yacc.c */ 5848 5824 #line 814 "parser.yy" 5825 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); } 5826 break; 5827 5828 case 176: 5829 5830 /* Line 1806 of yacc.c */ 5831 #line 816 "parser.yy" 5832 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(3) - (3)].sn) ) ) ) ) ); } 5833 break; 5834 5835 case 177: 5836 5837 /* Line 1806 of yacc.c */ 5838 #line 821 "parser.yy" 5849 5839 { (yyval.sn) = 0; } 5850 5840 break; 5851 5841 5852 case 175: 5853 5854 /* Line 1806 of yacc.c */ 5855 #line 820 "parser.yy" 5856 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); } 5857 break; 5858 5859 case 176: 5860 5861 /* Line 1806 of yacc.c */ 5862 #line 822 "parser.yy" 5863 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(3) - (3)].sn) ) ) ) ) ); } 5864 break; 5865 5866 case 177: 5842 case 179: 5867 5843 5868 5844 /* Line 1806 of yacc.c */ 5869 5845 #line 827 "parser.yy" 5846 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); } 5847 break; 5848 5849 case 180: 5850 5851 /* Line 1806 of yacc.c */ 5852 #line 829 "parser.yy" 5853 { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(2) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ) ) ) ); } 5854 break; 5855 5856 case 181: 5857 5858 /* Line 1806 of yacc.c */ 5859 #line 831 "parser.yy" 5860 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); } 5861 break; 5862 5863 case 182: 5864 5865 /* Line 1806 of yacc.c */ 5866 #line 833 "parser.yy" 5867 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_last( (yyvsp[(2) - (4)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(3) - (4)].sn)->set_last( (yyvsp[(4) - (4)].sn) ) ) ) ) ) ); } 5868 break; 5869 5870 case 183: 5871 5872 /* Line 1806 of yacc.c */ 5873 #line 838 "parser.yy" 5874 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); } 5875 break; 5876 5877 case 185: 5878 5879 /* Line 1806 of yacc.c */ 5880 #line 844 "parser.yy" 5870 5881 { (yyval.sn) = 0; } 5871 5882 break; 5872 5883 5873 case 179: 5874 5875 /* Line 1806 of yacc.c */ 5876 #line 833 "parser.yy" 5877 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); } 5878 break; 5879 5880 case 180: 5881 5882 /* Line 1806 of yacc.c */ 5883 #line 835 "parser.yy" 5884 { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(2) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ) ) ) ); } 5885 break; 5886 5887 case 181: 5888 5889 /* Line 1806 of yacc.c */ 5890 #line 837 "parser.yy" 5891 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); } 5892 break; 5893 5894 case 182: 5895 5896 /* Line 1806 of yacc.c */ 5897 #line 839 "parser.yy" 5898 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_last( (yyvsp[(2) - (4)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(3) - (4)].sn)->set_last( (yyvsp[(4) - (4)].sn) ) ) ) ) ) ); } 5899 break; 5900 5901 case 183: 5902 5903 /* Line 1806 of yacc.c */ 5904 #line 844 "parser.yy" 5884 case 186: 5885 5886 /* Line 1806 of yacc.c */ 5887 #line 846 "parser.yy" 5888 { (yyval.sn) = 0; } 5889 break; 5890 5891 case 187: 5892 5893 /* Line 1806 of yacc.c */ 5894 #line 851 "parser.yy" 5895 { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5896 break; 5897 5898 case 188: 5899 5900 /* Line 1806 of yacc.c */ 5901 #line 853 "parser.yy" 5902 { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); } 5903 break; 5904 5905 case 189: 5906 5907 /* Line 1806 of yacc.c */ 5908 #line 855 "parser.yy" 5909 { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); } 5910 break; 5911 5912 case 190: 5913 5914 /* Line 1806 of yacc.c */ 5915 #line 860 "parser.yy" 5916 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); } 5917 break; 5918 5919 case 191: 5920 5921 /* Line 1806 of yacc.c */ 5922 #line 862 "parser.yy" 5923 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); } 5924 break; 5925 5926 case 192: 5927 5928 /* Line 1806 of yacc.c */ 5929 #line 867 "parser.yy" 5930 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); } 5931 break; 5932 5933 case 193: 5934 5935 /* Line 1806 of yacc.c */ 5936 #line 871 "parser.yy" 5937 { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); } 5938 break; 5939 5940 case 194: 5941 5942 /* Line 1806 of yacc.c */ 5943 #line 874 "parser.yy" 5944 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); } 5945 break; 5946 5947 case 195: 5948 5949 /* Line 1806 of yacc.c */ 5950 #line 878 "parser.yy" 5951 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); } 5952 break; 5953 5954 case 196: 5955 5956 /* Line 1806 of yacc.c */ 5957 #line 881 "parser.yy" 5905 5958 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); } 5906 5959 break; 5907 5960 5908 case 185: 5909 5910 /* Line 1806 of yacc.c */ 5911 #line 850 "parser.yy" 5912 { (yyval.sn) = 0; } 5913 break; 5914 5915 case 186: 5916 5917 /* Line 1806 of yacc.c */ 5918 #line 852 "parser.yy" 5919 { (yyval.sn) = 0; } 5920 break; 5921 5922 case 187: 5923 5924 /* Line 1806 of yacc.c */ 5925 #line 857 "parser.yy" 5926 { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5927 break; 5928 5929 case 188: 5930 5931 /* Line 1806 of yacc.c */ 5932 #line 859 "parser.yy" 5933 { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); } 5934 break; 5935 5936 case 189: 5937 5938 /* Line 1806 of yacc.c */ 5939 #line 861 "parser.yy" 5940 { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); } 5941 break; 5942 5943 case 190: 5944 5945 /* Line 1806 of yacc.c */ 5946 #line 866 "parser.yy" 5947 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); } 5948 break; 5949 5950 case 191: 5951 5952 /* Line 1806 of yacc.c */ 5953 #line 868 "parser.yy" 5954 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); } 5955 break; 5956 5957 case 192: 5958 5959 /* Line 1806 of yacc.c */ 5960 #line 873 "parser.yy" 5961 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); } 5962 break; 5963 5964 case 193: 5965 5966 /* Line 1806 of yacc.c */ 5967 #line 877 "parser.yy" 5968 { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); } 5969 break; 5970 5971 case 194: 5972 5973 /* Line 1806 of yacc.c */ 5974 #line 880 "parser.yy" 5975 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); } 5976 break; 5977 5978 case 195: 5979 5980 /* Line 1806 of yacc.c */ 5981 #line 884 "parser.yy" 5982 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); } 5983 break; 5984 5985 case 196: 5961 case 197: 5962 5963 /* Line 1806 of yacc.c */ 5964 #line 885 "parser.yy" 5965 { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); } 5966 break; 5967 5968 case 198: 5986 5969 5987 5970 /* Line 1806 of yacc.c */ 5988 5971 #line 887 "parser.yy" 5989 { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); } 5990 break; 5991 5992 case 197: 5972 { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); } 5973 break; 5974 5975 case 199: 5976 5977 /* Line 1806 of yacc.c */ 5978 #line 889 "parser.yy" 5979 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); } 5980 break; 5981 5982 case 200: 5993 5983 5994 5984 /* Line 1806 of yacc.c */ 5995 5985 #line 891 "parser.yy" 5996 { (yyval.sn) = new StatementNode( build_ branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break) ); }5997 break; 5998 5999 case 198:5986 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); } 5987 break; 5988 5989 case 201: 6000 5990 6001 5991 /* Line 1806 of yacc.c */ 6002 5992 #line 893 "parser.yy" 6003 { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); }6004 break;6005 6006 case 199:6007 6008 /* Line 1806 of yacc.c */6009 #line 895 "parser.yy"6010 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }6011 break;6012 6013 case 200:6014 6015 /* Line 1806 of yacc.c */6016 #line 897 "parser.yy"6017 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }6018 break;6019 6020 case 201:6021 6022 /* Line 1806 of yacc.c */6023 #line 899 "parser.yy"6024 5993 { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (5)].en) ) ); } 6025 5994 break; … … 6028 5997 6029 5998 /* Line 1806 of yacc.c */ 6030 #line 904"parser.yy"5999 #line 898 "parser.yy" 6031 6000 { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), (yyvsp[(3) - (3)].sn), 0 ) ); } 6032 6001 break; … … 6035 6004 6036 6005 /* Line 1806 of yacc.c */ 6037 #line 90 6"parser.yy"6006 #line 900 "parser.yy" 6038 6007 { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), 0, (yyvsp[(3) - (3)].sn) ) ); } 6039 6008 break; … … 6042 6011 6043 6012 /* Line 1806 of yacc.c */ 6044 #line 90 8"parser.yy"6013 #line 902 "parser.yy" 6045 6014 { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (4)].sn), (yyvsp[(3) - (4)].sn), (yyvsp[(4) - (4)].sn) ) ); } 6046 6015 break; … … 6049 6018 6050 6019 /* Line 1806 of yacc.c */ 6020 #line 909 "parser.yy" 6021 { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); } 6022 break; 6023 6024 case 207: 6025 6026 /* Line 1806 of yacc.c */ 6027 #line 911 "parser.yy" 6028 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); } 6029 break; 6030 6031 case 208: 6032 6033 /* Line 1806 of yacc.c */ 6034 #line 913 "parser.yy" 6035 { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); } 6036 break; 6037 6038 case 209: 6039 6040 /* Line 1806 of yacc.c */ 6051 6041 #line 915 "parser.yy" 6052 { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }6053 break;6054 6055 case 207:6056 6057 /* Line 1806 of yacc.c */6058 #line 917 "parser.yy"6059 6042 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); } 6060 6043 break; 6061 6044 6062 case 208:6063 6064 /* Line 1806 of yacc.c */6065 #line 919 "parser.yy"6066 { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }6067 break;6068 6069 case 209:6070 6071 /* Line 1806 of yacc.c */6072 #line 921 "parser.yy"6073 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }6074 break;6075 6076 6045 case 210: 6077 6046 6078 6047 /* Line 1806 of yacc.c */ 6048 #line 920 "parser.yy" 6049 { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); } 6050 break; 6051 6052 case 211: 6053 6054 /* Line 1806 of yacc.c */ 6055 #line 922 "parser.yy" 6056 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); } 6057 break; 6058 6059 case 212: 6060 6061 /* Line 1806 of yacc.c */ 6062 #line 924 "parser.yy" 6063 { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); } 6064 break; 6065 6066 case 213: 6067 6068 /* Line 1806 of yacc.c */ 6079 6069 #line 926 "parser.yy" 6080 { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }6081 break;6082 6083 case 211:6084 6085 /* Line 1806 of yacc.c */6086 #line 928 "parser.yy"6087 6070 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); } 6088 6071 break; 6089 6072 6090 case 212:6091 6092 /* Line 1806 of yacc.c */6093 #line 930 "parser.yy"6094 { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }6095 break;6096 6097 case 213:6098 6099 /* Line 1806 of yacc.c */6100 #line 932 "parser.yy"6101 { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }6102 break;6103 6104 6073 case 214: 6105 6074 6106 6075 /* Line 1806 of yacc.c */ 6107 #line 93 7"parser.yy"6076 #line 931 "parser.yy" 6108 6077 { 6109 6078 (yyval.sn) = new StatementNode( build_finally( (yyvsp[(2) - (2)].sn) ) ); … … 6114 6083 6115 6084 /* Line 1806 of yacc.c */ 6116 #line 9 50"parser.yy"6085 #line 944 "parser.yy" 6117 6086 { 6118 6087 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6124 6093 6125 6094 /* Line 1806 of yacc.c */ 6126 #line 9 55"parser.yy"6095 #line 949 "parser.yy" 6127 6096 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 6128 6097 break; … … 6131 6100 6132 6101 /* Line 1806 of yacc.c */ 6133 #line 95 7"parser.yy"6102 #line 951 "parser.yy" 6134 6103 { 6135 6104 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6141 6110 6142 6111 /* Line 1806 of yacc.c */ 6112 #line 960 "parser.yy" 6113 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ) ); } 6114 break; 6115 6116 case 221: 6117 6118 /* Line 1806 of yacc.c */ 6119 #line 962 "parser.yy" 6120 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); } 6121 break; 6122 6123 case 222: 6124 6125 /* Line 1806 of yacc.c */ 6126 #line 964 "parser.yy" 6127 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); } 6128 break; 6129 6130 case 223: 6131 6132 /* Line 1806 of yacc.c */ 6143 6133 #line 966 "parser.yy" 6144 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - ( 6)].flag), (yyvsp[(4) - (6)].constant), 0) ); }6145 break; 6146 6147 case 22 1:6134 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].en) ) ); } 6135 break; 6136 6137 case 224: 6148 6138 6149 6139 /* Line 1806 of yacc.c */ 6150 6140 #line 968 "parser.yy" 6151 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); }6152 break;6153 6154 case 222:6155 6156 /* Line 1806 of yacc.c */6157 #line 970 "parser.yy"6158 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); }6159 break;6160 6161 case 223:6162 6163 /* Line 1806 of yacc.c */6164 #line 972 "parser.yy"6165 { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].en) ) ); }6166 break;6167 6168 case 224:6169 6170 /* Line 1806 of yacc.c */6171 #line 974 "parser.yy"6172 6141 { (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) ) ); } 6173 6142 break; … … 6176 6145 6177 6146 /* Line 1806 of yacc.c */ 6178 #line 97 9"parser.yy"6147 #line 973 "parser.yy" 6179 6148 { (yyval.flag) = false; } 6180 6149 break; … … 6183 6152 6184 6153 /* Line 1806 of yacc.c */ 6185 #line 9 81"parser.yy"6154 #line 975 "parser.yy" 6186 6155 { (yyval.flag) = true; } 6187 6156 break; … … 6190 6159 6191 6160 /* Line 1806 of yacc.c */ 6192 #line 98 6"parser.yy"6161 #line 980 "parser.yy" 6193 6162 { (yyval.en) = 0; } 6194 6163 break; … … 6197 6166 6198 6167 /* Line 1806 of yacc.c */ 6199 #line 9 93"parser.yy"6168 #line 987 "parser.yy" 6200 6169 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); } 6201 6170 break; … … 6204 6173 6205 6174 /* Line 1806 of yacc.c */ 6206 #line 99 8"parser.yy"6175 #line 992 "parser.yy" 6207 6176 { (yyval.en) = new ExpressionNode( build_asmexpr( 0, (yyvsp[(1) - (4)].constant), (yyvsp[(3) - (4)].en) ) ); } 6208 6177 break; … … 6211 6180 6212 6181 /* Line 1806 of yacc.c */ 6213 #line 1000"parser.yy"6182 #line 994 "parser.yy" 6214 6183 { (yyval.en) = new ExpressionNode( build_asmexpr( (yyvsp[(2) - (7)].en), (yyvsp[(4) - (7)].constant), (yyvsp[(6) - (7)].en) ) ); } 6215 6184 break; … … 6218 6187 6219 6188 /* Line 1806 of yacc.c */ 6220 #line 1005"parser.yy"6189 #line 999 "parser.yy" 6221 6190 { (yyval.en) = 0; } 6222 6191 break; … … 6225 6194 6226 6195 /* Line 1806 of yacc.c */ 6227 #line 100 7"parser.yy"6196 #line 1001 "parser.yy" 6228 6197 { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); } 6229 6198 break; … … 6232 6201 6233 6202 /* Line 1806 of yacc.c */ 6234 #line 100 9"parser.yy"6203 #line 1003 "parser.yy" 6235 6204 { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( (yyvsp[(3) - (3)].constant) ) ); } 6236 6205 break; … … 6239 6208 6240 6209 /* Line 1806 of yacc.c */ 6241 #line 10 14"parser.yy"6210 #line 1008 "parser.yy" 6242 6211 { 6243 6212 (yyval.label) = new LabelNode(); (yyval.label)->labels.push_back( *(yyvsp[(1) - (1)].tok) ); … … 6249 6218 6250 6219 /* Line 1806 of yacc.c */ 6251 #line 101 9"parser.yy"6220 #line 1013 "parser.yy" 6252 6221 { 6253 6222 (yyval.label) = (yyvsp[(1) - (3)].label); (yyvsp[(1) - (3)].label)->labels.push_back( *(yyvsp[(3) - (3)].tok) ); … … 6259 6228 6260 6229 /* Line 1806 of yacc.c */ 6261 #line 102 9"parser.yy"6230 #line 1023 "parser.yy" 6262 6231 { (yyval.decl) = 0; } 6263 6232 break; … … 6266 6235 6267 6236 /* Line 1806 of yacc.c */ 6268 #line 103 6"parser.yy"6237 #line 1030 "parser.yy" 6269 6238 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); } 6270 6239 break; … … 6273 6242 6274 6243 /* Line 1806 of yacc.c */ 6275 #line 10 41"parser.yy"6244 #line 1035 "parser.yy" 6276 6245 { (yyval.decl) = 0; } 6277 6246 break; … … 6280 6249 6281 6250 /* Line 1806 of yacc.c */ 6282 #line 104 8"parser.yy"6251 #line 1042 "parser.yy" 6283 6252 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); } 6284 6253 break; … … 6287 6256 6288 6257 /* Line 1806 of yacc.c */ 6289 #line 10 62"parser.yy"6258 #line 1056 "parser.yy" 6290 6259 {} 6291 6260 break; … … 6294 6263 6295 6264 /* Line 1806 of yacc.c */ 6296 #line 10 63"parser.yy"6265 #line 1057 "parser.yy" 6297 6266 {} 6298 6267 break; … … 6301 6270 6302 6271 /* Line 1806 of yacc.c */ 6303 #line 10 92"parser.yy"6272 #line 1086 "parser.yy" 6304 6273 { 6305 6274 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6311 6280 6312 6281 /* Line 1806 of yacc.c */ 6313 #line 109 9"parser.yy"6282 #line 1093 "parser.yy" 6314 6283 { 6315 6284 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6321 6290 6322 6291 /* Line 1806 of yacc.c */ 6323 #line 1 104"parser.yy"6292 #line 1098 "parser.yy" 6324 6293 { 6325 6294 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (6)].tok), TypedefTable::ID ); … … 6331 6300 6332 6301 /* Line 1806 of yacc.c */ 6333 #line 11 14"parser.yy"6302 #line 1108 "parser.yy" 6334 6303 { 6335 6304 typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) ); … … 6341 6310 6342 6311 /* Line 1806 of yacc.c */ 6343 #line 111 9"parser.yy"6312 #line 1113 "parser.yy" 6344 6313 { 6345 6314 typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) ); … … 6351 6320 6352 6321 /* Line 1806 of yacc.c */ 6353 #line 11 24"parser.yy"6322 #line 1118 "parser.yy" 6354 6323 { 6355 6324 typedefTable.setNextIdentifier( *(yyvsp[(3) - (4)].tok) ); … … 6361 6330 6362 6331 /* Line 1806 of yacc.c */ 6363 #line 11 32"parser.yy"6332 #line 1126 "parser.yy" 6364 6333 { 6365 6334 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6371 6340 6372 6341 /* Line 1806 of yacc.c */ 6373 #line 113 7"parser.yy"6342 #line 1131 "parser.yy" 6374 6343 { 6375 6344 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6381 6350 6382 6351 /* Line 1806 of yacc.c */ 6383 #line 11 42"parser.yy"6352 #line 1136 "parser.yy" 6384 6353 { 6385 6354 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6391 6360 6392 6361 /* Line 1806 of yacc.c */ 6393 #line 114 7"parser.yy"6362 #line 1141 "parser.yy" 6394 6363 { 6395 6364 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6401 6370 6402 6371 /* Line 1806 of yacc.c */ 6403 #line 11 52"parser.yy"6372 #line 1146 "parser.yy" 6404 6373 { 6405 6374 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::ID ); … … 6411 6380 6412 6381 /* Line 1806 of yacc.c */ 6413 #line 11 83"parser.yy"6382 #line 1177 "parser.yy" 6414 6383 { 6415 6384 (yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true ); … … 6420 6389 6421 6390 /* Line 1806 of yacc.c */ 6422 #line 118 7"parser.yy"6391 #line 1181 "parser.yy" 6423 6392 { 6424 6393 (yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true ); … … 6429 6398 6430 6399 /* Line 1806 of yacc.c */ 6431 #line 11 94"parser.yy"6400 #line 1188 "parser.yy" 6432 6401 { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); } 6433 6402 break; … … 6436 6405 6437 6406 /* Line 1806 of yacc.c */ 6438 #line 119 8"parser.yy"6407 #line 1192 "parser.yy" 6439 6408 { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (9)].decl)->appendList( (yyvsp[(7) - (9)].decl) ) ); } 6440 6409 break; … … 6443 6412 6444 6413 /* Line 1806 of yacc.c */ 6445 #line 1 203"parser.yy"6414 #line 1197 "parser.yy" 6446 6415 { 6447 6416 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6453 6422 6454 6423 /* Line 1806 of yacc.c */ 6455 #line 120 8"parser.yy"6424 #line 1202 "parser.yy" 6456 6425 { 6457 6426 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6463 6432 6464 6433 /* Line 1806 of yacc.c */ 6465 #line 12 13"parser.yy"6434 #line 1207 "parser.yy" 6466 6435 { 6467 6436 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::TD ); … … 6473 6442 6474 6443 /* Line 1806 of yacc.c */ 6475 #line 12 24"parser.yy"6444 #line 1218 "parser.yy" 6476 6445 { 6477 6446 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6483 6452 6484 6453 /* Line 1806 of yacc.c */ 6485 #line 122 9"parser.yy"6454 #line 1223 "parser.yy" 6486 6455 { 6487 6456 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6493 6462 6494 6463 /* Line 1806 of yacc.c */ 6495 #line 12 34"parser.yy"6464 #line 1228 "parser.yy" 6496 6465 { 6497 6466 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6503 6472 6504 6473 /* Line 1806 of yacc.c */ 6505 #line 123 9"parser.yy"6474 #line 1233 "parser.yy" 6506 6475 { 6507 6476 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6513 6482 6514 6483 /* Line 1806 of yacc.c */ 6515 #line 12 44"parser.yy"6484 #line 1238 "parser.yy" 6516 6485 { 6517 6486 typedefTable.addToEnclosingScope( TypedefTable::TD ); … … 6523 6492 6524 6493 /* Line 1806 of yacc.c */ 6525 #line 12 53"parser.yy"6494 #line 1247 "parser.yy" 6526 6495 { 6527 6496 typedefTable.addToEnclosingScope( *(yyvsp[(2) - (4)].tok), TypedefTable::TD ); … … 6533 6502 6534 6503 /* Line 1806 of yacc.c */ 6535 #line 125 8"parser.yy"6504 #line 1252 "parser.yy" 6536 6505 { 6537 6506 typedefTable.addToEnclosingScope( *(yyvsp[(5) - (7)].tok), TypedefTable::TD ); … … 6543 6512 6544 6513 /* Line 1806 of yacc.c */ 6545 #line 12 75"parser.yy"6514 #line 1269 "parser.yy" 6546 6515 { 6547 6516 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6553 6522 6554 6523 /* Line 1806 of yacc.c */ 6555 #line 12 80"parser.yy"6524 #line 1274 "parser.yy" 6556 6525 { 6557 6526 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 6563 6532 6564 6533 /* Line 1806 of yacc.c */ 6565 #line 1 302"parser.yy"6534 #line 1296 "parser.yy" 6566 6535 { (yyval.decl) = 0; } 6567 6536 break; … … 6570 6539 6571 6540 /* Line 1806 of yacc.c */ 6572 #line 13 14"parser.yy"6541 #line 1308 "parser.yy" 6573 6542 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6574 6543 break; … … 6577 6546 6578 6547 /* Line 1806 of yacc.c */ 6548 #line 1319 "parser.yy" 6549 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); } 6550 break; 6551 6552 case 305: 6553 6554 /* Line 1806 of yacc.c */ 6555 #line 1321 "parser.yy" 6556 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); } 6557 break; 6558 6559 case 306: 6560 6561 /* Line 1806 of yacc.c */ 6562 #line 1323 "parser.yy" 6563 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); } 6564 break; 6565 6566 case 307: 6567 6568 /* Line 1806 of yacc.c */ 6579 6569 #line 1325 "parser.yy" 6580 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode:: Const); }6581 break; 6582 6583 case 30 5:6570 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); } 6571 break; 6572 6573 case 308: 6584 6574 6585 6575 /* Line 1806 of yacc.c */ 6586 6576 #line 1327 "parser.yy" 6587 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode:: Restrict); }6588 break; 6589 6590 case 30 6:6577 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); } 6578 break; 6579 6580 case 309: 6591 6581 6592 6582 /* Line 1806 of yacc.c */ 6593 6583 #line 1329 "parser.yy" 6594 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }6595 break;6596 6597 case 307:6598 6599 /* Line 1806 of yacc.c */6600 #line 1331 "parser.yy"6601 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }6602 break;6603 6604 case 308:6605 6606 /* Line 1806 of yacc.c */6607 #line 1333 "parser.yy"6608 { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }6609 break;6610 6611 case 309:6612 6613 /* Line 1806 of yacc.c */6614 #line 1335 "parser.yy"6615 6584 { 6616 6585 typedefTable.enterScope(); … … 6621 6590 6622 6591 /* Line 1806 of yacc.c */ 6623 #line 133 9"parser.yy"6592 #line 1333 "parser.yy" 6624 6593 { 6625 6594 typedefTable.leaveScope(); … … 6631 6600 6632 6601 /* Line 1806 of yacc.c */ 6633 #line 134 8"parser.yy"6602 #line 1342 "parser.yy" 6634 6603 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6635 6604 break; … … 6638 6607 6639 6608 /* Line 1806 of yacc.c */ 6640 #line 13 50"parser.yy"6609 #line 1344 "parser.yy" 6641 6610 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6642 6611 break; … … 6645 6614 6646 6615 /* Line 1806 of yacc.c */ 6647 #line 13 61"parser.yy"6616 #line 1355 "parser.yy" 6648 6617 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6649 6618 break; … … 6652 6621 6653 6622 /* Line 1806 of yacc.c */ 6623 #line 1360 "parser.yy" 6624 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); } 6625 break; 6626 6627 case 317: 6628 6629 /* Line 1806 of yacc.c */ 6630 #line 1362 "parser.yy" 6631 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); } 6632 break; 6633 6634 case 318: 6635 6636 /* Line 1806 of yacc.c */ 6637 #line 1364 "parser.yy" 6638 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); } 6639 break; 6640 6641 case 319: 6642 6643 /* Line 1806 of yacc.c */ 6654 6644 #line 1366 "parser.yy" 6655 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }6656 break;6657 6658 case 317:6659 6660 /* Line 1806 of yacc.c */6661 #line 1368 "parser.yy"6662 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); }6663 break;6664 6665 case 318:6666 6667 /* Line 1806 of yacc.c */6668 #line 1370 "parser.yy"6669 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }6670 break;6671 6672 case 319:6673 6674 /* Line 1806 of yacc.c */6675 #line 1372 "parser.yy"6676 6645 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Register ); } 6677 6646 break; … … 6680 6649 6681 6650 /* Line 1806 of yacc.c */ 6682 #line 13 75"parser.yy"6651 #line 1369 "parser.yy" 6683 6652 { (yyval.decl) = new DeclarationNode; (yyval.decl)->isInline = true; } 6684 6653 break; … … 6687 6656 6688 6657 /* Line 1806 of yacc.c */ 6689 #line 137 7"parser.yy"6658 #line 1371 "parser.yy" 6690 6659 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); } 6691 6660 break; … … 6694 6663 6695 6664 /* Line 1806 of yacc.c */ 6696 #line 13 80"parser.yy"6665 #line 1374 "parser.yy" 6697 6666 { (yyval.decl) = new DeclarationNode; (yyval.decl)->isNoreturn = true; } 6698 6667 break; … … 6701 6670 6702 6671 /* Line 1806 of yacc.c */ 6703 #line 13 82"parser.yy"6672 #line 1376 "parser.yy" 6704 6673 { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Threadlocal ); } 6705 6674 break; … … 6708 6677 6709 6678 /* Line 1806 of yacc.c */ 6679 #line 1381 "parser.yy" 6680 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); } 6681 break; 6682 6683 case 325: 6684 6685 /* Line 1806 of yacc.c */ 6686 #line 1383 "parser.yy" 6687 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); } 6688 break; 6689 6690 case 326: 6691 6692 /* Line 1806 of yacc.c */ 6693 #line 1385 "parser.yy" 6694 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); } 6695 break; 6696 6697 case 327: 6698 6699 /* Line 1806 of yacc.c */ 6710 6700 #line 1387 "parser.yy" 6701 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); } 6702 break; 6703 6704 case 328: 6705 6706 /* Line 1806 of yacc.c */ 6707 #line 1389 "parser.yy" 6708 { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Long ); } 6709 break; 6710 6711 case 329: 6712 6713 /* Line 1806 of yacc.c */ 6714 #line 1391 "parser.yy" 6715 { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Short ); } 6716 break; 6717 6718 case 330: 6719 6720 /* Line 1806 of yacc.c */ 6721 #line 1393 "parser.yy" 6722 { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Signed ); } 6723 break; 6724 6725 case 331: 6726 6727 /* Line 1806 of yacc.c */ 6728 #line 1395 "parser.yy" 6729 { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); } 6730 break; 6731 6732 case 332: 6733 6734 /* Line 1806 of yacc.c */ 6735 #line 1397 "parser.yy" 6736 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); } 6737 break; 6738 6739 case 333: 6740 6741 /* Line 1806 of yacc.c */ 6742 #line 1399 "parser.yy" 6743 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 6744 break; 6745 6746 case 334: 6747 6748 /* Line 1806 of yacc.c */ 6749 #line 1401 "parser.yy" 6750 { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Complex ); } 6751 break; 6752 6753 case 335: 6754 6755 /* Line 1806 of yacc.c */ 6756 #line 1403 "parser.yy" 6757 { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); } 6758 break; 6759 6760 case 336: 6761 6762 /* Line 1806 of yacc.c */ 6763 #line 1405 "parser.yy" 6764 { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); } 6765 break; 6766 6767 case 337: 6768 6769 /* Line 1806 of yacc.c */ 6770 #line 1407 "parser.yy" 6711 6771 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); } 6712 6772 break; 6713 6773 6714 case 325: 6715 6716 /* Line 1806 of yacc.c */ 6717 #line 1389 "parser.yy" 6718 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); } 6719 break; 6720 6721 case 326: 6722 6723 /* Line 1806 of yacc.c */ 6724 #line 1391 "parser.yy" 6725 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); } 6726 break; 6727 6728 case 327: 6729 6730 /* Line 1806 of yacc.c */ 6731 #line 1393 "parser.yy" 6732 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); } 6733 break; 6734 6735 case 328: 6736 6737 /* Line 1806 of yacc.c */ 6738 #line 1395 "parser.yy" 6739 { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Long ); } 6740 break; 6741 6742 case 329: 6743 6744 /* Line 1806 of yacc.c */ 6745 #line 1397 "parser.yy" 6746 { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Short ); } 6747 break; 6748 6749 case 330: 6750 6751 /* Line 1806 of yacc.c */ 6752 #line 1399 "parser.yy" 6753 { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Signed ); } 6754 break; 6755 6756 case 331: 6757 6758 /* Line 1806 of yacc.c */ 6759 #line 1401 "parser.yy" 6760 { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); } 6761 break; 6762 6763 case 332: 6764 6765 /* Line 1806 of yacc.c */ 6766 #line 1403 "parser.yy" 6767 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); } 6768 break; 6769 6770 case 333: 6771 6772 /* Line 1806 of yacc.c */ 6773 #line 1405 "parser.yy" 6774 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 6775 break; 6776 6777 case 334: 6778 6779 /* Line 1806 of yacc.c */ 6780 #line 1407 "parser.yy" 6781 { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Complex ); } 6782 break; 6783 6784 case 335: 6774 case 338: 6785 6775 6786 6776 /* Line 1806 of yacc.c */ 6787 6777 #line 1409 "parser.yy" 6788 { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); }6789 break;6790 6791 case 336:6792 6793 /* Line 1806 of yacc.c */6794 #line 1411 "parser.yy"6795 { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }6796 break;6797 6798 case 337:6799 6800 /* Line 1806 of yacc.c */6801 #line 1413 "parser.yy"6802 6778 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); } 6803 6779 break; 6804 6780 6805 case 338:6806 6807 /* Line 1806 of yacc.c */6808 #line 1415 "parser.yy"6809 { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }6810 break;6811 6812 6781 case 340: 6813 6782 6814 6783 /* Line 1806 of yacc.c */ 6784 #line 1416 "parser.yy" 6785 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6786 break; 6787 6788 case 341: 6789 6790 /* Line 1806 of yacc.c */ 6791 #line 1418 "parser.yy" 6792 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6793 break; 6794 6795 case 342: 6796 6797 /* Line 1806 of yacc.c */ 6798 #line 1420 "parser.yy" 6799 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6800 break; 6801 6802 case 343: 6803 6804 /* Line 1806 of yacc.c */ 6815 6805 #line 1422 "parser.yy" 6806 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); } 6807 break; 6808 6809 case 345: 6810 6811 /* Line 1806 of yacc.c */ 6812 #line 1428 "parser.yy" 6813 { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6814 break; 6815 6816 case 347: 6817 6818 /* Line 1806 of yacc.c */ 6819 #line 1435 "parser.yy" 6816 6820 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6817 6821 break; 6818 6822 6819 case 34 1:6820 6821 /* Line 1806 of yacc.c */ 6822 #line 14 24"parser.yy"6823 case 348: 6824 6825 /* Line 1806 of yacc.c */ 6826 #line 1437 "parser.yy" 6823 6827 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6824 6828 break; 6825 6829 6826 case 342: 6827 6828 /* Line 1806 of yacc.c */ 6829 #line 1426 "parser.yy" 6830 case 349: 6831 6832 /* Line 1806 of yacc.c */ 6833 #line 1439 "parser.yy" 6834 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); } 6835 break; 6836 6837 case 350: 6838 6839 /* Line 1806 of yacc.c */ 6840 #line 1444 "parser.yy" 6841 { (yyval.decl) = (yyvsp[(3) - (4)].decl); } 6842 break; 6843 6844 case 351: 6845 6846 /* Line 1806 of yacc.c */ 6847 #line 1446 "parser.yy" 6848 { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); } 6849 break; 6850 6851 case 352: 6852 6853 /* Line 1806 of yacc.c */ 6854 #line 1448 "parser.yy" 6855 { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); } 6856 break; 6857 6858 case 353: 6859 6860 /* Line 1806 of yacc.c */ 6861 #line 1450 "parser.yy" 6862 { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); } 6863 break; 6864 6865 case 355: 6866 6867 /* Line 1806 of yacc.c */ 6868 #line 1456 "parser.yy" 6869 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6870 break; 6871 6872 case 356: 6873 6874 /* Line 1806 of yacc.c */ 6875 #line 1458 "parser.yy" 6876 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6877 break; 6878 6879 case 357: 6880 6881 /* Line 1806 of yacc.c */ 6882 #line 1460 "parser.yy" 6830 6883 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6831 6884 break; 6832 6885 6833 case 343: 6834 6835 /* Line 1806 of yacc.c */ 6836 #line 1428 "parser.yy" 6837 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); } 6838 break; 6839 6840 case 345: 6841 6842 /* Line 1806 of yacc.c */ 6843 #line 1434 "parser.yy" 6844 { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6845 break; 6846 6847 case 347: 6848 6849 /* Line 1806 of yacc.c */ 6850 #line 1441 "parser.yy" 6886 case 359: 6887 6888 /* Line 1806 of yacc.c */ 6889 #line 1466 "parser.yy" 6851 6890 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6852 6891 break; 6853 6892 6854 case 3 48:6855 6856 /* Line 1806 of yacc.c */ 6857 #line 14 43"parser.yy"6893 case 360: 6894 6895 /* Line 1806 of yacc.c */ 6896 #line 1468 "parser.yy" 6858 6897 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6859 6898 break; 6860 6899 6861 case 349: 6862 6863 /* Line 1806 of yacc.c */ 6864 #line 1445 "parser.yy" 6865 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); } 6866 break; 6867 6868 case 350: 6869 6870 /* Line 1806 of yacc.c */ 6871 #line 1450 "parser.yy" 6872 { (yyval.decl) = (yyvsp[(3) - (4)].decl); } 6873 break; 6874 6875 case 351: 6876 6877 /* Line 1806 of yacc.c */ 6878 #line 1452 "parser.yy" 6879 { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); } 6880 break; 6881 6882 case 352: 6883 6884 /* Line 1806 of yacc.c */ 6885 #line 1454 "parser.yy" 6886 { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); } 6887 break; 6888 6889 case 353: 6890 6891 /* Line 1806 of yacc.c */ 6892 #line 1456 "parser.yy" 6893 { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); } 6894 break; 6895 6896 case 355: 6897 6898 /* Line 1806 of yacc.c */ 6899 #line 1462 "parser.yy" 6900 case 362: 6901 6902 /* Line 1806 of yacc.c */ 6903 #line 1474 "parser.yy" 6900 6904 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6901 6905 break; 6902 6906 6903 case 3 56:6904 6905 /* Line 1806 of yacc.c */ 6906 #line 14 64"parser.yy"6907 case 363: 6908 6909 /* Line 1806 of yacc.c */ 6910 #line 1476 "parser.yy" 6907 6911 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6908 6912 break; 6909 6913 6910 case 3 57:6911 6912 /* Line 1806 of yacc.c */ 6913 #line 14 66"parser.yy"6914 case 364: 6915 6916 /* Line 1806 of yacc.c */ 6917 #line 1478 "parser.yy" 6914 6918 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 6915 6919 break; 6916 6920 6917 case 359: 6918 6919 /* Line 1806 of yacc.c */ 6920 #line 1472 "parser.yy" 6921 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6922 break; 6923 6924 case 360: 6925 6926 /* Line 1806 of yacc.c */ 6927 #line 1474 "parser.yy" 6921 case 365: 6922 6923 /* Line 1806 of yacc.c */ 6924 #line 1483 "parser.yy" 6925 { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); } 6926 break; 6927 6928 case 366: 6929 6930 /* Line 1806 of yacc.c */ 6931 #line 1485 "parser.yy" 6932 { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 6933 break; 6934 6935 case 367: 6936 6937 /* Line 1806 of yacc.c */ 6938 #line 1487 "parser.yy" 6928 6939 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 6929 6940 break; 6930 6941 6931 case 362:6932 6933 /* Line 1806 of yacc.c */6934 #line 1480 "parser.yy"6935 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }6936 break;6937 6938 case 363:6939 6940 /* Line 1806 of yacc.c */6941 #line 1482 "parser.yy"6942 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }6943 break;6944 6945 case 364:6946 6947 /* Line 1806 of yacc.c */6948 #line 1484 "parser.yy"6949 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }6950 break;6951 6952 case 365:6953 6954 /* Line 1806 of yacc.c */6955 #line 1489 "parser.yy"6956 { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); }6957 break;6958 6959 case 366:6960 6961 /* Line 1806 of yacc.c */6962 #line 1491 "parser.yy"6963 { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); }6964 break;6965 6966 case 367:6967 6968 /* Line 1806 of yacc.c */6969 #line 1493 "parser.yy"6970 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }6971 break;6972 6973 6942 case 370: 6974 6943 6975 6944 /* Line 1806 of yacc.c */ 6976 #line 1 503"parser.yy"6945 #line 1497 "parser.yy" 6977 6946 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (4)].aggKey), nullptr, nullptr, (yyvsp[(3) - (4)].decl), true ); } 6978 6947 break; … … 6981 6950 6982 6951 /* Line 1806 of yacc.c */ 6983 #line 1 505"parser.yy"6952 #line 1499 "parser.yy" 6984 6953 { 6985 6954 typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); … … 6991 6960 6992 6961 /* Line 1806 of yacc.c */ 6962 #line 1504 "parser.yy" 6963 { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); } 6964 break; 6965 6966 case 373: 6967 6968 /* Line 1806 of yacc.c */ 6969 #line 1506 "parser.yy" 6970 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), nullptr, (yyvsp[(5) - (6)].decl), true ); } 6971 break; 6972 6973 case 374: 6974 6975 /* Line 1806 of yacc.c */ 6976 #line 1508 "parser.yy" 6977 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), nullptr, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); } 6978 break; 6979 6980 case 375: 6981 6982 /* Line 1806 of yacc.c */ 6993 6983 #line 1510 "parser.yy" 6994 { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }6995 break;6996 6997 case 373:6998 6999 /* Line 1806 of yacc.c */7000 #line 1512 "parser.yy"7001 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), nullptr, (yyvsp[(5) - (6)].decl), true ); }7002 break;7003 7004 case 374:7005 7006 /* Line 1806 of yacc.c */7007 #line 1514 "parser.yy"7008 { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), nullptr, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); }7009 break;7010 7011 case 375:7012 7013 /* Line 1806 of yacc.c */7014 #line 1516 "parser.yy"7015 6984 { (yyval.decl) = (yyvsp[(2) - (2)].decl); } 7016 6985 break; … … 7019 6988 7020 6989 /* Line 1806 of yacc.c */ 7021 #line 15 21"parser.yy"6990 #line 1515 "parser.yy" 7022 6991 { (yyval.aggKey) = DeclarationNode::Struct; } 7023 6992 break; … … 7026 6995 7027 6996 /* Line 1806 of yacc.c */ 7028 #line 15 23"parser.yy"6997 #line 1517 "parser.yy" 7029 6998 { (yyval.aggKey) = DeclarationNode::Union; } 7030 6999 break; … … 7033 7002 7034 7003 /* Line 1806 of yacc.c */ 7035 #line 152 8"parser.yy"7004 #line 1522 "parser.yy" 7036 7005 { (yyval.decl) = 0; } 7037 7006 break; … … 7040 7009 7041 7010 /* Line 1806 of yacc.c */ 7011 #line 1524 "parser.yy" 7012 { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); } 7013 break; 7014 7015 case 381: 7016 7017 /* Line 1806 of yacc.c */ 7042 7018 #line 1530 "parser.yy" 7043 { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }7044 break;7045 7046 case 381:7047 7048 /* Line 1806 of yacc.c */7049 #line 1536 "parser.yy"7050 7019 { (yyval.decl) = (yyvsp[(2) - (3)].decl)->set_extension( true ); } 7051 7020 break; … … 7054 7023 7055 7024 /* Line 1806 of yacc.c */ 7056 #line 153 9"parser.yy"7025 #line 1533 "parser.yy" 7057 7026 { // mark all fields in list 7058 7027 for ( DeclarationNode *iter = (yyvsp[(2) - (3)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) … … 7065 7034 7066 7035 /* Line 1806 of yacc.c */ 7067 #line 154 9"parser.yy"7036 #line 1543 "parser.yy" 7068 7037 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addName( (yyvsp[(2) - (2)].tok) ); } 7069 7038 break; … … 7072 7041 7073 7042 /* Line 1806 of yacc.c */ 7074 #line 15 51"parser.yy"7043 #line 1545 "parser.yy" 7075 7044 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(1) - (3)].decl)->cloneType( (yyvsp[(3) - (3)].tok) ) ); } 7076 7045 break; … … 7079 7048 7080 7049 /* Line 1806 of yacc.c */ 7081 #line 15 53"parser.yy"7050 #line 1547 "parser.yy" 7082 7051 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(1) - (2)].decl)->cloneType( 0 ) ); } 7083 7052 break; … … 7086 7055 7087 7056 /* Line 1806 of yacc.c */ 7088 #line 155 8"parser.yy"7057 #line 1552 "parser.yy" 7089 7058 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7090 7059 break; … … 7093 7062 7094 7063 /* Line 1806 of yacc.c */ 7095 #line 15 60"parser.yy"7064 #line 1554 "parser.yy" 7096 7065 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(1) - (4)].decl)->cloneBaseType( (yyvsp[(4) - (4)].decl) ) ); } 7097 7066 break; … … 7100 7069 7101 7070 /* Line 1806 of yacc.c */ 7102 #line 15 65"parser.yy"7071 #line 1559 "parser.yy" 7103 7072 { (yyval.decl) = DeclarationNode::newName( 0 ); /* XXX */ } 7104 7073 break; … … 7107 7076 7108 7077 /* Line 1806 of yacc.c */ 7078 #line 1561 "parser.yy" 7079 { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); } 7080 break; 7081 7082 case 392: 7083 7084 /* Line 1806 of yacc.c */ 7085 #line 1564 "parser.yy" 7086 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); } 7087 break; 7088 7089 case 393: 7090 7091 /* Line 1806 of yacc.c */ 7109 7092 #line 1567 "parser.yy" 7110 { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); }7111 break;7112 7113 case 392:7114 7115 /* Line 1806 of yacc.c */7116 #line 1570 "parser.yy"7117 7093 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); } 7118 7094 break; 7119 7095 7120 case 39 3:7096 case 395: 7121 7097 7122 7098 /* Line 1806 of yacc.c */ 7123 7099 #line 1573 "parser.yy" 7124 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }7125 break;7126 7127 case 395:7128 7129 /* Line 1806 of yacc.c */7130 #line 1579 "parser.yy"7131 7100 { (yyval.en) = 0; } 7132 7101 break; … … 7135 7104 7136 7105 /* Line 1806 of yacc.c */ 7137 #line 15 81"parser.yy"7106 #line 1575 "parser.yy" 7138 7107 { (yyval.en) = (yyvsp[(1) - (1)].en); } 7139 7108 break; … … 7142 7111 7143 7112 /* Line 1806 of yacc.c */ 7144 #line 158 6"parser.yy"7113 #line 1580 "parser.yy" 7145 7114 { (yyval.en) = (yyvsp[(2) - (2)].en); } 7146 7115 break; … … 7149 7118 7150 7119 /* Line 1806 of yacc.c */ 7151 #line 15 95"parser.yy"7120 #line 1589 "parser.yy" 7152 7121 { (yyval.decl) = DeclarationNode::newEnum( nullptr, (yyvsp[(3) - (5)].decl) ); } 7153 7122 break; … … 7156 7125 7157 7126 /* Line 1806 of yacc.c */ 7158 #line 159 7"parser.yy"7127 #line 1591 "parser.yy" 7159 7128 { 7160 7129 typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); … … 7166 7135 7167 7136 /* Line 1806 of yacc.c */ 7168 #line 1 602"parser.yy"7137 #line 1596 "parser.yy" 7169 7138 { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); } 7170 7139 break; … … 7173 7142 7174 7143 /* Line 1806 of yacc.c */ 7175 #line 1 604"parser.yy"7144 #line 1598 "parser.yy" 7176 7145 { (yyval.decl) = DeclarationNode::newEnum( (yyvsp[(2) - (7)].tok), (yyvsp[(5) - (7)].decl) ); } 7177 7146 break; … … 7180 7149 7181 7150 /* Line 1806 of yacc.c */ 7182 #line 160 9"parser.yy"7151 #line 1603 "parser.yy" 7183 7152 { (yyval.decl) = DeclarationNode::newEnumConstant( (yyvsp[(1) - (2)].tok), (yyvsp[(2) - (2)].en) ); } 7184 7153 break; … … 7187 7156 7188 7157 /* Line 1806 of yacc.c */ 7189 #line 16 11"parser.yy"7158 #line 1605 "parser.yy" 7190 7159 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( DeclarationNode::newEnumConstant( (yyvsp[(3) - (4)].tok), (yyvsp[(4) - (4)].en) ) ); } 7191 7160 break; … … 7194 7163 7195 7164 /* Line 1806 of yacc.c */ 7196 #line 161 6"parser.yy"7165 #line 1610 "parser.yy" 7197 7166 { (yyval.en) = 0; } 7198 7167 break; … … 7201 7170 7202 7171 /* Line 1806 of yacc.c */ 7203 #line 161 8"parser.yy"7172 #line 1612 "parser.yy" 7204 7173 { (yyval.en) = (yyvsp[(2) - (2)].en); } 7205 7174 break; … … 7208 7177 7209 7178 /* Line 1806 of yacc.c */ 7210 #line 16 25"parser.yy"7179 #line 1619 "parser.yy" 7211 7180 { (yyval.decl) = 0; } 7212 7181 break; … … 7215 7184 7216 7185 /* Line 1806 of yacc.c */ 7217 #line 16 33"parser.yy"7186 #line 1627 "parser.yy" 7218 7187 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7219 7188 break; … … 7222 7191 7223 7192 /* Line 1806 of yacc.c */ 7224 #line 16 35"parser.yy"7193 #line 1629 "parser.yy" 7225 7194 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); } 7226 7195 break; … … 7229 7198 7230 7199 /* Line 1806 of yacc.c */ 7231 #line 163 7"parser.yy"7200 #line 1631 "parser.yy" 7232 7201 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); } 7233 7202 break; … … 7236 7205 7237 7206 /* Line 1806 of yacc.c */ 7238 #line 16 45"parser.yy"7207 #line 1639 "parser.yy" 7239 7208 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7240 7209 break; … … 7243 7212 7244 7213 /* Line 1806 of yacc.c */ 7245 #line 164 7"parser.yy"7214 #line 1641 "parser.yy" 7246 7215 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7247 7216 break; … … 7250 7219 7251 7220 /* Line 1806 of yacc.c */ 7221 #line 1643 "parser.yy" 7222 { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); } 7223 break; 7224 7225 case 419: 7226 7227 /* Line 1806 of yacc.c */ 7252 7228 #line 1649 "parser.yy" 7253 { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); }7254 break;7255 7256 case 419:7257 7258 /* Line 1806 of yacc.c */7259 #line 1655 "parser.yy"7260 7229 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7261 7230 break; … … 7264 7233 7265 7234 /* Line 1806 of yacc.c */ 7266 #line 16 60"parser.yy"7235 #line 1654 "parser.yy" 7267 7236 { (yyval.decl) = 0; } 7268 7237 break; … … 7271 7240 7272 7241 /* Line 1806 of yacc.c */ 7273 #line 166 7"parser.yy"7242 #line 1661 "parser.yy" 7274 7243 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); } 7275 7244 break; … … 7278 7247 7279 7248 /* Line 1806 of yacc.c */ 7280 #line 16 74"parser.yy"7249 #line 1668 "parser.yy" 7281 7250 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7282 7251 break; … … 7285 7254 7286 7255 /* Line 1806 of yacc.c */ 7287 #line 167 6"parser.yy"7256 #line 1670 "parser.yy" 7288 7257 { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); } 7289 7258 break; … … 7292 7261 7293 7262 /* Line 1806 of yacc.c */ 7294 #line 16 85"parser.yy"7263 #line 1679 "parser.yy" 7295 7264 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); } 7296 7265 break; … … 7299 7268 7300 7269 /* Line 1806 of yacc.c */ 7301 #line 168 8"parser.yy"7270 #line 1682 "parser.yy" 7302 7271 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); } 7303 7272 break; … … 7306 7275 7307 7276 /* Line 1806 of yacc.c */ 7308 #line 16 90"parser.yy"7277 #line 1684 "parser.yy" 7309 7278 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addName( (yyvsp[(3) - (4)].tok) )->addQualifiers( (yyvsp[(1) - (4)].decl) ); } 7310 7279 break; … … 7313 7282 7314 7283 /* Line 1806 of yacc.c */ 7284 #line 1694 "parser.yy" 7285 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7286 break; 7287 7288 case 438: 7289 7290 /* Line 1806 of yacc.c */ 7315 7291 #line 1700 "parser.yy" 7316 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }7317 break;7318 7319 case 438:7320 7321 /* Line 1806 of yacc.c */7322 #line 1706 "parser.yy"7323 7292 { 7324 7293 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7330 7299 7331 7300 /* Line 1806 of yacc.c */ 7332 #line 17 11"parser.yy"7301 #line 1705 "parser.yy" 7333 7302 { 7334 7303 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7340 7309 7341 7310 /* Line 1806 of yacc.c */ 7342 #line 17 20"parser.yy"7311 #line 1714 "parser.yy" 7343 7312 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7344 7313 break; … … 7347 7316 7348 7317 /* Line 1806 of yacc.c */ 7349 #line 172 9"parser.yy"7318 #line 1723 "parser.yy" 7350 7319 { (yyval.decl) = DeclarationNode::newName( (yyvsp[(1) - (1)].tok) ); } 7351 7320 break; … … 7354 7323 7355 7324 /* Line 1806 of yacc.c */ 7356 #line 17 31"parser.yy"7325 #line 1725 "parser.yy" 7357 7326 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( DeclarationNode::newName( (yyvsp[(3) - (3)].tok) ) ); } 7358 7327 break; … … 7361 7330 7362 7331 /* Line 1806 of yacc.c */ 7363 #line 175 6"parser.yy"7332 #line 1750 "parser.yy" 7364 7333 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7365 7334 break; … … 7368 7337 7369 7338 /* Line 1806 of yacc.c */ 7370 #line 17 64"parser.yy"7339 #line 1758 "parser.yy" 7371 7340 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); } 7372 7341 break; … … 7375 7344 7376 7345 /* Line 1806 of yacc.c */ 7377 #line 176 9"parser.yy"7346 #line 1763 "parser.yy" 7378 7347 { (yyval.in) = 0; } 7379 7348 break; … … 7382 7351 7383 7352 /* Line 1806 of yacc.c */ 7353 #line 1765 "parser.yy" 7354 { (yyval.in) = (yyvsp[(2) - (2)].in); } 7355 break; 7356 7357 case 462: 7358 7359 /* Line 1806 of yacc.c */ 7360 #line 1767 "parser.yy" 7361 { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); } 7362 break; 7363 7364 case 463: 7365 7366 /* Line 1806 of yacc.c */ 7384 7367 #line 1771 "parser.yy" 7385 { (yyval.in) = (yyvsp[(2) - (2)].in); }7386 break; 7387 7388 case 46 2:7389 7390 /* Line 1806 of yacc.c */ 7391 #line 177 3"parser.yy"7392 { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }7393 break; 7394 7395 case 46 3:7368 { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); } 7369 break; 7370 7371 case 464: 7372 7373 /* Line 1806 of yacc.c */ 7374 #line 1772 "parser.yy" 7375 { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); } 7376 break; 7377 7378 case 465: 7396 7379 7397 7380 /* Line 1806 of yacc.c */ 7398 7381 #line 1777 "parser.yy" 7399 { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); }7400 break;7401 7402 case 464:7403 7404 /* Line 1806 of yacc.c */7405 #line 1778 "parser.yy"7406 { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); }7407 break;7408 7409 case 465:7410 7411 /* Line 1806 of yacc.c */7412 #line 1783 "parser.yy"7413 7382 { (yyval.in) = 0; } 7414 7383 break; … … 7417 7386 7418 7387 /* Line 1806 of yacc.c */ 7419 #line 17 85"parser.yy"7388 #line 1779 "parser.yy" 7420 7389 { (yyval.in) = (yyvsp[(2) - (2)].in)->set_designators( (yyvsp[(1) - (2)].en) ); } 7421 7390 break; … … 7424 7393 7425 7394 /* Line 1806 of yacc.c */ 7426 #line 178 6"parser.yy"7395 #line 1780 "parser.yy" 7427 7396 { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (3)].in)->set_last( (yyvsp[(3) - (3)].in) ) ); } 7428 7397 break; … … 7431 7400 7432 7401 /* Line 1806 of yacc.c */ 7433 #line 178 8"parser.yy"7402 #line 1782 "parser.yy" 7434 7403 { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (4)].in)->set_last( (yyvsp[(4) - (4)].in)->set_designators( (yyvsp[(3) - (4)].en) ) ) ); } 7435 7404 break; … … 7438 7407 7439 7408 /* Line 1806 of yacc.c */ 7409 #line 1798 "parser.yy" 7410 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); } 7411 break; 7412 7413 case 473: 7414 7415 /* Line 1806 of yacc.c */ 7440 7416 #line 1804 "parser.yy" 7441 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); }7442 break; 7443 7444 case 47 3:7417 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); } 7418 break; 7419 7420 case 474: 7445 7421 7446 7422 /* Line 1806 of yacc.c */ 7447 7423 #line 1810 "parser.yy" 7448 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); }7449 break;7450 7451 case 474:7452 7453 /* Line 1806 of yacc.c */7454 #line 1816 "parser.yy"7455 7424 { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(2) - (2)].tok) ) ); } 7456 7425 break; … … 7459 7428 7460 7429 /* Line 1806 of yacc.c */ 7430 #line 1813 "parser.yy" 7431 { (yyval.en) = (yyvsp[(3) - (5)].en); } 7432 break; 7433 7434 case 476: 7435 7436 /* Line 1806 of yacc.c */ 7437 #line 1815 "parser.yy" 7438 { (yyval.en) = (yyvsp[(3) - (5)].en); } 7439 break; 7440 7441 case 477: 7442 7443 /* Line 1806 of yacc.c */ 7444 #line 1817 "parser.yy" 7445 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); } 7446 break; 7447 7448 case 478: 7449 7450 /* Line 1806 of yacc.c */ 7461 7451 #line 1819 "parser.yy" 7462 { (yyval.en) = (yyvsp[(3) - (5)].en); }7463 break;7464 7465 case 476:7466 7467 /* Line 1806 of yacc.c */7468 #line 1821 "parser.yy"7469 { (yyval.en) = (yyvsp[(3) - (5)].en); }7470 break;7471 7472 case 477:7473 7474 /* Line 1806 of yacc.c */7475 #line 1823 "parser.yy"7476 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); }7477 break;7478 7479 case 478:7480 7481 /* Line 1806 of yacc.c */7482 #line 1825 "parser.yy"7483 7452 { (yyval.en) = (yyvsp[(4) - (6)].en); } 7484 7453 break; … … 7487 7456 7488 7457 /* Line 1806 of yacc.c */ 7489 #line 184 9"parser.yy"7458 #line 1843 "parser.yy" 7490 7459 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7491 7460 break; … … 7494 7463 7495 7464 /* Line 1806 of yacc.c */ 7496 #line 18 51"parser.yy"7465 #line 1845 "parser.yy" 7497 7466 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 7498 7467 break; … … 7501 7470 7502 7471 /* Line 1806 of yacc.c */ 7472 #line 1847 "parser.yy" 7473 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); } 7474 break; 7475 7476 case 484: 7477 7478 /* Line 1806 of yacc.c */ 7503 7479 #line 1853 "parser.yy" 7504 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }7505 break;7506 7507 case 484:7508 7509 /* Line 1806 of yacc.c */7510 #line 1859 "parser.yy"7511 7480 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7512 7481 break; … … 7515 7484 7516 7485 /* Line 1806 of yacc.c */ 7517 #line 18 61"parser.yy"7486 #line 1855 "parser.yy" 7518 7487 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 7519 7488 break; … … 7522 7491 7523 7492 /* Line 1806 of yacc.c */ 7493 #line 1860 "parser.yy" 7494 { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); } 7495 break; 7496 7497 case 488: 7498 7499 /* Line 1806 of yacc.c */ 7524 7500 #line 1866 "parser.yy" 7525 { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }7526 break;7527 7528 case 488:7529 7530 /* Line 1806 of yacc.c */7531 #line 1872 "parser.yy"7532 7501 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(3) - (4)].decl) ); } 7533 7502 break; … … 7536 7505 7537 7506 /* Line 1806 of yacc.c */ 7538 #line 187 7"parser.yy"7507 #line 1871 "parser.yy" 7539 7508 { typedefTable.addToEnclosingScope( *(yyvsp[(2) - (2)].tok), TypedefTable::TD ); } 7540 7509 break; … … 7543 7512 7544 7513 /* Line 1806 of yacc.c */ 7514 #line 1873 "parser.yy" 7515 { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); } 7516 break; 7517 7518 case 492: 7519 7520 /* Line 1806 of yacc.c */ 7545 7521 #line 1879 "parser.yy" 7546 { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); }7547 break;7548 7549 case 492:7550 7551 /* Line 1806 of yacc.c */7552 #line 1885 "parser.yy"7553 7522 { (yyval.tclass) = DeclarationNode::Otype; } 7554 7523 break; … … 7557 7526 7558 7527 /* Line 1806 of yacc.c */ 7559 #line 188 7"parser.yy"7528 #line 1881 "parser.yy" 7560 7529 { (yyval.tclass) = DeclarationNode::Ftype; } 7561 7530 break; … … 7564 7533 7565 7534 /* Line 1806 of yacc.c */ 7566 #line 188 9"parser.yy"7535 #line 1883 "parser.yy" 7567 7536 { (yyval.tclass) = DeclarationNode::Dtype; } 7568 7537 break; … … 7571 7540 7572 7541 /* Line 1806 of yacc.c */ 7573 #line 18 94"parser.yy"7542 #line 1888 "parser.yy" 7574 7543 { (yyval.decl) = 0; } 7575 7544 break; … … 7578 7547 7579 7548 /* Line 1806 of yacc.c */ 7580 #line 189 6"parser.yy"7549 #line 1890 "parser.yy" 7581 7550 { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); } 7582 7551 break; … … 7585 7554 7586 7555 /* Line 1806 of yacc.c */ 7587 #line 1 901"parser.yy"7556 #line 1895 "parser.yy" 7588 7557 { 7589 7558 typedefTable.openTrait( *(yyvsp[(2) - (5)].tok) ); … … 7595 7564 7596 7565 /* Line 1806 of yacc.c */ 7597 #line 190 6"parser.yy"7566 #line 1900 "parser.yy" 7598 7567 { (yyval.decl) = (yyvsp[(4) - (5)].decl); } 7599 7568 break; … … 7602 7571 7603 7572 /* Line 1806 of yacc.c */ 7604 #line 190 8"parser.yy"7573 #line 1902 "parser.yy" 7605 7574 { (yyval.decl) = 0; } 7606 7575 break; … … 7609 7578 7610 7579 /* Line 1806 of yacc.c */ 7611 #line 19 13"parser.yy"7580 #line 1907 "parser.yy" 7612 7581 { (yyval.en) = new ExpressionNode( build_typevalue( (yyvsp[(1) - (1)].decl) ) ); } 7613 7582 break; … … 7616 7585 7617 7586 /* Line 1806 of yacc.c */ 7618 #line 191 6"parser.yy"7587 #line 1910 "parser.yy" 7619 7588 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( build_typevalue( (yyvsp[(3) - (3)].decl) ) ) ) ); } 7620 7589 break; … … 7623 7592 7624 7593 /* Line 1806 of yacc.c */ 7625 #line 191 8"parser.yy"7594 #line 1912 "parser.yy" 7626 7595 { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); } 7627 7596 break; … … 7630 7599 7631 7600 /* Line 1806 of yacc.c */ 7632 #line 19 23"parser.yy"7601 #line 1917 "parser.yy" 7633 7602 { (yyval.decl) = (yyvsp[(2) - (2)].decl); } 7634 7603 break; … … 7637 7606 7638 7607 /* Line 1806 of yacc.c */ 7639 #line 19 25"parser.yy"7608 #line 1919 "parser.yy" 7640 7609 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) ); } 7641 7610 break; … … 7644 7613 7645 7614 /* Line 1806 of yacc.c */ 7646 #line 192 7"parser.yy"7615 #line 1921 "parser.yy" 7647 7616 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl)->copyStorageClasses( (yyvsp[(1) - (3)].decl) ) ); } 7648 7617 break; … … 7651 7620 7652 7621 /* Line 1806 of yacc.c */ 7653 #line 19 32"parser.yy"7622 #line 1926 "parser.yy" 7654 7623 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addAssertions( (yyvsp[(2) - (2)].decl) ); } 7655 7624 break; … … 7658 7627 7659 7628 /* Line 1806 of yacc.c */ 7660 #line 19 34"parser.yy"7629 #line 1928 "parser.yy" 7661 7630 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addAssertions( (yyvsp[(2) - (4)].decl) )->addType( (yyvsp[(4) - (4)].decl) ); } 7662 7631 break; … … 7665 7634 7666 7635 /* Line 1806 of yacc.c */ 7667 #line 193 9"parser.yy"7636 #line 1933 "parser.yy" 7668 7637 { 7669 7638 typedefTable.addToEnclosingScope( *(yyvsp[(1) - (1)].tok), TypedefTable::TD ); … … 7675 7644 7676 7645 /* Line 1806 of yacc.c */ 7677 #line 19 44"parser.yy"7646 #line 1938 "parser.yy" 7678 7647 { 7679 7648 typedefTable.addToEnclosingScope( *(yyvsp[(1) - (6)].tok), TypedefTable::TG ); … … 7685 7654 7686 7655 /* Line 1806 of yacc.c */ 7687 #line 19 52"parser.yy"7656 #line 1946 "parser.yy" 7688 7657 { 7689 7658 typedefTable.addToEnclosingScope( *(yyvsp[(2) - (9)].tok), TypedefTable::ID ); … … 7695 7664 7696 7665 /* Line 1806 of yacc.c */ 7697 #line 195 7"parser.yy"7666 #line 1951 "parser.yy" 7698 7667 { 7699 7668 typedefTable.enterTrait( *(yyvsp[(2) - (8)].tok) ); … … 7705 7674 7706 7675 /* Line 1806 of yacc.c */ 7707 #line 19 62"parser.yy"7676 #line 1956 "parser.yy" 7708 7677 { 7709 7678 typedefTable.leaveTrait(); … … 7716 7685 7717 7686 /* Line 1806 of yacc.c */ 7718 #line 19 72"parser.yy"7687 #line 1966 "parser.yy" 7719 7688 { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); } 7720 7689 break; … … 7723 7692 7724 7693 /* Line 1806 of yacc.c */ 7725 #line 19 82"parser.yy"7694 #line 1976 "parser.yy" 7726 7695 { 7727 7696 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7733 7702 7734 7703 /* Line 1806 of yacc.c */ 7735 #line 198 7"parser.yy"7704 #line 1981 "parser.yy" 7736 7705 { 7737 7706 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7743 7712 7744 7713 /* Line 1806 of yacc.c */ 7745 #line 19 92"parser.yy"7714 #line 1986 "parser.yy" 7746 7715 { 7747 7716 typedefTable.addToEnclosingScope2( *(yyvsp[(5) - (5)].tok), TypedefTable::ID ); … … 7753 7722 7754 7723 /* Line 1806 of yacc.c */ 7755 #line 2000"parser.yy"7724 #line 1994 "parser.yy" 7756 7725 { 7757 7726 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7763 7732 7764 7733 /* Line 1806 of yacc.c */ 7765 #line 2005"parser.yy"7734 #line 1999 "parser.yy" 7766 7735 { 7767 7736 typedefTable.addToEnclosingScope2( TypedefTable::ID ); … … 7773 7742 7774 7743 /* Line 1806 of yacc.c */ 7775 #line 20 15"parser.yy"7744 #line 2009 "parser.yy" 7776 7745 {} 7777 7746 break; … … 7780 7749 7781 7750 /* Line 1806 of yacc.c */ 7751 #line 2011 "parser.yy" 7752 { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl); } 7753 break; 7754 7755 case 526: 7756 7757 /* Line 1806 of yacc.c */ 7782 7758 #line 2017 "parser.yy" 7783 { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl); }7784 break;7785 7786 case 526:7787 7788 /* Line 1806 of yacc.c */7789 #line 2023 "parser.yy"7790 7759 { (yyval.decl) = (yyvsp[(1) - (3)].decl) != nullptr ? (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ) : (yyvsp[(3) - (3)].decl); } 7791 7760 break; … … 7794 7763 7795 7764 /* Line 1806 of yacc.c */ 7796 #line 202 8"parser.yy"7765 #line 2022 "parser.yy" 7797 7766 { (yyval.decl) = 0; } 7798 7767 break; … … 7801 7770 7802 7771 /* Line 1806 of yacc.c */ 7803 #line 203 6"parser.yy"7772 #line 2030 "parser.yy" 7804 7773 {} 7805 7774 break; … … 7808 7777 7809 7778 /* Line 1806 of yacc.c */ 7810 #line 203 8"parser.yy"7779 #line 2032 "parser.yy" 7811 7780 { 7812 7781 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" … … 7818 7787 7819 7788 /* Line 1806 of yacc.c */ 7820 #line 20 43"parser.yy"7789 #line 2037 "parser.yy" 7821 7790 { 7822 7791 linkage = linkageStack.top(); … … 7829 7798 7830 7799 /* Line 1806 of yacc.c */ 7831 #line 204 9"parser.yy"7800 #line 2043 "parser.yy" 7832 7801 { // mark all fields in list 7833 7802 for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) … … 7840 7809 7841 7810 /* Line 1806 of yacc.c */ 7842 #line 20 64"parser.yy"7811 #line 2058 "parser.yy" 7843 7812 { 7844 7813 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7851 7820 7852 7821 /* Line 1806 of yacc.c */ 7853 #line 20 70"parser.yy"7822 #line 2064 "parser.yy" 7854 7823 { 7855 7824 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7862 7831 7863 7832 /* Line 1806 of yacc.c */ 7864 #line 207 9"parser.yy"7833 #line 2073 "parser.yy" 7865 7834 { 7866 7835 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7873 7842 7874 7843 /* Line 1806 of yacc.c */ 7875 #line 20 85"parser.yy"7844 #line 2079 "parser.yy" 7876 7845 { 7877 7846 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7882 7851 7883 7852 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: 7884 7864 7885 7865 /* Line 1806 of yacc.c */ … … 7892 7872 break; 7893 7873 7894 case 54 1:7874 case 542: 7895 7875 7896 7876 /* Line 1806 of yacc.c */ 7897 7877 #line 2097 "parser.yy" 7898 {7899 typedefTable.addToEnclosingScope( TypedefTable::ID );7900 typedefTable.leaveScope();7901 (yyval.decl) = (yyvsp[(2) - (3)].decl)->addFunctionBody( (yyvsp[(3) - (3)].sn) )->addQualifiers( (yyvsp[(1) - (3)].decl) );7902 }7903 break;7904 7905 case 542:7906 7907 /* Line 1806 of yacc.c */7908 #line 2103 "parser.yy"7909 7878 { 7910 7879 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7917 7886 7918 7887 /* Line 1806 of yacc.c */ 7919 #line 21 11"parser.yy"7888 #line 2105 "parser.yy" 7920 7889 { 7921 7890 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7928 7897 7929 7898 /* Line 1806 of yacc.c */ 7930 #line 211 7"parser.yy"7899 #line 2111 "parser.yy" 7931 7900 { 7932 7901 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7939 7908 7940 7909 /* Line 1806 of yacc.c */ 7941 #line 21 25"parser.yy"7910 #line 2119 "parser.yy" 7942 7911 { 7943 7912 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7950 7919 7951 7920 /* Line 1806 of yacc.c */ 7952 #line 21 31"parser.yy"7921 #line 2125 "parser.yy" 7953 7922 { 7954 7923 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 7961 7930 7962 7931 /* Line 1806 of yacc.c */ 7963 #line 214 6"parser.yy"7932 #line 2140 "parser.yy" 7964 7933 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 7965 7934 break; … … 7968 7937 7969 7938 /* Line 1806 of yacc.c */ 7970 #line 21 51"parser.yy"7939 #line 2145 "parser.yy" 7971 7940 { delete (yyvsp[(3) - (5)].str); } 7972 7941 break; … … 7975 7944 7976 7945 /* Line 1806 of yacc.c */ 7977 #line 215 6"parser.yy"7946 #line 2150 "parser.yy" 7978 7947 { (yyval.decl) = 0; } 7979 7948 break; … … 7982 7951 7983 7952 /* Line 1806 of yacc.c */ 7953 #line 2157 "parser.yy" 7954 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 7955 break; 7956 7957 case 557: 7958 7959 /* Line 1806 of yacc.c */ 7984 7960 #line 2163 "parser.yy" 7985 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }7986 break;7987 7988 case 557:7989 7990 /* Line 1806 of yacc.c */7991 #line 2169 "parser.yy"7992 7961 { (yyval.decl) = 0; } 7993 7962 break; … … 7996 7965 7997 7966 /* Line 1806 of yacc.c */ 7967 #line 2174 "parser.yy" 7968 { delete (yyvsp[(3) - (4)].en); } 7969 break; 7970 7971 case 563: 7972 7973 /* Line 1806 of yacc.c */ 7974 #line 2178 "parser.yy" 7975 { delete (yyvsp[(1) - (1)].tok); } 7976 break; 7977 7978 case 564: 7979 7980 /* Line 1806 of yacc.c */ 7981 #line 2179 "parser.yy" 7982 { delete (yyvsp[(1) - (1)].decl); } 7983 break; 7984 7985 case 565: 7986 7987 /* Line 1806 of yacc.c */ 7998 7988 #line 2180 "parser.yy" 7999 { delete (yyvsp[(3) - (4)].en); }8000 break;8001 8002 case 563:8003 8004 /* Line 1806 of yacc.c */8005 #line 2184 "parser.yy"8006 { delete (yyvsp[(1) - (1)].tok); }8007 break;8008 8009 case 564:8010 8011 /* Line 1806 of yacc.c */8012 #line 2185 "parser.yy"8013 7989 { delete (yyvsp[(1) - (1)].decl); } 8014 7990 break; 8015 7991 8016 case 56 5:8017 8018 /* Line 1806 of yacc.c */ 8019 #line 218 6"parser.yy"7992 case 566: 7993 7994 /* Line 1806 of yacc.c */ 7995 #line 2181 "parser.yy" 8020 7996 { delete (yyvsp[(1) - (1)].decl); } 8021 7997 break; 8022 7998 8023 case 566:8024 8025 /* Line 1806 of yacc.c */8026 #line 2187 "parser.yy"8027 { delete (yyvsp[(1) - (1)].decl); }8028 break;8029 8030 7999 case 567: 8031 8000 8032 8001 /* Line 1806 of yacc.c */ 8033 #line 22 22"parser.yy"8002 #line 2216 "parser.yy" 8034 8003 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8035 8004 break; … … 8038 8007 8039 8008 /* Line 1806 of yacc.c */ 8040 #line 22 25"parser.yy"8009 #line 2219 "parser.yy" 8041 8010 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8042 8011 break; … … 8045 8014 8046 8015 /* Line 1806 of yacc.c */ 8047 #line 222 7"parser.yy"8016 #line 2221 "parser.yy" 8048 8017 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8049 8018 break; … … 8052 8021 8053 8022 /* Line 1806 of yacc.c */ 8054 #line 22 32"parser.yy"8023 #line 2226 "parser.yy" 8055 8024 { 8056 8025 typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) ); … … 8062 8031 8063 8032 /* Line 1806 of yacc.c */ 8064 #line 223 7"parser.yy"8033 #line 2231 "parser.yy" 8065 8034 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8066 8035 break; … … 8069 8038 8070 8039 /* Line 1806 of yacc.c */ 8071 #line 22 42"parser.yy"8040 #line 2236 "parser.yy" 8072 8041 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8073 8042 break; … … 8076 8045 8077 8046 /* Line 1806 of yacc.c */ 8078 #line 22 44"parser.yy"8047 #line 2238 "parser.yy" 8079 8048 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8080 8049 break; … … 8083 8052 8084 8053 /* Line 1806 of yacc.c */ 8085 #line 224 6"parser.yy"8054 #line 2240 "parser.yy" 8086 8055 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8087 8056 break; … … 8090 8059 8091 8060 /* Line 1806 of yacc.c */ 8061 #line 2245 "parser.yy" 8062 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8063 break; 8064 8065 case 577: 8066 8067 /* Line 1806 of yacc.c */ 8068 #line 2247 "parser.yy" 8069 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8070 break; 8071 8072 case 578: 8073 8074 /* Line 1806 of yacc.c */ 8075 #line 2249 "parser.yy" 8076 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8077 break; 8078 8079 case 579: 8080 8081 /* Line 1806 of yacc.c */ 8092 8082 #line 2251 "parser.yy" 8083 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8084 break; 8085 8086 case 580: 8087 8088 /* Line 1806 of yacc.c */ 8089 #line 2256 "parser.yy" 8090 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8091 break; 8092 8093 case 581: 8094 8095 /* Line 1806 of yacc.c */ 8096 #line 2258 "parser.yy" 8097 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8098 break; 8099 8100 case 582: 8101 8102 /* Line 1806 of yacc.c */ 8103 #line 2267 "parser.yy" 8104 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8105 break; 8106 8107 case 584: 8108 8109 /* Line 1806 of yacc.c */ 8110 #line 2270 "parser.yy" 8111 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8112 break; 8113 8114 case 585: 8115 8116 /* Line 1806 of yacc.c */ 8117 #line 2275 "parser.yy" 8118 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8119 break; 8120 8121 case 586: 8122 8123 /* Line 1806 of yacc.c */ 8124 #line 2277 "parser.yy" 8125 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8126 break; 8127 8128 case 587: 8129 8130 /* Line 1806 of yacc.c */ 8131 #line 2279 "parser.yy" 8132 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8133 break; 8134 8135 case 588: 8136 8137 /* Line 1806 of yacc.c */ 8138 #line 2284 "parser.yy" 8139 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8140 break; 8141 8142 case 589: 8143 8144 /* Line 1806 of yacc.c */ 8145 #line 2286 "parser.yy" 8146 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8147 break; 8148 8149 case 590: 8150 8151 /* Line 1806 of yacc.c */ 8152 #line 2288 "parser.yy" 8153 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8154 break; 8155 8156 case 591: 8157 8158 /* Line 1806 of yacc.c */ 8159 #line 2293 "parser.yy" 8160 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8161 break; 8162 8163 case 592: 8164 8165 /* Line 1806 of yacc.c */ 8166 #line 2295 "parser.yy" 8167 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8168 break; 8169 8170 case 593: 8171 8172 /* Line 1806 of yacc.c */ 8173 #line 2297 "parser.yy" 8174 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8175 break; 8176 8177 case 597: 8178 8179 /* Line 1806 of yacc.c */ 8180 #line 2312 "parser.yy" 8181 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); } 8182 break; 8183 8184 case 598: 8185 8186 /* Line 1806 of yacc.c */ 8187 #line 2314 "parser.yy" 8188 { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); } 8189 break; 8190 8191 case 599: 8192 8193 /* Line 1806 of yacc.c */ 8194 #line 2316 "parser.yy" 8195 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8196 break; 8197 8198 case 600: 8199 8200 /* Line 1806 of yacc.c */ 8201 #line 2321 "parser.yy" 8202 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8203 break; 8204 8205 case 601: 8206 8207 /* Line 1806 of yacc.c */ 8208 #line 2323 "parser.yy" 8209 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8210 break; 8211 8212 case 602: 8213 8214 /* Line 1806 of yacc.c */ 8215 #line 2325 "parser.yy" 8216 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8217 break; 8218 8219 case 603: 8220 8221 /* Line 1806 of yacc.c */ 8222 #line 2330 "parser.yy" 8223 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8224 break; 8225 8226 case 604: 8227 8228 /* Line 1806 of yacc.c */ 8229 #line 2332 "parser.yy" 8230 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8231 break; 8232 8233 case 605: 8234 8235 /* Line 1806 of yacc.c */ 8236 #line 2334 "parser.yy" 8237 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8238 break; 8239 8240 case 606: 8241 8242 /* Line 1806 of yacc.c */ 8243 #line 2349 "parser.yy" 8244 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8245 break; 8246 8247 case 608: 8248 8249 /* Line 1806 of yacc.c */ 8250 #line 2352 "parser.yy" 8251 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8252 break; 8253 8254 case 609: 8255 8256 /* Line 1806 of yacc.c */ 8257 #line 2354 "parser.yy" 8258 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8259 break; 8260 8261 case 611: 8262 8263 /* Line 1806 of yacc.c */ 8264 #line 2360 "parser.yy" 8265 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8266 break; 8267 8268 case 612: 8269 8270 /* Line 1806 of yacc.c */ 8271 #line 2365 "parser.yy" 8272 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8273 break; 8274 8275 case 613: 8276 8277 /* Line 1806 of yacc.c */ 8278 #line 2367 "parser.yy" 8279 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8280 break; 8281 8282 case 614: 8283 8284 /* Line 1806 of yacc.c */ 8285 #line 2369 "parser.yy" 8286 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8287 break; 8288 8289 case 615: 8290 8291 /* Line 1806 of yacc.c */ 8292 #line 2374 "parser.yy" 8093 8293 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8094 8294 break; 8095 8295 8096 case 577:8097 8098 /* Line 1806 of yacc.c */ 8099 #line 2 253"parser.yy"8296 case 616: 8297 8298 /* Line 1806 of yacc.c */ 8299 #line 2376 "parser.yy" 8100 8300 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8101 8301 break; 8102 8302 8103 case 578:8104 8105 /* Line 1806 of yacc.c */ 8106 #line 2 255"parser.yy"8303 case 617: 8304 8305 /* Line 1806 of yacc.c */ 8306 #line 2378 "parser.yy" 8107 8307 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8108 8308 break; 8109 8309 8110 case 579:8111 8112 /* Line 1806 of yacc.c */ 8113 #line 2 257"parser.yy"8310 case 618: 8311 8312 /* Line 1806 of yacc.c */ 8313 #line 2380 "parser.yy" 8114 8314 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8115 8315 break; 8116 8316 8117 case 580: 8118 8119 /* Line 1806 of yacc.c */ 8120 #line 2262 "parser.yy" 8317 case 619: 8318 8319 /* Line 1806 of yacc.c */ 8320 #line 2385 "parser.yy" 8321 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8322 break; 8323 8324 case 620: 8325 8326 /* Line 1806 of yacc.c */ 8327 #line 2387 "parser.yy" 8121 8328 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8122 8329 break; 8123 8330 8124 case 581:8125 8126 /* Line 1806 of yacc.c */ 8127 #line 2 264"parser.yy"8331 case 621: 8332 8333 /* Line 1806 of yacc.c */ 8334 #line 2389 "parser.yy" 8128 8335 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8129 8336 break; 8130 8337 8131 case 582:8132 8133 /* Line 1806 of yacc.c */ 8134 #line 2 273"parser.yy"8338 case 622: 8339 8340 /* Line 1806 of yacc.c */ 8341 #line 2399 "parser.yy" 8135 8342 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8136 8343 break; 8137 8344 8138 case 584:8139 8140 /* Line 1806 of yacc.c */ 8141 #line 2 276"parser.yy"8345 case 624: 8346 8347 /* Line 1806 of yacc.c */ 8348 #line 2402 "parser.yy" 8142 8349 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8143 8350 break; 8144 8351 8145 case 585: 8146 8147 /* Line 1806 of yacc.c */ 8148 #line 2281 "parser.yy" 8352 case 625: 8353 8354 /* Line 1806 of yacc.c */ 8355 #line 2404 "parser.yy" 8356 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8357 break; 8358 8359 case 626: 8360 8361 /* Line 1806 of yacc.c */ 8362 #line 2409 "parser.yy" 8363 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8364 break; 8365 8366 case 627: 8367 8368 /* Line 1806 of yacc.c */ 8369 #line 2411 "parser.yy" 8370 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8371 break; 8372 8373 case 628: 8374 8375 /* Line 1806 of yacc.c */ 8376 #line 2413 "parser.yy" 8377 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8378 break; 8379 8380 case 629: 8381 8382 /* Line 1806 of yacc.c */ 8383 #line 2418 "parser.yy" 8384 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8385 break; 8386 8387 case 630: 8388 8389 /* Line 1806 of yacc.c */ 8390 #line 2420 "parser.yy" 8391 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8392 break; 8393 8394 case 631: 8395 8396 /* Line 1806 of yacc.c */ 8397 #line 2422 "parser.yy" 8398 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8399 break; 8400 8401 case 632: 8402 8403 /* Line 1806 of yacc.c */ 8404 #line 2424 "parser.yy" 8405 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8406 break; 8407 8408 case 633: 8409 8410 /* Line 1806 of yacc.c */ 8411 #line 2429 "parser.yy" 8149 8412 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8150 8413 break; 8151 8414 8152 case 586:8153 8154 /* Line 1806 of yacc.c */ 8155 #line 2 283"parser.yy"8415 case 634: 8416 8417 /* Line 1806 of yacc.c */ 8418 #line 2431 "parser.yy" 8156 8419 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8157 8420 break; 8158 8421 8159 case 587:8160 8161 /* Line 1806 of yacc.c */ 8162 #line 2 285"parser.yy"8422 case 635: 8423 8424 /* Line 1806 of yacc.c */ 8425 #line 2433 "parser.yy" 8163 8426 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8164 8427 break; 8165 8428 8166 case 588: 8167 8168 /* Line 1806 of yacc.c */ 8169 #line 2290 "parser.yy" 8170 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8171 break; 8172 8173 case 589: 8174 8175 /* Line 1806 of yacc.c */ 8176 #line 2292 "parser.yy" 8177 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8178 break; 8179 8180 case 590: 8181 8182 /* Line 1806 of yacc.c */ 8183 #line 2294 "parser.yy" 8184 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8185 break; 8186 8187 case 591: 8188 8189 /* Line 1806 of yacc.c */ 8190 #line 2299 "parser.yy" 8191 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8192 break; 8193 8194 case 592: 8195 8196 /* Line 1806 of yacc.c */ 8197 #line 2301 "parser.yy" 8198 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8199 break; 8200 8201 case 593: 8202 8203 /* Line 1806 of yacc.c */ 8204 #line 2303 "parser.yy" 8205 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8206 break; 8207 8208 case 597: 8209 8210 /* Line 1806 of yacc.c */ 8211 #line 2318 "parser.yy" 8212 { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); } 8213 break; 8214 8215 case 598: 8216 8217 /* Line 1806 of yacc.c */ 8218 #line 2320 "parser.yy" 8219 { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); } 8220 break; 8221 8222 case 599: 8223 8224 /* Line 1806 of yacc.c */ 8225 #line 2322 "parser.yy" 8226 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8227 break; 8228 8229 case 600: 8230 8231 /* Line 1806 of yacc.c */ 8232 #line 2327 "parser.yy" 8233 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8234 break; 8235 8236 case 601: 8237 8238 /* Line 1806 of yacc.c */ 8239 #line 2329 "parser.yy" 8240 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8241 break; 8242 8243 case 602: 8244 8245 /* Line 1806 of yacc.c */ 8246 #line 2331 "parser.yy" 8247 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8248 break; 8249 8250 case 603: 8251 8252 /* Line 1806 of yacc.c */ 8253 #line 2336 "parser.yy" 8254 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8255 break; 8256 8257 case 604: 8258 8259 /* Line 1806 of yacc.c */ 8260 #line 2338 "parser.yy" 8261 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8262 break; 8263 8264 case 605: 8265 8266 /* Line 1806 of yacc.c */ 8267 #line 2340 "parser.yy" 8268 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8269 break; 8270 8271 case 606: 8272 8273 /* Line 1806 of yacc.c */ 8274 #line 2355 "parser.yy" 8429 case 636: 8430 8431 /* Line 1806 of yacc.c */ 8432 #line 2464 "parser.yy" 8275 8433 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8276 8434 break; 8277 8435 8278 case 6 08:8279 8280 /* Line 1806 of yacc.c */ 8281 #line 2 358"parser.yy"8436 case 638: 8437 8438 /* Line 1806 of yacc.c */ 8439 #line 2467 "parser.yy" 8282 8440 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8283 8441 break; 8284 8442 8285 case 6 09:8286 8287 /* Line 1806 of yacc.c */ 8288 #line 2 360"parser.yy"8443 case 639: 8444 8445 /* Line 1806 of yacc.c */ 8446 #line 2469 "parser.yy" 8289 8447 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8290 8448 break; 8291 8449 8292 case 611:8293 8294 /* Line 1806 of yacc.c */8295 #line 2366 "parser.yy"8296 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8297 break;8298 8299 case 612:8300 8301 /* Line 1806 of yacc.c */8302 #line 2371 "parser.yy"8303 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }8304 break;8305 8306 case 613:8307 8308 /* Line 1806 of yacc.c */8309 #line 2373 "parser.yy"8310 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }8311 break;8312 8313 case 614:8314 8315 /* Line 1806 of yacc.c */8316 #line 2375 "parser.yy"8317 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8318 break;8319 8320 case 615:8321 8322 /* Line 1806 of yacc.c */8323 #line 2380 "parser.yy"8324 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }8325 break;8326 8327 case 616:8328 8329 /* Line 1806 of yacc.c */8330 #line 2382 "parser.yy"8331 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }8332 break;8333 8334 case 617:8335 8336 /* Line 1806 of yacc.c */8337 #line 2384 "parser.yy"8338 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }8339 break;8340 8341 case 618:8342 8343 /* Line 1806 of yacc.c */8344 #line 2386 "parser.yy"8345 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8346 break;8347 8348 case 619:8349 8350 /* Line 1806 of yacc.c */8351 #line 2391 "parser.yy"8352 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }8353 break;8354 8355 case 620:8356 8357 /* Line 1806 of yacc.c */8358 #line 2393 "parser.yy"8359 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }8360 break;8361 8362 case 621:8363 8364 /* Line 1806 of yacc.c */8365 #line 2395 "parser.yy"8366 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8367 break;8368 8369 case 622:8370 8371 /* Line 1806 of yacc.c */8372 #line 2405 "parser.yy"8373 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8374 break;8375 8376 case 624:8377 8378 /* Line 1806 of yacc.c */8379 #line 2408 "parser.yy"8380 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8381 break;8382 8383 case 625:8384 8385 /* Line 1806 of yacc.c */8386 #line 2410 "parser.yy"8387 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8388 break;8389 8390 case 626:8391 8392 /* Line 1806 of yacc.c */8393 #line 2415 "parser.yy"8394 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }8395 break;8396 8397 case 627:8398 8399 /* Line 1806 of yacc.c */8400 #line 2417 "parser.yy"8401 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }8402 break;8403 8404 case 628:8405 8406 /* Line 1806 of yacc.c */8407 #line 2419 "parser.yy"8408 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8409 break;8410 8411 case 629:8412 8413 /* Line 1806 of yacc.c */8414 #line 2424 "parser.yy"8415 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }8416 break;8417 8418 case 630:8419 8420 /* Line 1806 of yacc.c */8421 #line 2426 "parser.yy"8422 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }8423 break;8424 8425 case 631:8426 8427 /* Line 1806 of yacc.c */8428 #line 2428 "parser.yy"8429 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }8430 break;8431 8432 case 632:8433 8434 /* Line 1806 of yacc.c */8435 #line 2430 "parser.yy"8436 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8437 break;8438 8439 case 633:8440 8441 /* Line 1806 of yacc.c */8442 #line 2435 "parser.yy"8443 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }8444 break;8445 8446 case 634:8447 8448 /* Line 1806 of yacc.c */8449 #line 2437 "parser.yy"8450 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }8451 break;8452 8453 case 635:8454 8455 /* Line 1806 of yacc.c */8456 #line 2439 "parser.yy"8457 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8458 break;8459 8460 case 636:8461 8462 /* Line 1806 of yacc.c */8463 #line 2470 "parser.yy"8464 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8465 break;8466 8467 case 638:8468 8469 /* Line 1806 of yacc.c */8470 #line 2473 "parser.yy"8471 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8472 break;8473 8474 case 639:8475 8476 /* Line 1806 of yacc.c */8477 #line 2475 "parser.yy"8478 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8479 break;8480 8481 8450 case 640: 8482 8451 8483 8452 /* Line 1806 of yacc.c */ 8484 #line 24 80"parser.yy"8453 #line 2474 "parser.yy" 8485 8454 { 8486 8455 typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) ); … … 8492 8461 8493 8462 /* Line 1806 of yacc.c */ 8494 #line 24 85"parser.yy"8463 #line 2479 "parser.yy" 8495 8464 { 8496 8465 typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) ); … … 8502 8471 8503 8472 /* Line 1806 of yacc.c */ 8504 #line 24 93"parser.yy"8473 #line 2487 "parser.yy" 8505 8474 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8506 8475 break; … … 8509 8478 8510 8479 /* Line 1806 of yacc.c */ 8511 #line 24 95"parser.yy"8480 #line 2489 "parser.yy" 8512 8481 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8513 8482 break; … … 8516 8485 8517 8486 /* Line 1806 of yacc.c */ 8518 #line 249 7"parser.yy"8487 #line 2491 "parser.yy" 8519 8488 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8520 8489 break; … … 8523 8492 8524 8493 /* Line 1806 of yacc.c */ 8525 #line 2 502"parser.yy"8494 #line 2496 "parser.yy" 8526 8495 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8527 8496 break; … … 8530 8499 8531 8500 /* Line 1806 of yacc.c */ 8532 #line 2 504"parser.yy"8501 #line 2498 "parser.yy" 8533 8502 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8534 8503 break; … … 8537 8506 8538 8507 /* Line 1806 of yacc.c */ 8539 #line 250 9"parser.yy"8508 #line 2503 "parser.yy" 8540 8509 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); } 8541 8510 break; … … 8544 8513 8545 8514 /* Line 1806 of yacc.c */ 8546 #line 25 11"parser.yy"8515 #line 2505 "parser.yy" 8547 8516 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8548 8517 break; … … 8551 8520 8552 8521 /* Line 1806 of yacc.c */ 8553 #line 252 6"parser.yy"8522 #line 2520 "parser.yy" 8554 8523 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8555 8524 break; … … 8558 8527 8559 8528 /* Line 1806 of yacc.c */ 8560 #line 252 8"parser.yy"8529 #line 2522 "parser.yy" 8561 8530 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8562 8531 break; … … 8565 8534 8566 8535 /* Line 1806 of yacc.c */ 8536 #line 2527 "parser.yy" 8537 { (yyval.decl) = DeclarationNode::newPointer( 0 ); } 8538 break; 8539 8540 case 653: 8541 8542 /* Line 1806 of yacc.c */ 8543 #line 2529 "parser.yy" 8544 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); } 8545 break; 8546 8547 case 654: 8548 8549 /* Line 1806 of yacc.c */ 8550 #line 2531 "parser.yy" 8551 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8552 break; 8553 8554 case 655: 8555 8556 /* Line 1806 of yacc.c */ 8567 8557 #line 2533 "parser.yy" 8558 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8559 break; 8560 8561 case 656: 8562 8563 /* Line 1806 of yacc.c */ 8564 #line 2535 "parser.yy" 8565 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8566 break; 8567 8568 case 658: 8569 8570 /* Line 1806 of yacc.c */ 8571 #line 2541 "parser.yy" 8572 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8573 break; 8574 8575 case 659: 8576 8577 /* Line 1806 of yacc.c */ 8578 #line 2543 "parser.yy" 8579 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8580 break; 8581 8582 case 660: 8583 8584 /* Line 1806 of yacc.c */ 8585 #line 2545 "parser.yy" 8586 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8587 break; 8588 8589 case 661: 8590 8591 /* Line 1806 of yacc.c */ 8592 #line 2550 "parser.yy" 8593 { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); } 8594 break; 8595 8596 case 662: 8597 8598 /* Line 1806 of yacc.c */ 8599 #line 2552 "parser.yy" 8600 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8601 break; 8602 8603 case 663: 8604 8605 /* Line 1806 of yacc.c */ 8606 #line 2554 "parser.yy" 8607 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8608 break; 8609 8610 case 664: 8611 8612 /* Line 1806 of yacc.c */ 8613 #line 2560 "parser.yy" 8614 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); } 8615 break; 8616 8617 case 665: 8618 8619 /* Line 1806 of yacc.c */ 8620 #line 2562 "parser.yy" 8621 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); } 8622 break; 8623 8624 case 667: 8625 8626 /* Line 1806 of yacc.c */ 8627 #line 2568 "parser.yy" 8628 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); } 8629 break; 8630 8631 case 668: 8632 8633 /* Line 1806 of yacc.c */ 8634 #line 2570 "parser.yy" 8635 { (yyval.decl) = DeclarationNode::newVarArray( 0 ); } 8636 break; 8637 8638 case 669: 8639 8640 /* Line 1806 of yacc.c */ 8641 #line 2572 "parser.yy" 8642 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); } 8643 break; 8644 8645 case 670: 8646 8647 /* Line 1806 of yacc.c */ 8648 #line 2574 "parser.yy" 8649 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); } 8650 break; 8651 8652 case 672: 8653 8654 /* Line 1806 of yacc.c */ 8655 #line 2589 "parser.yy" 8656 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8657 break; 8658 8659 case 673: 8660 8661 /* Line 1806 of yacc.c */ 8662 #line 2591 "parser.yy" 8663 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8664 break; 8665 8666 case 674: 8667 8668 /* Line 1806 of yacc.c */ 8669 #line 2596 "parser.yy" 8568 8670 { (yyval.decl) = DeclarationNode::newPointer( 0 ); } 8569 8671 break; 8570 8672 8571 case 6 53:8572 8573 /* Line 1806 of yacc.c */ 8574 #line 25 35"parser.yy"8673 case 675: 8674 8675 /* Line 1806 of yacc.c */ 8676 #line 2598 "parser.yy" 8575 8677 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); } 8576 8678 break; 8577 8679 8578 case 6 54:8579 8580 /* Line 1806 of yacc.c */ 8581 #line 2 537"parser.yy"8680 case 676: 8681 8682 /* Line 1806 of yacc.c */ 8683 #line 2600 "parser.yy" 8582 8684 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8583 8685 break; 8584 8686 8585 case 6 55:8586 8587 /* Line 1806 of yacc.c */ 8588 #line 2 539"parser.yy"8687 case 677: 8688 8689 /* Line 1806 of yacc.c */ 8690 #line 2602 "parser.yy" 8589 8691 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8590 8692 break; 8591 8693 8592 case 6 56:8593 8594 /* Line 1806 of yacc.c */ 8595 #line 2 541"parser.yy"8694 case 678: 8695 8696 /* Line 1806 of yacc.c */ 8697 #line 2604 "parser.yy" 8596 8698 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8597 8699 break; 8598 8700 8599 case 6 58:8600 8601 /* Line 1806 of yacc.c */ 8602 #line 2 547"parser.yy"8701 case 680: 8702 8703 /* Line 1806 of yacc.c */ 8704 #line 2610 "parser.yy" 8603 8705 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8604 8706 break; 8605 8707 8606 case 6 59:8607 8608 /* Line 1806 of yacc.c */ 8609 #line 2 549"parser.yy"8708 case 681: 8709 8710 /* Line 1806 of yacc.c */ 8711 #line 2612 "parser.yy" 8610 8712 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8611 8713 break; 8612 8714 8613 case 6 60:8614 8615 /* Line 1806 of yacc.c */ 8616 #line 2 551"parser.yy"8715 case 682: 8716 8717 /* Line 1806 of yacc.c */ 8718 #line 2614 "parser.yy" 8617 8719 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8618 8720 break; 8619 8721 8620 case 6 61:8621 8622 /* Line 1806 of yacc.c */ 8623 #line 2 556"parser.yy"8722 case 683: 8723 8724 /* Line 1806 of yacc.c */ 8725 #line 2619 "parser.yy" 8624 8726 { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); } 8625 8727 break; 8626 8728 8627 case 6 62:8628 8629 /* Line 1806 of yacc.c */ 8630 #line 2 558"parser.yy"8729 case 684: 8730 8731 /* Line 1806 of yacc.c */ 8732 #line 2621 "parser.yy" 8631 8733 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8632 8734 break; 8633 8735 8634 case 6 63:8635 8636 /* Line 1806 of yacc.c */ 8637 #line 2 560"parser.yy"8736 case 685: 8737 8738 /* Line 1806 of yacc.c */ 8739 #line 2623 "parser.yy" 8638 8740 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8639 8741 break; 8640 8742 8641 case 664: 8642 8643 /* Line 1806 of yacc.c */ 8644 #line 2566 "parser.yy" 8743 case 687: 8744 8745 /* Line 1806 of yacc.c */ 8746 #line 2630 "parser.yy" 8747 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); } 8748 break; 8749 8750 case 689: 8751 8752 /* Line 1806 of yacc.c */ 8753 #line 2641 "parser.yy" 8645 8754 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); } 8646 8755 break; 8647 8756 8648 case 6 65:8649 8650 /* Line 1806 of yacc.c */ 8651 #line 2 568"parser.yy"8652 { (yyval.decl) = DeclarationNode::new Array( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); }8653 break; 8654 8655 case 6 67:8656 8657 /* Line 1806 of yacc.c */ 8658 #line 2 574"parser.yy"8659 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); }8660 break; 8661 8662 case 6 68:8663 8664 /* Line 1806 of yacc.c */ 8665 #line 2 576"parser.yy"8666 { (yyval.decl) = DeclarationNode::new VarArray( 0); }8667 break; 8668 8669 case 6 69:8670 8671 /* Line 1806 of yacc.c */ 8672 #line 2 578"parser.yy"8673 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false )); }8674 break; 8675 8676 case 6 70:8677 8678 /* Line 1806 of yacc.c */ 8679 #line 2 580"parser.yy"8680 { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 )); }8681 break; 8682 8683 case 6 72:8684 8685 /* Line 1806 of yacc.c */ 8686 #line 2 595"parser.yy"8757 case 690: 8758 8759 /* Line 1806 of yacc.c */ 8760 #line 2644 "parser.yy" 8761 { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); } 8762 break; 8763 8764 case 691: 8765 8766 /* Line 1806 of yacc.c */ 8767 #line 2646 "parser.yy" 8768 { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); } 8769 break; 8770 8771 case 692: 8772 8773 /* Line 1806 of yacc.c */ 8774 #line 2649 "parser.yy" 8775 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); } 8776 break; 8777 8778 case 693: 8779 8780 /* Line 1806 of yacc.c */ 8781 #line 2651 "parser.yy" 8782 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); } 8783 break; 8784 8785 case 694: 8786 8787 /* Line 1806 of yacc.c */ 8788 #line 2653 "parser.yy" 8789 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); } 8790 break; 8791 8792 case 696: 8793 8794 /* Line 1806 of yacc.c */ 8795 #line 2667 "parser.yy" 8687 8796 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8688 8797 break; 8689 8798 8690 case 6 73:8691 8692 /* Line 1806 of yacc.c */ 8693 #line 2 597"parser.yy"8799 case 697: 8800 8801 /* Line 1806 of yacc.c */ 8802 #line 2669 "parser.yy" 8694 8803 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); } 8695 8804 break; 8696 8805 8697 case 6 74:8698 8699 /* Line 1806 of yacc.c */ 8700 #line 26 02"parser.yy"8806 case 698: 8807 8808 /* Line 1806 of yacc.c */ 8809 #line 2674 "parser.yy" 8701 8810 { (yyval.decl) = DeclarationNode::newPointer( 0 ); } 8702 8811 break; 8703 8812 8704 case 6 75:8705 8706 /* Line 1806 of yacc.c */ 8707 #line 26 04"parser.yy"8813 case 699: 8814 8815 /* Line 1806 of yacc.c */ 8816 #line 2676 "parser.yy" 8708 8817 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); } 8709 8818 break; 8710 8819 8711 case 676:8712 8713 /* Line 1806 of yacc.c */ 8714 #line 26 06"parser.yy"8820 case 700: 8821 8822 /* Line 1806 of yacc.c */ 8823 #line 2678 "parser.yy" 8715 8824 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); } 8716 8825 break; 8717 8826 8718 case 677:8719 8720 /* Line 1806 of yacc.c */ 8721 #line 26 08"parser.yy"8827 case 701: 8828 8829 /* Line 1806 of yacc.c */ 8830 #line 2680 "parser.yy" 8722 8831 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); } 8723 8832 break; 8724 8833 8725 case 678:8726 8727 /* Line 1806 of yacc.c */ 8728 #line 26 10"parser.yy"8834 case 702: 8835 8836 /* Line 1806 of yacc.c */ 8837 #line 2682 "parser.yy" 8729 8838 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8730 8839 break; 8731 8840 8732 case 680:8733 8734 /* Line 1806 of yacc.c */ 8735 #line 26 16"parser.yy"8841 case 704: 8842 8843 /* Line 1806 of yacc.c */ 8844 #line 2688 "parser.yy" 8736 8845 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8737 8846 break; 8738 8847 8739 case 681:8740 8741 /* Line 1806 of yacc.c */ 8742 #line 26 18"parser.yy"8848 case 705: 8849 8850 /* Line 1806 of yacc.c */ 8851 #line 2690 "parser.yy" 8743 8852 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); } 8744 8853 break; 8745 8854 8746 case 682:8747 8748 /* Line 1806 of yacc.c */ 8749 #line 26 20"parser.yy"8855 case 706: 8856 8857 /* Line 1806 of yacc.c */ 8858 #line 2692 "parser.yy" 8750 8859 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8751 8860 break; 8752 8861 8753 case 683: 8754 8755 /* Line 1806 of yacc.c */ 8756 #line 2625 "parser.yy" 8757 { (yyval.decl) = DeclarationNode::newFunction( nullptr, nullptr, (yyvsp[(3) - (5)].decl), nullptr ); } 8758 break; 8759 8760 case 684: 8761 8762 /* Line 1806 of yacc.c */ 8763 #line 2627 "parser.yy" 8862 case 707: 8863 8864 /* Line 1806 of yacc.c */ 8865 #line 2697 "parser.yy" 8764 8866 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); } 8765 8867 break; 8766 8868 8767 case 685:8768 8769 /* Line 1806 of yacc.c */ 8770 #line 26 29 "parser.yy"8869 case 708: 8870 8871 /* Line 1806 of yacc.c */ 8872 #line 2699 "parser.yy" 8771 8873 { (yyval.decl) = (yyvsp[(2) - (3)].decl); } 8772 8874 break; 8773 8875 8774 case 687:8775 8776 /* Line 1806 of yacc.c */8777 #line 2636 "parser.yy"8778 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }8779 break;8780 8781 case 689:8782 8783 /* Line 1806 of yacc.c */8784 #line 2647 "parser.yy"8785 { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }8786 break;8787 8788 case 690:8789 8790 /* Line 1806 of yacc.c */8791 #line 2650 "parser.yy"8792 { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }8793 break;8794 8795 case 691:8796 8797 /* Line 1806 of yacc.c */8798 #line 2652 "parser.yy"8799 { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); }8800 break;8801 8802 case 692:8803 8804 /* Line 1806 of yacc.c */8805 #line 2655 "parser.yy"8806 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }8807 break;8808 8809 case 693:8810 8811 /* Line 1806 of yacc.c */8812 #line 2657 "parser.yy"8813 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); }8814 break;8815 8816 case 694:8817 8818 /* Line 1806 of yacc.c */8819 #line 2659 "parser.yy"8820 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); }8821 break;8822 8823 case 696:8824 8825 /* Line 1806 of yacc.c */8826 #line 2673 "parser.yy"8827 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8828 break;8829 8830 case 697:8831 8832 /* Line 1806 of yacc.c */8833 #line 2675 "parser.yy"8834 { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }8835 break;8836 8837 case 698:8838 8839 /* Line 1806 of yacc.c */8840 #line 2680 "parser.yy"8841 { (yyval.decl) = DeclarationNode::newPointer( 0 ); }8842 break;8843 8844 case 699:8845 8846 /* Line 1806 of yacc.c */8847 #line 2682 "parser.yy"8848 { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }8849 break;8850 8851 case 700:8852 8853 /* Line 1806 of yacc.c */8854 #line 2684 "parser.yy"8855 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }8856 break;8857 8858 case 701:8859 8860 /* Line 1806 of yacc.c */8861 #line 2686 "parser.yy"8862 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }8863 break;8864 8865 case 702:8866 8867 /* Line 1806 of yacc.c */8868 #line 2688 "parser.yy"8869 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8870 break;8871 8872 case 704:8873 8874 /* Line 1806 of yacc.c */8875 #line 2694 "parser.yy"8876 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }8877 break;8878 8879 case 705:8880 8881 /* Line 1806 of yacc.c */8882 #line 2696 "parser.yy"8883 { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }8884 break;8885 8886 case 706:8887 8888 /* Line 1806 of yacc.c */8889 #line 2698 "parser.yy"8890 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8891 break;8892 8893 case 707:8894 8895 /* Line 1806 of yacc.c */8896 #line 2703 "parser.yy"8897 { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }8898 break;8899 8900 case 708:8901 8902 /* Line 1806 of yacc.c */8903 #line 2705 "parser.yy"8904 { (yyval.decl) = (yyvsp[(2) - (3)].decl); }8905 break;8906 8907 8876 case 711: 8908 8877 8909 8878 /* Line 1806 of yacc.c */ 8910 #line 27 15"parser.yy"8879 #line 2709 "parser.yy" 8911 8880 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 8912 8881 break; … … 8915 8884 8916 8885 /* Line 1806 of yacc.c */ 8886 #line 2719 "parser.yy" 8887 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 8888 break; 8889 8890 case 715: 8891 8892 /* Line 1806 of yacc.c */ 8893 #line 2721 "parser.yy" 8894 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 8895 break; 8896 8897 case 716: 8898 8899 /* Line 1806 of yacc.c */ 8900 #line 2723 "parser.yy" 8901 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 8902 break; 8903 8904 case 717: 8905 8906 /* Line 1806 of yacc.c */ 8917 8907 #line 2725 "parser.yy" 8908 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 8909 break; 8910 8911 case 718: 8912 8913 /* Line 1806 of yacc.c */ 8914 #line 2727 "parser.yy" 8918 8915 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 8919 8916 break; 8920 8917 8921 case 71 5:8922 8923 /* Line 1806 of yacc.c */ 8924 #line 272 7"parser.yy"8918 case 719: 8919 8920 /* Line 1806 of yacc.c */ 8921 #line 2729 "parser.yy" 8925 8922 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 8926 8923 break; 8927 8924 8928 case 716:8929 8930 /* Line 1806 of yacc.c */8931 #line 2729 "parser.yy"8932 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }8933 break;8934 8935 case 717:8936 8937 /* Line 1806 of yacc.c */8938 #line 2731 "parser.yy"8939 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }8940 break;8941 8942 case 718:8943 8944 /* Line 1806 of yacc.c */8945 #line 2733 "parser.yy"8946 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }8947 break;8948 8949 case 719:8950 8951 /* Line 1806 of yacc.c */8952 #line 2735 "parser.yy"8953 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }8954 break;8955 8956 8925 case 720: 8957 8926 8958 8927 /* Line 1806 of yacc.c */ 8928 #line 2736 "parser.yy" 8929 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8930 break; 8931 8932 case 721: 8933 8934 /* Line 1806 of yacc.c */ 8935 #line 2738 "parser.yy" 8936 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); } 8937 break; 8938 8939 case 722: 8940 8941 /* Line 1806 of yacc.c */ 8942 #line 2740 "parser.yy" 8943 { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8944 break; 8945 8946 case 723: 8947 8948 /* Line 1806 of yacc.c */ 8959 8949 #line 2742 "parser.yy" 8960 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false) ); }8961 break; 8962 8963 case 72 1:8950 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); } 8951 break; 8952 8953 case 724: 8964 8954 8965 8955 /* Line 1806 of yacc.c */ … … 8968 8958 break; 8969 8959 8970 case 722: 8971 8972 /* Line 1806 of yacc.c */ 8973 #line 2746 "parser.yy" 8960 case 725: 8961 8962 /* Line 1806 of yacc.c */ 8963 #line 2747 "parser.yy" 8964 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8965 break; 8966 8967 case 726: 8968 8969 /* Line 1806 of yacc.c */ 8970 #line 2749 "parser.yy" 8971 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); } 8972 break; 8973 8974 case 727: 8975 8976 /* Line 1806 of yacc.c */ 8977 #line 2751 "parser.yy" 8974 8978 { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8975 8979 break; 8976 8980 8977 case 72 3:8978 8979 /* Line 1806 of yacc.c */ 8980 #line 27 48"parser.yy"8981 case 728: 8982 8983 /* Line 1806 of yacc.c */ 8984 #line 2753 "parser.yy" 8981 8985 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); } 8982 8986 break; 8983 8987 8984 case 724: 8985 8986 /* Line 1806 of yacc.c */ 8987 #line 2750 "parser.yy" 8988 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); } 8989 break; 8990 8991 case 725: 8992 8993 /* Line 1806 of yacc.c */ 8994 #line 2753 "parser.yy" 8995 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 8996 break; 8997 8998 case 726: 8988 case 729: 8999 8989 9000 8990 /* Line 1806 of yacc.c */ … … 9003 8993 break; 9004 8994 9005 case 727: 9006 9007 /* Line 1806 of yacc.c */ 9008 #line 2757 "parser.yy" 9009 { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 9010 break; 9011 9012 case 728: 9013 9014 /* Line 1806 of yacc.c */ 9015 #line 2759 "parser.yy" 9016 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); } 9017 break; 9018 9019 case 729: 9020 9021 /* Line 1806 of yacc.c */ 9022 #line 2761 "parser.yy" 8995 case 730: 8996 8997 /* Line 1806 of yacc.c */ 8998 #line 2760 "parser.yy" 8999 { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); } 9000 break; 9001 9002 case 731: 9003 9004 /* Line 1806 of yacc.c */ 9005 #line 2762 "parser.yy" 9006 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); } 9007 break; 9008 9009 case 732: 9010 9011 /* Line 1806 of yacc.c */ 9012 #line 2767 "parser.yy" 9013 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); } 9014 break; 9015 9016 case 733: 9017 9018 /* Line 1806 of yacc.c */ 9019 #line 2769 "parser.yy" 9020 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); } 9021 break; 9022 9023 case 735: 9024 9025 /* Line 1806 of yacc.c */ 9026 #line 2796 "parser.yy" 9027 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 9028 break; 9029 9030 case 739: 9031 9032 /* Line 1806 of yacc.c */ 9033 #line 2807 "parser.yy" 9034 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9035 break; 9036 9037 case 740: 9038 9039 /* Line 1806 of yacc.c */ 9040 #line 2809 "parser.yy" 9041 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9042 break; 9043 9044 case 741: 9045 9046 /* Line 1806 of yacc.c */ 9047 #line 2811 "parser.yy" 9048 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9049 break; 9050 9051 case 742: 9052 9053 /* Line 1806 of yacc.c */ 9054 #line 2813 "parser.yy" 9055 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9056 break; 9057 9058 case 743: 9059 9060 /* Line 1806 of yacc.c */ 9061 #line 2815 "parser.yy" 9062 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9063 break; 9064 9065 case 744: 9066 9067 /* Line 1806 of yacc.c */ 9068 #line 2817 "parser.yy" 9069 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9070 break; 9071 9072 case 745: 9073 9074 /* Line 1806 of yacc.c */ 9075 #line 2824 "parser.yy" 9076 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); } 9077 break; 9078 9079 case 746: 9080 9081 /* Line 1806 of yacc.c */ 9082 #line 2826 "parser.yy" 9083 { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); } 9084 break; 9085 9086 case 747: 9087 9088 /* Line 1806 of yacc.c */ 9089 #line 2828 "parser.yy" 9023 9090 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); } 9024 9091 break; 9025 9092 9026 case 730: 9027 9028 /* Line 1806 of yacc.c */ 9029 #line 2766 "parser.yy" 9030 { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); } 9031 break; 9032 9033 case 731: 9034 9035 /* Line 1806 of yacc.c */ 9036 #line 2768 "parser.yy" 9037 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); } 9038 break; 9039 9040 case 732: 9041 9042 /* Line 1806 of yacc.c */ 9043 #line 2773 "parser.yy" 9044 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); } 9045 break; 9046 9047 case 733: 9048 9049 /* Line 1806 of yacc.c */ 9050 #line 2775 "parser.yy" 9051 { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); } 9052 break; 9053 9054 case 735: 9055 9056 /* Line 1806 of yacc.c */ 9057 #line 2802 "parser.yy" 9058 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); } 9059 break; 9060 9061 case 739: 9062 9063 /* Line 1806 of yacc.c */ 9064 #line 2813 "parser.yy" 9065 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9066 break; 9067 9068 case 740: 9069 9070 /* Line 1806 of yacc.c */ 9071 #line 2815 "parser.yy" 9072 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9073 break; 9074 9075 case 741: 9076 9077 /* Line 1806 of yacc.c */ 9078 #line 2817 "parser.yy" 9079 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9080 break; 9081 9082 case 742: 9083 9084 /* Line 1806 of yacc.c */ 9085 #line 2819 "parser.yy" 9086 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9087 break; 9088 9089 case 743: 9090 9091 /* Line 1806 of yacc.c */ 9092 #line 2821 "parser.yy" 9093 { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 9094 break; 9095 9096 case 744: 9097 9098 /* Line 1806 of yacc.c */ 9099 #line 2823 "parser.yy" 9100 { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); } 9101 break; 9102 9103 case 745: 9093 case 748: 9104 9094 9105 9095 /* Line 1806 of yacc.c */ … … 9108 9098 break; 9109 9099 9110 case 74 6:9100 case 749: 9111 9101 9112 9102 /* Line 1806 of yacc.c */ … … 9115 9105 break; 9116 9106 9117 case 7 47:9107 case 750: 9118 9108 9119 9109 /* Line 1806 of yacc.c */ … … 9122 9112 break; 9123 9113 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 9145 9114 case 751: 9146 9115 9147 9116 /* Line 1806 of yacc.c */ 9148 #line 28 45"parser.yy"9117 #line 2839 "parser.yy" 9149 9118 { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); } 9150 9119 break; … … 9153 9122 9154 9123 /* Line 1806 of yacc.c */ 9155 #line 28 52"parser.yy"9124 #line 2846 "parser.yy" 9156 9125 { (yyval.decl) = DeclarationNode::newFunction( nullptr, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), nullptr ); } 9157 9126 break; … … 9160 9129 9161 9130 /* Line 1806 of yacc.c */ 9162 #line 28 54"parser.yy"9131 #line 2848 "parser.yy" 9163 9132 { (yyval.decl) = DeclarationNode::newFunction( nullptr, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), nullptr ); } 9164 9133 break; … … 9167 9136 9168 9137 /* Line 1806 of yacc.c */ 9169 #line 287 8"parser.yy"9138 #line 2872 "parser.yy" 9170 9139 { (yyval.en) = 0; } 9171 9140 break; … … 9174 9143 9175 9144 /* Line 1806 of yacc.c */ 9176 #line 28 80"parser.yy"9145 #line 2874 "parser.yy" 9177 9146 { (yyval.en) = (yyvsp[(2) - (2)].en); } 9178 9147 break; … … 9181 9150 9182 9151 /* Line 1806 of yacc.c */ 9183 #line 91 84"Parser/parser.cc"9152 #line 9153 "Parser/parser.cc" 9184 9153 default: break; 9185 9154 } … … 9412 9381 9413 9382 /* Line 2067 of yacc.c */ 9414 #line 28 83"parser.yy"9383 #line 2877 "parser.yy" 9415 9384 9416 9385 // ----end of grammar---- -
src/Parser/parser.yy
r1f44196 r3a2128f 199 199 200 200 %type<decl> field_declaration field_declaration_list field_declarator field_declaring_list 201 %type<en> field field_list field_name fraction_constants 201 %type<en> field field_list 202 %type<tok> field_name 202 203 203 204 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 383 384 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 384 385 | 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 ) ) ); }388 387 | postfix_expression ARROW no_attr_identifier 389 388 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 390 389 | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector 391 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }392 390 | postfix_expression ICR 393 391 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); } … … 423 421 field: // CFA, tuple field selector 424 422 field_name 423 { $$ = new ExpressionNode( build_varref( $1 ) ); } 425 424 | REALDECIMALconstant field 426 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2) ) ); }425 { $$ = new ExpressionNode( build_fieldSel( $2, build_varref( $1 ) ) ); } 427 426 | REALDECIMALconstant '[' push field_list pop ']' 428 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), build_tuple( $4) ) ); }427 { $$ = new ExpressionNode( build_fieldSel( $4, build_varref( $1 ) ) ); } 429 428 | field_name '.' field 430 { $$ = new ExpressionNode( build_fieldSel( $ 1, maybeMoveBuild<Expression>( $3) ) ); }429 { $$ = new ExpressionNode( build_fieldSel( $3, build_varref( $1 ) ) ); } 431 430 | field_name '.' '[' push field_list pop ']' 432 { $$ = new ExpressionNode( build_fieldSel( $ 1, build_tuple( $5) ) ); }431 { $$ = new ExpressionNode( build_fieldSel( $5, build_varref( $1 ) ) ); } 433 432 | field_name ARROW field 434 { $$ = new ExpressionNode( build_pfieldSel( $ 1, maybeMoveBuild<Expression>( $3) ) ); }433 { $$ = new ExpressionNode( build_pfieldSel( $3, build_varref( $1 ) ) ); } 435 434 | field_name ARROW '[' push field_list pop ']' 436 { $$ = new ExpressionNode( build_pfieldSel( $ 1, build_tuple( $5) ) ); }435 { $$ = new ExpressionNode( build_pfieldSel( $5, build_varref( $1 ) ) ); } 437 436 ; 438 437 439 438 field_name: 440 439 INTEGERconstant fraction_constants 441 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }440 { $$ = $1; } 442 441 | FLOATINGconstant fraction_constants 443 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }442 { $$ = $1; } 444 443 | no_attr_identifier fraction_constants 445 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); }444 { $$ = $1; } 446 445 ; 447 446 448 447 fraction_constants: 449 448 // empty 450 { $$ = nullptr; }451 449 | 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 }456 450 ; 457 451 -
src/ResolvExpr/Alternative.cc
r1f44196 r3a2128f 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() : cost( Cost::zero ), cvtCost( Cost::zero ),expr( 0 ) {}22 Alternative::Alternative() : 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;52 37 return *this; 53 38 } … … 69 54 expr->print( os, indent ); 70 55 os << "(types:" << std::endl; 71 os << std::string( indent+4, ' ' ); 72 expr->get_result()->print( os, indent + 4 ); 73 os << std::endl << ")" << std::endl; 56 printAll( expr->get_results(), os, indent + 4 ); 57 os << ")" << std::endl; 74 58 } else { 75 59 os << "Null expression!" << std::endl; -
src/ResolvExpr/Alternative.h
r1f44196 r3a2128f 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 );36 34 ~Alternative(); 37 35 38 36 void initialize( const Alternative &src, Alternative &dest ); 39 37 40 38 void print( std::ostream &os, int indent = 0 ) const; 41 39 42 40 Cost cost; 43 41 Cost cvtCost; -
src/ResolvExpr/AlternativeFinder.cc
r1f44196 r3a2128f 38 38 #include "SynTree/TypeSubstitution.h" 39 39 #include "SymTab/Validate.h" 40 #include "Tuples/Tuple s.h"41 #include "Tuples/ Explode.h"40 #include "Tuples/TupleAssignment.h" 41 #include "Tuples/NameMatcher.h" 42 42 #include "Common/utility.h" 43 43 #include "InitTweak/InitTweak.h" 44 #include "InitTweak/GenInit.h"45 44 #include "ResolveTypeof.h" 46 45 … … 65 64 } 66 65 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 75 66 namespace { 76 67 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) { … … 85 76 out.push_back( i->expr->clone() ); 86 77 } 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; 87 86 } 88 87 … … 102 101 PruneStruct current( candidate ); 103 102 std::string mangleName; 104 {105 Type * newType = candidate->expr->get_result()->clone();103 for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) { 104 Type *newType = (*retType)->clone(); 106 105 candidate->env.apply( newType ); 107 mangleName = SymTab::Mangler::mangle( newType );106 mangleName += SymTab::Mangler::mangle( newType ); 108 107 delete newType; 109 108 } … … 134 133 if ( ! target->second.isAmbiguous ) { 135 134 Alternative &alt = *target->second.candidate; 136 alt.env.applyFree( alt.expr->get_result() ); 135 for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) { 136 alt.env.applyFree( *result ); 137 } 137 138 *out++ = alt; 138 139 } 139 140 } 141 142 } 143 144 template< typename InputIterator, typename OutputIterator > 145 void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) { 146 AltList alternatives; 147 148 // select the alternatives that have the minimum parameter cost 149 Cost minCost = Cost::infinity; 150 for ( AltList::iterator i = begin; i != end; ++i ) { 151 if ( i->cost < minCost ) { 152 minCost = i->cost; 153 i->cost = i->cvtCost; 154 alternatives.clear(); 155 alternatives.push_back( *i ); 156 } else if ( i->cost == minCost ) { 157 i->cost = i->cvtCost; 158 alternatives.push_back( *i ); 159 } 160 } 161 std::copy( alternatives.begin(), alternatives.end(), out ); 162 } 163 164 template< typename InputIterator > 165 void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) { 166 while ( begin != end ) { 167 result.simpleCombine( (*begin++).env ); 168 } 140 169 } 141 170 142 171 void renameTypes( Expression *expr ) { 143 expr->get_result()->accept( global_renamer ); 172 for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 173 (*i)->accept( global_renamer ); 174 } 144 175 } 145 176 } … … 173 204 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) { 174 205 if ( adjust ) { 175 adjustExprType ( i->expr->get_result(), i->env, indexer );206 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer ); 176 207 } 177 208 } … … 209 240 } 210 241 211 // std::unordered_map< Expression *, UniqueExpr * > ;212 213 242 template< typename StructOrUnionType > 214 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 215 // by this point, member must be a name expr 216 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member ); 217 const std::string & name = nameExpr->get_name(); 243 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) { 218 244 std::list< Declaration* > members; 219 245 aggInst->lookup( name, members ); … … 228 254 } 229 255 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 meaning233 // xxx - this should be improved by memoizing the value of constant exprs234 // 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 } // if242 } // if243 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {244 // xxx - temporary hack until 0/1 are int constants245 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 } // if252 }253 254 256 void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) { 255 257 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); … … 257 259 258 260 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 259 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr ); 260 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 261 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 261 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr ); 262 assert( appExpr ); 263 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 264 assert( pointer ); 265 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 266 assert( function ); 262 267 263 268 Cost convCost( 0, 0, 0 ); … … 265 270 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 266 271 std::list< Expression* >& actuals = appExpr->get_args(); 267 268 std::list< Type * > formalTypes;269 std::list< Type * >::iterator formalType = formalTypes.end();270 271 272 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 (*actualExpr)->get_result()->print(std::cerr, 8 );277 printAll( (*actualExpr)->get_results(), std::cerr, 8 ); 278 278 ) 279 279 std::list< DeclarationWithType* >::iterator startFormal = formal; 280 280 Cost actualCost; 281 std::list< Type * > flatActualTypes; 282 flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) ); 283 for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) { 284 285 286 // tuple handling code 287 if ( formalType == formalTypes.end() ) { 288 // the type of the formal parameter may be a tuple type. To make this easier to work with, 289 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 290 // iterator once its types have been extracted. Once a particular formal parameter's type has 291 // been exhausted load the next formal parameter's type. 292 if ( formal == formals.end() ) { 293 if ( function->get_isVarArgs() ) { 294 convCost += Cost( 1, 0, 0 ); 295 break; 296 } else { 297 return Cost::infinity; 298 } 281 for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) { 282 if ( formal == formals.end() ) { 283 if ( function->get_isVarArgs() ) { 284 convCost += Cost( 1, 0, 0 ); 285 break; 286 } else { 287 return Cost::infinity; 299 288 } 300 formalTypes.clear();301 flatten( (*formal)->get_type(), back_inserter( formalTypes ) );302 formalType = formalTypes.begin();303 ++formal;304 289 } 305 306 290 PRINT( 307 291 std::cerr << std::endl << "converting "; 308 (*actual Type)->print( std::cerr, 8 );292 (*actual)->print( std::cerr, 8 ); 309 293 std::cerr << std::endl << " to "; 310 294 (*formal)->get_type()->print( std::cerr, 8 ); 311 295 ) 312 Cost newCost = conversionCost( *actual Type, *formalType, indexer, alt.env );296 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env ); 313 297 PRINT( 314 298 std::cerr << std::endl << "cost is" << newCost << std::endl; … … 321 305 actualCost += newCost; 322 306 323 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );324 325 formal Type++;307 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 ); 308 309 formal++; 326 310 } 327 311 if ( actualCost != Cost( 0, 0, 0 ) ) { … … 372 356 /// Adds type variables to the open variable set and marks their assertions 373 357 void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) { 374 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {358 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 375 359 unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind(); 376 360 for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { … … 381 365 } 382 366 383 /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType, 384 /// producing expression(s) in out and their total cost in cost. 385 template< typename AltIterator, typename OutputIterator > 386 bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) { 387 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) { 388 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType 389 TupleExpr * tupleExpr = new TupleExpr(); 390 for ( Type * type : *tupleType ) { 391 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) { 392 delete tupleExpr; 393 return false; 394 } 395 } 396 tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) ); 397 *out++ = tupleExpr; 398 } else if ( actualIt != actualEnd ) { 399 // both actualType and formalType are atomic (non-tuple) types - if they unify 400 // then accept actual as an argument, otherwise return false (fail to instantiate argument) 401 Expression * actual = actualIt->expr; 402 Type * actualType = actual->get_result(); 403 PRINT( 404 std::cerr << "formal type is "; 405 formalType->print( std::cerr ); 406 std::cerr << std::endl << "actual type is "; 407 actualType->print( std::cerr ); 408 std::cerr << std::endl; 409 ) 410 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 411 return false; 412 } 413 // move the expression from the alternative to the output iterator 414 *out++ = actual; 415 actualIt->expr = nullptr; 416 cost += actualIt->cost; 417 ++actualIt; 418 } else { 419 // End of actuals - Handle default values 420 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) { 421 // so far, only constant expressions are accepted as default values 422 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) { 423 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) { 424 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 425 // xxx - Don't know if this is right 426 *out++ = cnstexpr->clone(); 427 return true; 428 } // if 429 } // if 430 } // if 431 } // if 432 return false; 433 } // if 434 return true; 435 } 436 437 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) { 367 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) { 438 368 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv ); 439 369 // make sure we don't widen any existing bindings … … 443 373 resultEnv.extractOpenVars( openVars ); 444 374 445 // flatten actuals so that each actual has an atomic (non-tuple) type 446 AltList exploded; 447 Tuples::explode( actuals, indexer, back_inserter( exploded ) ); 448 449 AltList::iterator actualExpr = exploded.begin(); 450 AltList::iterator actualEnd = exploded.end(); 451 for ( DeclarationWithType * formal : formals ) { 452 // match flattened actuals with formal parameters - actuals will be grouped to match 453 // with formals as appropriate 454 Cost cost; 455 std::list< Expression * > newExprs; 456 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); 457 if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) { 458 deleteAll( newExprs ); 459 return false; 460 } 461 // success - produce argument as a new alternative 462 assert( newExprs.size() == 1 ); 463 out.push_back( Alternative( newExprs.front(), resultEnv, cost ) ); 464 } 465 if ( actualExpr != actualEnd ) { 466 // there are still actuals remaining, but we've run out of formal parameters to match against 467 // this is okay only if the function is variadic 468 if ( ! isVarArgs ) { 469 return false; 470 } 471 out.splice( out.end(), exploded, actualExpr, actualEnd ); 375 /* 376 Tuples::NameMatcher matcher( formals ); 377 try { 378 matcher.match( actuals ); 379 } catch ( Tuples::NoMatch &e ) { 380 std::cerr << "Alternative doesn't match: " << e.message << std::endl; 381 } 382 */ 383 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 384 for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 385 for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) { 386 if ( formal == formals.end() ) { 387 return isVarArgs; 388 } 389 PRINT( 390 std::cerr << "formal type is "; 391 (*formal)->get_type()->print( std::cerr ); 392 std::cerr << std::endl << "actual type is "; 393 (*actual)->print( std::cerr ); 394 std::cerr << std::endl; 395 ) 396 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 397 return false; 398 } 399 formal++; 400 } 401 } 402 // Handling of default values 403 while ( formal != formals.end() ) { 404 if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) ) 405 if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() )) 406 // so far, only constant expressions are accepted as default values 407 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) 408 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) 409 if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 410 // XXX Don't know if this is right 411 actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) ); 412 formal++; 413 if ( formal == formals.end()) break; 414 } 415 return false; 472 416 } 473 417 return true; … … 556 500 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 557 501 Expression *varExpr = new VariableExpr( candDecl ); 558 delete varExpr->get_result(); 559 varExpr->set_result( adjType->clone() ); 502 deleteAll( varExpr->get_results() ); 503 varExpr->get_results().clear(); 504 varExpr->get_results().push_front( adjType->clone() ); 560 505 PRINT( 561 506 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; … … 600 545 601 546 template< typename OutputIterator > 602 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, constAltList &actualAlt, OutputIterator out ) {547 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) { 603 548 OpenVarSet openVars; 604 549 AssertionSet resultNeed, resultHave; 605 550 TypeEnvironment resultEnv; 606 551 makeUnifiableVars( funcType, openVars, resultNeed ); 607 AltList instantiatedActuals; // filled by instantiate function 608 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 552 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) { 609 553 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 610 Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals) );611 makeExprList( instantiatedActuals, appExpr->get_args() );554 Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) ); 555 makeExprList( actualAlt, appExpr->get_args() ); 612 556 PRINT( 613 557 std::cerr << "need assertions:" << std::endl; … … 630 574 PointerType pt( Type::Qualifiers(), v.clone() ); 631 575 UntypedExpr *vexpr = untypedExpr->clone(); 632 vexpr-> set_result( pt.clone() );576 vexpr->get_results().push_front( pt.clone() ); 633 577 alternatives.push_back( Alternative( vexpr, env, Cost()) ); 634 578 return; … … 643 587 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 644 588 645 // take care of possible tuple assignments 646 // if not tuple assignment, assignment is taken care of as a normal function call 647 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities ); 589 Tuples::TupleAssignSpotter tassign( this ); 590 if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) { 591 // take care of possible tuple assignments, or discard expression 592 return; 593 } // else ... 648 594 649 595 AltList candidates; … … 658 604 // check if the type is pointer to function 659 605 PointerType *pointer; 660 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {606 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) { 661 607 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 662 608 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 694 640 // check if the type is pointer to function 695 641 PointerType *pointer; 696 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) { 642 if ( funcOp->expr->get_results().size() == 1 643 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) { 697 644 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 698 645 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 718 665 719 666 PRINT( 720 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr ); 721 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 722 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 667 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr ); 668 assert( appExpr ); 669 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 670 assert( pointer ); 671 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 672 assert( function ); 723 673 std::cerr << "Case +++++++++++++" << std::endl; 724 674 std::cerr << "formals are:" << std::endl; … … 742 692 743 693 bool isLvalue( Expression *expr ) { 744 // xxx - recurse into tuples? 745 return expr->has_result() && expr->get_result()->get_isLvalue(); 694 for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 695 if ( !(*i)->get_isLvalue() ) return false; 696 } // for 697 return true; 746 698 } 747 699 … … 757 709 758 710 void AlternativeFinder::visit( CastExpr *castExpr ) { 759 Type *& toType = castExpr->get_result(); 760 toType = resolveTypeof( toType, indexer ); 761 SymTab::validateType( toType, &indexer ); 762 adjustExprType( toType, env, indexer ); 711 for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) { 712 *i = resolveTypeof( *i, indexer ); 713 SymTab::validateType( *i, &indexer ); 714 adjustExprType( *i, env, indexer ); 715 } // for 763 716 764 717 AlternativeFinder finder( indexer, env ); … … 774 727 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 775 728 // to. 776 int discardedValues = (*i).expr->get_result ()->size() - castExpr->get_result()->size();729 int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size(); 777 730 if ( discardedValues < 0 ) continue; 778 // xxx - may need to go into tuple types and extract relavent types and use unifyList 731 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 732 std::advance( candidate_end, castExpr->get_results().size() ); 779 733 // unification run for side-effects 780 unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 781 Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env ); 734 unifyList( castExpr->get_results().begin(), castExpr->get_results().end(), 735 (*i).expr->get_results().begin(), candidate_end, 736 i->env, needAssertions, haveAssertions, openVars, indexer ); 737 Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end, 738 castExpr->get_results().begin(), castExpr->get_results().end(), 739 indexer, i->env ); 782 740 if ( thisCost != Cost::infinity ) { 783 741 // count one safe conversion for each value that is thrown away … … 802 760 803 761 for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) { 804 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() )) {805 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );806 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {807 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );808 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {809 addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() );762 if ( agg->expr->get_results().size() == 1 ) { 763 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) { 764 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 765 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) { 766 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 767 } // if 810 768 } // if 811 769 } // for … … 833 791 renameTypes( alternatives.back().expr ); 834 792 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) { 835 NameExpr nameExpr( "" ); 836 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 793 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 837 794 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) { 838 NameExpr nameExpr( "" ); 839 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 795 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 840 796 } // if 841 797 } // for … … 938 894 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 939 895 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 940 alternatives.back().expr-> set_result( (*i)->get_type()->clone() );896 alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() ); 941 897 } // for 942 898 } // if … … 961 917 finder.find( attrExpr->get_expr() ); 962 918 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 963 if ( choice->expr->get_result ()->size() == 1 ) {964 resolveAttr(*i, function, choice->expr->get_result (), choice->env );919 if ( choice->expr->get_results().size() == 1 ) { 920 resolveAttr(*i, function, choice->expr->get_results().front(), choice->env ); 965 921 } // fi 966 922 } // for … … 1004 960 AssertionSet needAssertions, haveAssertions; 1005 961 Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost ); 1006 Type* commonType = nullptr;1007 if ( unify ( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType) ) {962 std::list< Type* > commonTypes; 963 if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) { 1008 964 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() ); 1009 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 965 std::list< Type* >::const_iterator original = second->expr->get_results().begin(); 966 std::list< Type* >::const_iterator commonType = commonTypes.begin(); 967 for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) { 968 if ( *commonType ) { 969 newExpr->get_results().push_back( *commonType ); 970 } else { 971 newExpr->get_results().push_back( (*original)->clone() ); 972 } // if 973 } // for 1010 974 newAlt.expr = newExpr; 1011 975 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); … … 1035 999 TupleExpr *newExpr = new TupleExpr; 1036 1000 makeExprList( *i, newExpr->get_exprs() ); 1037 newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) ); 1001 for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) { 1002 for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) { 1003 newExpr->get_results().push_back( (*resultType)->clone() ); 1004 } // for 1005 } // for 1038 1006 1039 1007 TypeEnvironment compositeEnv; … … 1056 1024 } 1057 1025 } 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 1077 1026 } // namespace ResolvExpr 1078 1027 -
src/ResolvExpr/AlternativeFinder.h
r1f44196 r3a2128f 67 67 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ); 68 68 virtual void visit( ConstructorExpr * ctorExpr ); 69 virtual void visit( TupleIndexExpr *tupleExpr ); 70 virtual void visit( TupleAssignExpr *tupleExpr ); 71 virtual void visit( UniqueExpr *unqExpr ); 72 /// Runs a new alternative finder on each element in [begin, end) 73 /// and writes each alternative finder to out. 69 public: // xxx - temporary hack - should make Tuples::TupleAssignment a friend 74 70 template< typename InputIterator, typename OutputIterator > 75 71 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 76 72 73 private: 77 74 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 78 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 79 /// Adds alternatives for member expressions where the left side has tuple type 80 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 75 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ); 81 76 /// Adds alternatives for offsetof expressions, given the base type and name of the member 82 77 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 83 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out);78 bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ); 84 79 template< typename OutputIterator > 85 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, constAltList &actualAlt, OutputIterator out );80 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ); 86 81 template< typename OutputIterator > 87 82 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); … … 94 89 95 90 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 cost102 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 }125 91 } // namespace ResolvExpr 126 92 -
src/ResolvExpr/AlternativePrinter.cc
r1f44196 r3a2128f 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 i->expr->get_result()->print(os );35 printAll( i->expr->get_results(), os ); 36 36 // i->print( os ); 37 37 os << std::endl; -
src/ResolvExpr/ConversionCost.cc
r1f44196 r3a2128f 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() && destIt != destAsTuple->get_types().end()) {242 while ( srcIt != tupleType->get_types().end() ) { 243 243 Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env ); 244 244 if ( newCost == Cost::infinity ) { -
src/ResolvExpr/FindOpenVars.cc
r1f44196 r3a2128f 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 ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {49 for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 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 ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {58 for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 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
r1f44196 r3a2128f 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 ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {127 for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 128 128 std::ostringstream output; 129 129 output << "_" << level << "_" << (*i)->get_name(); -
src/ResolvExpr/ResolveTypeof.cc
r1f44196 r3a2128f 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->has_result() && ! newExpr->get_result()->isVoid() ); 61 Type *newType = newExpr->get_result(); 60 assert( newExpr->get_results().size() > 0 ); 61 Type *newType; 62 if ( newExpr->get_results().size() > 1 ) { 63 TupleType *tupleType = new TupleType( Type::Qualifiers() ); 64 cloneAll( newExpr->get_results(), tupleType->get_types() ); 65 newType = tupleType; 66 } else { 67 newType = newExpr->get_results().front()->clone(); 68 } // if 62 69 delete typeofType; 63 70 return newType; -
src/ResolvExpr/Resolver.cc
r1f44196 r3a2128f 19 19 #include "RenameVars.h" 20 20 #include "ResolveTypeof.h" 21 #include "typeops.h"22 21 #include "SynTree/Statement.h" 23 22 #include "SynTree/Type.h" … … 69 68 void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & ); 70 69 void fallbackInit( ConstructorInit * ctorInit ); 71 72 Type * functionReturn = nullptr; 73 Type *initContext = nullptr; 70 std::list< Type * > functionReturn; 71 Type *initContext; 74 72 bool inEnumDecl = false; 75 73 }; … … 159 157 const TypeEnvironment *newEnv = 0; 160 158 for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 161 if ( i->expr->get_result ()->size() == 1 && isIntegralType( i->expr->get_result() ) ) {159 if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) { 162 160 if ( newExpr ) { 163 161 throw SemanticError( "Too many interpretations for case control expression", untyped ); … … 236 234 Type *new_type = resolveTypeof( functionDecl->get_type(), *this ); 237 235 functionDecl->set_type( new_type ); 238 ValueGuard< Type * > oldFunctionReturn( functionReturn ); 239 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 236 std::list< Type * > oldFunctionReturn = functionReturn; 237 functionReturn.clear(); 238 for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) { 239 functionReturn.push_back( (*i)->get_type() ); 240 } // for 240 241 SymTab::Indexer::visit( functionDecl ); 242 functionReturn = oldFunctionReturn; 241 243 } 242 244 … … 336 338 void Resolver::visit( ReturnStmt *returnStmt ) { 337 339 if ( returnStmt->get_expr() ) { 338 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 340 CastExpr *castExpr = new CastExpr( returnStmt->get_expr() ); 341 cloneAll( functionReturn, castExpr->get_results() ); 339 342 Expression *newExpr = findSingleExpression( castExpr, *this ); 340 343 delete castExpr; … … 381 384 if ( isCharType( at->get_base() ) ) { 382 385 // check if the resolved type is char * 383 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result () ) ) {386 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) { 384 387 if ( isCharType( pt->get_base() ) ) { 385 388 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; … … 443 446 (*iter)->accept( *this ); 444 447 } // 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 }451 448 } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) { 452 449 resolveAggrInit( st->get_baseStruct(), iter, end ); -
src/ResolvExpr/TypeEnvironment.cc
r1f44196 r3a2128f 158 158 } 159 159 160 void TypeEnvironment::add( const Type::ForallList&tyDecls ) {161 for ( Type::ForallList::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {160 void TypeEnvironment::add( const std::list< TypeDecl* > &tyDecls ) { 161 for ( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) { 162 162 EqvClass newClass; 163 163 newClass.vars.insert( (*i)->get_name() ); -
src/ResolvExpr/TypeEnvironment.h
r1f44196 r3a2128f 55 55 bool lookup( const std::string &var, EqvClass &eqvClass ) const; 56 56 void add( const EqvClass &eqvClass ); 57 void add( const Type::ForallList&tyDecls );57 void add( const std::list< TypeDecl* > &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
r1f44196 r3a2128f 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 } // for610 return tupleType;611 }612 }613 599 } // namespace ResolvExpr 614 600 -
src/ResolvExpr/typeops.h
r1f44196 r3a2128f 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 149 146 // in CommonType.cc 150 147 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); … … 155 152 // in Occurs.cc 156 153 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 157 158 // flatten tuple type into list of types159 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 }169 154 } // namespace ResolvExpr 170 155 -
src/SymTab/Autogen.cc
r1f44196 r3a2128f 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_result();118 Type *& assignVarExprType = assignVarExpr->get_results().front(); 119 119 assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType ); 120 assignVarExpr->set_result( assignVarExprType );121 120 ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr ); 122 121 assignExpr->get_args().push_back( new VariableExpr( dstParam ) ); -
src/SymTab/Indexer.cc
r1f44196 r3a2128f 40 40 41 41 namespace SymTab { 42 template< typename TreeType, typename VisitorType >43 inline void accept NewScope( TreeType *tree, VisitorType &visitor ) {42 template< typename Container, typename VisitorType > 43 inline void acceptAllNewScope( Container &container, VisitorType &visitor ) { 44 44 visitor.enterScope(); 45 maybeAccept( tree, visitor );45 acceptAll( container, 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 * > ¶ms = 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 NewScope( applicationExpr->get_result(), *this );339 acceptAllNewScope( applicationExpr->get_results(), *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 NewScope( untypedExpr->get_result(), *this );345 acceptAllNewScope( untypedExpr->get_results(), *this ); 346 346 acceptAll( untypedExpr->get_args(), *this ); 347 347 } 348 348 349 349 void Indexer::visit( NameExpr *nameExpr ) { 350 accept NewScope( nameExpr->get_result(), *this );350 acceptAllNewScope( nameExpr->get_results(), *this ); 351 351 } 352 352 353 353 void Indexer::visit( AddressExpr *addressExpr ) { 354 accept NewScope( addressExpr->get_result(), *this );354 acceptAllNewScope( addressExpr->get_results(), *this ); 355 355 maybeAccept( addressExpr->get_arg(), *this ); 356 356 } 357 357 358 358 void Indexer::visit( LabelAddressExpr *labAddressExpr ) { 359 accept NewScope( labAddressExpr->get_result(), *this );359 acceptAllNewScope( labAddressExpr->get_results(), *this ); 360 360 maybeAccept( labAddressExpr->get_arg(), *this ); 361 361 } 362 362 363 363 void Indexer::visit( CastExpr *castExpr ) { 364 accept NewScope( castExpr->get_result(), *this );364 acceptAllNewScope( castExpr->get_results(), *this ); 365 365 maybeAccept( castExpr->get_arg(), *this ); 366 366 } 367 367 368 368 void Indexer::visit( UntypedMemberExpr *memberExpr ) { 369 accept NewScope( memberExpr->get_result(), *this );369 acceptAllNewScope( memberExpr->get_results(), *this ); 370 370 maybeAccept( memberExpr->get_aggregate(), *this ); 371 371 } 372 372 373 373 void Indexer::visit( MemberExpr *memberExpr ) { 374 accept NewScope( memberExpr->get_result(), *this );374 acceptAllNewScope( memberExpr->get_results(), *this ); 375 375 maybeAccept( memberExpr->get_aggregate(), *this ); 376 376 } 377 377 378 378 void Indexer::visit( VariableExpr *variableExpr ) { 379 accept NewScope( variableExpr->get_result(), *this );379 acceptAllNewScope( variableExpr->get_results(), *this ); 380 380 } 381 381 382 382 void Indexer::visit( ConstantExpr *constantExpr ) { 383 accept NewScope( constantExpr->get_result(), *this );383 acceptAllNewScope( constantExpr->get_results(), *this ); 384 384 maybeAccept( constantExpr->get_constant(), *this ); 385 385 } 386 386 387 387 void Indexer::visit( SizeofExpr *sizeofExpr ) { 388 accept NewScope( sizeofExpr->get_result(), *this );388 acceptAllNewScope( sizeofExpr->get_results(), *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 NewScope( alignofExpr->get_result(), *this );397 acceptAllNewScope( alignofExpr->get_results(), *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 NewScope( offsetofExpr->get_result(), *this );406 acceptAllNewScope( offsetofExpr->get_results(), *this ); 407 407 maybeAccept( offsetofExpr->get_type(), *this ); 408 408 } 409 409 410 410 void Indexer::visit( OffsetofExpr *offsetofExpr ) { 411 accept NewScope( offsetofExpr->get_result(), *this );411 acceptAllNewScope( offsetofExpr->get_results(), *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 NewScope( offsetPackExpr->get_result(), *this );417 acceptAllNewScope( offsetPackExpr->get_results(), *this ); 418 418 maybeAccept( offsetPackExpr->get_type(), *this ); 419 419 } 420 420 421 421 void Indexer::visit( AttrExpr *attrExpr ) { 422 accept NewScope( attrExpr->get_result(), *this );422 acceptAllNewScope( attrExpr->get_results(), *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 NewScope( logicalExpr->get_result(), *this );431 acceptAllNewScope( logicalExpr->get_results(), *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 NewScope( conditionalExpr->get_result(), *this );437 acceptAllNewScope( conditionalExpr->get_results(), *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 NewScope( commaExpr->get_result(), *this );444 acceptAllNewScope( commaExpr->get_results(), *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 NewScope( tupleExpr->get_result(), *this );450 acceptAllNewScope( tupleExpr->get_results(), *this ); 451 451 acceptAll( tupleExpr->get_exprs(), *this ); 452 452 } 453 453 454 void Indexer::visit( TupleAssignExpr *tupleExpr ) { 455 acceptNewScope( tupleExpr->get_result(), *this ); 456 enterScope(); 457 acceptAll( tupleExpr->get_tempDecls(), *this ); 458 acceptAll( tupleExpr->get_assigns(), *this ); 459 leaveScope(); 454 void Indexer::visit( SolvedTupleExpr *tupleExpr ) { 455 acceptAllNewScope( tupleExpr->get_results(), *this ); 456 acceptAll( tupleExpr->get_exprs(), *this ); 460 457 } 461 458 462 459 void Indexer::visit( TypeExpr *typeExpr ) { 463 accept NewScope( typeExpr->get_result(), *this );460 acceptAllNewScope( typeExpr->get_results(), *this ); 464 461 maybeAccept( typeExpr->get_type(), *this ); 465 462 } … … 472 469 473 470 void Indexer::visit( UntypedValofExpr *valofExpr ) { 474 accept NewScope( valofExpr->get_result(), *this );471 acceptAllNewScope( valofExpr->get_results(), *this ); 475 472 maybeAccept( valofExpr->get_body(), *this ); 476 473 } -
src/SymTab/Indexer.h
r1f44196 r3a2128f 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 ); 66 68 virtual void visit( TypeExpr *typeExpr ); 67 69 virtual void visit( AsmExpr *asmExpr ); 68 70 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
r1f44196 r3a2128f 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 ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {260 for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 261 261 switch ( (*i)->get_kind() ) { 262 262 case TypeDecl::Any: -
src/SymTab/Validate.cc
r1f44196 r3a2128f 23 23 // - All enumeration constants have type EnumInstType. 24 24 // 25 // - The type "void" never occurs in lists of function parameter or return types . A function26 // taking no arguments has no argument types .25 // - The type "void" never occurs in lists of function parameter or return types; neither do tuple types. A function 26 // taking no arguments has no argument types, and tuples are flattened. 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 // xxx - shouldn't this be declsToAddBefore? 245 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 ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {433 for ( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) { 434 434 std::list< DeclarationWithType * > toBeDone, nextRound; 435 435 toBeDone.splice( toBeDone.end(), (*type )->get_assertions() ); -
src/SynTree/AddressExpr.cc
r1f44196 r3a2128f 19 19 20 20 AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) { 21 if ( arg->has_result()) {22 set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );23 } 21 for ( std::list< Type* >::const_iterator i = arg->get_results().begin(); i != arg->get_results().end(); ++i ) { 22 get_results().push_back( new PointerType( Type::Qualifiers(), (*i)->clone() ) ); 23 } // for 24 24 } 25 25 … … 35 35 if ( arg ) { 36 36 os << std::string( indent+2, ' ' ); 37 arg->print( os, indent+2 );37 arg->print( os, indent+2 ); 38 38 } // if 39 39 } -
src/SynTree/ApplicationExpr.cc
r1f44196 r3a2128f 21 21 #include "TypeSubstitution.h" 22 22 #include "Common/utility.h" 23 #include "ResolvExpr/typeops.h" 23 24 24 25 25 ParamEntry::ParamEntry( const ParamEntry &other ) : … … 43 43 44 44 ApplicationExpr::ApplicationExpr( Expression *funcExpr ) : function( funcExpr ) { 45 PointerType *pointer = safe_dynamic_cast< PointerType* >( funcExpr->get_result() ); 46 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 45 PointerType *pointer = dynamic_cast< PointerType* >( funcExpr->get_results().front() ); 46 assert( pointer ); 47 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 48 assert( function ); 47 49 48 set_result( ResolvExpr::extractResultType( function ) );49 50 assert( has_result() );50 for ( std::list< DeclarationWithType* >::const_iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 51 get_results().push_back( (*i)->get_type()->clone() ); 52 } // for 51 53 } 52 54 -
src/SynTree/CommaExpr.cc
r1f44196 r3a2128f 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 set_result( maybeClone( arg2->get_result() ) ); 26 // get_type->set_isLvalue( false ); 25 cloneAll( arg2->get_results(), get_results() ); 26 // for ( Type *& type : get_results() ) { 27 // type->set_isLvalue( false ); 28 // } 27 29 } 28 30 -
src/SynTree/CompoundStmt.cc
r1f44196 r3a2128f 20 20 #include "Expression.h" 21 21 #include "Declaration.h" 22 #include "SynTree/VarExprReplacer.h"23 22 24 23 using std::string; 25 24 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 map 35 virtual void visit( VariableExpr * varExpr ) { 36 if ( declMap.count( varExpr->get_var() ) ) { 37 varExpr->set_var( declMap.at( varExpr->get_var() ) ); 38 } 39 } 40 }; 41 26 42 27 43 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) { … … 31 47 cloneAll( other.kids, kids ); 32 48 33 // when cloning a compound statement, we may end up cloning declarations which 34 // are referred to by VariableExprs throughout the block. Cloning a VariableExpr 35 // does a shallow copy, so the VariableExpr will end up pointing to the original 36 // declaration. If the original declaration is deleted, e.g. because the original 37 // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case, 38 // find all DeclarationWithType nodes (since a VariableExpr must point to a 39 // DeclarationWithType) in the original CompoundStmt and map them to the cloned 40 // node in the new CompoundStmt ('this'), then replace the Declarations referred to 41 // by each VariableExpr according to the constructed map. Note that only the declarations 42 // in the current level are collected into the map, because child CompoundStmts will 43 // recursively execute this routine. There may be more efficient ways of doing 44 // this. 45 VarExprReplacer::DeclMap declMap; 46 std::list< Statement * >::const_iterator origit = other.kids.begin(); 47 for ( Statement * s : kids ) { 48 assert( origit != other.kids.end() ); 49 Statement * origStmt = *origit++; 50 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) { 51 DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( origStmt ); 52 assert( origDeclStmt ); 53 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) { 54 DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() ); 55 assert( origdwt ); 56 assert( dwt->get_name() == origdwt->get_name() ); 57 declMap[ origdwt ] = dwt; 58 } 59 } 60 } 61 if ( ! declMap.empty() ) { 62 VarExprReplacer replacer( declMap ); 63 accept( replacer ); 64 } 49 // when cloning a compound statement, we may end up cloning declarations which 50 // are referred to by VariableExprs throughout the block. Cloning a VariableExpr 51 // does a shallow copy, so the VariableExpr will end up pointing to the original 52 // declaration. If the original declaration is deleted, e.g. because the original 53 // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case, 54 // find all DeclarationWithType nodes (since a VariableExpr must point to a 55 // DeclarationWithType) in the original CompoundStmt and map them to the cloned 56 // node in the new CompoundStmt ('this'), then replace the Declarations referred to 57 // by each VariableExpr according to the constructed map. Note that only the declarations 58 // in the current level are collected into the map, because child CompoundStmts will 59 // recursively execute this routine. There may be more efficient ways of doing 60 // this. 61 VarExprReplacer::DeclMap declMap; 62 std::list< Statement * >::const_iterator origit = other.kids.begin(); 63 for ( Statement * s : kids ) { 64 assert( origit != other.kids.end() ); 65 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) { 66 DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( *origit ); 67 assert( origDeclStmt ); 68 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) { 69 DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() ); 70 assert( origdwt ); 71 declMap[ origdwt ] = dwt; 72 } 73 } 74 } 75 if ( ! declMap.empty() ) { 76 VarExprReplacer replacer( declMap ); 77 accept( replacer ); 78 } 65 79 } 66 80 -
src/SynTree/Expression.cc
r1f44196 r3a2128f 31 31 32 32 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 ) { 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 ); 36 37 } 37 38 … … 39 40 delete env; 40 41 delete argName; // xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix 41 delete result; 42 deleteAll( results ); 43 } 44 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 42 51 } 43 52 … … 59 68 60 69 ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) { 61 set_result( constant.get_type()->clone() );70 add_result( constant.get_type()->clone() ); 62 71 } 63 72 … … 76 85 assert( var ); 77 86 assert( var->get_type() ); 78 Type * type = var->get_type()->clone(); 79 type->set_isLvalue( true ); 80 set_result( type ); 87 add_result( var->get_type()->clone() ); 88 for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) { 89 (*i)->set_isLvalue( true ); 90 } // for 81 91 } 82 92 … … 100 110 SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) : 101 111 Expression( _aname ), expr(expr_), type(0), isType(false) { 102 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );112 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 103 113 } 104 114 105 115 SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) : 106 116 Expression( _aname ), expr(0), type(type_), isType(true) { 107 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );117 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 108 118 } 109 119 … … 131 141 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) : 132 142 Expression( _aname ), expr(expr_), type(0), isType(false) { 133 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );143 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 134 144 } 135 145 136 146 AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) : 137 147 Expression( _aname ), expr(0), type(type_), isType(true) { 138 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );148 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 139 149 } 140 150 … … 162 172 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) : 163 173 Expression( _aname ), type(type_), member(member_) { 164 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );174 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 165 175 } 166 176 … … 187 197 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) : 188 198 Expression( _aname ), type(type_), member(member_) { 189 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );199 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 190 200 } 191 201 … … 219 229 220 230 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) { 221 set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );231 add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 222 232 } 223 233 … … 274 284 275 285 CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) { 276 set_result(toType);286 add_result(toType); 277 287 } 278 288 279 289 CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) { 280 set_result( new VoidType( Type::Qualifiers() ) );281 290 } 282 291 … … 294 303 arg->print(os, indent+2); 295 304 os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl; 296 os << std::string( indent+2, ' ' ); 297 if ( result->isVoid() ) { 298 os << "nothing"; 305 if ( results.empty() ) { 306 os << std::string( indent+2, ' ' ) << "nothing" << std::endl; 299 307 } else { 300 result->print( os, indent+2);308 printAll(results, os, indent+2); 301 309 } // if 302 os << std::endl; 303 Expression::print( os, indent ); 304 } 305 306 UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) : 310 Expression::print( os, indent ); 311 } 312 313 UntypedMemberExpr::UntypedMemberExpr( std::string _member, Expression *_aggregate, Expression *_aname ) : 307 314 Expression( _aname ), member(_member), aggregate(_aggregate) {} 308 315 309 316 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) : 310 Expression( other ), member( maybeClone( other.member )), aggregate( maybeClone( other.aggregate ) ) {317 Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) { 311 318 } 312 319 313 320 UntypedMemberExpr::~UntypedMemberExpr() { 314 321 delete aggregate; 315 delete member;316 322 } 317 323 318 324 void UntypedMemberExpr::print( std::ostream &os, int indent ) const { 319 os << "Untyped Member Expression, with field: " << std::endl; 320 os << std::string( indent+2, ' ' ); 321 get_member()->print(os, indent+4); 322 os << std::string( indent+2, ' ' ); 325 os << "Untyped Member Expression, with field: " << get_member(); 323 326 324 327 Expression *agg = get_aggregate(); 325 os << " from aggregate: " << std::endl;328 os << ", from aggregate: "; 326 329 if (agg != 0) { 327 os << std::string( indent + 4, ' ' );328 agg->print(os, indent + 4);330 os << std::string( indent + 2, ' ' ); 331 agg->print(os, indent + 2); 329 332 } 330 333 os << std::string( indent+2, ' ' ); … … 335 338 MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) : 336 339 Expression( _aname ), member(_member), aggregate(_aggregate) { 337 set_result( member->get_type()->clone() ); 338 get_result()->set_isLvalue( true ); 340 add_result( member->get_type()->clone() ); 341 for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) { 342 (*i)->set_isLvalue( true ); 343 } // for 339 344 } 340 345 … … 367 372 } 368 373 369 UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) : 370 Expression( _aname ), function(_function), args(_args) {}374 375 UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function ) {} 371 376 372 377 UntypedExpr::UntypedExpr( const UntypedExpr &other ) : … … 375 380 } 376 381 382 UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) : 383 Expression( _aname ), function(_function), args(_args) {} 384 377 385 UntypedExpr::~UntypedExpr() { 378 386 delete function; 379 387 deleteAll( args ); 380 388 } 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 RHS401 ret->set_result( arg2->get_result()->clone() );402 }403 return ret;404 }405 406 389 407 390 void UntypedExpr::print( std::ostream &os, int indent ) const { … … 436 419 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) : 437 420 Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp) { 438 set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );421 add_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 439 422 } 440 423 … … 471 454 472 455 void ConditionalExpr::print( std::ostream &os, int indent ) const { 473 os << "Conditional expression on: " << std::endl; 474 os << std::string( indent+2, ' ' ); 456 os << std::string( indent, ' ' ) << "Conditional expression on: " << std::endl; 475 457 arg1->print( os, indent+2 ); 476 458 os << std::string( indent, ' ' ) << "First alternative:" << std::endl; 477 os << std::string( indent+2, ' ' );478 459 arg2->print( os, indent+2 ); 479 460 os << std::string( indent, ' ' ) << "Second alternative:" << std::endl; 480 os << std::string( indent+2, ' ' );481 461 arg3->print( os, indent+2 ); 482 462 os << std::endl; … … 497 477 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) { 498 478 assert( callExpr ); 499 assert( callExpr->has_result() ); 500 set_result( callExpr->get_result()->clone() ); 479 cloneAll( callExpr->get_results(), results ); 501 480 } 502 481 … … 531 510 Expression * arg = InitTweak::getCallArg( callExpr, 0 ); 532 511 assert( arg ); 533 set_result( maybeClone( arg->get_result() ));512 cloneAll( arg->get_results(), results ); 534 513 } 535 514 … … 551 530 552 531 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) { 553 assert( type && initializer ); 554 set_result( type->clone() ); 555 } 556 557 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( other.type->clone() ), initializer( other.initializer->clone() ) {} 532 add_result( type->clone() ); 533 } 534 535 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {} 558 536 559 537 CompoundLiteralExpr::~CompoundLiteralExpr() { … … 564 542 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const { 565 543 os << "Compound Literal Expression: " << std::endl; 566 os << std::string( indent+2, ' ' ); 567 type->print( os, indent + 2 ); 568 os << std::string( indent+2, ' ' ); 569 initializer->print( os, indent + 2 ); 544 if ( type ) type->print( os, indent + 2 ); 545 if ( initializer ) initializer->print( os, indent + 2 ); 570 546 } 571 547 … … 581 557 582 558 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {} 583 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ),low( other.low->clone() ), high( other.high->clone() ) {}559 RangeExpr::RangeExpr( const RangeExpr &other ) : low( other.low->clone() ), high( other.high->clone() ) {} 584 560 void RangeExpr::print( std::ostream &os, int indent ) const { 585 os << "Range Expression: ";561 os << std::string( indent, ' ' ) << "Range Expression: "; 586 562 low->print( os, indent ); 587 563 os << " ... "; 588 564 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 }633 565 } 634 566 -
src/SynTree/Expression.h
r1f44196 r3a2128f 32 32 virtual ~Expression(); 33 33 34 Type *& get_result() { return result; } 35 void set_result( Type *newValue ) { result = newValue; } 36 bool has_result() const { return result != nullptr; } 34 std::list<Type *>& get_results() { return results; } 35 void add_result( Type *t ); 37 36 38 37 TypeSubstitution *get_env() const { return env; } … … 48 47 virtual void print( std::ostream &os, int indent = 0 ) const; 49 48 protected: 50 Type * result;49 std::list<Type *> results; 51 50 TypeSubstitution *env; 52 51 Expression* argName; // if expression is used as an argument, it can be "designated" by this name … … 99 98 class UntypedExpr : public Expression { 100 99 public: 101 UntypedExpr( Expression *function, const std::list<Expression *> &args = std::list< Expression * >(),Expression *_aname = nullptr );100 UntypedExpr( Expression *function, Expression *_aname = nullptr ); 102 101 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 116 113 virtual UntypedExpr *clone() const { return new UntypedExpr( *this ); } 117 114 virtual void accept( Visitor &v ) { v.visit( this ); } … … 203 200 class UntypedMemberExpr : public Expression { 204 201 public: 205 UntypedMemberExpr( Expression *member, Expression *aggregate, Expression *_aname = nullptr );202 UntypedMemberExpr( std::string member, Expression *aggregate, Expression *_aname = nullptr ); 206 203 UntypedMemberExpr( const UntypedMemberExpr &other ); 207 204 virtual ~UntypedMemberExpr(); 208 205 209 Expression *get_member() const { return member; }210 void set_member( Expression *newValue ) { member = newValue; }206 std::string get_member() const { return member; } 207 void set_member( const std::string &newValue ) { member = newValue; } 211 208 Expression *get_aggregate() const { return aggregate; } 212 209 void set_aggregate( Expression *newValue ) { aggregate = newValue; } … … 217 214 virtual void print( std::ostream &os, int indent = 0 ) const; 218 215 private: 219 Expression *member;216 std::string member; 220 217 Expression *aggregate; 221 218 }; … … 486 483 }; 487 484 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 on 504 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 488 521 /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter) 489 522 class TypeExpr : public Expression { … … 585 618 CompoundLiteralExpr( Type * type, Initializer * initializer ); 586 619 CompoundLiteralExpr( const CompoundLiteralExpr &other ); 587 virtual~CompoundLiteralExpr();620 ~CompoundLiteralExpr(); 588 621 589 622 Type * get_type() const { return type; } … … 637 670 private: 638 671 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 analyzer660 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 analyzer681 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 expression702 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 tempDecls717 std::list< ObjectDecl * > tempDecls; // temporaries for address of lhs exprs718 };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;765 672 }; 766 673 -
src/SynTree/Initializer.h
r1f44196 r3a2128f 23 23 24 24 #include <cassert> 25 26 const std::list<Expression*> noDesignators;27 25 28 26 // Initializer: base class for object initializers (provide default values) -
src/SynTree/Mutator.cc
r1f44196 r3a2128f 178 178 179 179 Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) { 180 applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ));180 mutateAll( applicationExpr->get_results(), *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 untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ));187 mutateAll( untypedExpr->get_results(), *this ); 188 188 mutateAll( untypedExpr->get_args(), *this ); 189 189 return untypedExpr; … … 191 191 192 192 Expression *Mutator::mutate( NameExpr *nameExpr ) { 193 nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ));193 mutateAll( nameExpr->get_results(), *this ); 194 194 return nameExpr; 195 195 } 196 196 197 197 Expression *Mutator::mutate( AddressExpr *addressExpr ) { 198 addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ));198 mutateAll( addressExpr->get_results(), *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 labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ));204 mutateAll( labelAddressExpr->get_results(), *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 castExpr->set_result( maybeMutate( castExpr->get_result(), *this ));210 mutateAll( castExpr->get_results(), *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 memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) ); 217 memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) ); 218 memberExpr->set_member( maybeMutate( memberExpr->get_member(), *this ) ); 219 return memberExpr; 220 } 221 222 Expression *Mutator::mutate( MemberExpr *memberExpr ) { 223 memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) ); 216 mutateAll( memberExpr->get_results(), *this ); 224 217 memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) ); 225 218 return memberExpr; 226 219 } 227 220 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 228 227 Expression *Mutator::mutate( VariableExpr *variableExpr ) { 229 variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ));228 mutateAll( variableExpr->get_results(), *this ); 230 229 return variableExpr; 231 230 } 232 231 233 232 Expression *Mutator::mutate( ConstantExpr *constantExpr ) { 234 constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ));233 mutateAll( constantExpr->get_results(), *this ); 235 234 // maybeMutate( constantExpr->get_constant(), *this ) 236 235 return constantExpr; … … 238 237 239 238 Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) { 240 sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ));239 mutateAll( sizeofExpr->get_results(), *this ); 241 240 if ( sizeofExpr->get_isType() ) { 242 241 sizeofExpr->set_type( maybeMutate( sizeofExpr->get_type(), *this ) ); … … 248 247 249 248 Expression *Mutator::mutate( AlignofExpr *alignofExpr ) { 250 alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ));249 mutateAll( alignofExpr->get_results(), *this ); 251 250 if ( alignofExpr->get_isType() ) { 252 251 alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) ); … … 258 257 259 258 Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) { 260 offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ));259 mutateAll( offsetofExpr->get_results(), *this ); 261 260 offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) ); 262 261 return offsetofExpr; … … 264 263 265 264 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) { 266 offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ));265 mutateAll( offsetofExpr->get_results(), *this ); 267 266 offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) ); 268 267 offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) ); … … 271 270 272 271 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) { 273 offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ));272 mutateAll( offsetPackExpr->get_results(), *this ); 274 273 offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) ); 275 274 return offsetPackExpr; … … 277 276 278 277 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 279 attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ));278 mutateAll( attrExpr->get_results(), *this ); 280 279 if ( attrExpr->get_isType() ) { 281 280 attrExpr->set_type( maybeMutate( attrExpr->get_type(), *this ) ); … … 287 286 288 287 Expression *Mutator::mutate( LogicalExpr *logicalExpr ) { 289 logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ));288 mutateAll( logicalExpr->get_results(), *this ); 290 289 logicalExpr->set_arg1( maybeMutate( logicalExpr->get_arg1(), *this ) ); 291 290 logicalExpr->set_arg2( maybeMutate( logicalExpr->get_arg2(), *this ) ); … … 294 293 295 294 Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) { 296 conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ));295 mutateAll( conditionalExpr->get_results(), *this ); 297 296 conditionalExpr->set_arg1( maybeMutate( conditionalExpr->get_arg1(), *this ) ); 298 297 conditionalExpr->set_arg2( maybeMutate( conditionalExpr->get_arg2(), *this ) ); … … 302 301 303 302 Expression *Mutator::mutate( CommaExpr *commaExpr ) { 304 commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ));303 mutateAll( commaExpr->get_results(), *this ); 305 304 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) ); 306 305 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) ); … … 308 307 } 309 308 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 310 321 Expression *Mutator::mutate( TypeExpr *typeExpr ) { 311 typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ));322 mutateAll( typeExpr->get_results(), *this ); 312 323 typeExpr->set_type( maybeMutate( typeExpr->get_type(), *this ) ); 313 324 return typeExpr; … … 329 340 330 341 Expression* Mutator::mutate( ConstructorExpr *ctorExpr ) { 331 ctorExpr->set_result( maybeMutate( ctorExpr->get_result(), *this ));342 mutateAll( ctorExpr->get_results(), *this ); 332 343 ctorExpr->set_callExpr( maybeMutate( ctorExpr->get_callExpr(), *this ) ); 333 344 return ctorExpr; … … 335 346 336 347 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) { 337 compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ));348 mutateAll( compLitExpr->get_results(), *this ); 338 349 compLitExpr->set_type( maybeMutate( compLitExpr->get_type(), *this ) ); 339 350 compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) ); … … 342 353 343 354 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) { 344 valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ));355 mutateAll( valofExpr->get_results(), *this ); 345 356 return valofExpr; 346 357 } … … 350 361 rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) ); 351 362 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;390 363 } 391 364 -
src/SynTree/Mutator.h
r1f44196 r3a2128f 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 ); 73 75 virtual Expression* mutate( TypeExpr *typeExpr ); 74 76 virtual Expression* mutate( AsmExpr *asmExpr ); … … 78 80 virtual Expression* mutate( UntypedValofExpr *valofExpr ); 79 81 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 );86 82 87 83 virtual Type* mutate( VoidType *basicType ); -
src/SynTree/ReferenceToType.cc
r1f44196 r3a2128f 56 56 } 57 57 } // namespace 58 59 StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct ) : Parent( tq, baseStruct->get_name() ), baseStruct( baseStruct ) {}60 58 61 59 std::string StructInstType::typeString() const { return "struct"; } -
src/SynTree/SynTree.h
r1f44196 r3a2128f 76 76 class ConditionalExpr; 77 77 class CommaExpr; 78 class TupleExpr; 79 class SolvedTupleExpr; 78 80 class TypeExpr; 79 81 class AsmExpr; … … 83 85 class UntypedValofExpr; 84 86 class RangeExpr; 85 class TupleExpr;86 class TupleIndexExpr;87 class MemberTupleExpr;88 class TupleAssignExpr;89 class StmtExpr;90 class UniqueExpr;91 87 92 88 class Type; -
src/SynTree/TupleExpr.cc
r1f44196 r3a2128f 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"22 18 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 } 19 TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) { 29 20 } 30 21 … … 38 29 39 30 void TupleExpr::print( std::ostream &os, int indent ) const { 40 os << "Tuple:" << std::endl;31 os << std::string( indent, ' ' ) << "Tuple:" << std::endl; 41 32 printAll( exprs, os, indent+2 ); 42 33 Expression::print( os, indent ); 43 34 } 44 35 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() ); 36 SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname ) : Expression( _aname ) { 37 std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs)); 50 38 } 51 39 52 TupleIndexExpr::TupleIndexExpr( const TupleIndexExpr &other ) : Expression( other ), tuple( other.tuple->clone() ), index( other.index ) { 40 SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other ) : Expression( other ) { 41 cloneAll( other.exprs, exprs ); 53 42 } 54 43 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; 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 ); 64 47 Expression::print( os, indent ); 65 48 } 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 tempDecls99 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 130 49 131 50 // Local Variables: // -
src/SynTree/TupleType.cc
r1f44196 r3a2128f 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 , const std::list< Type * > & types ) : Type( tq ), types( types) {19 TupleType::TupleType( const Type::Qualifiers &tq ) : Type( tq ) { 20 20 } 21 21 -
src/SynTree/Type.h
r1f44196 r3a2128f 20 20 #include "Visitor.h" 21 21 #include "Mutator.h" 22 #include "Common/utility.h"23 22 24 23 class Type { … … 28 27 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 ) {} 29 28 30 Qualifiers &operator&=( const Qualifiers &other );31 29 Qualifiers &operator+=( const Qualifiers &other ); 32 30 Qualifiers &operator-=( const Qualifiers &other ); … … 65 63 void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; } 66 64 void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; } 67 68 typedef std::list<TypeDecl *> ForallList; 69 ForallList& get_forall() { return forall; } 70 71 /// How many elemental types are represented by this type 72 virtual unsigned size() const { return 1; }; 73 virtual bool isVoid() const { return size() == 0; } 65 std::list<TypeDecl*>& get_forall() { return forall; } 74 66 75 67 virtual Type *clone() const = 0; … … 79 71 private: 80 72 Qualifiers tq; 81 ForallListforall;73 std::list<TypeDecl*> forall; 82 74 }; 83 75 … … 85 77 public: 86 78 VoidType( const Type::Qualifiers &tq ); 87 88 virtual unsigned size() const { return 0; };89 79 90 80 virtual VoidType *clone() const { return new VoidType( *this ); } … … 244 234 public: 245 235 StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {} 246 StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct );247 236 StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {} 248 237 … … 359 348 class TupleType : public Type { 360 349 public: 361 TupleType( const Type::Qualifiers &tq , const std::list< Type * > & types = std::list< Type * >());350 TupleType( const Type::Qualifiers &tq ); 362 351 TupleType( const TupleType& ); 363 352 virtual ~TupleType(); 364 353 365 typedef std::list<Type*> value_type;366 typedef value_type::iterator iterator;367 368 354 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(); }373 355 374 356 virtual TupleType *clone() const { return new TupleType( *this ); } … … 460 442 }; 461 443 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 471 444 inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) { 472 445 isConst |= other.isConst; -
src/SynTree/TypeSubstitution.cc
r1f44196 r3a2128f 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 ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {151 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 152 152 boundVars.insert( (*tyvar )->get_name() ); 153 153 } // for … … 163 163 // bind type variables from forall-qualifiers 164 164 if ( freeOnly ) { 165 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {165 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 166 166 boundVars.insert( (*tyvar )->get_name() ); 167 167 } // for -
src/SynTree/Visitor.cc
r1f44196 r3a2128f 150 150 151 151 void Visitor::visit( ApplicationExpr *applicationExpr ) { 152 maybeAccept( applicationExpr->get_result(), *this );152 acceptAll( applicationExpr->get_results(), *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 maybeAccept( untypedExpr->get_result(), *this );158 acceptAll( untypedExpr->get_results(), *this ); 159 159 acceptAll( untypedExpr->get_args(), *this ); 160 160 } 161 161 162 162 void Visitor::visit( NameExpr *nameExpr ) { 163 maybeAccept( nameExpr->get_result(), *this );163 acceptAll( nameExpr->get_results(), *this ); 164 164 } 165 165 166 166 void Visitor::visit( AddressExpr *addressExpr ) { 167 maybeAccept( addressExpr->get_result(), *this );167 acceptAll( addressExpr->get_results(), *this ); 168 168 maybeAccept( addressExpr->get_arg(), *this ); 169 169 } 170 170 171 171 void Visitor::visit( LabelAddressExpr *labAddressExpr ) { 172 maybeAccept( labAddressExpr->get_result(), *this );172 acceptAll( labAddressExpr->get_results(), *this ); 173 173 maybeAccept( labAddressExpr->get_arg(), *this ); 174 174 } 175 175 176 176 void Visitor::visit( CastExpr *castExpr ) { 177 maybeAccept( castExpr->get_result(), *this );177 acceptAll( castExpr->get_results(), *this ); 178 178 maybeAccept( castExpr->get_arg(), *this ); 179 179 } 180 180 181 181 void Visitor::visit( UntypedMemberExpr *memberExpr ) { 182 maybeAccept( memberExpr->get_result(), *this );182 acceptAll( memberExpr->get_results(), *this ); 183 183 maybeAccept( memberExpr->get_aggregate(), *this ); 184 maybeAccept( memberExpr->get_member(), *this );185 184 } 186 185 187 186 void Visitor::visit( MemberExpr *memberExpr ) { 188 maybeAccept( memberExpr->get_result(), *this );187 acceptAll( memberExpr->get_results(), *this ); 189 188 maybeAccept( memberExpr->get_aggregate(), *this ); 190 189 } 191 190 192 191 void Visitor::visit( VariableExpr *variableExpr ) { 193 maybeAccept( variableExpr->get_result(), *this );192 acceptAll( variableExpr->get_results(), *this ); 194 193 } 195 194 196 195 void Visitor::visit( ConstantExpr *constantExpr ) { 197 maybeAccept( constantExpr->get_result(), *this );196 acceptAll( constantExpr->get_results(), *this ); 198 197 maybeAccept( constantExpr->get_constant(), *this ); 199 198 } 200 199 201 200 void Visitor::visit( SizeofExpr *sizeofExpr ) { 202 maybeAccept( sizeofExpr->get_result(), *this );201 acceptAll( sizeofExpr->get_results(), *this ); 203 202 if ( sizeofExpr->get_isType() ) { 204 203 maybeAccept( sizeofExpr->get_type(), *this ); … … 209 208 210 209 void Visitor::visit( AlignofExpr *alignofExpr ) { 211 maybeAccept( alignofExpr->get_result(), *this );210 acceptAll( alignofExpr->get_results(), *this ); 212 211 if ( alignofExpr->get_isType() ) { 213 212 maybeAccept( alignofExpr->get_type(), *this ); … … 218 217 219 218 void Visitor::visit( UntypedOffsetofExpr *offsetofExpr ) { 220 maybeAccept( offsetofExpr->get_result(), *this );219 acceptAll( offsetofExpr->get_results(), *this ); 221 220 maybeAccept( offsetofExpr->get_type(), *this ); 222 221 } 223 222 224 223 void Visitor::visit( OffsetofExpr *offsetofExpr ) { 225 maybeAccept( offsetofExpr->get_result(), *this );224 acceptAll( offsetofExpr->get_results(), *this ); 226 225 maybeAccept( offsetofExpr->get_type(), *this ); 227 226 maybeAccept( offsetofExpr->get_member(), *this ); … … 229 228 230 229 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) { 231 maybeAccept( offsetPackExpr->get_result(), *this );230 acceptAll( offsetPackExpr->get_results(), *this ); 232 231 maybeAccept( offsetPackExpr->get_type(), *this ); 233 232 } 234 233 235 234 void Visitor::visit( AttrExpr *attrExpr ) { 236 maybeAccept( attrExpr->get_result(), *this );235 acceptAll( attrExpr->get_results(), *this ); 237 236 if ( attrExpr->get_isType() ) { 238 237 maybeAccept( attrExpr->get_type(), *this ); … … 243 242 244 243 void Visitor::visit( LogicalExpr *logicalExpr ) { 245 maybeAccept( logicalExpr->get_result(), *this );244 acceptAll( logicalExpr->get_results(), *this ); 246 245 maybeAccept( logicalExpr->get_arg1(), *this ); 247 246 maybeAccept( logicalExpr->get_arg2(), *this ); … … 249 248 250 249 void Visitor::visit( ConditionalExpr *conditionalExpr ) { 251 maybeAccept( conditionalExpr->get_result(), *this );250 acceptAll( conditionalExpr->get_results(), *this ); 252 251 maybeAccept( conditionalExpr->get_arg1(), *this ); 253 252 maybeAccept( conditionalExpr->get_arg2(), *this ); … … 256 255 257 256 void Visitor::visit( CommaExpr *commaExpr ) { 258 maybeAccept( commaExpr->get_result(), *this );257 acceptAll( commaExpr->get_results(), *this ); 259 258 maybeAccept( commaExpr->get_arg1(), *this ); 260 259 maybeAccept( commaExpr->get_arg2(), *this ); 261 260 } 262 261 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 263 272 void Visitor::visit( TypeExpr *typeExpr ) { 264 maybeAccept( typeExpr->get_result(), *this );273 acceptAll( typeExpr->get_results(), *this ); 265 274 maybeAccept( typeExpr->get_type(), *this ); 266 275 } … … 279 288 280 289 void Visitor::visit( ConstructorExpr * ctorExpr ) { 281 maybeAccept( ctorExpr->get_result(), *this );290 acceptAll( ctorExpr->get_results(), *this ); 282 291 maybeAccept( ctorExpr->get_callExpr(), *this ); 283 292 } 284 293 285 294 void Visitor::visit( CompoundLiteralExpr *compLitExpr ) { 286 maybeAccept( compLitExpr->get_result(), *this );295 acceptAll( compLitExpr->get_results(), *this ); 287 296 maybeAccept( compLitExpr->get_type(), *this ); 288 297 maybeAccept( compLitExpr->get_initializer(), *this ); … … 290 299 291 300 void Visitor::visit( UntypedValofExpr *valofExpr ) { 292 maybeAccept( valofExpr->get_result(), *this );301 acceptAll( valofExpr->get_results(), *this ); 293 302 maybeAccept( valofExpr->get_body(), *this ); 294 303 } … … 297 306 maybeAccept( rangeExpr->get_low(), *this ); 298 307 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 );331 308 } 332 309 -
src/SynTree/Visitor.h
r1f44196 r3a2128f 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 ); 73 75 virtual void visit( TypeExpr *typeExpr ); 74 76 virtual void visit( AsmExpr *asmExpr ); … … 78 80 virtual void visit( UntypedValofExpr *valofExpr ); 79 81 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 );86 82 87 83 virtual void visit( VoidType *basicType ); -
src/SynTree/module.mk
r1f44196 r3a2128f 49 49 SynTree/AddStmtVisitor.cc \ 50 50 SynTree/TypeSubstitution.cc \ 51 SynTree/Attribute.cc \ 52 SynTree/VarExprReplacer.cc 51 SynTree/Attribute.cc 53 52 -
src/Tuples/TupleAssignment.cc
r1f44196 r3a2128f 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Nov 9 13:48:42 201611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 18 15:02:53 2015 13 13 // Update Count : 2 14 14 // … … 18 18 #include "ResolvExpr/typeops.h" 19 19 #include "SynTree/Expression.h" 20 #include "SynTree/Initializer.h" 21 #include "Tuples.h" 22 #include "Explode.h" 20 #include "TupleAssignment.h" 23 21 #include "Common/SemanticError.h" 24 #include "InitTweak/InitTweak.h"25 22 26 23 #include <functional> … … 30 27 #include <cassert> 31 28 #include <set> 32 #include <unordered_set>33 29 34 30 namespace Tuples { 35 class TupleAssignSpotter { 36 public: 37 // dispatcher for Tuple (multiple and mass) assignment operations 38 TupleAssignSpotter( ResolvExpr::AlternativeFinder & ); 39 void spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ); 40 41 private: 42 void match(); 43 44 struct Matcher { 45 public: 46 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 47 virtual ~Matcher() {} 48 virtual void match( std::list< Expression * > &out ) = 0; 49 ResolvExpr::AltList lhs, rhs; 50 TupleAssignSpotter &spotter; 51 std::list< ObjectDecl * > tmpDecls; 52 }; 53 54 struct MassAssignMatcher : public Matcher { 55 public: 56 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 57 virtual void match( std::list< Expression * > &out ); 58 }; 59 60 struct MultipleAssignMatcher : public Matcher { 61 public: 62 MultipleAssignMatcher( TupleAssignSpotter &spot, const ResolvExpr::AltList & alts ); 63 virtual void match( std::list< Expression * > &out ); 64 }; 65 66 ResolvExpr::AlternativeFinder ¤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 ) { 31 TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f ) 32 : currentFinder(f), matcher(0), hasMatched( false ) {} 33 34 bool TupleAssignSpotter::pointsToTuple( Expression *expr ) { 35 // also check for function returning tuple of reference types 36 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) ) 37 if ( isTuple(addr->get_arg() ) ) 38 return true; 39 return false; 40 } 41 42 bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) { 43 if ( dynamic_cast<TupleType *>(decl->get_type()) ) 44 return true; 45 return false; 46 } 47 48 bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) { 49 // true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function 73 50 if ( ! expr ) return false; 74 assert( expr->has_result() ); 75 return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1; 76 } 77 78 template< typename AltIter > 79 bool isMultAssign( AltIter begin, AltIter end ) { 80 // multiple assignment if more than one alternative in the range or if 81 // the alternative is a tuple 82 if ( begin == end ) return false; 83 if ( isTuple( begin->expr ) ) return true; 84 return ++begin != end; 85 } 86 87 bool pointsToTuple( Expression *expr ) { 88 // also check for function returning tuple of reference types 89 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 90 return pointsToTuple( castExpr->get_arg() ); 91 } else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) { 92 return isTuple( addr->get_arg() ); 93 } 94 return false; 95 } 96 97 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 98 TupleAssignSpotter spotter( currentFinder ); 99 spotter.spot( expr, possibilities ); 100 } 101 102 TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f ) 103 : currentFinder(f) {} 104 105 void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 106 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 107 if ( InitTweak::isCtorDtorAssign( op->get_name() ) ) { 108 fname = op->get_name(); 109 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 110 if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal 111 if ( ali->size() <= 1 && InitTweak::isAssignment( op->get_name() ) ) { 112 // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it 113 continue; 114 } 115 116 assert( ! ali->empty() ); 117 // grab args 2-N and group into a TupleExpr 118 const ResolvExpr::Alternative & alt1 = ali->front(); 119 auto begin = std::next(ali->begin(), 1), end = ali->end(); 120 if ( pointsToTuple(alt1.expr) ) { 121 if ( isMultAssign( begin, end ) ) { 122 matcher.reset( new MultipleAssignMatcher( *this, *ali ) ); 123 } else { 51 52 if ( dynamic_cast<TupleExpr *>(expr) ) 53 return true; 54 else if ( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) { 55 if ( isTupleVar(var->get_var()) ) 56 return true; 57 } 58 59 return false; 60 } 61 62 bool TupleAssignSpotter::match() { 63 assert ( matcher != 0 ); 64 65 std::list< Expression * > new_assigns; 66 if ( ! matcher->match(new_assigns) ) 67 return false; 68 69 if ( new_assigns.empty() ) return false; 70 /*return */matcher->solve( new_assigns ); 71 if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) { 72 // now resolve new assignments 73 std::list< Expression * > solved_assigns; 74 ResolvExpr::AltList solved_alts; 75 assert( currentFinder != 0 ); 76 77 ResolvExpr::AltList current; 78 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 79 //try { 80 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 81 finder.findWithAdjustment(*i); 82 // prune expressions that don't coincide with 83 ResolvExpr::AltList alts = finder.get_alternatives(); 84 assert( alts.size() == 1 ); 85 assert(alts.front().expr != 0 ); 86 current.push_back( finder.get_alternatives().front() ); 87 solved_assigns.push_back( alts.front().expr->clone() ); 88 //solved_assigns.back()->print(std::cerr); 89 /*} catch( ... ) { 90 continue; // no reasonable alternative found 91 }*/ 92 } 93 options.add_option( current ); 94 95 return true; 96 } else { // mass assignment 97 //if ( new_assigns.empty() ) return false; 98 std::list< Expression * > solved_assigns; 99 ResolvExpr::AltList solved_alts; 100 assert( currentFinder != 0 ); 101 102 ResolvExpr::AltList current; 103 if ( optMass.empty() ) { 104 for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i ) 105 optMass.push_back( ResolvExpr::AltList() ); 106 } 107 int cnt = 0; 108 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) { 109 110 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 111 finder.findWithAdjustment(*i); 112 ResolvExpr::AltList alts = finder.get_alternatives(); 113 assert( alts.size() == 1 ); 114 assert(alts.front().expr != 0 ); 115 current.push_back( finder.get_alternatives().front() ); 116 optMass[cnt].push_back( finder.get_alternatives().front() ); 117 solved_assigns.push_back( alts.front().expr->clone() ); 118 } 119 120 return true; 121 } 122 123 return false; 124 } 125 126 bool TupleAssignSpotter::isMVR( Expression *expr ) { 127 if ( expr->get_results().size() > 1 ) { 128 // MVR processing 129 return true; 130 } 131 return false; 132 } 133 134 bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) { 135 if ( NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) { 136 137 if ( assgnop->get_name() == std::string("?=?") ) { 138 139 for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 140 assert( ali->size() == 2 ); 141 ResolvExpr::AltList::iterator opit = ali->begin(); 142 ResolvExpr::Alternative op1 = *opit, op2 = *(++opit); 143 144 if ( pointsToTuple(op1.expr) ) { // also handles tuple vars 145 if ( isTuple( op2.expr, true ) ) 146 matcher = new MultipleAssignMatcher(op1.expr, op2.expr); 147 else if ( isMVR( op2.expr ) ) { 148 // handle MVR differently 149 } else 124 150 // mass assignment 125 matcher.reset( new MassAssignMatcher( *this, *ali ) ); 151 matcher = new MassAssignMatcher(op1.expr, op2.expr); 152 153 std::list< ResolvExpr::AltList > options; 154 if ( match() ) 155 /* 156 if ( hasMatched ) { 157 // throw SemanticError("Ambiguous tuple assignment"); 158 } else {*/ 159 // Matched for the first time 160 hasMatched = true; 161 /*} */ 162 } /* else if ( isTuple( op2 ) ) 163 throw SemanticError("Inapplicable tuple assignment."); 164 */ 165 } 166 167 if ( hasMatched ) { 168 if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) { 169 //options.print( std::cerr ); 170 std::list< ResolvExpr::AltList >best = options.get_best(); 171 if ( best.size() == 1 ) { 172 std::list<Expression *> solved_assigns; 173 for ( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ) { 174 solved_assigns.push_back( i->expr ); 175 } 176 /* assigning cost zero? */ 177 currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) ); 126 178 } 127 match(); 179 } else { 180 assert( ! optMass.empty() ); 181 ResolvExpr::AltList winners; 182 for ( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i ) 183 findMinCostAlt( i->begin(), i->end(), back_inserter(winners) ); 184 185 std::list< Expression *> solved_assigns; 186 for ( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i ) 187 solved_assigns.push_back( i->expr ); 188 currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) ); 128 189 } 129 190 } 130 191 } 131 192 } 132 } 133 134 void TupleAssignSpotter::match() { 135 assert ( matcher != 0 ); 136 137 std::list< Expression * > new_assigns; 138 matcher->match( new_assigns ); 139 140 if ( new_assigns.empty() ) return; 141 ResolvExpr::AltList current; 142 // now resolve new assignments 143 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 144 ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() ); 145 try { 146 finder.findWithAdjustment(*i); 147 } catch (...) { 148 return; // xxx - no match should not mean failure, it just means this particular tuple assignment isn't valid 193 return hasMatched; 194 } 195 196 void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) { 197 lhs.clear(); 198 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) ) 199 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) ) 200 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) ); 201 202 rhs.clear(); 203 } 204 205 TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{ 206 init(_lhs,_rhs); 207 } 208 209 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{ 210 init(_lhs,_rhs); 211 212 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) ) 213 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) ); 214 } 215 216 UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) { 217 if ( left && right ) { 218 std::list< Expression * > args; 219 args.push_back(new AddressExpr(left->clone())); args.push_back(right->clone()); 220 return new UntypedExpr(new NameExpr("?=?"), args); 221 } else 222 throw 0; // xxx - diagnose the problem 223 } 224 225 bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) { 226 if ( lhs.empty() || (rhs.size() != 1) ) return false; 227 228 for ( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) { 229 std::list< Expression * > args; 230 args.push_back( new AddressExpr(*l) ); 231 args.push_back( rhs.front() ); 232 out.push_back( new UntypedExpr(new NameExpr("?=?"), args) ); 233 } 234 235 return true; 236 } 237 238 bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) { 239 /* 240 std::list< Expression * > solved_assigns; 241 ResolvExpr::AltList solved_alts; 242 assert( currentFinder != 0 ); 243 244 ResolvExpr::AltList current; 245 if ( optMass.empty() ) { 246 for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i ) 247 optMass.push_back( ResolvExpr::AltList() ); 248 } 249 int cnt = 0; 250 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) { 251 252 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 253 finder.findWithAdjustment(*i); 254 ResolvExpr::AltList alts = finder.get_alternatives(); 255 assert( alts.size() == 1 ); 256 assert(alts.front().expr != 0 ); 257 current.push_back( finder.get_alternatives().front() ); 258 optMass[cnt].push_back( finder.get_alternatives().front() ); 259 solved_assigns.push_back( alts.front().expr->clone() ); 260 } 261 */ 262 return true; 263 } 264 265 bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) { 266 // need more complicated matching 267 if ( lhs.size() == rhs.size() ) { 268 zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn ); 269 return true; 270 } //else 271 //std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/ 272 return false; 273 } 274 275 bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) { 276 /* 277 std::list< Expression * > solved_assigns; 278 ResolvExpr::AltList solved_alts; 279 assert( currentFinder != 0 ); 280 281 ResolvExpr::AltList current; 282 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 283 //try { 284 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 285 finder.findWithAdjustment(*i); 286 // prune expressions that don't coincide with 287 ResolvExpr::AltList alts = finder.get_alternatives(); 288 assert( alts.size() == 1 ); 289 assert(alts.front().expr != 0 ); 290 current.push_back( finder.get_alternatives().front() ); 291 solved_assigns.push_back( alts.front().expr->clone() ); 292 //solved_assigns.back()->print(std::cerr); 293 //} catch( ... ) { 294 //continue; // no reasonable alternative found 295 //} 296 } 297 options.add_option( current ); 298 */ 299 300 return true; 301 } 302 303 void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) { 304 using namespace std; 305 306 options.push_back( opt ); 307 /* 308 vector< Cost > costs; 309 costs.reserve( opt.size() ); 310 transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) ); 311 */ 312 // transpose matrix 313 if ( costMatrix.empty() ) 314 for ( unsigned int i = 0; i< opt.size(); ++i) 315 costMatrix.push_back( vector<ResolvExpr::Cost>() ); 316 317 int cnt = 0; 318 for ( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ ) 319 costMatrix[cnt].push_back( i->cost ); 320 321 return; 322 } 323 324 std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() { 325 using namespace std; 326 using namespace ResolvExpr; 327 list< ResolvExpr::AltList > ret; 328 list< multiset<int> > solns; 329 for ( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) { 330 list<int> current; 331 findMinCost( i->begin(), i->end(), back_inserter(current) ); 332 solns.push_back( multiset<int>(current.begin(), current.end()) ); 333 } 334 // need to combine 335 multiset<int> result; 336 lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) ); 337 if ( result.size() != 1 ) 338 throw SemanticError("Ambiguous tuple expression"); 339 ret.push_back(get_option( *(result.begin() ))); 340 return ret; 341 } 342 343 void TupleAssignSpotter::Options::print( std::ostream &ostr ) { 344 using namespace std; 345 346 for ( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) { 347 for ( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j ) 348 ostr << *j << " " ; 349 ostr << std::endl; 350 } // for 351 return; 352 } 353 354 ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) { 355 return alt.cost; 356 } 357 358 template< typename InputIterator, typename OutputIterator > 359 void TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) { 360 using namespace ResolvExpr; 361 std::list<int> alternatives; 362 363 // select the alternatives that have the minimum parameter cost 364 Cost minCost = Cost::infinity; 365 unsigned int index = 0; 366 for ( InputIterator i = begin; i != end; ++i, index++ ) { 367 if ( *i < minCost ) { 368 minCost = *i; 369 alternatives.clear(); 370 alternatives.push_back( index ); 371 } else if ( *i == minCost ) { 372 alternatives.push_back( index ); 149 373 } 150 // prune expressions that don't coincide with 151 ResolvExpr::AltList alts = finder.get_alternatives(); 152 assert( alts.size() == 1 ); 153 assert( alts.front().expr != 0 ); 154 current.push_back( alts.front() ); 155 } 156 157 // extract expressions from the assignment alternatives to produce a list of assignments that 158 // together form a single alternative 159 std::list< Expression *> solved_assigns; 160 for ( ResolvExpr::Alternative & alt : current ) { 161 solved_assigns.push_back( alt.expr->clone() ); 162 } 163 // xxx - need to do this?? 164 ResolvExpr::TypeEnvironment compositeEnv; 165 simpleCombineEnvironments( current.begin(), current.end(), compositeEnv ); 166 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), compositeEnv, ResolvExpr::sumCost( current ) ) ); 167 } 168 169 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter) { 170 assert( ! alts.empty() ); 171 ResolvExpr::Alternative lhsAlt = alts.front(); 172 // peel off the cast that exists on ctor/dtor expressions 173 bool isCast = false; 174 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( lhsAlt.expr ) ) { 175 lhsAlt.expr = castExpr->get_arg(); 176 castExpr->set_arg( nullptr ); 177 delete castExpr; 178 isCast = true; 179 } 180 181 // explode the lhs so that each field of the tuple-valued-expr is assigned. 182 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs) ); 183 184 // and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed 185 if ( isCast ) { 186 for ( ResolvExpr::Alternative & alt : lhs ) { 187 Expression *& expr = alt.expr; 188 Type * castType = expr->get_result()->clone(); 189 Type * type = InitTweak::getPointerBase( castType ); 190 assert( type ); 191 type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 192 type->set_isLvalue( true ); // xxx - might not need this 193 expr = new CastExpr( expr, castType ); 194 } 195 } 196 } 197 198 TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 199 assert( alts.size() == 1 || alts.size() == 2 ); 200 if ( alts.size() == 2 ) { 201 rhs.push_back( alts.back() ); 202 } 203 } 204 205 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 206 // explode the rhs so that each field of the tuple-valued-expr is assigned. 207 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs) ); 208 } 209 210 UntypedExpr * createFunc( const std::string &fname, ObjectDecl *left, ObjectDecl *right ) { 211 assert( left ); 212 std::list< Expression * > args; 213 args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) ); 214 // args.push_back( new AddressExpr( new VariableExpr( left ) ) ); 215 if ( right ) args.push_back( new VariableExpr( right ) ); 216 return new UntypedExpr( new NameExpr( fname ), args ); 217 } 218 219 ObjectDecl * newObject( UniqueName & namer, Expression * expr ) { 220 assert( expr->has_result() && ! expr->get_result()->isVoid() ); 221 return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) ); 222 } 223 224 void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) { 225 static UniqueName lhsNamer( "__massassign_L" ); 226 static UniqueName rhsNamer( "__massassign_R" ); 227 assert ( ! lhs.empty() && rhs.size() <= 1); 228 229 ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr; 230 for ( ResolvExpr::Alternative & lhsAlt : lhs ) { 231 ObjectDecl * ltmp = newObject( lhsNamer, lhsAlt.expr ); 232 out.push_back( createFunc( spotter.fname, ltmp, rtmp ) ); 233 tmpDecls.push_back( ltmp ); 234 } 235 if ( rtmp ) tmpDecls.push_back( rtmp ); 236 } 237 238 void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) { 239 static UniqueName lhsNamer( "__multassign_L" ); 240 static UniqueName rhsNamer( "__multassign_R" ); 241 242 // xxx - need more complicated matching? 243 if ( lhs.size() == rhs.size() ) { 244 std::list< ObjectDecl * > ltmp; 245 std::list< ObjectDecl * > rtmp; 246 std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( ResolvExpr::Alternative & alt ){ 247 return newObject( lhsNamer, alt.expr ); 248 }); 249 std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( ResolvExpr::Alternative & alt ){ 250 return newObject( rhsNamer, alt.expr ); 251 }); 252 zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), [&](ObjectDecl * obj1, ObjectDecl * obj2 ) { return createFunc(spotter.fname, obj1, obj2); } ); 253 tmpDecls.splice( tmpDecls.end(), ltmp ); 254 tmpDecls.splice( tmpDecls.end(), rtmp ); 255 } 374 } 375 std::copy( alternatives.begin(), alternatives.end(), out ); 376 } 377 378 template< class InputIterator, class OutputIterator > 379 void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ) { 380 if ( begin == end ) return; 381 InputIterator test = begin; 382 383 if (++test == end) 384 { copy(begin->begin(), begin->end(), out); return; } 385 386 387 std::multiset<int> cur; // InputIterator::value_type::value_type 388 copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) ); 389 390 while ( test != end ) { 391 std::multiset<int> temp; 392 set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) ); 393 cur.clear(); 394 copy( temp.begin(), temp.end(), inserter(cur,cur.begin())); 395 ++test; 396 } 397 398 copy( cur.begin(), cur.end(), out ); 399 return; 400 } 401 402 ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) { 403 if ( index >= options.size() ) 404 throw 0; // XXX 405 std::list< ResolvExpr::AltList >::iterator it = options.begin(); 406 for ( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it ); 407 return *it; 256 408 } 257 409 } // namespace Tuples -
src/Tuples/module.mk
r1f44196 r3a2128f 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/TupleExpansion.cc \ 19 Tuples/Explode.cc 18 Tuples/NameMatcher.cc -
src/driver/cfa.cc
r1f44196 r3a2128f 244 244 nargs += 1; 245 245 } // if 246 args[nargs] = "-I" CFA_INCDIR "/concurrency";247 nargs += 1;248 246 args[nargs] = "-I" CFA_INCDIR "/containers"; 249 247 nargs += 1; -
src/libcfa/Makefile.am
r1f44196 r3a2128f 56 56 CC = ${abs_top_srcdir}/src/driver/cfa 57 57 58 headers = limits stdlib math iostream fstream iterator rational assert containers/vector concurrency/threads 59 runtimehdrs = concurrency 58 headers = limits stdlib math iostream fstream iterator rational containers/vector 60 59 libobjs = ${headers:=.o} 61 60 -
src/libcfa/Makefile.in
r1f44196 r3a2128f 92 92 am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) math.$(OBJEXT) \ 93 93 iostream.$(OBJEXT) fstream.$(OBJEXT) iterator.$(OBJEXT) \ 94 rational.$(OBJEXT) assert.$(OBJEXT) \ 95 containers/vector.$(OBJEXT) concurrency/threads.$(OBJEXT) 94 rational.$(OBJEXT) containers/vector.$(OBJEXT) 96 95 am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1) 97 96 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) … … 235 234 cfalib_DATA = builtins.cf extras.cf prelude.cf 236 235 MAINTAINERCLEANFILES = builtins.cf extras.cf ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}} 237 headers = limits stdlib math iostream fstream iterator rational assert containers/vector concurrency/threads 238 runtimehdrs = concurrency 236 headers = limits stdlib math iostream fstream iterator rational containers/vector 239 237 libobjs = ${headers:=.o} 240 238 libcfa_a_SOURCES = libcfa-prelude.c ${headers:=.c} … … 314 312 containers/vector.$(OBJEXT): containers/$(am__dirstamp) \ 315 313 containers/$(DEPDIR)/$(am__dirstamp) 316 concurrency/$(am__dirstamp):317 @$(MKDIR_P) concurrency318 @: > 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)324 314 libcfa.a: $(libcfa_a_OBJECTS) $(libcfa_a_DEPENDENCIES) $(EXTRA_libcfa_a_DEPENDENCIES) 325 315 $(AM_V_at)-rm -f libcfa.a … … 329 319 mostlyclean-compile: 330 320 -rm -f *.$(OBJEXT) 331 -rm -f concurrency/threads.$(OBJEXT)332 321 -rm -f containers/vector.$(OBJEXT) 333 322 … … 335 324 -rm -f *.tab.c 336 325 337 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Po@am__quote@338 326 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstream.Po@am__quote@ 339 327 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iostream.Po@am__quote@ … … 344 332 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rational.Po@am__quote@ 345 333 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@ 346 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/threads.Po@am__quote@347 334 @AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/vector.Po@am__quote@ 348 335 … … 518 505 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 519 506 -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)522 507 -rm -f containers/$(DEPDIR)/$(am__dirstamp) 523 508 -rm -f containers/$(am__dirstamp) … … 532 517 533 518 distclean: distclean-am 534 -rm -rf ./$(DEPDIR) con currency/$(DEPDIR) containers/$(DEPDIR)519 -rm -rf ./$(DEPDIR) containers/$(DEPDIR) 535 520 -rm -f Makefile 536 521 distclean-am: clean-am distclean-compile distclean-generic \ … … 578 563 579 564 maintainer-clean: maintainer-clean-am 580 -rm -rf ./$(DEPDIR) con currency/$(DEPDIR) containers/$(DEPDIR)565 -rm -rf ./$(DEPDIR) containers/$(DEPDIR) 581 566 -rm -f Makefile 582 567 maintainer-clean-am: distclean-am maintainer-clean-generic \ -
src/main.cc
r1f44196 r3a2128f 43 43 #include "Common/UnimplementedError.h" 44 44 #include "../config.h" 45 #include "Tuples/Tuples.h"46 45 47 46 using namespace std; … … 237 236 OPTPRINT( "tweakInit" ) 238 237 InitTweak::genInit( translationUnit ); 239 OPTPRINT( "expandMemberTuples" ); 240 Tuples::expandMemberTuples( translationUnit ); 238 241 239 if ( libcfap ) { 242 240 // generate the bodies of cfa library functions … … 263 261 return 0; 264 262 } // 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 reused267 Tuples::expandUniqueExpr( translationUnit );268 263 269 264 OPTPRINT("instantiateGenerics") … … 282 277 OPTPRINT( "box" ) 283 278 GenPoly::box( translationUnit ); 284 OPTPRINT( "expandTuples" ); // xxx - is this the right place for this?285 Tuples::expandTuples( translationUnit );286 279 287 280 // print tree right before code generation
Note:
See TracChangeset
for help on using the changeset viewer.