Changes in / [4eb43fa:f6cc734e]


Ignore:
Files:
3 added
9 deleted
95 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile_disabled

    r4eb43fa rf6cc734e  
    22
    33import groovy.transform.Field
    4 
    5 // For skipping stages
    6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
    74
    85//===========================================================================================================
     
    8582//===========================================================================================================
    8683def clean() {
    87         build_stage('Cleanup', true) {
     84        build_stage('Cleanup') {
    8885                // clean the build by wipping the build directory
    8986                dir(BuildDir) {
     
    9592//Compilation script is done here but environnement set-up and error handling is done in main loop
    9693def checkout() {
    97         build_stage('Checkout', true) {
     94        build_stage('Checkout') {
    9895                //checkout the source code and clean the repo
    9996                final scmVars = checkout scm
     
    106103
    107104def build() {
    108         // build_stage('Build', true) {
    109         //      // Build outside of the src tree to ease cleaning
    110         //      dir (BuildDir) {
    111         //              //Configure the conpilation (Output is not relevant)
    112         //              //Use the current directory as the installation target so nothing escapes the sandbox
    113         //              //Also specify the compiler by hand
    114         //              targets=""
    115         //              if( Settings.RunAllTests || Settings.RunBenchmark ) {
    116         //                      targets="--with-target-hosts='host:debug,host:nodebug'"
    117         //              } else {
    118         //                      targets="--with-target-hosts='host:debug'"
    119         //              }
    120 
    121         //              sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
    122 
    123         //              //Compile the project
    124         //              sh 'make -j 8 --no-print-directory'
    125         //      }
    126         // }
    127 
    128         debug = true
    129         release = Settings.RunAllTests || Settings.RunBenchmark
    130         build_stage('Build : configure', true) {
     105        build_stage('Build') {
    131106                // Build outside of the src tree to ease cleaning
    132107                dir (BuildDir) {
     
    143118                        sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
    144119
    145                         // Configure libcfa
    146                         sh 'make -j 8 --no-print-directory configure-libcfa'
    147                 }
    148         }
    149 
    150         build_stage('Build : cfa-cpp', true) {
    151                 // Build outside of the src tree to ease cleaning
    152                 dir (BuildDir) {
    153                         // Build driver
    154                         sh 'make -j 8 --no-print-directory -C driver'
    155 
    156                         // Build translator
    157                         sh 'make -j 8 --no-print-directory -C src'
    158                 }
    159         }
    160 
    161         build_stage('Build : libcfa(debug)', debug) {
    162                 // Build outside of the src tree to ease cleaning
    163                 dir (BuildDir) {
    164                         sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
    165                 }
    166         }
    167 
    168         build_stage('Build : libcfa(nodebug)', release) {
    169                 // Build outside of the src tree to ease cleaning
    170                 dir (BuildDir) {
    171                         sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
     120                        //Compile the project
     121                        sh 'make -j 8 --no-print-directory'
    172122                }
    173123        }
     
    175125
    176126def test() {
    177         build_stage('Test: short', !Settings.RunAllTests) {
     127        build_stage('Test') {
     128
    178129                dir (BuildDir) {
    179130                        //Run the tests from the tests directory
    180                         sh 'make --no-print-directory -C tests'
    181                 }
    182         }
    183 
    184         build_stage('Test: full', Settings.RunAllTests) {
    185                 dir (BuildDir) {
    186                         //Run the tests from the tests directory
    187                         sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes'
    188                         sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no '
     131                        if ( Settings.RunAllTests ) {
     132                                sh 'make --no-print-directory -C tests timeouts="--timeout=1200" all-tests debug=yes'
     133                                sh 'make --no-print-directory -C tests timeouts="--timeout=1200" all-tests debug=no '
     134                        }
     135                        else {
     136                                sh 'make --no-print-directory -C tests'
     137                        }
    189138                }
    190139        }
     
    192141
    193142def benchmark() {
    194         build_stage('Benchmark', Settings.RunBenchmark) {
     143        build_stage('Benchmark') {
     144
     145                if( !Settings.RunBenchmark ) return
     146
    195147                dir (BuildDir) {
    196148                        //Append bench results
     
    201153
    202154def build_doc() {
    203         build_stage('Documentation', Settings.BuildDocumentation) {
     155        build_stage('Documentation') {
     156
     157                if( !Settings.BuildDocumentation ) return
     158
    204159                dir ('doc/user') {
    205160                        make_doc()
     
    213168
    214169def publish() {
    215         build_stage('Publish', true) {
     170        build_stage('Publish') {
    216171
    217172                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
     
    457412}
    458413
    459 def build_stage(String name, boolean run, Closure block ) {
     414def build_stage(String name, Closure block ) {
    460415        StageName = name
    461416        echo " -------- ${StageName} -------- "
    462         if(run) {
    463                 stage(name, block)
    464         } else {
    465                 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
    466         }
     417        stage(name, block)
    467418}
    468419
  • Makefile.am

    r4eb43fa rf6cc734e  
    4040        $(MAKE) -C tests all-tests installed=yes debug=${debug}
    4141
    42 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@
    43         @true
    44 
    4542status: @LIBCFA_TARGET_MAKEFILES@
    4643        @echo -ne "translator\n\t"
  • Makefile.in

    r4eb43fa rf6cc734e  
    940940        $(MAKE) -C tests all-tests installed=yes debug=${debug}
    941941
    942 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@
    943         @true
    944 
    945942status: @LIBCFA_TARGET_MAKEFILES@
    946943        @echo -ne "translator\n\t"
  • benchmark/Makefile.am

    r4eb43fa rf6cc734e  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Jun 24 16:45:42 2019
    14 ## Update Count     : 53
     13## Last Modified On : Sun Jun 23 12:34:29 2019
     14## Update Count     : 52
    1515###############################################################################
    1616
     
    3131BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    3232BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
     33BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet))
    3334
    3435__quiet = verbose
     
    4546__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    4647__bench_v_UPP_verbose = $(AM_V_UPP)
     48__bench_v_QTHREAD_verbose = $(AM_V_CC)
    4749
    4850
     
    174176        ctxswitch-upp_thread.run        \
    175177        ctxswitch-goroutine.run         \
    176         ctxswitch-java_thread.run
     178        ctxswitch-java_thread.run       \
     179        ctxswitch-qthreads.run
    177180
    178181
     
    221224        @echo "java JavaThread" >> a.out
    222225        @chmod a+x a.out
     226
     227ctxswitch-qthreads$(EXEEXT):
     228        $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    223229
    224230## =========================================================================================================
     
    314320        creation-upp_thread.run                 \
    315321        creation-goroutine.run                  \
    316         creation-java_thread.run
     322        creation-java_thread.run                \
     323        creation-qthreads.run
    317324
    318325creation-cfa_coroutine$(EXEEXT):
     
    342349        @echo "java JavaThread" >> a.out
    343350        @chmod a+x a.out
     351
     352creation-qthreads$(EXEEXT):
     353        $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    344354
    345355## =========================================================================================================
  • doc/bibliography/pl.bib

    r4eb43fa rf6cc734e  
    954954    key         = {Cforall Benchmarks},
    955955    author      = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}},
    956     howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmark.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmark.tar}},
     956    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmarks}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmarks}},
    957957}
    958958
  • doc/papers/concurrency/Paper.tex

    r4eb43fa rf6cc734e  
    22
    33\articletype{RESEARCH ARTICLE}%
    4 
    5 % Referees
    6 % Doug Lea, dl@cs.oswego.edu, SUNY Oswego
    7 % Herb Sutter, hsutter@microsoft.com, Microsoft Corp
    8 % Gor Nishanov, gorn@microsoft.com, Microsoft Corp
    9 % James Noble, kjx@ecs.vuw.ac.nz, Victoria University of Wellington, School of Engineering and Computer Science
    104
    115\received{XXXXX}
     
    318312As a result, languages like Java, Scala, Objective-C~\cite{obj-c-book}, \CCeleven~\cite{C11}, and C\#~\cite{Csharp} adopt the 1:1 kernel-threading model, with a variety of presentation mechanisms.
    319313From 2000 onwards, languages like Go~\cite{Go}, Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, D~\cite{D}, and \uC~\cite{uC++,uC++book} have championed the M:N user-threading model, and many user-threading libraries have appeared~\cite{Qthreads,MPC,Marcel}, including putting green threads back into Java~\cite{Quasar}.
    320 The main argument for user-level threading is that it is lighter weight than kernel threading (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work units to facilitate load balancing by the runtime~\cite{Verch12}.
     314The main argument for user-level threading is that they are lighter weight than kernel threads (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work units to facilitate load balancing by the runtime~\cite{Verch12}.
    321315As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}.
    322316Finally, performant user-threading implementations (both time and space) meet or exceed direct kernel-threading implementations, while achieving the programming advantages of high concurrency levels and safety.
    323317
    324 A further effort over the past two decades is the development of language memory models to deal with the conflict between language features and compiler/hardware optimizations, \ie some language features are unsafe in the presence of aggressive sequential optimizations~\cite{Buhr95a,Boehm05}.
     318A further effort over the past two decades is the development of language memory models to deal with the conflict between language features and compiler/hardware optimizations, \ie, some language features are unsafe in the presence of aggressive sequential optimizations~\cite{Buhr95a,Boehm05}.
    325319The consequence is that a language must provide sufficient tools to program around safety issues, as inline and library code is all sequential to the compiler.
    326 One solution is low-level qualifiers and functions (\eg @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs.
     320One solution is low-level qualifiers and functions (\eg, @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs.
    327321A safer solution is high-level language constructs so the \emph{compiler} knows the optimization boundaries, and hence, provides implicit safety.
    328322This problem is best known with respect to concurrency, but applies to other complex control-flow, like exceptions\footnote{
     
    330324The key feature that dovetails with this paper is nonlocal exceptions allowing exceptions to be raised across stacks, with synchronous exceptions raised among coroutines and asynchronous exceptions raised among threads, similar to that in \uC~\cite[\S~5]{uC++}
    331325} and coroutines.
    332 Finally, language solutions allow matching constructs with language paradigm, \ie imperative and functional languages often have different presentations of the same concept to fit their programming model.
     326Finally, language solutions allow matching constructs with language paradigm, \ie, imperative and functional languages often have different presentations of the same concept to fit their programming model.
    333327
    334328Finally, it is important for a language to provide safety over performance \emph{as the default}, allowing careful reduction of safety for performance when necessary.
    335 Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie once there is spurious wakeup, signals-as-hints follow.
     329Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie, once there is spurious wakeup, signals-as-hints follow.
    336330However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice.
    337331Similarly, signals-as-hints are often a performance decision.
     
    343337Most augmented traditional (Fortran 18~\cite{Fortran18}, Cobol 14~\cite{Cobol14}, Ada 12~\cite{Ada12}, Java 11~\cite{Java11}) and new languages (Go~\cite{Go}, Rust~\cite{Rust}, and D~\cite{D}), except \CC, diverge from C with different syntax and semantics, only interoperate indirectly with C, and are not systems languages, for those with managed memory.
    344338As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
    345 While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (\eg objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
     339While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (\eg, objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
    346340Hence, rewriting and retraining costs for these languages, even \CC, are prohibitive for companies with a large C software-base.
    347341\CFA with its orthogonal feature-set, its high-performance runtime, and direct access to all existing C libraries circumvents these problems.
     
    373367\section{Stateful Function}
    374368
    375 The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg plugin, device driver, finite-state machine.
     369The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg, plugin, device driver, finite-state machine.
    376370Hence, a stateful function may not end when it returns to its caller, allowing it to be restarted with the data and execution location present at the point of suspension.
    377371This capability is accomplished by retaining a data/execution \emph{closure} between invocations.
    378 If the closure is fixed size, we call it a \emph{generator} (or \emph{stackless}), and its control flow is restricted, \eg suspending outside the generator is prohibited.
    379 If the closure is variable size, we call it a \emph{coroutine} (or \emph{stackful}), and as the names implies, often implemented with a separate stack with no programming restrictions.
     372If the closure is fixed size, we call it a \emph{generator} (or \emph{stackless}), and its control flow is restricted, \eg, suspending outside the generator is prohibited.
     373If the closure is variably sized, we call it a \emph{coroutine} (or \emph{stackful}), and as the names implies, often implemented with a separate stack with no programming restrictions.
    380374Hence, refactoring a stackless coroutine may require changing it to stackful.
    381 A foundational property of all \emph{stateful functions} is that resume/suspend \emph{do not} cause incremental stack growth, \ie resume/suspend operations are remembered through the closure not the stack.
     375A foundational property of all \emph{stateful functions} is that resume/suspend \emph{do not} cause incremental stack growth, \ie, resume/suspend operations are remembered through the closure not the stack.
    382376As well, activating a stateful function is \emph{asymmetric} or \emph{symmetric}, identified by resume/suspend (no cycles) and resume/resume (cycles).
    383377A fixed closure activated by modified call/return is faster than a variable closure activated by context switching.
    384 Additionally, any storage management for the closure (especially in unmanaged languages, \ie no garbage collection) must also be factored into design and performance.
     378Additionally, any storage management for the closure (especially in unmanaged languages, \ie, no garbage collection) must also be factored into design and performance.
    385379Therefore, selecting between stackless and stackful semantics is a tradeoff between programming requirements and performance, where stackless is faster and stackful is more general.
    386380Note, creation cost is amortized across usage, so activation cost is usually the dominant factor.
     
    654648\end{center}
    655649The example takes advantage of resuming a generator in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops.
    656 The destructor provides a newline, if formatted text ends with a full line.
     650The destructor provides a newline if formatted text ends with a full line.
    657651Figure~\ref{f:CFormatSim} shows the C implementation of the \CFA input generator with one additional field and the computed @goto@.
    658652For contrast, Figure~\ref{f:PythonFormatter} shows the equivalent Python format generator with the same properties as the Fibonacci generator.
     
    675669In contrast, the execution state is large, with one @resume@ and seven @suspend@s.
    676670Hence, the key benefits of the generator are correctness, safety, and maintenance because the execution states are transcribed directly into the programming language rather than using a table-driven approach.
    677 Because FSMs can be complex and frequently occur in important domains, direct generator support is important in a system programming language.
     671Because FSMs can be complex and frequently occur in important domains, direct support of the generator is crucial in a system programming language.
    678672
    679673\begin{figure}
     
    802796This semantics is basically a tail-call optimization, which compilers already perform.
    803797The example shows the assembly code to undo the generator's entry code before the direct jump.
    804 This assembly code depends on what entry code is generated, specifically if there are local variables and the level of optimization.
     798This assembly code depends on what entry code is generated, specifically if there are local variables, and the level of optimization.
    805799To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time.
    806800Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing.
     
    27252719Each benchmark experiment is run 31 times.
    27262720All omitted tests for other languages are functionally identical to the \CFA tests and available online~\cite{CforallBenchMarks}.
    2727 % tar --exclude=.deps --exclude=Makefile --exclude=Makefile.in --exclude=c.c --exclude=cxx.cpp --exclude=fetch_add.c -cvhf benchmark.tar benchmark
     2721
    27282722
    27292723\paragraph{Object Creation}
     
    27552749\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    27562750\CFA Coroutine Lazy             & 14.3          & 14.3          & 0.32          \\
    2757 \CFA Coroutine Eager    & 522.8         & 525.3         & 5.81          \\
     2751\CFA Coroutine Eager    & 2203.7        & 2205.6        & 26.03         \\
    27582752\CFA Thread                             & 1257.8        & 1291.2        & 86.19         \\
    27592753\uC Coroutine                   & 92.2          & 91.4          & 1.58          \\
  • doc/user/user.tex

    r4eb43fa rf6cc734e  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Jul 13 18:36:18 2019
    14 %% Update Count     : 3876
     13%% Last Modified On : Sat Jun 15 16:29:45 2019
     14%% Update Count     : 3847
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    26972697\subsection{Expressions}
    26982698
    2699 % Change order of expression evaluation.
    2700 % http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r2.pdf
    2701 
    27022699Multiple-return-value functions provide \CFA with a new syntax for expressing a combination of expressions in the return statement and a combination of types in a function signature.
    27032700These notions are generalized to provide \CFA with \newterm{tuple expression}s and \newterm{tuple type}s.
     
    33493346
    33503347
    3351 \section{Stream I/O Library}
    3352 \label{s:StreamIOLibrary}
     3348\section{I/O Stream Library}
     3349\label{s:IOStreamLibrary}
    33533350\index{input/output stream library}
    33543351\index{stream library}
    33553352
    3356 The goal of \CFA stream input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
    3357 Stream I/O can be implicitly or explicitly formatted.
    3358 Implicit formatting means \CFA selects the output or input format for values that match with the type of a variable.
    3359 Explicit formatting means additional information is specified to augment how an output or input of value is interpreted.
    3360 \CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators, and Python implicit spacing and newline.
    3361 Specifically:
     3353The goal of \CFA input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
     3354\CFA I/O combines ideas from C ©printf©, \CC, and Python.
     3355I/O can be unformatted or formatted.
     3356Unformatted means \CFA selects the output or input format for values that match with the type of a variable.
     3357Formatted means additional information is specified to augment how an output or input of value is interpreted.
     3358\CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators.
    33623359\begin{itemize}
    33633360\item
    3364 ©printf©/Python format codes are dense, making them difficult to read and remember.
     3361©printf© format codes are dense, making them difficult to read and remember.
    33653362\CFA/\CC format manipulators are named, making them easier to read and remember.
    33663363\item
    3367 ©printf©/Python separates format codes from associated variables, making it difficult to match codes with variables.
     3364©printf© separates format codes from associated variables, making it difficult to match codes with variables.
    33683365\CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding.
    33693366\item
    3370 Format manipulators in \CFA have local effect, whereas \CC have global effect, except ©setw©.
     3367Format manipulators in \CC have global rather than local effect, except ©setw©.
    33713368Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects.
    33723369Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location.
    33733370(To guarantee no side-effects, manipulator values must be saved and restored across function calls.)
    3374 \item
    3375 \CFA has more sophisticated implicit spacing between values than Python, plus implicit newline at the end of a print.
    33763371\end{itemize}
    33773372The \CFA header file for the I/O library is \Indexc{fstream.hfa}.
    33783373
    3379 For implicit formatted output, the common case is printing a series of variables separated by whitespace.
     3374For unformatted output, the common case is printing a sequence of variables separated by whitespace.
    33803375\begin{cquote}
    3381 \begin{tabular}{@{}l@{\hspace{2em}}l@{\hspace{2em}}l@{}}
    3382 \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}}       & \multicolumn{1}{c}{\textbf{Python}}   \\
     3376\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     3377\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
    33833378\begin{cfa}
    33843379int x = 1, y = 2, z = 3;
     
    33903385cout << x ®<< " "® << y ®<< " "® << z << endl;
    33913386\end{cfa}
    3392 &
    3393 \begin{cfa}
    3394 x = 1;  y = 2;  z = 3
    3395 print( x, y, z )
    3396 \end{cfa}
    33973387\\
    3398 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3399 1® ®2® ®3
    3400 \end{cfa}
    3401 &
    34023388\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    340333891® ®2® ®3
     
    34433429There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output.
    34443430
    3445 For implicit formatted input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable.
     3431For unformatter input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable.
    34463432\begin{cquote}
    34473433\begin{lrbox}{\LstBox}
     
    34503436\end{cfa}
    34513437\end{lrbox}
    3452 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{3em}}l@{}}
     3438\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    34533439\multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\
    3454 \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}}       & \multicolumn{1}{c}{\textbf{Python}}   \\
     3440\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
    34553441\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    34563442sin | x | y | z;
     
    34603446cin >> x >> y >> z;
    34613447\end{cfa}
    3462 &
    3463 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    3464 x = int(input());  y = float(input());  z = input();
    3465 \end{cfa}
    34663448\\
    34673449\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    34683450®1® ®2.5® ®A®
    3469 
    3470 
    34713451\end{cfa}
    34723452&
    34733453\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    34743454®1® ®2.5® ®A®
    3475 
    3476 
    3477 \end{cfa}
    3478 &
    3479 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3480 ®1®
    3481 ®2.5®
    3482 ®A®
    34833455\end{cfa}
    34843456\end{tabular}
     
    35093481
    35103482\item
    3511 A separator does not appear before or after a null (empty) C string, which is a local mechanism to disable insertion of the separator character.
     3483A separator does not appear before or after a null (empty) C string.
    35123484\begin{cfa}
    35133485sout | 1 | "" | 2 | "" | 3;
    35143486123
    35153487\end{cfa}
     3488which is a local mechanism to disable insertion of the separator character.
    35163489
    35173490\item
    35183491{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
    3519 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@, where \lstinline[basicstyle=\tt]@»@ is a closing citation mark.
     3492A seperator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
    35203493\begin{cfa}[belowskip=0pt]
    35213494sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     
    352534981®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x
    35263499\end{cfa}}%
    3527 
    3528 \item
    3529 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@, where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark.
     3500where \lstinline[basicstyle=\tt]@»@ is a closing citation mark.
     3501
     3502\item
     3503A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
    35303504%$
    35313505\begin{cfa}[mathescape=off]
     
    35383512\end{cfa}
    35393513%$
     3514where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark.
    35403515
    35413516\item
     
    36513626The tuple separator also responses to being turned on and off.
    36523627\begin{cfa}[belowskip=0pt]
    3653 sout | t1 | sepOff | t2; §\C{// turn off implicit separator for the next item
     3628sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator
    36543629\end{cfa}
    36553630\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36753650\subsection{Newline Manipulators}
    36763651
    3677 The following \Index{manipulators} control \Index{newline separation} for input and output.
     3652The following \Index{manipulator} controls \Index{newline separation} for input and output.
    36783653
    36793654For input:
     
    373037050b0 0b11011 0b11011 0b11011 0b11011
    37313706sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );
    3732 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b®(58 1s)®100101
     37070b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)100101
    37333708\end{cfa}
    37343709
     
    37733748
    37743749\item
    3775 \Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©.
    3776 Printing the base is the default.
     3750\Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©. Printing the base is the default.
    37773751\begin{cfa}[belowskip=0pt]
    37783752sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) );
     
    38083782®  ®4.000000 ® ®4.000000 4.000000
    38093783®  ®ab ® ®ab ab
     3784    ab    ab ab
    38103785\end{cfa}
    38113786If the value is larger, it is printed without truncation, ignoring the ©minimum©.
  • driver/cfa.cc

    r4eb43fa rf6cc734e  
    405405                args[nargs] = "--undefined=__cfaabi_appready_startup";
    406406                nargs += 1;
     407                args[nargs] = "-Xlinker";
     408                nargs += 1;
     409                args[nargs] = "--undefined=__cfaabi_dbg_record";
     410                nargs += 1;
    407411
    408412                // include the cfa library in case it's needed
     
    410414                nargs += 1;
    411415                args[nargs] = ( *new string( string("-Wl,-rpath," ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
    412                 nargs += 1;
    413                 args[nargs] = "-Wl,--push-state,--as-needed";
    414                 nargs += 1;
    415                 args[nargs] = "-lcfathread";
    416                 nargs += 1;
    417                 args[nargs] = "-Wl,--pop-state";
    418416                nargs += 1;
    419417                args[nargs] = "-lcfa";
  • libcfa/prelude/builtins.c

    r4eb43fa rf6cc734e  
    1010// Created On       : Fri Jul 21 16:21:03 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun 25 18:06:52 2019
    13 // Update Count     : 97
     12// Last Modified On : Tue Mar 26 23:10:36 2019
     13// Update Count     : 95
    1414//
    1515
     
    4949void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
    5050
    51 // implicit increment, decrement if += defined, and implicit not if != defined
     51// increment/decrement unification
    5252
    5353static inline {
     
    6363        forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } )
    6464        DT & ?--( DT & x ) { DT tmp = x; x -= 1; return tmp; }
    65 
    66         forall( dtype DT | { int ?!=?( const DT &, zero_t ); } )
    67         int !?( const DT & x ) { return !( x != 0 ); }
    6865} // distribution
    6966
  • libcfa/src/Makefile.am

    r4eb43fa rf6cc734e  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Jul 15 22:43:27 2019
    14 ## Update Count     : 241
     13## Last Modified On : Tue Jul 24 17:25:39 2018
     14## Update Count     : 240
    1515###############################################################################
    1616
     
    2222
    2323libdir = ${CFA_LIBDIR}
    24 lib_LTLIBRARIES = libcfa.la libcfathread.la
     24lib_LTLIBRARIES =  libcfa.la
    2525
    2626VPATH += :../prelude
     
    4141          containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
    4242
     43# not all platforms support concurrency, add option do disable it
     44headers_nosrc += concurrency/invoke.h
     45headers += concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
     46
    4347libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
    4448
    4549# not all platforms support concurrency, add option do disable it
    46 thread_headers_nosrc = concurrency/invoke.h
    47 thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
    48 thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa ${thread_headers:.hfa=.cfa}
     50libsrc += concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa
    4951else
    5052headers =
    51 thread_headers =
    5253headers_nosrc =
    53 thread_headers_nosrc =
    5454libsrc =
    5555endif
     
    6464$(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    6565
    66 thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
    67 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    68 
    6966
    7067# .deps inclusion is not done automatically by automake for new languages
     
    7572
    7673-include $(libdeps)
    77 
    78 thread_libdeps = $(join \
    79         $(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \
    80         $(notdir ${thread_libobjs:.lo=.Plo}) \
    81 )
    82 
    83 -include $(thread_libdeps)
    84 
    8574
    8675prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
     
    9685libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
    9786
    98 libcfathread_la_SOURCES = ${thread_libsrc}
    99 libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@
    100 
    10187stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ")
    10288
    10389cfa_includedir = $(CFA_INCDIR)
    104 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
     90nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc}
    10591
    10692#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/Makefile.in

    r4eb43fa rf6cc734e  
    142142        time.cfa stdlib.cfa common.cfa containers/maybe.cfa \
    143143        containers/pair.cfa containers/result.cfa \
    144         containers/vector.cfa
     144        containers/vector.cfa concurrency/coroutine.cfa \
     145        concurrency/thread.cfa concurrency/kernel.cfa \
     146        concurrency/monitor.cfa concurrency/mutex.cfa \
     147        concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
     148        concurrency/invoke.c concurrency/preemption.cfa
    145149am__dirstamp = $(am__leading_dot)dirstamp
    146150@BUILDLIB_TRUE@am__objects_1 = fstream.lo iostream.lo iterator.lo \
     
    148152@BUILDLIB_TRUE@ common.lo containers/maybe.lo \
    149153@BUILDLIB_TRUE@ containers/pair.lo containers/result.lo \
    150 @BUILDLIB_TRUE@ containers/vector.lo
     154@BUILDLIB_TRUE@ containers/vector.lo concurrency/coroutine.lo \
     155@BUILDLIB_TRUE@ concurrency/thread.lo concurrency/kernel.lo \
     156@BUILDLIB_TRUE@ concurrency/monitor.lo concurrency/mutex.lo
    151157@BUILDLIB_TRUE@am__objects_2 = startup.lo interpose.lo bits/debug.lo \
    152158@BUILDLIB_TRUE@ assert.lo exception.lo virtual.lo heap.lo \
    153 @BUILDLIB_TRUE@ $(am__objects_1)
     159@BUILDLIB_TRUE@ $(am__objects_1) \
     160@BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.lo \
     161@BUILDLIB_TRUE@ concurrency/alarm.lo concurrency/invoke.lo \
     162@BUILDLIB_TRUE@ concurrency/preemption.lo
    154163am_libcfa_la_OBJECTS = prelude.lo $(am__objects_2)
    155164libcfa_la_OBJECTS = $(am_libcfa_la_OBJECTS)
     
    161170        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
    162171        $(libcfa_la_LDFLAGS) $(LDFLAGS) -o $@
    163 libcfathread_la_LIBADD =
    164 am__libcfathread_la_SOURCES_DIST =  \
    165         concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
    166         concurrency/invoke.c concurrency/preemption.cfa \
    167         concurrency/coroutine.cfa concurrency/thread.cfa \
    168         concurrency/kernel.cfa concurrency/monitor.cfa \
    169         concurrency/mutex.cfa
    170 @BUILDLIB_TRUE@am__objects_3 = concurrency/coroutine.lo \
    171 @BUILDLIB_TRUE@ concurrency/thread.lo concurrency/kernel.lo \
    172 @BUILDLIB_TRUE@ concurrency/monitor.lo concurrency/mutex.lo
    173 @BUILDLIB_TRUE@am__objects_4 =  \
    174 @BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.lo \
    175 @BUILDLIB_TRUE@ concurrency/alarm.lo concurrency/invoke.lo \
    176 @BUILDLIB_TRUE@ concurrency/preemption.lo $(am__objects_3)
    177 am_libcfathread_la_OBJECTS = $(am__objects_4)
    178 libcfathread_la_OBJECTS = $(am_libcfathread_la_OBJECTS)
    179 libcfathread_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
    180         $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
    181         $(AM_CFLAGS) $(CFLAGS) $(libcfathread_la_LDFLAGS) $(LDFLAGS) \
    182         -o $@
    183172AM_V_P = $(am__v_P_@AM_V@)
    184173am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
     
    225214am__v_CCLD_0 = @echo "  CCLD    " $@;
    226215am__v_CCLD_1 =
    227 SOURCES = $(libcfa_la_SOURCES) $(libcfathread_la_SOURCES)
    228 DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST) \
    229         $(am__libcfathread_la_SOURCES_DIST)
     216SOURCES = $(libcfa_la_SOURCES)
     217DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST)
    230218am__can_run_installinfo = \
    231219  case $$AM_UPDATE_INFO_DIR in \
     
    237225        limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
    238226        containers/maybe.hfa containers/pair.hfa containers/result.hfa \
    239         containers/vector.hfa math.hfa gmp.hfa time_t.hfa \
    240         bits/align.hfa bits/containers.hfa bits/defs.hfa \
    241         bits/debug.hfa bits/locks.hfa concurrency/coroutine.hfa \
     227        containers/vector.hfa concurrency/coroutine.hfa \
    242228        concurrency/thread.hfa concurrency/kernel.hfa \
    243         concurrency/monitor.hfa concurrency/mutex.hfa \
    244         concurrency/invoke.h
     229        concurrency/monitor.hfa concurrency/mutex.hfa math.hfa gmp.hfa \
     230        time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa \
     231        bits/debug.hfa bits/locks.hfa concurrency/invoke.h
    245232HEADERS = $(nobase_cfa_include_HEADERS)
    246233am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     
    434421am__v_UPP_0 = @echo "  UPP     " $@;
    435422am__v_UPP_1 =
    436 lib_LTLIBRARIES = libcfa.la libcfathread.la
     423lib_LTLIBRARIES = libcfa.la
    437424
    438425# AM_CFLAGS for all cfa source
     
    446433
    447434#----------------------------------------------------------------------------------------------------------------
    448 @BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa
     435
     436# not all platforms support concurrency, add option do disable it
     437@BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa \
     438@BUILDLIB_TRUE@ bits/align.hfa bits/containers.hfa \
     439@BUILDLIB_TRUE@ bits/defs.hfa bits/debug.hfa bits/locks.hfa \
     440@BUILDLIB_TRUE@ concurrency/invoke.h
    449441@BUILDLIB_FALSE@headers =
    450 @BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
    451 @BUILDLIB_TRUE@   containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
    452 
     442@BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa \
     443@BUILDLIB_TRUE@ limits.hfa rational.hfa time.hfa stdlib.hfa \
     444@BUILDLIB_TRUE@ common.hfa containers/maybe.hfa \
     445@BUILDLIB_TRUE@ containers/pair.hfa containers/result.hfa \
     446@BUILDLIB_TRUE@ containers/vector.hfa concurrency/coroutine.hfa \
     447@BUILDLIB_TRUE@ concurrency/thread.hfa concurrency/kernel.hfa \
     448@BUILDLIB_TRUE@ concurrency/monitor.hfa concurrency/mutex.hfa
    453449@BUILDLIB_FALSE@libsrc =
    454 @BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
    455 @BUILDLIB_FALSE@thread_headers_nosrc =
    456450
    457451# not all platforms support concurrency, add option do disable it
    458 @BUILDLIB_TRUE@thread_headers_nosrc = concurrency/invoke.h
    459 @BUILDLIB_FALSE@thread_headers =
    460 @BUILDLIB_TRUE@thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
    461 @BUILDLIB_TRUE@thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa ${thread_headers:.hfa=.cfa}
     452@BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa \
     453@BUILDLIB_TRUE@ assert.cfa exception.c virtual.c heap.cfa \
     454@BUILDLIB_TRUE@ ${headers:.hfa=.cfa} \
     455@BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.S \
     456@BUILDLIB_TRUE@ concurrency/alarm.cfa concurrency/invoke.c \
     457@BUILDLIB_TRUE@ concurrency/preemption.cfa
    462458
    463459#----------------------------------------------------------------------------------------------------------------
     
    467463# add dependency of cfa files
    468464libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc))))
    469 thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
    470465
    471466# .deps inclusion is not done automatically by automake for new languages
     
    475470)
    476471
    477 thread_libdeps = $(join \
    478         $(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \
    479         $(notdir ${thread_libobjs:.lo=.Plo}) \
    480 )
    481 
    482472
    483473#----------------------------------------------------------------------------------------------------------------
    484474libcfa_la_SOURCES = prelude.cfa ${libsrc}
    485475libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
    486 libcfathread_la_SOURCES = ${thread_libsrc}
    487 libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@
    488476stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ")
    489477cfa_includedir = $(CFA_INCDIR)
    490 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
     478nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc}
    491479all: all-am
    492480
     
    579567containers/vector.lo: containers/$(am__dirstamp) \
    580568        containers/$(DEPDIR)/$(am__dirstamp)
    581 
    582 libcfa.la: $(libcfa_la_OBJECTS) $(libcfa_la_DEPENDENCIES) $(EXTRA_libcfa_la_DEPENDENCIES)
    583         $(AM_V_CCLD)$(libcfa_la_LINK) -rpath $(libdir) $(libcfa_la_OBJECTS) $(libcfa_la_LIBADD) $(LIBS)
    584569concurrency/$(am__dirstamp):
    585570        @$(MKDIR_P) concurrency
     
    588573        @$(MKDIR_P) concurrency/$(DEPDIR)
    589574        @: > concurrency/$(DEPDIR)/$(am__dirstamp)
    590 concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \
    591         concurrency/$(DEPDIR)/$(am__dirstamp)
    592 concurrency/alarm.lo: concurrency/$(am__dirstamp) \
    593         concurrency/$(DEPDIR)/$(am__dirstamp)
    594 concurrency/invoke.lo: concurrency/$(am__dirstamp) \
    595         concurrency/$(DEPDIR)/$(am__dirstamp)
    596 concurrency/preemption.lo: concurrency/$(am__dirstamp) \
    597         concurrency/$(DEPDIR)/$(am__dirstamp)
    598575concurrency/coroutine.lo: concurrency/$(am__dirstamp) \
    599576        concurrency/$(DEPDIR)/$(am__dirstamp)
     
    606583concurrency/mutex.lo: concurrency/$(am__dirstamp) \
    607584        concurrency/$(DEPDIR)/$(am__dirstamp)
    608 
    609 libcfathread.la: $(libcfathread_la_OBJECTS) $(libcfathread_la_DEPENDENCIES) $(EXTRA_libcfathread_la_DEPENDENCIES)
    610         $(AM_V_CCLD)$(libcfathread_la_LINK) -rpath $(libdir) $(libcfathread_la_OBJECTS) $(libcfathread_la_LIBADD) $(LIBS)
     585concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \
     586        concurrency/$(DEPDIR)/$(am__dirstamp)
     587concurrency/alarm.lo: concurrency/$(am__dirstamp) \
     588        concurrency/$(DEPDIR)/$(am__dirstamp)
     589concurrency/invoke.lo: concurrency/$(am__dirstamp) \
     590        concurrency/$(DEPDIR)/$(am__dirstamp)
     591concurrency/preemption.lo: concurrency/$(am__dirstamp) \
     592        concurrency/$(DEPDIR)/$(am__dirstamp)
     593
     594libcfa.la: $(libcfa_la_OBJECTS) $(libcfa_la_DEPENDENCIES) $(EXTRA_libcfa_la_DEPENDENCIES)
     595        $(AM_V_CCLD)$(libcfa_la_LINK) -rpath $(libdir) $(libcfa_la_OBJECTS) $(libcfa_la_LIBADD) $(LIBS)
    611596
    612597mostlyclean-compile:
     
    937922        $(am__mv) $$depbase.Tpo $$depbase.Plo
    938923$(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    939 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    940924
    941925-include $(libdeps)
    942 
    943 -include $(thread_libdeps)
    944926
    945927prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
  • libcfa/src/bits/containers.hfa

    r4eb43fa rf6cc734e  
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Oct 31 16:38:50 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 26 08:52:20 2019
    13 // Update Count     : 4
     11// Last Modified By : --
     12// Last Modified On : --
     13// Update Count     : 0
    1414
    1515#pragma once
     
    7878//-----------------------------------------------------------------------------
    7979#ifdef __cforall
    80         forall(dtype TYPE)
     80        forall(dtype TYPE | is_node(TYPE))
    8181        #define T TYPE
    8282#else
     
    9595
    9696#ifdef __cforall
    97         forall(dtype T)
     97        forall(dtype T | is_node(T))
    9898        static inline void ?{}( __stack(T) & this ) {
    9999                (this.top){ NULL };
     
    116116                return top;
    117117        }
    118 
    119         forall(dtype T | is_node(T))
    120         static inline int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
    121                 return this.top != 0;
    122         }
    123118#endif
    124119
     
    127122//-----------------------------------------------------------------------------
    128123#ifdef __cforall
    129         forall(dtype TYPE)
     124        forall(dtype TYPE | is_node(TYPE))
    130125        #define T TYPE
    131126#else
     
    146141#ifdef __cforall
    147142
    148         forall(dtype T)
     143        forall(dtype T | is_node(T))
    149144        static inline void ?{}( __queue(T) & this ) with( this ) {
    150145                head{ NULL };
     
    191186
    192187        forall(dtype T | is_node(T))
    193         static inline int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
     188        static inline bool ?!=?( __queue(T) & this, __attribute__((unused)) zero_t zero ) {
    194189                return this.head != 0;
    195190        }
     
    273268
    274269        forall(dtype T | sized(T))
    275         static inline int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
     270        static inline bool ?!=?( __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
    276271                return this.head != 0;
    277272        }
  • libcfa/src/bits/debug.cfa

    r4eb43fa rf6cc734e  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu Mar 30 12:30:01 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 22:17:35 2019
    13 // Update Count     : 4
     11// Last Modified By :
     12// Last Modified On :
     13// Update Count     : 1
    1414//
    1515
     
    2323}
    2424
    25 enum { buffer_size = 4096 };
     25enum { buffer_size = 512 };
    2626static char buffer[ buffer_size ];
    2727
  • libcfa/src/bits/defs.hfa

    r4eb43fa rf6cc734e  
    4141}
    4242#endif
    43 
    44 #if defined(__cforall_thread__)
    45 #define OPTIONAL_THREAD
    46 #else
    47 #define OPTIONAL_THREAD __attribute__((weak))
    48 #endif
  • libcfa/src/bits/locks.hfa

    r4eb43fa rf6cc734e  
    5050#ifdef __cforall
    5151        extern "C" {
    52                 extern void disable_interrupts() OPTIONAL_THREAD;
    53                 extern void enable_interrupts_noPoll() OPTIONAL_THREAD;
     52                extern void disable_interrupts();
     53                extern void enable_interrupts_noPoll();
    5454
    5555                #ifdef __CFA_DEBUG__
  • libcfa/src/concurrency/alarm.cfa

    r4eb43fa rf6cc734e  
    1313// Update Count     : 67
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816extern "C" {
  • libcfa/src/concurrency/coroutine.cfa

    r4eb43fa rf6cc734e  
    1313// Update Count     : 9
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816#include "coroutine.hfa"
     
    10098
    10199void ^?{}(coroutine_desc& this) {
    102         if(this.state != Halted && this.state != Start && this.state != Primed) {
     100        if(this.state != Halted && this.state != Start) {
    103101                coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    104102                coroutine_desc * dst = &this;
  • libcfa/src/concurrency/invoke.c

    r4eb43fa rf6cc734e  
    1313// Update Count     : 5
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816#include <stdbool.h>
     
    3331extern void __finish_creation( struct thread_desc * );
    3432extern void __leave_thread_monitor( struct thread_desc * this );
    35 extern void disable_interrupts() OPTIONAL_THREAD;
     33extern void disable_interrupts();
    3634extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    3735
  • libcfa/src/concurrency/invoke.h

    r4eb43fa rf6cc734e  
    4646        #ifdef __cforall
    4747        extern "Cforall" {
     48                static inline struct thread_desc             *& get_next( struct thread_desc             & this );
     49                static inline struct __condition_criterion_t *& get_next( struct __condition_criterion_t & this );
     50
    4851                extern thread_local struct KernelThreadData {
    4952                        struct thread_desc    * volatile this_thread;
  • libcfa/src/concurrency/kernel.cfa

    r4eb43fa rf6cc734e  
    1313// Update Count     : 25
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816//C Includes
     
    945943        }
    946944)
    947 
    948 //-----------------------------------------------------------------------------
    949 // Debug
    950 bool threading_enabled(void) {
    951         return true;
    952 }
    953945// Local Variables: //
    954946// mode: c //
  • libcfa/src/concurrency/kernel_private.hfa

    r4eb43fa rf6cc734e  
    2626
    2727extern "C" {
    28         void disable_interrupts() OPTIONAL_THREAD;
     28        void disable_interrupts();
    2929        void enable_interrupts_noPoll();
    3030        void enable_interrupts( __cfaabi_dbg_ctx_param );
  • libcfa/src/concurrency/monitor.cfa

    r4eb43fa rf6cc734e  
    1313// Update Count     : 9
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816#include "monitor.hfa"
  • libcfa/src/concurrency/mutex.cfa

    r4eb43fa rf6cc734e  
    1515// Update Count     : 0
    1616//
    17 
    18 #define __cforall_thread__
    1917
    2018#include "mutex.hfa"
  • libcfa/src/concurrency/preemption.cfa

    r4eb43fa rf6cc734e  
    1313// Update Count     : 37
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816#include "preemption.hfa"
  • libcfa/src/concurrency/thread.cfa

    r4eb43fa rf6cc734e  
    1313// Update Count     : 8
    1414//
    15 
    16 #define __cforall_thread__
    1715
    1816#include "thread.hfa"
  • libcfa/src/fstream.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 15 18:11:26 2019
    13 // Update Count     : 349
     12// Last Modified On : Thu May 16 08:33:28 2019
     13// Update Count     : 328
    1414//
    1515
     
    2424#include <assert.h>
    2525#include <errno.h>                                                                              // errno
    26 
    27 
    28 //*********************************** ofstream ***********************************
    29 
    3026
    3127#define IO_MSG "I/O error: "
     
    4137        sepSetCur( os, sepGet( os ) );
    4238        sepSetTuple( os, ", " );
    43 } // ?{}
     39}
    4440
    4541// private
     
    6056void ?{}( ofstream & os, const char * name, const char * mode ) {
    6157        open( os, name, mode );
    62 } // ?{}
    63 
     58}
    6459void ?{}( ofstream & os, const char * name ) {
    6560        open( os, name, "w" );
    66 } // ?{}
     61}
    6762
    6863void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
     
    10095} // sepSet
    10196
    102 void ends( ofstream & os ) {
    103         if ( getANL( os ) ) nl( os );
    104         else setPrt( os, false );                                                       // turn off
    105         if ( &os == &exit ) exit( EXIT_FAILURE );
    106         if ( &os == &abort ) abort();
    107 } // ends
    108 
    10997int fail( ofstream & os ) {
    11098        return os.file == 0 || ferror( (FILE *)(os.file) );
     
    119107        #ifdef __CFA_DEBUG__
    120108        if ( file == 0 ) {
    121                 abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
     109                abort( IO_MSG "open output file \"%s\", %s", name, strerror( errno ) );
    122110        } // if
    123111        #endif // __CFA_DEBUG__
     
    133121
    134122        if ( fclose( (FILE *)(os.file) ) == EOF ) {
    135                 abort | IO_MSG "close output" | nl | strerror( errno );
     123                abort( IO_MSG "close output %s", strerror( errno ) );
    136124        } // if
    137125} // close
     
    139127ofstream & write( ofstream & os, const char * data, size_t size ) {
    140128        if ( fail( os ) ) {
    141                 abort | IO_MSG "attempt write I/O on failed stream";
     129                abort( "attempt write I/O on failed stream\n" );
    142130        } // if
    143131
    144132        if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) {
    145                 abort | IO_MSG "write" | nl | strerror( errno );
     133                abort( IO_MSG "write %s", strerror( errno ) );
    146134        } // if
    147135        return os;
     
    154142        if ( len == EOF ) {
    155143                if ( ferror( (FILE *)(os.file) ) ) {
    156                         abort | IO_MSG "invalid write";
     144                        abort( "invalid write\n" );
    157145                } // if
    158146        } // if
     
    165153
    166154static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_) };
    167 ofstream & sout = soutFile, & stdout = soutFile;
     155ofstream & sout = soutFile;
    168156static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_) };
    169 ofstream & serr = serrFile, & stderr = serrFile;
    170 
    171 static ofstream exitFile = { (FILE *)(&_IO_2_1_stdout_) };
    172 ofstream & exit = exitFile;
    173 static ofstream abortFile = { (FILE *)(&_IO_2_1_stderr_) };
    174 ofstream & abort = abortFile;
    175 
    176 
    177 //*********************************** ifstream ***********************************
    178 
     157ofstream & serr = serrFile;
     158
     159// static ofstream sexitFile = { (FILE *)(&_IO_2_1_stdout_) };
     160// ofstream & sexit = sexitFile;
     161// static ofstream sabortFile = { (FILE *)(&_IO_2_1_stderr_) };
     162// ofstream & sabort = sabortFile;
     163
     164void nl( ofstream & os ) {
     165        if ( getANL( os ) ) (ofstream &)(nl( os ));                     // implementation only
     166        else setPrt( os, false );                                                       // turn off
     167}
     168
     169//---------------------------------------
    179170
    180171// private
     
    182173        is.file = file;
    183174        is.nlOnOff = false;
    184 } // ?{}
     175}
    185176
    186177// public
     
    189180void ?{}( ifstream & is, const char * name, const char * mode ) {
    190181        open( is, name, mode );
    191 } // ?{}
    192 
     182}
    193183void ?{}( ifstream & is, const char * name ) {
    194184        open( is, name, "r" );
    195 } // ?{}
     185}
    196186
    197187void nlOn( ifstream & os ) { os.nlOnOff = true; }
     
    211201        #ifdef __CFA_DEBUG__
    212202        if ( file == 0 ) {
    213                 abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
     203                abort( IO_MSG "open input file \"%s\", %s\n", name, strerror( errno ) );
    214204        } // if
    215205        #endif // __CFA_DEBUG__
     
    225215
    226216        if ( fclose( (FILE *)(is.file) ) == EOF ) {
    227                 abort | IO_MSG "close input" | nl | strerror( errno );
     217                abort( IO_MSG "close input %s", strerror( errno ) );
    228218        } // if
    229219} // close
     
    231221ifstream & read( ifstream & is, char * data, size_t size ) {
    232222        if ( fail( is ) ) {
    233                 abort | IO_MSG "attempt read I/O on failed stream";
     223                abort( "attempt read I/O on failed stream\n" );
    234224        } // if
    235225
    236226        if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) {
    237                 abort | IO_MSG "read" | nl | strerror( errno );
     227                abort( IO_MSG "read %s", strerror( errno ) );
    238228        } // if
    239229        return is;
     
    242232ifstream &ungetc( ifstream & is, char c ) {
    243233        if ( fail( is ) ) {
    244                 abort | IO_MSG "attempt ungetc I/O on failed stream";
     234                abort( "attempt ungetc I/O on failed stream\n" );
    245235        } // if
    246236
    247237        if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
    248                 abort | IO_MSG "ungetc" | nl | strerror( errno );
     238                abort( IO_MSG "ungetc %s", strerror( errno ) );
    249239        } // if
    250240        return is;
     
    258248        if ( len == EOF ) {
    259249                if ( ferror( (FILE *)(is.file) ) ) {
    260                         abort | IO_MSG "invalid read";
     250                        abort( "invalid read\n" );
    261251                } // if
    262252        } // if
     
    267257
    268258static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) };
    269 ifstream & sin = sinFile, & stdin = sinFile;
     259ifstream & sin = sinFile;
    270260
    271261// Local Variables: //
  • libcfa/src/fstream.hfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 15 18:10:23 2019
    13 // Update Count     : 167
     12// Last Modified On : Thu May 16 08:34:10 2019
     13// Update Count     : 157
    1414//
    1515
     
    1717
    1818#include "iostream.hfa"
    19 
    20 
    21 //*********************************** ofstream ***********************************
    22 
    2319
    2420enum { sepSize = 16 };
     
    6056void sepSetTuple( ofstream &, const char * );
    6157
    62 void ends( ofstream & os );
    6358int fail( ofstream & );
    6459int flush( ofstream & );
     
    7368void ?{}( ofstream & os, const char * name );
    7469
    75 extern ofstream & sout, & stdout, & serr, & stderr;             // aliases
    76 extern ofstream & exit, & abort;
     70extern ofstream & sout, & serr;
    7771
    78 
    79 //*********************************** ifstream ***********************************
     72// extern ofstream & sout, & serr, & sexit, & sabort;
     73// void nl( ofstream & os );
    8074
    8175
     
    10296void ?{}( ifstream & is, const char * name );
    10397
    104 extern ifstream & sin, & stdin;                                                 // aliases
     98extern ifstream & sin;
    10599
    106100// Local Variables: //
  • libcfa/src/gmp.hfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 15:25:05 2019
    13 // Update Count     : 27
     12// Last Modified On : Sat Apr 20 09:01:52 2019
     13// Update Count     : 24
    1414//
    1515
     
    1919
    2020#include <gmp.h>                                                                                // GNU multi-precise integers
    21 #include <fstream.hfa>                                                                  // sout
     21#include <fstream.hfa>                                                                          // sout
    2222
    2323struct Int { mpz_t mpz; };                                                              // wrap GMP implementation
    2424
    25 static inline {
    26         // constructor
    27         void ?{}( Int & this ) { mpz_init( this.mpz ); }
    28         void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
    29         void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
    30         void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
    31         void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
    32         void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
    33         void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
    34         void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
    35 
    36         // literal
    37         Int ?`mp( signed long int init ) { return (Int){ init }; }
    38         Int ?`mp( unsigned long int init ) { return (Int){ init }; }
    39         Int ?`mp( const char * init ) { return (Int){ init }; }
    40 
    41         // assignment
    42         Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; }
    43         Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
    44         Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
    45         Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
    46 
    47         char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    48         short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    49         int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    50         long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    51         unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    52         unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    53         unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    54         unsigned long int ?=?( unsigned long int & lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    55 
    56         // conversions
    57         long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
    58         unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
    59 
    60         // comparison
    61         int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
    62         int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
    63         int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
    64         int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
    65         int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
    66 
    67         int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    68         int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
    69         int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    70         int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
    71         int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    72 
    73         int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
    74         int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
    75         int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
    76         int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
    77         int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
    78 
    79         int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
    80         int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
    81         int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
    82         int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
    83         int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
    84 
    85         int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    86         int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
    87         int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    88         int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
    89         int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    90 
    91         int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    92         int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
    93         int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    94         int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
    95         int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    96 
    97         // arithmetic
    98         Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
    99         Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
    100         Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
    101 
    102         Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
    103         Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
    104         Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
    105         Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
    106         Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
    107         Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; }
    108 
    109         Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
    110         Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    111         Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    112         Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    113         Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    114         Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; }
    115 
    116         Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
    117         Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    118         Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    119         Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    120         Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    121         Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; }
    122 
    123         Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
    124         Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
    125         Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
    126         Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
    127         Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
    128         Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; }
    129         Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; }
    130         Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; }
    131         Int ++?( Int & lhs ) { return lhs += 1; }
    132         Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; }
    133 
    134         Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
    135         Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
    136         Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
    137         Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
    138         Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
    139         Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; }
    140         Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; }
    141         Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; }
    142         Int --?( Int & lhs ) { return lhs -= 1; }
    143         Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; }
    144 
    145         Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
    146         Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    147         Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    148         Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    149         Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    150         Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; }
    151         Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; }
    152         Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; }
    153 
    154         // some code for operators "/" and "%" taken from g++ gmpxx.h
    155         Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
    156         Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
    157         Int ?/?( unsigned long int dividend, Int divisor ) {
    158                 Int quotient;
    159                 if ( mpz_sgn( divisor.mpz ) >= 0 ) {
    160                         if ( mpz_fits_ulong_p( divisor.mpz ) )
    161                                 mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( divisor.mpz ) );
    162                         else
    163                                 mpz_set_ui( quotient.mpz, 0 );
    164                 } else {
    165                         mpz_neg( quotient.mpz, divisor.mpz );
    166                         if ( mpz_fits_ulong_p( quotient.mpz ) ) {
    167                                 mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( quotient.mpz ) );
    168                                 mpz_neg( quotient.mpz, quotient.mpz );
    169                         } else
    170                                 mpz_set_ui( quotient.mpz, 0 );
    171                 } // if
    172                 return quotient;
    173         } // ?/?
    174         Int ?/?( Int dividend, long int divisor ) {
    175                 Int quotient;
    176                 if ( divisor >= 0 )
    177                         mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor );
    178                 else {
    179                         mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, -divisor );
     25// constructor
     26static inline void ?{}( Int & this ) { mpz_init( this.mpz ); }
     27static inline void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
     28static inline void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
     29static inline void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
     30static inline void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
     31static inline void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
     32static inline void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
     33static inline void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
     34
     35// literal
     36static inline Int ?`mp( signed long int init ) { return (Int){ init }; }
     37static inline Int ?`mp( unsigned long int init ) { return (Int){ init }; }
     38static inline Int ?`mp( const char * init ) { return (Int){ init }; }
     39
     40// assignment
     41static inline Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; }
     42static inline Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
     43static inline Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
     44static inline Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return lhs; }
     45
     46static inline char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     47static inline short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     48static inline int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     49static inline long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     50static inline unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     51static inline unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     52static inline unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     53static inline unsigned long int ?=?( unsigned long int & lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     54
     55// conversions
     56static inline long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
     57static inline unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
     58
     59// comparison
     60static inline int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
     61static inline int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
     62static inline int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
     63static inline int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
     64static inline int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
     65
     66static inline int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     67static inline int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
     68static inline int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     69static inline int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
     70static inline int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     71
     72static inline int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
     73static inline int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
     74static inline int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
     75static inline int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
     76static inline int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
     77
     78static inline int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
     79static inline int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
     80static inline int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
     81static inline int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
     82static inline int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
     83
     84static inline int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     85static inline int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
     86static inline int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     87static inline int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
     88static inline int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     89
     90static inline int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     91static inline int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
     92static inline int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     93static inline int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
     94static inline int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     95
     96// arithmetic
     97static inline Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
     98static inline Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
     99static inline Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
     100
     101static inline Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
     102static inline Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
     103static inline Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
     104static inline Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
     105static inline Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
     106static inline Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; }
     107
     108static inline Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
     109static inline Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     110static inline Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     111static inline Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     112static inline Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     113static inline Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; }
     114
     115static inline Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
     116static inline Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     117static inline Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     118static inline Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     119static inline Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     120static inline Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; }
     121
     122static inline Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
     123static inline Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
     124static inline Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
     125static inline Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
     126static inline Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
     127static inline Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; }
     128static inline Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; }
     129static inline Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; }
     130static inline Int ++?( Int & lhs ) { return lhs += 1; }
     131static inline Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; }
     132
     133static inline Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
     134static inline Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
     135static inline Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
     136static inline Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
     137static inline Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
     138static inline Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; }
     139static inline Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; }
     140static inline Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; }
     141static inline Int --?( Int & lhs ) { return lhs -= 1; }
     142static inline Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; }
     143
     144static inline Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
     145static inline Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     146static inline Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     147static inline Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     148static inline Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     149static inline Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; }
     150static inline Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; }
     151static inline Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; }
     152
     153// some code for operators "/" and "%" taken from g++ gmpxx.h
     154static inline Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
     155static inline Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
     156static inline Int ?/?( unsigned long int dividend, Int divisor ) {
     157        Int quotient;
     158    if ( mpz_sgn( divisor.mpz ) >= 0 ) {
     159                if ( mpz_fits_ulong_p( divisor.mpz ) )
     160                        mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( divisor.mpz ) );
     161                else
     162                        mpz_set_ui( quotient.mpz, 0 );
     163        } else {
     164                mpz_neg( quotient.mpz, divisor.mpz );
     165                if ( mpz_fits_ulong_p( quotient.mpz ) ) {
     166                        mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( quotient.mpz ) );
    180167                        mpz_neg( quotient.mpz, quotient.mpz );
    181                 } // if
    182                 return quotient;
    183         } // ?/?
    184         Int ?/?( long int dividend, Int divisor ) {
    185                 Int quotient;
    186                 if ( mpz_fits_slong_p( divisor.mpz ) )
    187                         mpz_set_si( quotient.mpz, dividend / mpz_get_si( divisor.mpz ) );
    188                 else {
    189                         // if divisor is bigger than a long then the quotient must be zero, unless dividend==LONG_MIN and
    190                         // dividend==-LONG_MIN in which case the quotient is -1
    191                         mpz_set_si( quotient.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? -1 : 0 );
    192                 } // if
    193                 return quotient;
    194         } // ?/?
    195         Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; }
    196         Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; }
    197         Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; }
    198 
    199         [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
    200         [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
    201 
    202         Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
    203         Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
    204         Int ?%?( unsigned long int dividend, Int divisor ) {
    205                 Int remainder;
    206                 if ( mpz_sgn( divisor.mpz ) >= 0 ) {
    207                         if ( mpz_fits_ulong_p( divisor.mpz ) )
    208                                 mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( divisor.mpz ) );
    209                         else
    210                                 mpz_set_ui( remainder.mpz, dividend );
    211                 } else {
    212                         mpz_neg( remainder.mpz, divisor.mpz );
    213                         if ( mpz_fits_ulong_p( remainder.mpz ) )
    214                                 mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( remainder.mpz ) );
    215                         else
    216                                 mpz_set_ui( remainder.mpz, dividend );
    217                 } // if
    218                 return remainder;
    219         } // ?%?
    220         Int ?%?( Int dividend, long int divisor ) {
    221                 Int remainder;
    222                 mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
    223                 return remainder;
    224         } // ?%?
    225         Int ?%?( long int dividend, Int divisor ) {
    226                 Int remainder;
    227                 if ( mpz_fits_slong_p( divisor.mpz ) )
    228                         mpz_set_si( remainder.mpz, dividend % mpz_get_si( divisor.mpz ) );
    229                 else {
    230                         // if divisor is bigger than a long then the remainder is dividend unchanged, unless dividend==LONG_MIN and
    231                         // dividend==-LONG_MIN in which case the remainder is 0
    232                         mpz_set_si( remainder.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? 0 : dividend);
    233                 } // if
    234                 return remainder;
    235         } // ?%?
    236         Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; }
    237         Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; }
    238         Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; }
    239 
    240         Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
    241         Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; }
    242         Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
    243         Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; }
    244 
    245         // number functions
    246         Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
    247         Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
    248         Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
    249         Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
    250         Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
    251         void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
    252         Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
    253         Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
    254         Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
    255         int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
    256         Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
    257 
    258         // I/O
    259         forall( dtype istype | istream( istype ) )
    260                 istype & ?|?( istype & is, Int & mp ) {
    261                 gmp_scanf( "%Zd", &mp );
    262                 return is;
     168                } else
     169                        mpz_set_ui( quotient.mpz, 0 );
     170        } // if
     171        return quotient;
     172} // ?/?
     173static inline Int ?/?( Int dividend, long int divisor ) {
     174        Int quotient;
     175    if ( divisor >= 0 )
     176                mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor );
     177    else {
     178                mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, -divisor );
     179                mpz_neg( quotient.mpz, quotient.mpz );
     180        } // if
     181        return quotient;
     182} // ?/?
     183static inline Int ?/?( long int dividend, Int divisor ) {
     184        Int quotient;
     185    if ( mpz_fits_slong_p( divisor.mpz ) )
     186                mpz_set_si( quotient.mpz, dividend / mpz_get_si( divisor.mpz ) );
     187    else {
     188        // if divisor is bigger than a long then the quotient must be zero, unless dividend==LONG_MIN and
     189        // dividend==-LONG_MIN in which case the quotient is -1
     190        mpz_set_si( quotient.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? -1 : 0 );
     191        } // if
     192        return quotient;
     193} // ?/?
     194static inline Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; }
     195static inline Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; }
     196static inline Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; }
     197
     198static inline [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
     199static inline [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
     200
     201static inline Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
     202static inline Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
     203static inline Int ?%?( unsigned long int dividend, Int divisor ) {
     204        Int remainder;
     205    if ( mpz_sgn( divisor.mpz ) >= 0 ) {
     206                if ( mpz_fits_ulong_p( divisor.mpz ) )
     207                        mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( divisor.mpz ) );
     208                else
     209                        mpz_set_ui( remainder.mpz, dividend );
     210        } else {
     211                mpz_neg( remainder.mpz, divisor.mpz );
     212                if ( mpz_fits_ulong_p( remainder.mpz ) )
     213                        mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( remainder.mpz ) );
     214                else
     215                        mpz_set_ui( remainder.mpz, dividend );
     216        } // if
     217        return remainder;
     218} // ?%?
     219static inline Int ?%?( Int dividend, long int divisor ) {
     220        Int remainder;
     221    mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
     222        return remainder;
     223} // ?%?
     224static inline Int ?%?( long int dividend, Int divisor ) {
     225        Int remainder;
     226    if ( mpz_fits_slong_p( divisor.mpz ) )
     227                mpz_set_si( remainder.mpz, dividend % mpz_get_si( divisor.mpz ) );
     228        else {
     229                // if divisor is bigger than a long then the remainder is dividend unchanged, unless dividend==LONG_MIN and
     230                // dividend==-LONG_MIN in which case the remainder is 0
     231        mpz_set_si( remainder.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? 0 : dividend);
     232        } // if
     233        return remainder;
     234} // ?%?
     235static inline Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; }
     236static inline Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; }
     237static inline Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; }
     238
     239static inline Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
     240static inline Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; }
     241static inline Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
     242static inline Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; }
     243
     244// number functions
     245static inline Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
     246static inline Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
     247static inline Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
     248static inline Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
     249static inline Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
     250static inline void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
     251static inline Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
     252static inline Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
     253static inline Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
     254static inline int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
     255static inline Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
     256
     257// I/O
     258static inline forall( dtype istype | istream( istype ) )
     259istype & ?|?( istype & is, Int & mp ) {
     260        gmp_scanf( "%Zd", &mp );
     261        return is;
     262} // ?|?
     263
     264static inline forall( dtype ostype | ostream( ostype ) ) {
     265        ostype & ?|?( ostype & os, Int mp ) {
     266                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     267                gmp_printf( "%Zd", mp.mpz );
     268                sepOn( os );
     269                return os;
    263270        } // ?|?
    264271
    265         forall( dtype ostype | ostream( ostype ) ) {
    266                 ostype & ?|?( ostype & os, Int mp ) {
    267                         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    268                         gmp_printf( "%Zd", mp.mpz );
    269                         sepOn( os );
    270                         return os;
    271                 } // ?|?
    272 
    273                 void ?|?( ostype & os, Int mp ) {
    274                         (ostype)(os | mp); ends( os );
    275                 } // ?|?
    276         } // distribution
     272        void ?|?( ostype & os, Int mp ) {
     273                (ostype)(os | mp); nl( os );
     274        } // ?|?
    277275} // distribution
    278276
  • libcfa/src/interpose.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 22:57:16 2019
    13 // Update Count     : 116
     12// Last Modified On : Sat May  5 11:37:35 2018
     13// Update Count     : 111
    1414//
    1515
     
    8181//=============================================================================================
    8282
    83 void sigHandler_segv( __CFA_SIGPARMS__ );
    84 void sigHandler_ill ( __CFA_SIGPARMS__ );
    85 void sigHandler_fpe ( __CFA_SIGPARMS__ );
    86 void sigHandler_abrt( __CFA_SIGPARMS__ );
    87 void sigHandler_term( __CFA_SIGPARMS__ );
     83void sigHandler_segv ( __CFA_SIGPARMS__ );
     84void sigHandler_ill  ( __CFA_SIGPARMS__ );
     85void sigHandler_fpe  ( __CFA_SIGPARMS__ );
     86void sigHandler_abort( __CFA_SIGPARMS__ );
     87void sigHandler_term ( __CFA_SIGPARMS__ );
    8888
    8989struct {
     
    110110                __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
    111111                __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
    112                 __cfaabi_sigaction( SIGABRT, sigHandler_abrt, SA_SIGINFO | SA_RESETHAND);
     112                __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND);
    113113                __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
    114114                __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
     
    204204                        if ( *p == '(' ) {
    205205                                name = p;
    206                         } else if ( *p == '+' ) {
     206                        }
     207                        else if ( *p == '+' ) {
    207208                                offset_begin = p;
    208                         } else if ( *p == ')' ) {
     209                        }
     210                        else if ( *p == ')' ) {
    209211                                offset_end = p;
    210212                                break;
     
    221223
    222224                        __cfaabi_dbg_bits_print_nolock( "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
    223                 } else {                                                                                // otherwise, print the whole line
     225                }
     226                // otherwise, print the whole line
     227                else {
    224228                        __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] );
    225229                }
     
    254258}
    255259
    256 void sigHandler_abrt( __CFA_SIGPARMS__ ) {
     260void sigHandler_abort( __CFA_SIGPARMS__ ) {
    257261        __cfaabi_backtrace();
    258262
  • libcfa/src/iostream.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 08:07:59 2019
    13 // Update Count     : 821
     12// Last Modified On : Thu Jun 13 17:21:10 2019
     13// Update Count     : 812
    1414//
    1515
     
    3030
    3131
    32 //*********************************** ostream ***********************************
     32//*********************************** Ostream ***********************************
    3333
    3434
     
    4040        } // ?|?
    4141        void ?|?( ostype & os, zero_t z ) {
    42                 (ostype &)(os | z); ends( os );
     42                (ostype &)(os | z); nl( os );
    4343        } // ?|?
    4444
     
    4949        } // ?|?
    5050        void ?|?( ostype & os, one_t o ) {
    51                 (ostype &)(os | o); ends( os );
     51                (ostype &)(os | o); nl( os );
    5252        } // ?|?
    5353
     
    5858        } // ?|?
    5959        void ?|?( ostype & os, bool b ) {
    60                 (ostype &)(os | b); ends( os );
     60                (ostype &)(os | b); nl( os );
    6161        } // ?|?
    6262
     
    6767        } // ?|?
    6868        void ?|?( ostype & os, char c ) {
    69                 (ostype &)(os | c); ends( os );
     69                (ostype &)(os | c); nl( os );
    7070        } // ?|?
    7171
     
    7676        } // ?|?
    7777        void ?|?( ostype & os, signed char sc ) {
    78                 (ostype &)(os | sc); ends( os );
     78                (ostype &)(os | sc); nl( os );
    7979        } // ?|?
    8080
     
    8585        } // ?|?
    8686        void ?|?( ostype & os, unsigned char usc ) {
    87                 (ostype &)(os | usc); ends( os );
     87                (ostype &)(os | usc); nl( os );
    8888        } // ?|?
    8989
     
    9494        } // ?|?
    9595        void & ?|?( ostype & os, short int si ) {
    96                 (ostype &)(os | si); ends( os );
     96                (ostype &)(os | si); nl( os );
    9797        } // ?|?
    9898
     
    103103        } // ?|?
    104104        void & ?|?( ostype & os, unsigned short int usi ) {
    105                 (ostype &)(os | usi); ends( os );
     105                (ostype &)(os | usi); nl( os );
    106106        } // ?|?
    107107
     
    112112        } // ?|?
    113113        void & ?|?( ostype & os, int i ) {
    114                 (ostype &)(os | i); ends( os );
     114                (ostype &)(os | i); nl( os );
    115115        } // ?|?
    116116
     
    121121        } // ?|?
    122122        void & ?|?( ostype & os, unsigned int ui ) {
    123                 (ostype &)(os | ui); ends( os );
     123                (ostype &)(os | ui); nl( os );
    124124        } // ?|?
    125125
     
    130130        } // ?|?
    131131        void & ?|?( ostype & os, long int li ) {
    132                 (ostype &)(os | li); ends( os );
     132                (ostype &)(os | li); nl( os );
    133133        } // ?|?
    134134
     
    139139        } // ?|?
    140140        void & ?|?( ostype & os, unsigned long int uli ) {
    141                 (ostype &)(os | uli); ends( os );
     141                (ostype &)(os | uli); nl( os );
    142142        } // ?|?
    143143
     
    148148        } // ?|?
    149149        void & ?|?( ostype & os, long long int lli ) {
    150                 (ostype &)(os | lli); ends( os );
     150                (ostype &)(os | lli); nl( os );
    151151        } // ?|?
    152152
     
    157157        } // ?|?
    158158        void & ?|?( ostype & os, unsigned long long int ulli ) {
    159                 (ostype &)(os | ulli); ends( os );
     159                (ostype &)(os | ulli); nl( os );
    160160        } // ?|?
    161161
     
    180180        } // ?|?
    181181        void & ?|?( ostype & os, float f ) {
    182                 (ostype &)(os | f); ends( os );
     182                (ostype &)(os | f); nl( os );
    183183        } // ?|?
    184184
     
    189189        } // ?|?
    190190        void & ?|?( ostype & os, double d ) {
    191                 (ostype &)(os | d); ends( os );
     191                (ostype &)(os | d); nl( os );
    192192        } // ?|?
    193193
     
    198198        } // ?|?
    199199        void & ?|?( ostype & os, long double ld ) {
    200                 (ostype &)(os | ld); ends( os );
     200                (ostype &)(os | ld); nl( os );
    201201        } // ?|?
    202202
     
    210210        } // ?|?
    211211        void & ?|?( ostype & os, float _Complex fc ) {
    212                 (ostype &)(os | fc); ends( os );
     212                (ostype &)(os | fc); nl( os );
    213213        } // ?|?
    214214
     
    222222        } // ?|?
    223223        void & ?|?( ostype & os, double _Complex dc ) {
    224                 (ostype &)(os | dc); ends( os );
     224                (ostype &)(os | dc); nl( os );
    225225        } // ?|?
    226226
     
    234234        } // ?|?
    235235        void & ?|?( ostype & os, long double _Complex ldc ) {
    236                 (ostype &)(os | ldc); ends( os );
     236                (ostype &)(os | ldc); nl( os );
    237237        } // ?|?
    238238
     
    276276        } // ?|?
    277277        void ?|?( ostype & os, const char * str ) {
    278                 (ostype &)(os | str); ends( os );
     278                (ostype &)(os | str); nl( os );
    279279        } // ?|?
    280280
     
    305305        } // ?|?
    306306        void ?|?( ostype & os, const void * p ) {
    307                 (ostype &)(os | p); ends( os );
     307                (ostype &)(os | p); nl( os );
    308308        } // ?|?
    309309
     
    315315        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    316316                (ostype &)(manip( os ));
    317                 if ( getPrt( os ) ) ends( os );                                 // something printed ?
     317                if ( getPrt( os ) ) nl( os );                                   // something printed ?
    318318                setPrt( os, false );                                                    // turn off
    319319        } // ?|?
     
    335335        } // nl
    336336
     337        void nl( ostype & os ) {
     338                if ( getANL( os ) ) (ostype &)(nl( os ));               // implementation only
     339                else setPrt( os, false );                                               // turn off
     340        } // nl
     341
    337342        ostype & nonl( ostype & os ) {
    338343                setPrt( os, false );                                                    // turn off
     
    381386        } // ?|?
    382387        void ?|?( ostype & os, T arg, Params rest ) {
    383                 // (ostype &)(?|?( os, arg, rest )); ends( os );
     388                // (ostype &)(?|?( os, arg, rest )); nl( os );
    384389                (ostype &)(os | arg);                                                   // print first argument
    385390                sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
    386391                (ostype &)(os | rest);                                                  // print remaining arguments
    387392                sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
    388                 ends( os );
     393                nl( os );
    389394        } // ?|?
    390395} // distribution
     
    403408} // distribution
    404409
    405 //*********************************** manipulators ***********************************
    406 
    407 //*********************************** integral ***********************************
     410//*********************************** Manipulators ***********************************
     411
     412//*********************************** Integral ***********************************
    408413
    409414static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     
    473478                return os; \
    474479        } /* ?|? */ \
    475         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     480        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
    476481} // distribution
    477482
     
    487492IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
    488493
    489 //*********************************** floating point ***********************************
     494//*********************************** Floating Point ***********************************
    490495
    491496#define PrintWithDP2( os, format, val, ... ) \
     
    499504                                if ( ! f.flags.left ) { \
    500505                                        buf[i] = '.'; buf[i + 1] = '\0'; \
    501                                         if ( buf[0] == ' ' ) bufbeg = 1;        /* decimal point within width */ \
     506                                        if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
    502507                                } else { \
    503508                                        for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
     
    536541                return os; \
    537542        } /* ?|? */ \
    538         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     543        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
    539544} // distribution
    540545
     
    542547FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
    543548
    544 //*********************************** character ***********************************
     549//*********************************** Character ***********************************
    545550
    546551forall( dtype ostype | ostream( ostype ) ) {
    547552        ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
    548                 if ( f.base != 'c' ) {                                                  // bespoke binary/octal/hex format
     553                if ( f.base != 'c' ) {                                                          // bespoke binary/octal/hex format
    549554                        _Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} };
    550555                        fmtuc.flags.pc = f.flags.pc;
     
    558563
    559564                #define CFMTNP "% * "
    560                 char fmtstr[sizeof(CFMTNP)];                                    // sizeof includes '\0'
     565                char fmtstr[sizeof(CFMTNP)];                                            // sizeof includes '\0'
    561566                memcpy( &fmtstr, CFMTNP, sizeof(CFMTNP) );
    562                 int star = 1;                                                                   // position before first '*'
     567                int star = 1;                                                                           // position before first '*'
    563568
    564569                // Insert flags into spaces before '*', from right to left.
     
    566571                fmtstr[star] = '%';
    567572
    568                 fmtstr[sizeof(CFMTNP)-2] = f.base;                              // sizeof includes '\0'
     573                fmtstr[sizeof(CFMTNP)-2] = f.base;                                      // sizeof includes '\0'
    569574                // printf( "%d %s\n", f.wd, &fmtstr[star] );
    570575                fmt( os, &fmtstr[star], f.wd, f.val );
    571576                return os;
    572577        } // ?|?
    573         void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
     578        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); nl( os ); }
    574579} // distribution
    575580
    576 //*********************************** C string ***********************************
     581//*********************************** C String ***********************************
    577582
    578583forall( dtype ostype | ostream( ostype ) ) {
     
    616621                return os;
    617622        } // ?|?
    618         void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
     623        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); nl( os ); }
    619624} // distribution
    620625
    621626
    622 //*********************************** istream ***********************************
     627//*********************************** Istream ***********************************
    623628
    624629
     
    631636                else {
    632637                        fprintf( stderr, "invalid Boolean constant\n" );
    633                         abort();                                                                        // cannot use abort stream
     638                        abort();
    634639                } // if
    635640                return is;
     
    639644                char temp;
    640645                for () {
    641                         fmt( is, "%c", &temp );                                         // must pass pointer through varg to fmt
     646                        fmt( is, "%c", &temp );                                                 // must pass pointer through varg to fmt
    642647                        // do not overwrite parameter with newline unless appropriate
    643648                        if ( temp != '\n' || getANL( is ) ) { c = temp; break; }
     
    766771} // distribution
    767772
    768 //*********************************** manipulators ***********************************
     773//*********************************** Manipulators ***********************************
    769774
    770775forall( dtype istype | istream( istype ) )
     
    773778        if ( ! f.s ) {
    774779                // printf( "skip %s %d\n", f.scanset, f.wd );
    775                 if ( f.wd == -1 ) fmt( is, f.scanset, "" );             // no input arguments
     780                if ( f.wd == -1 ) fmt( is, f.scanset, "" ); // no input arguments
    776781                else for ( f.wd ) fmt( is, "%*c" );
    777782                return is;
  • libcfa/src/iostream.hfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 12:08:38 2019
    13 // Update Count     : 334
     12// Last Modified On : Thu Jun 13 17:20:21 2019
     13// Update Count     : 325
    1414//
    1515
     
    1919
    2020
    21 //*********************************** ostream ***********************************
     21//*********************************** Ostream ***********************************
    2222
    2323
     
    4747        void sepSetTuple( ostype &, const char * );                     // set tuple separator to string (15 character maximum)
    4848
    49         void ends( ostype & os );                                                       // end of output statement
    5049        int fail( ostype & );
    5150        int flush( ostype & );
     
    9998        void ?|?( ostype &, unsigned long long int );
    10099
    101         ostype & ?|?( ostype &, float );
    102         void ?|?( ostype &, float );
     100        ostype & ?|?( ostype &, float ); // FIX ME: should not be required
     101        void ?|?( ostype &, float ); // FIX ME: should not be required
    103102        ostype & ?|?( ostype &, double );
    104103        void ?|?( ostype &, double );
     
    127126        void ?|?( ostype &, ostype & (*)( ostype & ) );
    128127        ostype & nl( ostype & );
     128        void nl( ostype & );
    129129        ostype & nonl( ostype & );
    130130        ostype & sep( ostype & );
     
    150150} // distribution
    151151
    152 //*********************************** manipulators ***********************************
     152//*********************************** Manipulators ***********************************
    153153
    154154forall( otype T )
     
    169169}; // _Ostream_Manip
    170170
    171 //*********************************** integral ***********************************
     171//*********************************** Integral ***********************************
    172172
    173173// See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular
     
    207207IntegralFMTDecl( unsigned long long int, 'u' )
    208208
    209 //*********************************** floating point ***********************************
     209//*********************************** Floating Point ***********************************
    210210
    211211// Default suffix for values with no fraction is "."
     
    236236FloatingPointFMTDecl( long double )
    237237
    238 //*********************************** character ***********************************
     238//*********************************** Character ***********************************
    239239
    240240static inline {
     
    253253} // ?|?
    254254
    255 //*********************************** C string ***********************************
     255//*********************************** C String ***********************************
    256256
    257257static inline {
     
    272272
    273273
    274 //*********************************** istream ***********************************
     274//*********************************** Istream ***********************************
    275275
    276276
     
    326326} // distribution
    327327
    328 //*********************************** manipulators ***********************************
     328//*********************************** Manipulators ***********************************
    329329
    330330struct _Istream_Cstr {
     
    403403
    404404
    405 //*********************************** time ***********************************
     405//*********************************** Time ***********************************
    406406
    407407
  • libcfa/src/rational.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 18:12:08 2019
    13 // Update Count     : 184
     12// Last Modified On : Thu Mar 28 17:33:03 2019
     13// Update Count     : 181
    1414//
    1515
     
    3535        static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
    3636                if ( d == (RationalImpl){0} ) {
    37                         abort | "Invalid rational number construction: denominator cannot be equal to 0.";
     37                        abort( "Invalid rational number construction: denominator cannot be equal to 0.\n" );
    3838                } // exit
    3939                if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
     
    167167
    168168                void ?|?( ostype & os, Rational(RationalImpl) r ) {
    169                         (ostype &)(os | r); ends( os );
     169                        (ostype &)(os | r); nl( os );
    170170                } // ?|?
    171171        } // distribution
  • libcfa/src/stdlib.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun 24 17:34:44 2019
    13 // Update Count     : 462
     12// Last Modified On : Thu Jul 12 08:03:59 2018
     13// Update Count     : 458
    1414//
    1515
     
    6565forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
    6666T * anew( size_t dim, Params p ) {
    67         T * arr = alloc( dim );
     67        T *arr = alloc( dim );
    6868        for ( unsigned int i = 0; i < dim; i += 1 ) {
    6969                (arr[i]){ p };                                                                  // run constructor
     
    252252long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); }
    253253
    254 //---------------------------------------
    255 
    256 bool threading_enabled(void) __attribute__((weak)) {
    257         return false;
    258 }
    259254
    260255// Local Variables: //
  • libcfa/src/stdlib.hfa

    r4eb43fa rf6cc734e  
    1515
    1616#pragma once
    17 
    18 #include "bits/defs.hfa"
    1917
    2018#include <stdlib.h>                                                                             // *alloc, strto*, ato*
     
    248246#include "common.hfa"
    249247
    250 //---------------------------------------
    251 
    252 extern bool threading_enabled(void) OPTIONAL_THREAD;
    253 
    254248// Local Variables: //
    255249// mode: c //
  • libcfa/src/time.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 08:41:55 2019
    13 // Update Count     : 65
     12// Last Modified On : Sun Dec 23 22:57:48 2018
     13// Update Count     : 57
    1414//
    1515
    1616#include "time.hfa"
    17 #include "fstream.hfa"
     17#include "iostream.hfa"
    1818#include <stdio.h>                                                                              // snprintf
    1919#include <assert.h>
     
    3737                if ( ns != 0 ) {                                                                // some ?
    3838                        char buf[16];
    39                         (ostype &)(os | nanomsd( ns, buf ));            // print nanoseconds
     39                        (ostype &)(os | nanomsd( ns, buf ));                    // print nanoseconds
    4040                } // if
    4141                return os;
     
    4343
    4444        void ?|?( ostype & os, Duration dur ) with( dur ) {
    45                 (ostype &)(os | dur); ends( os );
     45                (ostype &)(os | dur); nl( os );
    4646        } // ?|?
    4747} // distribution
     
    5252
    5353#ifdef __CFA_DEBUG__
    54 static void tabort( int year, int month, int day, int hour, int min, int sec, int nsec ) {
    55         abort | "Attempt to create Time( year=" | year | "(>=1970), month=" | month | "(1-12), day=" | day | "(1-31), hour=" | hour | "(0-23), min=" | min | "(0-59), sec=" | sec
    56                   | "(0-60), nsec=" | nsec | "(0-999_999_999), which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038.";
    57 } // tabort
     54#define CreateFmt "Attempt to create Time( year=%d (>=1970), month=%d (1-12), day=%d (1-31), hour=%d (0-23), min=%d (0-59), sec=%d (0-60), nsec=%d (0-999_999_999), " \
     55        "which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038."
    5856#endif // __CFA_DEBUG__
    5957
     
    6563#ifdef __CFA_DEBUG__
    6664        if ( month < 1 || 12 < month ) {
    67                 tabort( year, month, day, hour, min, sec, nsec );
     65                abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
    6866        } // if
    6967#endif // __CFA_DEBUG__
     
    7169#ifdef __CFA_DEBUG__
    7270        if ( day < 1 || 31 < day ) {
    73                 tabort( year, month, day, hour, min, sec, nsec );
     71                abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
    7472        } // if
    7573#endif // __CFA_DEBUG__
     
    8179#ifdef __CFA_DEBUG__
    8280        if ( epochsec == (time_t)-1 ) {
    83                 tabort( year, month, day, hour, min, sec, nsec );
     81                abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
    8482        } // if
    8583#endif // __CFA_DEBUG__
     
    8785#ifdef __CFA_DEBUG__
    8886        if ( tv > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
    89                 tabort( year, month, day, hour, min, sec, nsec );
     87                abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
    9088        } // if
    9189#endif // __CFA_DEBUG__
     
    152150                long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;   // compute nanoseconds
    153151                if ( ns == 0 ) {                                                                // none ?
    154                         (ostype &)(os | buf);                                           // print date/time/year
     152                        (ostype &)(os | buf);                                                   // print date/time/year
    155153                } else {
    156154                        buf[19] = '\0';                                                         // truncate to "Wed Jun 30 21:49:08"
    157155                        char buf2[16];
    158156                        nanomsd( ns, buf2 );                                            // compute nanoseconds
    159                         (ostype &)(os | buf | buf2 | ' ' | &buf[20]); // print date/time, nanoseconds and year
     157                        (ostype &)(os | buf | buf2 | ' ' | &buf[20]);   // print date/time, nanoseconds and year
    160158                } // if
    161159                return os;
     
    163161
    164162        void ?|?( ostype & os, Time time ) with( time ) {
    165                 (ostype &)(os | time); ends( os );
     163                (ostype &)(os | time); nl( os );
    166164        } // ?|?
    167165} // distribution
  • src/AST/Convert.cpp

    r4eb43fa rf6cc734e  
    518518        }
    519519
    520         const ast::Decl * visit( const ast::WithStmt * node ) override final {
     520        const ast::Stmt * visit( const ast::WithStmt * node ) override final {
    521521                if ( inCache( node ) ) return nullptr;
    522522                auto stmt = new WithStmt(
     
    524524                        get<Statement>().accept1( node->stmt )
    525525                );
    526                 declPostamble( stmt, node );
    527                 return nullptr;
     526                return stmtPostamble( stmt, node );
    528527        }
    529528
     
    10511050                                get<Expression>().accept1(node->expr),
    10521051                                inCache(node->deleteStmt) ?
    1053                                         strict_dynamic_cast<Declaration*>(this->node) :
    1054                                         get<Declaration>().accept1(node->deleteStmt)
     1052                                        this->node :
     1053                                        get<BaseSyntaxNode>().accept1(node->deleteStmt)
    10551054                        )
    10561055                );
     
    13671366        ast::Node * node = nullptr;
    13681367        /// cache of nodes that might be referenced by readonly<> for de-duplication
    1369         std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {};
     1368        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};
    13701369
    13711370        // Local Utilities:
     
    14341433                to<std::vector>::from( make_labels( std::move( labels ) ) )
    14351434
    1436         static ast::CV::Qualifiers cv( const Type * ty ) { return { ty->tq.val }; }
     1435        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
    14371436
    14381437        /// returns true and sets `node` if in cache
    1439         bool inCache( const BaseSyntaxNode * old ) {
     1438        bool inCache( BaseSyntaxNode * old ) {
    14401439                auto it = cache.find( old );
    14411440                if ( it == cache.end() ) return false;
     
    14461445        // Now all the visit functions:
    14471446
    1448         virtual void visit( const ObjectDecl * old ) override final {
     1447        virtual void visit( ObjectDecl * old ) override final {
    14491448                auto&& type = GET_ACCEPT_1(type, Type);
    14501449                auto&& init = GET_ACCEPT_1(init, Init);
     
    14771476        }
    14781477
    1479         virtual void visit( const FunctionDecl * old ) override final {
     1478        virtual void visit( FunctionDecl * old ) override final {
    14801479                if ( inCache( old ) ) return;
    14811480                auto decl = new ast::FunctionDecl{
     
    15101509        }
    15111510
    1512         virtual void visit( const StructDecl * old ) override final {
     1511        virtual void visit( StructDecl * old ) override final {
    15131512                if ( inCache( old ) ) return;
    15141513                auto decl = new ast::StructDecl(
     
    15351534        }
    15361535
    1537         virtual void visit( const UnionDecl * old ) override final {
     1536        virtual void visit( UnionDecl * old ) override final {
    15381537                if ( inCache( old ) ) return;
    15391538                auto decl = new ast::UnionDecl(
     
    15551554        }
    15561555
    1557         virtual void visit( const EnumDecl * old ) override final {
     1556        virtual void visit( EnumDecl * old ) override final {
    15581557                if ( inCache( old ) ) return;
    15591558                auto decl = new ast::EnumDecl(
     
    15751574        }
    15761575
    1577         virtual void visit( const TraitDecl * old ) override final {
     1576        virtual void visit( TraitDecl * old ) override final {
    15781577                if ( inCache( old ) ) return;
    15791578                auto decl = new ast::TraitDecl(
     
    15951594        }
    15961595
    1597         virtual void visit( const TypeDecl * old ) override final {
     1596        virtual void visit( TypeDecl * old ) override final {
    15981597                if ( inCache( old ) ) return;
    15991598                auto decl = new ast::TypeDecl{
     
    16151614        }
    16161615
    1617         virtual void visit( const TypedefDecl * old ) override final {
     1616        virtual void visit( TypedefDecl * old ) override final {
    16181617                auto decl = new ast::TypedefDecl(
    16191618                        old->location,
     
    16321631        }
    16331632
    1634         virtual void visit( const AsmDecl * old ) override final {
     1633        virtual void visit( AsmDecl * old ) override final {
    16351634                auto decl = new ast::AsmDecl{
    16361635                        old->location,
     
    16441643        }
    16451644
    1646         virtual void visit( const StaticAssertDecl * old ) override final {
     1645        virtual void visit( StaticAssertDecl * old ) override final {
    16471646                auto decl = new ast::StaticAssertDecl{
    16481647                        old->location,
     
    16571656        }
    16581657
    1659         virtual void visit( const CompoundStmt * old ) override final {
     1658        virtual void visit( CompoundStmt * old ) override final {
    16601659                if ( inCache( old ) ) return;
    16611660                auto stmt = new ast::CompoundStmt(
     
    16691668        }
    16701669
    1671         virtual void visit( const ExprStmt * old ) override final {
     1670        virtual void visit( ExprStmt * old ) override final {
    16721671                if ( inCache( old ) ) return;
    16731672                this->node = new ast::ExprStmt(
     
    16791678        }
    16801679
    1681         virtual void visit( const AsmStmt * old ) override final {
     1680        virtual void visit( AsmStmt * old ) override final {
    16821681                if ( inCache( old ) ) return;
    16831682                this->node = new ast::AsmStmt(
     
    16941693        }
    16951694
    1696         virtual void visit( const DirectiveStmt * old ) override final {
     1695        virtual void visit( DirectiveStmt * old ) override final {
    16971696                if ( inCache( old ) ) return;
    16981697                this->node = new ast::DirectiveStmt(
     
    17041703        }
    17051704
    1706         virtual void visit( const IfStmt * old ) override final {
     1705        virtual void visit( IfStmt * old ) override final {
    17071706                if ( inCache( old ) ) return;
    17081707                this->node = new ast::IfStmt(
     
    17171716        }
    17181717
    1719         virtual void visit( const SwitchStmt * old ) override final {
     1718        virtual void visit( SwitchStmt * old ) override final {
    17201719                if ( inCache( old ) ) return;
    17211720                this->node = new ast::SwitchStmt(
     
    17281727        }
    17291728
    1730         virtual void visit( const CaseStmt * old ) override final {
     1729        virtual void visit( CaseStmt * old ) override final {
    17311730                if ( inCache( old ) ) return;
    17321731                this->node = new ast::CaseStmt(
     
    17391738        }
    17401739
    1741         virtual void visit( const WhileStmt * old ) override final {
     1740        virtual void visit( WhileStmt * old ) override final {
    17421741                if ( inCache( old ) ) return;
    17431742                this->node = new ast::WhileStmt(
     
    17521751        }
    17531752
    1754         virtual void visit( const ForStmt * old ) override final {
     1753        virtual void visit( ForStmt * old ) override final {
    17551754                if ( inCache( old ) ) return;
    17561755                this->node = new ast::ForStmt(
     
    17651764        }
    17661765
    1767         virtual void visit( const BranchStmt * old ) override final {
     1766        virtual void visit( BranchStmt * old ) override final {
    17681767                if ( inCache( old ) ) return;
    17691768                if (old->computedTarget) {
     
    18021801        }
    18031802
    1804         virtual void visit( const ReturnStmt * old ) override final {
     1803        virtual void visit( ReturnStmt * old ) override final {
    18051804                if ( inCache( old ) ) return;
    18061805                this->node = new ast::ReturnStmt(
     
    18121811        }
    18131812
    1814         virtual void visit( const ThrowStmt * old ) override final {
     1813        virtual void visit( ThrowStmt * old ) override final {
    18151814                if ( inCache( old ) ) return;
    18161815                ast::ExceptionKind kind;
     
    18361835        }
    18371836
    1838         virtual void visit( const TryStmt * old ) override final {
     1837        virtual void visit( TryStmt * old ) override final {
    18391838                if ( inCache( old ) ) return;
    18401839                this->node = new ast::TryStmt(
     
    18481847        }
    18491848
    1850         virtual void visit( const CatchStmt * old ) override final {
     1849        virtual void visit( CatchStmt * old ) override final {
    18511850                if ( inCache( old ) ) return;
    18521851                ast::ExceptionKind kind;
     
    18731872        }
    18741873
    1875         virtual void visit( const FinallyStmt * old ) override final {
     1874        virtual void visit( FinallyStmt * old ) override final {
    18761875                if ( inCache( old ) ) return;
    18771876                this->node = new ast::FinallyStmt(
     
    18831882        }
    18841883
    1885         virtual void visit( const WaitForStmt * old ) override final {
     1884        virtual void visit( WaitForStmt * old ) override final {
    18861885                if ( inCache( old ) ) return;
    18871886                ast::WaitForStmt * stmt = new ast::WaitForStmt(
     
    19151914        }
    19161915
    1917         virtual void visit( const WithStmt * old ) override final {
     1916        virtual void visit( WithStmt * old ) override final {
    19181917                if ( inCache( old ) ) return;
    19191918                this->node = new ast::WithStmt(
    19201919                        old->location,
    19211920                        GET_ACCEPT_V(exprs, Expr),
    1922                         GET_ACCEPT_1(stmt, Stmt)
     1921                        GET_ACCEPT_1(stmt, Stmt),
     1922                        GET_LABELS_V(old->labels)
    19231923                );
    19241924                cache.emplace( old, this->node );
    19251925        }
    19261926
    1927         virtual void visit( const NullStmt * old ) override final {
     1927        virtual void visit( NullStmt * old ) override final {
    19281928                if ( inCache( old ) ) return;
    19291929                this->node = new ast::NullStmt(
     
    19341934        }
    19351935
    1936         virtual void visit( const DeclStmt * old ) override final {
     1936        virtual void visit( DeclStmt * old ) override final {
    19371937                if ( inCache( old ) ) return;
    19381938                this->node = new ast::DeclStmt(
     
    19441944        }
    19451945
    1946         virtual void visit( const ImplicitCtorDtorStmt * old ) override final {
     1946        virtual void visit( ImplicitCtorDtorStmt * old ) override final {
    19471947                if ( inCache( old ) ) return;
    19481948                auto stmt = new ast::ImplicitCtorDtorStmt(
     
    20012001        }
    20022002
    2003         ast::Expr * visitBaseExpr_SkipResultType( const Expression * old, ast::Expr * nw) {
     2003        ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
    20042004
    20052005                nw->env    = convertTypeSubstitution(old->env);
     
    20112011        }
    20122012
    2013         ast::Expr * visitBaseExpr( const Expression * old, ast::Expr * nw) {
     2013        ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
    20142014
    20152015                nw->result = GET_ACCEPT_1(result, Type);
     
    20172017        }
    20182018
    2019         virtual void visit( const ApplicationExpr * old ) override final {
     2019        virtual void visit( ApplicationExpr * old ) override final {
    20202020                this->node = visitBaseExpr( old,
    20212021                        new ast::ApplicationExpr(
     
    20272027        }
    20282028
    2029         virtual void visit( const UntypedExpr * old ) override final {
     2029        virtual void visit( UntypedExpr * old ) override final {
    20302030                this->node = visitBaseExpr( old,
    20312031                        new ast::UntypedExpr(
     
    20372037        }
    20382038
    2039         virtual void visit( const NameExpr * old ) override final {
     2039        virtual void visit( NameExpr * old ) override final {
    20402040                this->node = visitBaseExpr( old,
    20412041                        new ast::NameExpr(
     
    20462046        }
    20472047
    2048         virtual void visit( const CastExpr * old ) override final {
     2048        virtual void visit( CastExpr * old ) override final {
    20492049                this->node = visitBaseExpr( old,
    20502050                        new ast::CastExpr(
     
    20562056        }
    20572057
    2058         virtual void visit( const KeywordCastExpr * old) override final {
     2058        virtual void visit( KeywordCastExpr * old) override final {
    20592059                ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
    20602060                switch (old->target) {
     
    20812081        }
    20822082
    2083         virtual void visit( const VirtualCastExpr * old ) override final {
     2083        virtual void visit( VirtualCastExpr * old ) override final {
    20842084                this->node = visitBaseExpr_SkipResultType( old,
    20852085                        new ast::VirtualCastExpr(
     
    20912091        }
    20922092
    2093         virtual void visit( const AddressExpr * old ) override final {
     2093        virtual void visit( AddressExpr * old ) override final {
    20942094                this->node = visitBaseExpr( old,
    20952095                        new ast::AddressExpr(
     
    21002100        }
    21012101
    2102         virtual void visit( const LabelAddressExpr * old ) override final {
     2102        virtual void visit( LabelAddressExpr * old ) override final {
    21032103                this->node = visitBaseExpr( old,
    21042104                        new ast::LabelAddressExpr(
     
    21092109        }
    21102110
    2111         virtual void visit( const UntypedMemberExpr * old ) override final {
     2111        virtual void visit( UntypedMemberExpr * old ) override final {
    21122112                this->node = visitBaseExpr( old,
    21132113                        new ast::UntypedMemberExpr(
     
    21192119        }
    21202120
    2121         virtual void visit( const MemberExpr * old ) override final {
     2121        virtual void visit( MemberExpr * old ) override final {
    21222122                this->node = visitBaseExpr( old,
    21232123                        new ast::MemberExpr(
     
    21292129        }
    21302130
    2131         virtual void visit( const VariableExpr * old ) override final {
     2131        virtual void visit( VariableExpr * old ) override final {
    21322132                auto expr = new ast::VariableExpr(
    21332133                        old->location
     
    21402140        }
    21412141
    2142         virtual void visit( const ConstantExpr * old ) override final {
     2142        virtual void visit( ConstantExpr * old ) override final {
    21432143                ast::ConstantExpr *rslt = new ast::ConstantExpr(
    21442144                        old->location,
    21452145                        GET_ACCEPT_1(result, Type),
    2146                         old->constant.rep,
     2146                        old->constant.get_value(),
    21472147                        old->constant.ival
    21482148                );
    2149                 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.type );
     2149                rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() );
    21502150                this->node = visitBaseExpr( old, rslt );
    21512151        }
    21522152
    2153         virtual void visit( const SizeofExpr * old ) override final {
     2153        virtual void visit( SizeofExpr * old ) override final {
    21542154                assert (old->expr || old->type);
    21552155                assert (! (old->expr && old->type));
     
    21722172        }
    21732173
    2174         virtual void visit( const AlignofExpr * old ) override final {
     2174        virtual void visit( AlignofExpr * old ) override final {
    21752175                assert (old->expr || old->type);
    21762176                assert (! (old->expr && old->type));
     
    21932193        }
    21942194
    2195         virtual void visit( const UntypedOffsetofExpr * old ) override final {
     2195        virtual void visit( UntypedOffsetofExpr * old ) override final {
    21962196                this->node = visitBaseExpr( old,
    21972197                        new ast::UntypedOffsetofExpr(
     
    22032203        }
    22042204
    2205         virtual void visit( const OffsetofExpr * old ) override final {
     2205        virtual void visit( OffsetofExpr * old ) override final {
    22062206                this->node = visitBaseExpr( old,
    22072207                        new ast::OffsetofExpr(
     
    22132213        }
    22142214
    2215         virtual void visit( const OffsetPackExpr * old ) override final {
     2215        virtual void visit( OffsetPackExpr * old ) override final {
    22162216                this->node = visitBaseExpr( old,
    22172217                        new ast::OffsetPackExpr(
     
    22222222        }
    22232223
    2224         virtual void visit( const LogicalExpr * old ) override final {
     2224        virtual void visit( LogicalExpr * old ) override final {
    22252225                this->node = visitBaseExpr( old,
    22262226                        new ast::LogicalExpr(
     
    22352235        }
    22362236
    2237         virtual void visit( const ConditionalExpr * old ) override final {
     2237        virtual void visit( ConditionalExpr * old ) override final {
    22382238                this->node = visitBaseExpr( old,
    22392239                        new ast::ConditionalExpr(
     
    22462246        }
    22472247
    2248         virtual void visit( const CommaExpr * old ) override final {
     2248        virtual void visit( CommaExpr * old ) override final {
    22492249                this->node = visitBaseExpr( old,
    22502250                        new ast::CommaExpr(
     
    22562256        }
    22572257
    2258         virtual void visit( const TypeExpr * old ) override final {
     2258        virtual void visit( TypeExpr * old ) override final {
    22592259                this->node = visitBaseExpr( old,
    22602260                        new ast::TypeExpr(
     
    22652265        }
    22662266
    2267         virtual void visit( const AsmExpr * old ) override final {
     2267        virtual void visit( AsmExpr * old ) override final {
    22682268                this->node = visitBaseExpr( old,
    22692269                        new ast::AsmExpr(
     
    22762276        }
    22772277
    2278         virtual void visit( const ImplicitCopyCtorExpr * old ) override final {
     2278        virtual void visit( ImplicitCopyCtorExpr * old ) override final {
    22792279                auto rslt = new ast::ImplicitCopyCtorExpr(
    22802280                        old->location,
     
    22852285        }
    22862286
    2287         virtual void visit( const ConstructorExpr * old ) override final {
     2287        virtual void visit( ConstructorExpr * old ) override final {
    22882288                this->node = visitBaseExpr( old,
    22892289                        new ast::ConstructorExpr(
     
    22942294        }
    22952295
    2296         virtual void visit( const CompoundLiteralExpr * old ) override final {
     2296        virtual void visit( CompoundLiteralExpr * old ) override final {
    22972297                this->node = visitBaseExpr_SkipResultType( old,
    22982298                        new ast::CompoundLiteralExpr(
     
    23042304        }
    23052305
    2306         virtual void visit( const RangeExpr * old ) override final {
     2306        virtual void visit( RangeExpr * old ) override final {
    23072307                this->node = visitBaseExpr( old,
    23082308                        new ast::RangeExpr(
     
    23142314        }
    23152315
    2316         virtual void visit( const UntypedTupleExpr * old ) override final {
     2316        virtual void visit( UntypedTupleExpr * old ) override final {
    23172317                this->node = visitBaseExpr( old,
    23182318                        new ast::UntypedTupleExpr(
     
    23232323        }
    23242324
    2325         virtual void visit( const TupleExpr * old ) override final {
     2325        virtual void visit( TupleExpr * old ) override final {
    23262326                this->node = visitBaseExpr( old,
    23272327                        new ast::TupleExpr(
     
    23322332        }
    23332333
    2334         virtual void visit( const TupleIndexExpr * old ) override final {
     2334        virtual void visit( TupleIndexExpr * old ) override final {
    23352335                this->node = visitBaseExpr( old,
    23362336                        new ast::TupleIndexExpr(
     
    23422342        }
    23432343
    2344         virtual void visit( const TupleAssignExpr * old ) override final {
     2344        virtual void visit( TupleAssignExpr * old ) override final {
    23452345                this->node = visitBaseExpr_SkipResultType( old,
    23462346                        new ast::TupleAssignExpr(
     
    23522352        }
    23532353
    2354         virtual void visit( const StmtExpr * old ) override final {
     2354        virtual void visit( StmtExpr * old ) override final {
    23552355                auto rslt = new ast::StmtExpr(
    23562356                        old->location,
     
    23632363        }
    23642364
    2365         virtual void visit( const UniqueExpr * old ) override final {
     2365        virtual void visit( UniqueExpr * old ) override final {
    23662366                auto rslt = new ast::UniqueExpr(
    23672367                        old->location,
     
    23752375        }
    23762376
    2377         virtual void visit( const UntypedInitExpr * old ) override final {
     2377        virtual void visit( UntypedInitExpr * old ) override final {
    23782378                std::deque<ast::InitAlternative> initAlts;
    23792379                for (auto ia : old->initAlts) {
     
    23922392        }
    23932393
    2394         virtual void visit( const InitExpr * old ) override final {
     2394        virtual void visit( InitExpr * old ) override final {
    23952395                this->node = visitBaseExpr( old,
    23962396                        new ast::InitExpr(
     
    24022402        }
    24032403
    2404         virtual void visit( const DeletedExpr * old ) override final {
     2404        virtual void visit( DeletedExpr * old ) override final {
    24052405                this->node = visitBaseExpr( old,
    24062406                        new ast::DeletedExpr(
     
    24082408                                GET_ACCEPT_1(expr, Expr),
    24092409                                inCache(old->deleteStmt) ?
    2410                                         strict_dynamic_cast<ast::Decl*>(this->node) :
    2411                                         GET_ACCEPT_1(deleteStmt, Decl)
    2412                         )
    2413                 );
    2414         }
    2415 
    2416         virtual void visit( const DefaultArgExpr * old ) override final {
     2410                                        this->node :
     2411                                        GET_ACCEPT_1(deleteStmt, Node)
     2412                        )
     2413                );
     2414        }
     2415
     2416        virtual void visit( DefaultArgExpr * old ) override final {
    24172417                this->node = visitBaseExpr( old,
    24182418                        new ast::DefaultArgExpr(
     
    24232423        }
    24242424
    2425         virtual void visit( const GenericExpr * old ) override final {
     2425        virtual void visit( GenericExpr * old ) override final {
    24262426                std::vector<ast::GenericExpr::Association> associations;
    24272427                for (auto association : old->associations) {
     
    24402440        }
    24412441
    2442         void visitType( const Type * old, ast::Type * type ) {
     2442        void visitType( Type * old, ast::Type * type ) {
    24432443                // Some types do this in their constructor so add a check.
    24442444                if ( !old->attributes.empty() && type->attributes.empty() ) {
     
    24482448        }
    24492449
    2450         virtual void visit( const VoidType * old ) override final {
     2450        virtual void visit( VoidType * old ) override final {
    24512451                visitType( old, new ast::VoidType{ cv( old ) } );
    24522452        }
    24532453
    2454         virtual void visit( const BasicType * old ) override final {
     2454        virtual void visit( BasicType * old ) override final {
    24552455                auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
    24562456                // I believe this should always be a BasicType.
     
    24612461        }
    24622462
    2463         virtual void visit( const PointerType * old ) override final {
     2463        virtual void visit( PointerType * old ) override final {
    24642464                visitType( old, new ast::PointerType{
    24652465                        GET_ACCEPT_1( base, Type ),
     
    24712471        }
    24722472
    2473         virtual void visit( const ArrayType * old ) override final {
     2473        virtual void visit( ArrayType * old ) override final {
    24742474                visitType( old, new ast::ArrayType{
    24752475                        GET_ACCEPT_1( base, Type ),
     
    24812481        }
    24822482
    2483         virtual void visit( const ReferenceType * old ) override final {
     2483        virtual void visit( ReferenceType * old ) override final {
    24842484                visitType( old, new ast::ReferenceType{
    24852485                        GET_ACCEPT_1( base, Type ),
     
    24882488        }
    24892489
    2490         virtual void visit( const QualifiedType * old ) override final {
     2490        virtual void visit( QualifiedType * old ) override final {
    24912491                visitType( old, new ast::QualifiedType{
    24922492                        GET_ACCEPT_1( parent, Type ),
     
    24962496        }
    24972497
    2498         virtual void visit( const FunctionType * old ) override final {
     2498        virtual void visit( FunctionType * old ) override final {
    24992499                auto ty = new ast::FunctionType {
    25002500                        (ast::ArgumentFlag)old->isVarArgs,
     
    25072507        }
    25082508
    2509         void postvisit( const ReferenceToType * old, ast::ReferenceToType * ty ) {
     2509        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
    25102510                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
    25112511                ty->params = GET_ACCEPT_V( parameters, Expr );
     
    25142514        }
    25152515
    2516         virtual void visit( const StructInstType * old ) override final {
     2516        virtual void visit( StructInstType * old ) override final {
    25172517                ast::StructInstType * ty;
    25182518                if ( old->baseStruct ) {
     
    25322532        }
    25332533
    2534         virtual void visit( const UnionInstType * old ) override final {
     2534        virtual void visit( UnionInstType * old ) override final {
    25352535                ast::UnionInstType * ty;
    25362536                if ( old->baseUnion ) {
     
    25502550        }
    25512551
    2552         virtual void visit( const EnumInstType * old ) override final {
     2552        virtual void visit( EnumInstType * old ) override final {
    25532553                ast::EnumInstType * ty;
    25542554                if ( old->baseEnum ) {
     
    25682568        }
    25692569
    2570         virtual void visit( const TraitInstType * old ) override final {
     2570        virtual void visit( TraitInstType * old ) override final {
    25712571                ast::TraitInstType * ty;
    25722572                if ( old->baseTrait ) {
     
    25862586        }
    25872587
    2588         virtual void visit( const TypeInstType * old ) override final {
     2588        virtual void visit( TypeInstType * old ) override final {
    25892589                ast::TypeInstType * ty;
    25902590                if ( old->baseType ) {
     
    26062606        }
    26072607
    2608         virtual void visit( const TupleType * old ) override final {
     2608        virtual void visit( TupleType * old ) override final {
    26092609                visitType( old, new ast::TupleType{
    26102610                        GET_ACCEPT_V( types, Type ),
     
    26142614        }
    26152615
    2616         virtual void visit( const TypeofType * old ) override final {
     2616        virtual void visit( TypeofType * old ) override final {
    26172617                visitType( old, new ast::TypeofType{
    26182618                        GET_ACCEPT_1( expr, Expr ),
     
    26222622        }
    26232623
    2624         virtual void visit( const AttrType * ) override final {
     2624        virtual void visit( AttrType * ) override final {
    26252625                assertf( false, "AttrType deprecated in new AST." );
    26262626        }
    26272627
    2628         virtual void visit( const VarArgsType * old ) override final {
     2628        virtual void visit( VarArgsType * old ) override final {
    26292629                visitType( old, new ast::VarArgsType{ cv( old ) } );
    26302630        }
    26312631
    2632         virtual void visit( const ZeroType * old ) override final {
     2632        virtual void visit( ZeroType * old ) override final {
    26332633                visitType( old, new ast::ZeroType{ cv( old ) } );
    26342634        }
    26352635
    2636         virtual void visit( const OneType * old ) override final {
     2636        virtual void visit( OneType * old ) override final {
    26372637                visitType( old, new ast::OneType{ cv( old ) } );
    26382638        }
    26392639
    2640         virtual void visit( const GlobalScopeType * old ) override final {
     2640        virtual void visit( GlobalScopeType * old ) override final {
    26412641                visitType( old, new ast::GlobalScopeType{} );
    26422642        }
    26432643
    2644         virtual void visit( const Designation * old ) override final {
     2644        virtual void visit( Designation * old ) override final {
    26452645                this->node = new ast::Designation(
    26462646                        old->location,
     
    26492649        }
    26502650
    2651         virtual void visit( const SingleInit * old ) override final {
     2651        virtual void visit( SingleInit * old ) override final {
    26522652                this->node = new ast::SingleInit(
    26532653                        old->location,
     
    26572657        }
    26582658
    2659         virtual void visit( const ListInit * old ) override final {
     2659        virtual void visit( ListInit * old ) override final {
    26602660                this->node = new ast::ListInit(
    26612661                        old->location,
     
    26662666        }
    26672667
    2668         virtual void visit( const ConstructorInit * old ) override final {
     2668        virtual void visit( ConstructorInit * old ) override final {
    26692669                this->node = new ast::ConstructorInit(
    26702670                        old->location,
     
    26752675        }
    26762676
    2677         virtual void visit( const Constant * ) override final {
     2677        virtual void visit( Constant * ) override final {
    26782678                // Handled in visit( ConstantEpxr * ).
    26792679                // In the new tree, Constant fields are inlined into containing ConstantExpression.
     
    26812681        }
    26822682
    2683         virtual void visit( const Attribute * old ) override final {
     2683        virtual void visit( Attribute * old ) override final {
    26842684                this->node = new ast::Attribute(
    26852685                        old->name,
     
    26882688        }
    26892689
    2690         virtual void visit( const AttrExpr * ) override final {
     2690        virtual void visit( AttrExpr * ) override final {
    26912691                assertf( false, "AttrExpr deprecated in new AST." );
    26922692        }
  • src/AST/Decl.hpp

    r4eb43fa rf6cc734e  
    104104        ptr<Expr> bitfieldWidth;
    105105
    106         ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
    107                 const Init * init = nullptr, Storage::Classes storage = {},
    108                 Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr,
     106        ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 
     107                const Init * init = nullptr, Storage::Classes storage = {}, 
     108                Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr, 
    109109                std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
    110110        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
     
    325325};
    326326
    327 /// With statement `with (...) ...`
    328 class WithStmt final : public Decl {
    329 public:
    330         std::vector<ptr<Expr>> exprs;
    331         ptr<Stmt> stmt;
    332 
    333         WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt )
    334         : Decl(loc, "", Storage::Auto, Linkage::Cforall), exprs(std::move(exprs)), stmt(stmt) {}
    335 
    336         const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
    337 private:
    338         WithStmt * clone() const override { return new WithStmt{ *this }; }
    339         MUTATE_FRIEND
    340 };
    341 
    342327class AsmDecl : public Decl {
    343328public:
  • src/AST/Expr.hpp

    r4eb43fa rf6cc734e  
    5050
    5151        ParamEntry() : decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
    52         ParamEntry(
    53                 UniqueId id, const Decl * declptr, const Type * actual, const Type * formal,
     52        ParamEntry( 
     53                UniqueId id, const Decl * declptr, const Type * actual, const Type * formal, 
    5454                const Expr * e )
    5555        : decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {}
     
    115115                        case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough
    116116                        case Slots: return data.resnSlots;
    117                         case Params: assertf(false, "Cannot return to resnSlots from Params"); abort();
     117                        case Params: assert(!"Cannot return to resnSlots from Params");
    118118                        }
    119                         assertf(false, "unreachable");
     119                        return *((ResnSlots*)nullptr);
    120120                }
    121121
     
    124124                                return data.resnSlots;
    125125                        }
    126                         assertf(false, "Mode was not already resnSlots");
    127                         abort();
     126                        assert(!"Mode was not already resnSlots");
     127                        return *((ResnSlots*)nullptr);
    128128                }
    129129
     
    134134                        case Params: return data.inferParams;
    135135                        }
    136                         assertf(false, "unreachable");
     136                        assert(!"unreachable");
     137                        return *((InferredParams*)nullptr);
    137138                }
    138139
     
    141142                                return data.inferParams;
    142143                        }
    143                         assertf(false, "Mode was not already Params");
    144                         abort();
     144                        assert(!"Mode was not already Params");
     145                        return *((InferredParams*)nullptr);
    145146                }
    146147
    147148                void set_inferParams( InferredParams && ps ) {
    148149                        switch(mode) {
    149                         case Slots:
     150                        case Slots: 
    150151                                data.resnSlots.~ResnSlots();
    151152                                // fallthrough
    152                         case Empty:
     153                        case Empty: 
    153154                                new(&data.inferParams) InferredParams{ std::move( ps ) };
    154155                                mode = Params;
     
    174175                                        data.inferParams[p.first] = std::move(p.second);
    175176                                }
    176                         } else assertf(false, "invalid mode");
     177                        } else assert(!"invalid mode");
    177178                }
    178179        };
     
    386387
    387388        ConstantExpr(
    388                 const CodeLocation & loc, const Type * ty, const std::string & r,
     389                const CodeLocation & loc, const Type * ty, const std::string & r, 
    389390                        std::optional<unsigned long long> i )
    390391        : Expr( loc, ty ), rep( r ), ival( i ) {}
     
    772773public:
    773774        ptr<Expr> expr;
    774         readonly<Decl> deleteStmt;
    775 
    776         DeletedExpr( const CodeLocation & loc, const Expr * e, const Decl * del )
     775        readonly<Node> deleteStmt;
     776
     777        DeletedExpr( const CodeLocation & loc, const Expr * e, const Node * del )
    777778        : Expr( loc, e->result ), expr( e ), deleteStmt( del ) { assert( expr->result ); }
    778779
  • src/AST/Pass.hpp

    r4eb43fa rf6cc734e  
    115115        const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
    116116        const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
    117         const ast::Decl *             visit( const ast::WithStmt             * ) override final;
     117        const ast::Stmt *             visit( const ast::WithStmt             * ) override final;
    118118        const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
    119119        const ast::Stmt *             visit( const ast::DeclStmt             * ) override final;
  • src/AST/Pass.impl.hpp

    r4eb43fa rf6cc734e  
    909909// WithStmt
    910910template< typename pass_t >
    911 const ast::Decl * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
     911const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
    912912        VISIT_START( node );
    913913
  • src/AST/Print.cpp

    r4eb43fa rf6cc734e  
    3737}
    3838
    39 class Printer final : public Visitor {
     39class Printer : public Visitor {
    4040public:
    4141        ostream & os;
     
    272272
    273273public:
    274         virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
     274        virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
    275275                if ( ! node->name.empty() ) os << node->name << ": ";
    276276
     
    314314        }
    315315
    316         virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
     316        virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
    317317                if ( !node->name.empty() ) os << node->name << ": ";
    318318
     
    342342        }
    343343
    344         virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
     344        virtual const ast::Decl * visit( const ast::StructDecl * node ) {
    345345                print(node);
    346346                return node;
    347347        }
    348348
    349         virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
     349        virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
    350350                print(node);
    351351                return node;
    352352        }
    353353
    354         virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
     354        virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
    355355                print(node);
    356356                return node;
    357357        }
    358358
    359         virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
     359        virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
    360360                print(node);
    361361                return node;
    362362        }
    363363
    364         virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
     364        virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
    365365                preprint( node );
    366366                if ( ! short_mode && node->init ) {
     
    374374        }
    375375
    376         virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
    377                 preprint( node );
    378                 return node;
    379         }
    380 
    381         virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
     376        virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
     377                preprint( node );
     378                return node;
     379        }
     380
     381        virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
    382382                safe_print( node->stmt );
    383383                return node;
    384384        }
    385385
    386         virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
     386        virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
    387387                os << "Static Assert with condition: ";
    388388                ++indent;
     
    396396        }
    397397
    398         virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
     398        virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
    399399                os << "Compound Statement:" << endl;
    400400                ++indent;
     
    404404        }
    405405
    406         virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
     406        virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
    407407                ++indent;
    408408                os << "Expression Statement:" << endl << indent;
     
    412412        }
    413413
    414         virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
     414        virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
    415415                os << "Assembler Statement:" << endl;
    416416                ++indent;
     
    433433        }
    434434
    435         virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
     435        virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
    436436                os << "GCC Directive: " << node->directive << endl;
    437437                return node;
    438438        }
    439439
    440         virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
     440        virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
    441441                os << "If on condition:" << endl;
    442442                ++indent;
     
    473473        }
    474474
    475         virtual const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
     475        virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
    476476                if ( node->isDoWhile ) { os << "Do-"; }
    477477                os << "While on condition:" << endl;
     
    490490        }
    491491
    492         virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
     492        virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
    493493                os << "For Statement" << endl;
    494494
     
    532532        }
    533533
    534         virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
     534        virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
    535535                os << "Switch on condition: ";
    536536                safe_print( node->cond );
     
    546546        }
    547547
    548         virtual const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
     548        virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
    549549                if ( node->isDefault() ) {
    550550                        os << indent << "Default ";
     
    565565        }
    566566
    567         virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
     567        virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
    568568                os << "Branch (" << node->kindName() << ")" << endl;
    569569                ++indent;
     
    586586        }
    587587
    588         virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
     588        virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
    589589                os << "Return Statement, returning";
    590590                if ( node->expr ) {
     
    601601        }
    602602
    603         virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
     603        virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
    604604                if ( node->target ) os << "Non-Local ";
    605605
     
    621621        }
    622622
    623         virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
     623        virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
    624624                ++indent;
    625625                os << "Try Statement" << endl << indent-1
     
    642642        }
    643643
    644         virtual const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
     644        virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
    645645                os << "Catch ";
    646646                switch ( node->kind ) {
     
    667667        }
    668668
    669         virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
     669        virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
    670670                os << "Finally Statement" << endl;
    671671                os << indent << "... with block:" << endl;
     
    678678        }
    679679
    680         virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
     680        virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
    681681                os << "Waitfor Statement" << endl;
    682682                indent += 2;
     
    732732        }
    733733
    734         virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
     734        virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
    735735                os << "With statement" << endl;
    736736                os << indent << "... with expressions:" << endl;
     
    744744        }
    745745
    746         virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
     746        virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
    747747                os << "Null Statement" << endl;
    748748                print( node->labels );
     
    751751        }
    752752
    753         virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
     753        virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
    754754                os << "Declaration of ";
    755755                safe_print( node->decl );
     
    758758        }
    759759
    760         virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
     760        virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
    761761                os << "Implicit Ctor Dtor Statement" << endl;
    762762                os << indent << "... with Ctor/Dtor: ";
     
    769769        }
    770770
    771         virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
     771        virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
    772772                ++indent;
    773773                os << "Application of" << endl << indent;
     
    784784        }
    785785
    786         virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
     786        virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
    787787                ++indent;
    788788                os << "Applying untyped:" << endl;
     
    797797        }
    798798
    799         virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
     799        virtual const ast::Expr * visit( const ast::NameExpr * node ) {
    800800                os << "Name: " << node->name;
    801801                postprint( node );
     
    804804        }
    805805
    806         virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
     806        virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
    807807                os << "Address of:" << endl;
    808808                ++indent;
     
    815815        }
    816816
    817         virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
     817        virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
    818818                os << "Address of label:" << node->arg;
    819819
     
    821821        }
    822822
    823         virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
     823        virtual const ast::Expr * visit( const ast::CastExpr * node ) {
    824824                ++indent;
    825825                os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent;
     
    841841        }
    842842
    843         virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
     843        virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
    844844                ++indent;
    845845                os << "Keyword Cast of:" << endl << indent;
     
    852852        }
    853853
    854         virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
     854        virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
    855855                ++indent;
    856856                os << "Virtual Cast of:" << endl << indent;
     
    869869        }
    870870
    871         virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
     871        virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
    872872                ++indent;
    873873                os << "Untyped Member Expression, with field: " << endl << indent;
     
    881881        }
    882882
    883         virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
     883        virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
    884884                ++indent;
    885885                os << "Member Expression, with field:" << endl << indent;
     
    893893        }
    894894
    895         virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
     895        virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
    896896                os << "Variable Expression: ";
    897897                short_print( node->var );
     
    901901        }
    902902
    903         virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
     903        virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
    904904                os << "Constant Expression (" << node->rep;
    905905                if ( node->result ) {
     
    913913        }
    914914
    915         virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
     915        virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
    916916                os << "Sizeof Expression on: ";
    917917                ++indent;
     
    924924        }
    925925
    926         virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
     926        virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
    927927                os << "Alignof Expression on: ";
    928928                ++indent;
     
    935935        }
    936936
    937         virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
     937        virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
    938938                os << "Untyped Offsetof Expression on member " << node->member << " of ";
    939939                ++indent;
     
    945945        }
    946946
    947         virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
     947        virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
    948948                os << "Offsetof Expression on member " << node->member->name << " of ";
    949949                ++indent;
     
    955955        }
    956956
    957         virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
     957        virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
    958958                os << "Offset Pack Expression on: ";
    959959                ++indent;
     
    965965        }
    966966
    967         virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
     967        virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
    968968                os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
    969969                safe_print( node->arg1 );
     
    975975        }
    976976
    977         virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
     977        virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
    978978                ++indent;
    979979                os << "Conditional expression on:" << endl << indent;
     
    989989        }
    990990
    991         virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
     991        virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
    992992                ++indent;
    993993                os << "Comma Expression:" << endl << indent;
     
    10011001        }
    10021002
    1003         virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
     1003        virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
    10041004                safe_print( node->type );
    10051005                postprint( node );
     
    10081008        }
    10091009
    1010         virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
     1010        virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
    10111011                os << "Asm Expression:" << endl;
    10121012                ++indent;
     
    10191019        }
    10201020
    1021         virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
     1021        virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
    10221022                ++indent;
    10231023                os << "Implicit Copy Constructor Expression:" << endl << indent;
     
    10291029        }
    10301030
    1031         virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
     1031        virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
    10321032                os <<  "Constructor Expression:" << endl << indent+1;
    10331033                indent += 2;
     
    10391039        }
    10401040
    1041         virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
     1041        virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
    10421042                ++indent;
    10431043                os << "Compound Literal Expression: " << endl << indent;
     
    10511051        }
    10521052
    1053         virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
     1053        virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
    10541054                os << "Range Expression: ";
    10551055                safe_print( node->low );
     
    10611061        }
    10621062
    1063         virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
     1063        virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
    10641064                os << "Untyped Tuple:" << endl;
    10651065                ++indent;
     
    10711071        }
    10721072
    1073         virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
     1073        virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
    10741074                os << "Tuple:" << endl;
    10751075                ++indent;
     
    10811081        }
    10821082
    1083         virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
     1083        virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
    10841084                os << "Tuple Index Expression, with tuple:" << endl;
    10851085                ++indent;
     
    10931093        }
    10941094
    1095         virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
     1095        virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
    10961096                os << "Tuple Assignment Expression, with stmt expr:" << endl;
    10971097                ++indent;
     
    11041104        }
    11051105
    1106         virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
     1106        virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
    11071107                ++indent;
    11081108                os << "Statement Expression:" << endl << indent;
     
    11221122        }
    11231123
    1124         virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
     1124        virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
    11251125                ++indent;
    11261126                os << "Unique Expression with id: " << node->id << endl << indent;
     
    11361136        }
    11371137
    1138         virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
     1138        virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
    11391139                ++indent;
    11401140                os << "Untyped Init Expression" << endl << indent;
     
    11521152        }
    11531153
    1154         virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
     1154        virtual const ast::Expr * visit( const ast::InitExpr * node ) {
    11551155                ++indent;
    11561156                os << "Init Expression" << endl << indent;
     
    11631163        }
    11641164
    1165         virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
     1165        virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
    11661166                ++indent;
    11671167                os << "Deleted Expression" << endl << indent;
     
    11741174        }
    11751175
    1176         virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
     1176        virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
    11771177                ++indent;
    11781178                os << "Default Argument Expression" << endl << indent;
     
    11831183        }
    11841184
    1185         virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
     1185        virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
    11861186                ++indent;
    11871187                os << "C11 _Generic Expression" << endl << indent;
     
    12061206        }
    12071207
    1208         virtual const ast::Type * visit( const ast::VoidType * node ) override final {
     1208        virtual const ast::Type * visit( const ast::VoidType * node ) {
    12091209                preprint( node );
    12101210                os << "void";
     
    12121212        }
    12131213
    1214         virtual const ast::Type * visit( const ast::BasicType * node ) override final {
     1214        virtual const ast::Type * visit( const ast::BasicType * node ) {
    12151215                preprint( node );
    12161216                os << ast::BasicType::typeNames[ node->kind ];
     
    12181218        }
    12191219
    1220         virtual const ast::Type * visit( const ast::PointerType * node ) override final {
     1220        virtual const ast::Type * visit( const ast::PointerType * node ) {
    12211221                preprint( node );
    12221222                if ( ! node->isArray() ) {
     
    12411241        }
    12421242
    1243         virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
     1243        virtual const ast::Type * visit( const ast::ArrayType * node ) {
    12441244                preprint( node );
    12451245                if ( node->isStatic ) {
     
    12651265        }
    12661266
    1267         virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
     1267        virtual const ast::Type * visit( const ast::ReferenceType * node ) {
    12681268                preprint( node );
    12691269                os << "reference to ";
     
    12731273        }
    12741274
    1275         virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
     1275        virtual const ast::Type * visit( const ast::QualifiedType * node ) {
    12761276                preprint( node );
    12771277                ++indent;
     
    12861286        }
    12871287
    1288         virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
     1288        virtual const ast::Type * visit( const ast::FunctionType * node ) {
    12891289                preprint( node );
    12901290
     
    13151315        }
    13161316
    1317         virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
     1317        virtual const ast::Type * visit( const ast::StructInstType * node ) {
    13181318                preprint( node );
    13191319                os << "instance of struct " << node->name;
     
    13261326        }
    13271327
    1328         virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
     1328        virtual const ast::Type * visit( const ast::UnionInstType * node ) {
    13291329                preprint( node );
    13301330                os << "instance of union " << node->name;
     
    13371337        }
    13381338
    1339         virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
     1339        virtual const ast::Type * visit( const ast::EnumInstType * node ) {
    13401340                preprint( node );
    13411341                os << "instance of enum " << node->name;
     
    13481348        }
    13491349
    1350         virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
     1350        virtual const ast::Type * visit( const ast::TraitInstType * node ) {
    13511351                preprint( node );
    13521352                os << "instance of trait " << node->name;
     
    13561356        }
    13571357
    1358         virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
     1358        virtual const ast::Type * visit( const ast::TypeInstType * node ) {
    13591359                preprint( node );
    13601360                os << "instance of type " << node->name
     
    13651365        }
    13661366
    1367         virtual const ast::Type * visit( const ast::TupleType * node ) override final {
     1367        virtual const ast::Type * visit( const ast::TupleType * node ) {
    13681368                preprint( node );
    13691369                os << "tuple of types" << endl;
     
    13751375        }
    13761376
    1377         virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
     1377        virtual const ast::Type * visit( const ast::TypeofType * node ) {
    13781378                preprint( node );
    13791379                if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
     
    13841384        }
    13851385
    1386         virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
     1386        virtual const ast::Type * visit( const ast::VarArgsType * node ) {
    13871387                preprint( node );
    13881388                os << "builtin var args pack";
     
    13901390        }
    13911391
    1392         virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
     1392        virtual const ast::Type * visit( const ast::ZeroType * node ) {
    13931393                preprint( node );
    13941394                os << "zero_t";
     
    13961396        }
    13971397
    1398         virtual const ast::Type * visit( const ast::OneType * node ) override final {
     1398        virtual const ast::Type * visit( const ast::OneType * node ) {
    13991399                preprint( node );
    14001400                os << "one_t";
     
    14021402        }
    14031403
    1404         virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
     1404        virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
    14051405                preprint( node );
    14061406                os << "Global Scope Type";
     
    14081408        }
    14091409
    1410         virtual const ast::Designation * visit( const ast::Designation * node ) override final {
     1410        virtual const ast::Designation * visit( const ast::Designation * node ) {
    14111411                if ( node->designators.empty() ) return node;
    14121412                os << "... designated by: " << endl;
     
    14211421        }
    14221422
    1423         virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
     1423        virtual const ast::Init * visit( const ast::SingleInit * node ) {
    14241424                os << "Simple Initializer: ";
    14251425                safe_print( node->value );
     
    14271427        }
    14281428
    1429         virtual const ast::Init * visit( const ast::ListInit * node ) override final {
     1429        virtual const ast::Init * visit( const ast::ListInit * node ) {
    14301430                os << "Compound initializer: " << endl;
    14311431                ++indent;
     
    14451445        }
    14461446
    1447         virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
     1447        virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
    14481448                os << "Constructor initializer: " << endl;
    14491449                if ( node->ctor ) {
     
    14701470        }
    14711471
    1472         virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
     1472        virtual const ast::Attribute * visit( const ast::Attribute * node ) {
    14731473                if ( node->empty() ) return node;
    14741474                os << "Attribute with name: " << node->name;
     
    14811481        }
    14821482
    1483         virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
     1483        virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
    14841484                os << indent << "Types:" << endl;
    14851485                for ( const auto& i : *node ) {
  • src/AST/Stmt.hpp

    r4eb43fa rf6cc734e  
    382382};
    383383
     384/// With statement `with (...) ...`
     385class WithStmt final : public Stmt {
     386public:
     387        std::vector<ptr<Expr>> exprs;
     388        ptr<Stmt> stmt;
     389
     390        WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt,
     391                std::vector<Label> && labels = {} )
     392        : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
     393
     394        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     395private:
     396        WithStmt * clone() const override { return new WithStmt{ *this }; }
     397        MUTATE_FRIEND
     398};
     399
    384400/// Any declaration in a (compound) statement.
    385401class DeclStmt final : public Stmt {
  • src/AST/SymbolTable.cpp

    r4eb43fa rf6cc734e  
    7373
    7474SymbolTable::SymbolTable()
    75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
     75: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
    7676  prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
    7777
     
    171171}
    172172
    173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) {
     173void SymbolTable::addDeletedId( const DeclWithType * decl, const Node * deleter ) {
    174174        // default handling of conflicts is to raise an error
    175175        addId( decl, OnConflict::error(), nullptr, deleter );
     
    189189                        }
    190190                }
    191                 // does not need to be added to the table if both existing and added have a base that are
     191                // does not need to be added to the table if both existing and added have a base that are 
    192192                // the same
    193193                return true;
     
    209209        const std::string &id = decl->name;
    210210
    211         if ( ! typeTable ) {
     211        if ( ! typeTable ) { 
    212212                typeTable = TypeTable::new_ptr();
    213213        } else {
    214214                ++*stats().map_lookups;
    215215                auto existing = typeTable->find( id );
    216                 if ( existing != typeTable->end()
    217                         && existing->second.scope == scope
     216                if ( existing != typeTable->end() 
     217                        && existing->second.scope == scope 
    218218                        && addedTypeConflicts( existing->second.decl, decl ) ) return;
    219219        }
    220 
     220       
    221221        lazyInitScope();
    222222        ++*stats().map_mutations;
     
    237237                ++*stats().map_lookups;
    238238                auto existing = structTable->find( id );
    239                 if ( existing != structTable->end()
    240                         && existing->second.scope == scope
     239                if ( existing != structTable->end() 
     240                        && existing->second.scope == scope 
    241241                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    242242        }
     
    256256                ++*stats().map_lookups;
    257257                auto existing = enumTable->find( id );
    258                 if ( existing != enumTable->end()
    259                         && existing->second.scope == scope
     258                if ( existing != enumTable->end() 
     259                        && existing->second.scope == scope 
    260260                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    261261        }
    262 
     262       
    263263        lazyInitScope();
    264264        ++*stats().map_mutations;
     
    279279                ++*stats().map_lookups;
    280280                auto existing = unionTable->find( id );
    281                 if ( existing != unionTable->end()
    282                         && existing->second.scope == scope
     281                if ( existing != unionTable->end() 
     282                        && existing->second.scope == scope 
    283283                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    284284        }
     
    298298                ++*stats().map_lookups;
    299299                auto existing = traitTable->find( id );
    300                 if ( existing != traitTable->end()
    301                         && existing->second.scope == scope
     300                if ( existing != traitTable->end() 
     301                        && existing->second.scope == scope 
    302302                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    303303        }
     
    309309
    310310
    311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ) {
     311void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt ) {
    312312        for ( const Expr * expr : withExprs ) {
    313313                if ( ! expr->result ) continue;
    314314                const Type * resTy = expr->result->stripReferences();
    315315                auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );
    316                 assertf( aggrType, "WithStmt expr has non-aggregate type: %s",
     316                assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 
    317317                        toString( expr->result ).c_str() );
    318318                const AggregateDecl * aggr = aggrType->aggr();
    319                 assertf( aggr, "WithStmt has null aggregate from type: %s",
     319                assertf( aggr, "WithStmt has null aggregate from type: %s", 
    320320                        toString( expr->result ).c_str() );
    321 
     321               
    322322                addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
    323323        }
     
    373373        }
    374374
    375         /// gets the declaration for the function acting on a type specified by otype key,
     375        /// gets the declaration for the function acting on a type specified by otype key, 
    376376        /// nullptr if none such
    377         const FunctionDecl * getFunctionForOtype(
     377        const FunctionDecl * getFunctionForOtype( 
    378378                        const DeclWithType * decl, const std::string & otypeKey ) {
    379379                auto func = dynamic_cast< const FunctionDecl * >( decl );
     
    383383}
    384384
    385 bool SymbolTable::removeSpecialOverrides(
     385bool SymbolTable::removeSpecialOverrides( 
    386386                SymbolTable::IdData & data, SymbolTable::MangleTable::Ptr & mangleTable ) {
    387         // if a type contains user defined ctor/dtor/assign, then special rules trigger, which
    388         // determine the set of ctor/dtor/assign that can be used  by the requester. In particular,
    389         // if the user defines a default ctor, then the generated default ctor is unavailable,
    390         // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
    391         // field ctors are available. If the user defines any ctor then the generated default ctor
    392         // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
    393         // anything that looks like a copy constructor, then the generated copy constructor is
     387        // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
     388        // determine the set of ctor/dtor/assign that can be used  by the requester. In particular, 
     389        // if the user defines a default ctor, then the generated default ctor is unavailable, 
     390        // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
     391        // field ctors are available. If the user defines any ctor then the generated default ctor 
     392        // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
     393        // anything that looks like a copy constructor, then the generated copy constructor is 
    394394        // unavailable, and likewise for the assignment operator.
    395395
     
    450450                // if this is the first user-defined function, delete non-user-defined overloads
    451451                std::vector< MangleTable::value_type > deleted;
    452 
     452               
    453453                for ( const auto& entry : *mangleTable ) {
    454454                        // skip decls that aren't functions or are for the wrong type
     
    489489                        if ( dataIsCopyFunc ) {
    490490                                // remove current function if exists a user-defined copy function
    491                                 // since the signatures for copy functions don't need to match exactly, using
     491                                // since the signatures for copy functions don't need to match exactly, using 
    492492                                // a delete statement is the wrong approach
    493493                                if ( InitTweak::isCopyFunction( decl ) ) return false;
     
    499499                }
    500500        }
    501 
     501       
    502502        // nothing (more) to fix, return true
    503503        return true;
     
    525525
    526526bool SymbolTable::addedIdConflicts(
    527                 const SymbolTable::IdData & existing, const DeclWithType * added,
    528                 SymbolTable::OnConflict handleConflicts, const Decl * deleter ) {
    529         // if we're giving the same name mangling to things of different types then there is something
     527                const SymbolTable::IdData & existing, const DeclWithType * added, 
     528                SymbolTable::OnConflict handleConflicts, const Node * deleter ) {
     529        // if we're giving the same name mangling to things of different types then there is something 
    530530        // wrong
    531531        assert( (isObject( added ) && isObject( existing.id ) )
    532532                || ( isFunction( added ) && isFunction( existing.id ) ) );
    533 
     533       
    534534        if ( existing.id->linkage.is_overrideable ) {
    535535                // new definition shadows the autogenerated one, even at the same scope
    536536                return false;
    537         } else if ( existing.id->linkage.is_mangled
    538                         || ResolvExpr::typesCompatible(
     537        } else if ( existing.id->linkage.is_mangled 
     538                        || ResolvExpr::typesCompatible( 
    539539                                added->get_type(), existing.id->get_type(), SymbolTable{} ) ) {
    540 
     540               
    541541                // it is a conflict if one declaration is deleted and the other is not
    542542                if ( deleter && ! existing.deleter ) {
     
    555555                if ( isDefinition( added ) && isDefinition( existing.id ) ) {
    556556                        if ( handleConflicts.mode == OnConflict::Error ) {
    557                                 SemanticError( added,
    558                                         isFunction( added ) ?
    559                                                 "duplicate function definition for " :
     557                                SemanticError( added, 
     558                                        isFunction( added ) ? 
     559                                                "duplicate function definition for " : 
    560560                                                "duplicate object definition for " );
    561561                        }
     
    572572}
    573573
    574 void SymbolTable::addId(
    575                 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    576                 const Decl * deleter ) {
     574void SymbolTable::addId( 
     575                const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 
     576                const Node * deleter ) {
    577577        ++*stats().add_calls;
    578578        const std::string &name = decl->name;
     
    581581        std::string mangleName;
    582582        if ( decl->linkage.is_overrideable ) {
    583                 // mangle the name without including the appropriate suffix, so overridable routines
     583                // mangle the name without including the appropriate suffix, so overridable routines 
    584584                // are placed into the same "bucket" as their user defined versions.
    585585                mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } );
     
    588588        }
    589589
    590         // this ensures that no two declarations with the same unmangled name at the same scope
     590        // this ensures that no two declarations with the same unmangled name at the same scope 
    591591        // both have C linkage
    592592        if ( decl->linkage.is_mangled ) {
     
    596596                }
    597597        } else {
    598                 // NOTE: only correct if name mangling is completely isomorphic to C
     598                // NOTE: only correct if name mangling is completely isomorphic to C 
    599599                // type-compatibility, which it may not be.
    600600                if ( hasIncompatibleCDecl( name, mangleName ) ) {
     
    628628                                                idTable = idTable->set(
    629629                                                        name,
    630                                                         mangleTable->set(
    631                                                                 mangleName,
     630                                                        mangleTable->set( 
     631                                                                mangleName, 
    632632                                                                IdData{ existing->second, handleConflicts.deleter } ) );
    633633                                        }
     
    647647}
    648648
    649 void SymbolTable::addMembers(
     649void SymbolTable::addMembers( 
    650650                const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) {
    651651        for ( const Decl * decl : aggr->members ) {
     
    655655                                const Type * t = dwt->get_type()->stripReferences();
    656656                                if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) {
    657                                         if ( ! dynamic_cast<const StructInstType *>(rty)
     657                                        if ( ! dynamic_cast<const StructInstType *>(rty) 
    658658                                                && ! dynamic_cast<const UnionInstType *>(rty) ) continue;
    659659                                        ResolvExpr::Cost cost = ResolvExpr::Cost::zero;
    660660                                        const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost );
    661                                         addMembers(
     661                                        addMembers( 
    662662                                                rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts );
    663663                                }
     
    680680                if ( ! decl.second.id->linkage.is_mangled && decl.first == mangleName ) return true;
    681681        }
    682 
     682       
    683683        return false;
    684684}
  • src/AST/SymbolTable.hpp

    r4eb43fa rf6cc734e  
    3737                readonly<DeclWithType> id = nullptr;  ///< Identifier of declaration
    3838                readonly<Expr> baseExpr = nullptr;    ///< Implied containing aggregate (from WithExpr)
    39                 readonly<Decl> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
     39                readonly<Node> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
    4040                unsigned long scope = 0;              ///< Scope of identifier
    4141
    4242                IdData() = default;
    43                 IdData( const DeclWithType * i, const Expr * base, const Decl * del, unsigned long s )
     43                IdData( const DeclWithType * i, const Expr * base, const Node * del, unsigned long s )
    4444                : id( i ), baseExpr( base ), deleter( del ), scope( s ) {}
    45 
     45               
    4646                /// Modify an existing node with a new deleter
    47                 IdData( const IdData & o, const Decl * del )
     47                IdData( const IdData & o, const Node * del )
    4848                : id( o.id ), baseExpr( o.baseExpr ), deleter( del ), scope( o.scope ) {}
    4949
     
    5858        struct scoped {
    5959                readonly<D> decl;     ///< wrapped declaration
    60                 unsigned long scope;  ///< scope of this declaration
     60                unsigned long scope;  ///< scope of this declaration 
    6161
    6262                scoped(const D * d, unsigned long s) : decl(d), scope(s) {}
     
    8888        ~SymbolTable();
    8989
    90         // when using an indexer manually (e.g., within a mutator traversal), it is necessary to
     90        // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
    9191        // tell the indexer explicitly when scopes begin and end
    9292        void enterScope();
     
    118118        void addId( const DeclWithType * decl, const Expr * baseExpr = nullptr );
    119119        /// Adds a deleted identifier declaration to the symbol table
    120         void addDeletedId( const DeclWithType * decl, const Decl * deleter );
     120        void addDeletedId( const DeclWithType * decl, const Node * deleter );
    121121
    122122        /// Adds a type to the symbol table
     
    136136
    137137        /// adds all of the IDs from WithStmt exprs
    138         void addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt );
     138        void addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt );
    139139
    140140        /// convenience function for adding a list of Ids to the indexer
     
    154154        const SymbolTable * atScope( unsigned long i ) const;
    155155
    156         /// Removes matching autogenerated constructors and destructors so that they will not be
     156        /// Removes matching autogenerated constructors and destructors so that they will not be 
    157157        /// selected. If returns false, passed decl should not be added.
    158158        bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
     
    164164                        Delete  ///< Delete the earlier version with the delete statement
    165165                } mode;
    166                 const Decl * deleter;  ///< Statement that deletes this expression
     166                const Node * deleter;  ///< Statement that deletes this expression
    167167
    168168        private:
    169169                OnConflict() : mode(Error), deleter(nullptr) {}
    170                 OnConflict( const Decl * d ) : mode(Delete), deleter(d) {}
     170                OnConflict( const Node * d ) : mode(Delete), deleter(d) {}
    171171        public:
    172172                OnConflict( const OnConflict& ) = default;
    173173
    174174                static OnConflict error() { return {}; }
    175                 static OnConflict deleteWith( const Decl * d ) { return { d }; }
     175                static OnConflict deleteWith( const Node * d ) { return { d }; }
    176176        };
    177177
    178178        /// true if the existing identifier conflicts with the added identifier
    179179        bool addedIdConflicts(
    180                 const IdData & existing, const DeclWithType * added, OnConflict handleConflicts,
    181                 const Decl * deleter );
     180                const IdData & existing, const DeclWithType * added, OnConflict handleConflicts, 
     181                const Node * deleter );
    182182
    183183        /// common code for addId, addDeletedId, etc.
    184         void addId(
    185                 const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr,
    186                 const Decl * deleter = nullptr );
     184        void addId( 
     185                const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr, 
     186                const Node * deleter = nullptr );
    187187
    188188        /// adds all of the members of the Aggregate (addWith helper)
  • src/AST/Type.hpp

    r4eb43fa rf6cc734e  
    3737
    3838template< typename T > class Pass;
    39 
    40 struct ForallSubstitutor;
     39class ForallSubstitutor;
    4140
    4241class Type : public Node {
     
    170169        static const char *typeNames[];
    171170
    172         BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     171        BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 
    173172        : Type(q, std::move(as)), kind(k) {}
    174173
     
    277276public:
    278277        using ForallList = std::vector<ptr<TypeDecl>>;
    279 
     278       
    280279        ForallList forall;
    281280
     
    341340        bool hoistType = false;
    342341
    343         ReferenceToType(
     342        ReferenceToType( 
    344343                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    345344        : ParameterizedType(q, std::move(as)), params(), name(n) {}
     
    362361        readonly<StructDecl> base;
    363362
    364         StructInstType(
     363        StructInstType( 
    365364                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    366365        : ReferenceToType( n, q, std::move(as) ), base() {}
    367366
    368         StructInstType(
     367        StructInstType( 
    369368                const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    370369
     
    384383        readonly<UnionDecl> base;
    385384
    386         UnionInstType(
     385        UnionInstType( 
    387386                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    388387        : ReferenceToType( n, q, std::move(as) ), base() {}
    389388
    390         UnionInstType(
     389        UnionInstType( 
    391390                const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    392391
     
    406405        readonly<EnumDecl> base;
    407406
    408         EnumInstType(
     407        EnumInstType( 
    409408                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    410409        : ReferenceToType( n, q, std::move(as) ), base() {}
    411410
    412         EnumInstType(
     411        EnumInstType( 
    413412                const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    414413
     
    428427        readonly<TraitDecl> base;
    429428
    430         TraitInstType(
     429        TraitInstType( 
    431430                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    432431        : ReferenceToType( n, q, std::move(as) ), base() {}
    433 
    434         TraitInstType(
     432       
     433        TraitInstType( 
    435434                const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    436435
     
    452451        TypeVar::Kind kind;
    453452
    454         TypeInstType(
     453        TypeInstType( 
    455454                const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
    456455                std::vector<ptr<Attribute>> && as = {} )
    457456        : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
    458 
    459         TypeInstType(
     457       
     458        TypeInstType( 
    460459                const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
    461460                std::vector<ptr<Attribute>> && as = {} )
  • src/AST/Visitor.hpp

    r4eb43fa rf6cc734e  
    4848    virtual const ast::Stmt *             visit( const ast::FinallyStmt          * ) = 0;
    4949    virtual const ast::Stmt *             visit( const ast::WaitForStmt          * ) = 0;
    50     virtual const ast::Decl *             visit( const ast::WithStmt             * ) = 0;
     50    virtual const ast::Stmt *             visit( const ast::WithStmt             * ) = 0;
    5151    virtual const ast::NullStmt *         visit( const ast::NullStmt             * ) = 0;
    5252    virtual const ast::Stmt *             visit( const ast::DeclStmt             * ) = 0;
  • src/Common/PassVisitor.h

    r4eb43fa rf6cc734e  
    6060
    6161        virtual void visit( ObjectDecl * objectDecl ) override final;
    62         virtual void visit( const ObjectDecl * objectDecl ) override final;
    6362        virtual void visit( FunctionDecl * functionDecl ) override final;
    64         virtual void visit( const FunctionDecl * functionDecl ) override final;
    6563        virtual void visit( StructDecl * aggregateDecl ) override final;
    66         virtual void visit( const StructDecl * aggregateDecl ) override final;
    6764        virtual void visit( UnionDecl * aggregateDecl ) override final;
    68         virtual void visit( const UnionDecl * aggregateDecl ) override final;
    6965        virtual void visit( EnumDecl * aggregateDecl ) override final;
    70         virtual void visit( const EnumDecl * aggregateDecl ) override final;
    7166        virtual void visit( TraitDecl * aggregateDecl ) override final;
    72         virtual void visit( const TraitDecl * aggregateDecl ) override final;
    7367        virtual void visit( TypeDecl * typeDecl ) override final;
    74         virtual void visit( const TypeDecl * typeDecl ) override final;
    7568        virtual void visit( TypedefDecl * typeDecl ) override final;
    76         virtual void visit( const TypedefDecl * typeDecl ) override final;
    7769        virtual void visit( AsmDecl * asmDecl ) override final;
    78         virtual void visit( const AsmDecl * asmDecl ) override final;
    7970        virtual void visit( StaticAssertDecl * assertDecl ) override final;
    80         virtual void visit( const StaticAssertDecl * assertDecl ) override final;
    8171
    8272        virtual void visit( CompoundStmt * compoundStmt ) override final;
    83         virtual void visit( const CompoundStmt * compoundStmt ) override final;
    8473        virtual void visit( ExprStmt * exprStmt ) override final;
    85         virtual void visit( const ExprStmt * exprStmt ) override final;
    8674        virtual void visit( AsmStmt * asmStmt ) override final;
    87         virtual void visit( const AsmStmt * asmStmt ) override final;
    8875        virtual void visit( DirectiveStmt * dirStmt ) override final;
    89         virtual void visit( const DirectiveStmt * dirStmt ) override final;
    9076        virtual void visit( IfStmt * ifStmt ) override final;
    91         virtual void visit( const IfStmt * ifStmt ) override final;
    9277        virtual void visit( WhileStmt * whileStmt ) override final;
    93         virtual void visit( const WhileStmt * whileStmt ) override final;
    9478        virtual void visit( ForStmt * forStmt ) override final;
    95         virtual void visit( const ForStmt * forStmt ) override final;
    9679        virtual void visit( SwitchStmt * switchStmt ) override final;
    97         virtual void visit( const SwitchStmt * switchStmt ) override final;
    9880        virtual void visit( CaseStmt * caseStmt ) override final;
    99         virtual void visit( const CaseStmt * caseStmt ) override final;
    10081        virtual void visit( BranchStmt * branchStmt ) override final;
    101         virtual void visit( const BranchStmt * branchStmt ) override final;
    10282        virtual void visit( ReturnStmt * returnStmt ) override final;
    103         virtual void visit( const ReturnStmt * returnStmt ) override final;
    10483        virtual void visit( ThrowStmt * throwStmt ) override final;
    105         virtual void visit( const ThrowStmt * throwStmt ) override final;
    10684        virtual void visit( TryStmt * tryStmt ) override final;
    107         virtual void visit( const TryStmt * tryStmt ) override final;
    10885        virtual void visit( CatchStmt * catchStmt ) override final;
    109         virtual void visit( const CatchStmt * catchStmt ) override final;
    11086        virtual void visit( FinallyStmt * finallyStmt ) override final;
    111         virtual void visit( const FinallyStmt * finallyStmt ) override final;
    11287        virtual void visit( WaitForStmt * waitforStmt ) override final;
    113         virtual void visit( const WaitForStmt * waitforStmt ) override final;
    11488        virtual void visit( WithStmt * withStmt ) override final;
    115         virtual void visit( const WithStmt * withStmt ) override final;
    11689        virtual void visit( NullStmt * nullStmt ) override final;
    117         virtual void visit( const NullStmt * nullStmt ) override final;
    11890        virtual void visit( DeclStmt * declStmt ) override final;
    119         virtual void visit( const DeclStmt * declStmt ) override final;
    12091        virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
    121         virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
    12292
    12393        virtual void visit( ApplicationExpr * applicationExpr ) override final;
    124         virtual void visit( const ApplicationExpr * applicationExpr ) override final;
    12594        virtual void visit( UntypedExpr * untypedExpr ) override final;
    126         virtual void visit( const UntypedExpr * untypedExpr ) override final;
    12795        virtual void visit( NameExpr * nameExpr ) override final;
    128         virtual void visit( const NameExpr * nameExpr ) override final;
    12996        virtual void visit( CastExpr * castExpr ) override final;
    130         virtual void visit( const CastExpr * castExpr ) override final;
    13197        virtual void visit( KeywordCastExpr * castExpr ) override final;
    132         virtual void visit( const KeywordCastExpr * castExpr ) override final;
    13398        virtual void visit( VirtualCastExpr * castExpr ) override final;
    134         virtual void visit( const VirtualCastExpr * castExpr ) override final;
    13599        virtual void visit( AddressExpr * addressExpr ) override final;
    136         virtual void visit( const AddressExpr * addressExpr ) override final;
    137100        virtual void visit( LabelAddressExpr * labAddressExpr ) override final;
    138         virtual void visit( const LabelAddressExpr * labAddressExpr ) override final;
    139101        virtual void visit( UntypedMemberExpr * memberExpr ) override final;
    140         virtual void visit( const UntypedMemberExpr * memberExpr ) override final;
    141102        virtual void visit( MemberExpr * memberExpr ) override final;
    142         virtual void visit( const MemberExpr * memberExpr ) override final;
    143103        virtual void visit( VariableExpr * variableExpr ) override final;
    144         virtual void visit( const VariableExpr * variableExpr ) override final;
    145104        virtual void visit( ConstantExpr * constantExpr ) override final;
    146         virtual void visit( const ConstantExpr * constantExpr ) override final;
    147105        virtual void visit( SizeofExpr * sizeofExpr ) override final;
    148         virtual void visit( const SizeofExpr * sizeofExpr ) override final;
    149106        virtual void visit( AlignofExpr * alignofExpr ) override final;
    150         virtual void visit( const AlignofExpr * alignofExpr ) override final;
    151107        virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final;
    152         virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final;
    153108        virtual void visit( OffsetofExpr * offsetofExpr ) override final;
    154         virtual void visit( const OffsetofExpr * offsetofExpr ) override final;
    155109        virtual void visit( OffsetPackExpr * offsetPackExpr ) override final;
    156         virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final;
    157110        virtual void visit( AttrExpr * attrExpr ) override final;
    158         virtual void visit( const AttrExpr * attrExpr ) override final;
    159111        virtual void visit( LogicalExpr * logicalExpr ) override final;
    160         virtual void visit( const LogicalExpr * logicalExpr ) override final;
    161112        virtual void visit( ConditionalExpr * conditionalExpr ) override final;
    162         virtual void visit( const ConditionalExpr * conditionalExpr ) override final;
    163113        virtual void visit( CommaExpr * commaExpr ) override final;
    164         virtual void visit( const CommaExpr * commaExpr ) override final;
    165114        virtual void visit( TypeExpr * typeExpr ) override final;
    166         virtual void visit( const TypeExpr * typeExpr ) override final;
    167115        virtual void visit( AsmExpr * asmExpr ) override final;
    168         virtual void visit( const AsmExpr * asmExpr ) override final;
    169116        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
    170         virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
    171117        virtual void visit( ConstructorExpr *  ctorExpr ) override final;
    172         virtual void visit( const ConstructorExpr *  ctorExpr ) override final;
    173118        virtual void visit( CompoundLiteralExpr * compLitExpr ) override final;
    174         virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final;
    175119        virtual void visit( RangeExpr * rangeExpr ) override final;
    176         virtual void visit( const RangeExpr * rangeExpr ) override final;
    177120        virtual void visit( UntypedTupleExpr * tupleExpr ) override final;
    178         virtual void visit( const UntypedTupleExpr * tupleExpr ) override final;
    179121        virtual void visit( TupleExpr * tupleExpr ) override final;
    180         virtual void visit( const TupleExpr * tupleExpr ) override final;
    181122        virtual void visit( TupleIndexExpr * tupleExpr ) override final;
    182         virtual void visit( const TupleIndexExpr * tupleExpr ) override final;
    183123        virtual void visit( TupleAssignExpr * assignExpr ) override final;
    184         virtual void visit( const TupleAssignExpr * assignExpr ) override final;
    185124        virtual void visit( StmtExpr *  stmtExpr ) override final;
    186         virtual void visit( const StmtExpr *  stmtExpr ) override final;
    187125        virtual void visit( UniqueExpr *  uniqueExpr ) override final;
    188         virtual void visit( const UniqueExpr *  uniqueExpr ) override final;
    189126        virtual void visit( UntypedInitExpr *  initExpr ) override final;
    190         virtual void visit( const UntypedInitExpr *  initExpr ) override final;
    191127        virtual void visit( InitExpr *  initExpr ) override final;
    192         virtual void visit( const InitExpr *  initExpr ) override final;
    193128        virtual void visit( DeletedExpr *  delExpr ) override final;
    194         virtual void visit( const DeletedExpr *  delExpr ) override final;
    195129        virtual void visit( DefaultArgExpr * argExpr ) override final;
    196         virtual void visit( const DefaultArgExpr * argExpr ) override final;
    197130        virtual void visit( GenericExpr * genExpr ) override final;
    198         virtual void visit( const GenericExpr * genExpr ) override final;
    199131
    200132        virtual void visit( VoidType * basicType ) override final;
    201         virtual void visit( const VoidType * basicType ) override final;
    202133        virtual void visit( BasicType * basicType ) override final;
    203         virtual void visit( const BasicType * basicType ) override final;
    204134        virtual void visit( PointerType * pointerType ) override final;
    205         virtual void visit( const PointerType * pointerType ) override final;
    206135        virtual void visit( ArrayType * arrayType ) override final;
    207         virtual void visit( const ArrayType * arrayType ) override final;
    208136        virtual void visit( ReferenceType * referenceType ) override final;
    209         virtual void visit( const ReferenceType * referenceType ) override final;
    210137        virtual void visit( QualifiedType * qualType ) override final;
    211         virtual void visit( const QualifiedType * qualType ) override final;
    212138        virtual void visit( FunctionType * functionType ) override final;
    213         virtual void visit( const FunctionType * functionType ) override final;
    214139        virtual void visit( StructInstType * aggregateUseType ) override final;
    215         virtual void visit( const StructInstType * aggregateUseType ) override final;
    216140        virtual void visit( UnionInstType * aggregateUseType ) override final;
    217         virtual void visit( const UnionInstType * aggregateUseType ) override final;
    218141        virtual void visit( EnumInstType * aggregateUseType ) override final;
    219         virtual void visit( const EnumInstType * aggregateUseType ) override final;
    220142        virtual void visit( TraitInstType * aggregateUseType ) override final;
    221         virtual void visit( const TraitInstType * aggregateUseType ) override final;
    222143        virtual void visit( TypeInstType * aggregateUseType ) override final;
    223         virtual void visit( const TypeInstType * aggregateUseType ) override final;
    224144        virtual void visit( TupleType * tupleType ) override final;
    225         virtual void visit( const TupleType * tupleType ) override final;
    226145        virtual void visit( TypeofType * typeofType ) override final;
    227         virtual void visit( const TypeofType * typeofType ) override final;
    228146        virtual void visit( AttrType * attrType ) override final;
    229         virtual void visit( const AttrType * attrType ) override final;
    230147        virtual void visit( VarArgsType * varArgsType ) override final;
    231         virtual void visit( const VarArgsType * varArgsType ) override final;
    232148        virtual void visit( ZeroType * zeroType ) override final;
    233         virtual void visit( const ZeroType * zeroType ) override final;
    234149        virtual void visit( OneType * oneType ) override final;
    235         virtual void visit( const OneType * oneType ) override final;
    236150        virtual void visit( GlobalScopeType * globalType ) override final;
    237         virtual void visit( const GlobalScopeType * globalType ) override final;
    238151
    239152        virtual void visit( Designation * designation ) override final;
    240         virtual void visit( const Designation * designation ) override final;
    241153        virtual void visit( SingleInit * singleInit ) override final;
    242         virtual void visit( const SingleInit * singleInit ) override final;
    243154        virtual void visit( ListInit * listInit ) override final;
    244         virtual void visit( const ListInit * listInit ) override final;
    245155        virtual void visit( ConstructorInit * ctorInit ) override final;
    246         virtual void visit( const ConstructorInit * ctorInit ) override final;
    247156
    248157        virtual void visit( Constant * constant ) override final;
    249         virtual void visit( const Constant * constant ) override final;
    250158
    251159        virtual void visit( Attribute * attribute ) override final;
    252         virtual void visit( const Attribute * attribute ) override final;
    253160
    254161        virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final;
     
    279186        virtual Statement * mutate( FinallyStmt * finallyStmt ) override final;
    280187        virtual Statement * mutate( WaitForStmt * waitforStmt ) override final;
    281         virtual Declaration * mutate( WithStmt * withStmt ) override final;
     188        virtual Statement * mutate( WithStmt * withStmt ) override final;
    282189        virtual NullStmt * mutate( NullStmt * nullStmt ) override final;
    283190        virtual Statement * mutate( DeclStmt * declStmt ) override final;
     
    358265
    359266        template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
    360         template<typename pass_t> friend void acceptAll( const std::list< const Declaration * > &decls, PassVisitor< pass_t >& visitor );
    361267        template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
    362268        template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor );
    363         template< typename TreeType, typename pass_t > friend void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_t > & visitor );
    364269        template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator );
    365270        template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor );
    366         template< typename Container, typename pass_t > friend void maybeAccept_impl( const Container & container, PassVisitor< pass_t > & visitor );
    367271        template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator );
    368272
    369273        template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
    370         template<typename node_type> void call_previsit ( const node_type * node ) { previsit_impl ( pass, node, 0 ); }
    371274        template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
    372         template<typename node_type> void call_postvisit( const node_type * node ) { postvisit_impl( pass, node, 0 ); }
    373275
    374276        template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
     
    384286        void visitStatementList ( std::list< Statement* > &statements );
    385287        void mutateStatementList( std::list< Statement* > &statements );
    386         void visitStatementList ( const std::list< Statement * > & statements );
    387288
    388289        template< typename func_t >
     
    390291        Statement * visitStatement ( Statement * stmt );
    391292        Statement * mutateStatement( Statement * stmt );
    392         void visitStatement ( const Statement * stmt );
    393293
    394294        template< typename func_t >
     
    396296        Expression * visitExpression ( Expression * expr );
    397297        Expression * mutateExpression( Expression * expr );
    398         void visitExpression ( const Expression * expr );
    399298
    400299
     
    410309        void indexerScopeEnter  ()                                    { indexer_impl_enterScope  ( pass, 0       ); }
    411310        void indexerScopeLeave  ()                                    { indexer_impl_leaveScope  ( pass, 0       ); }
    412         void indexerAddId       ( const DeclarationWithType * node  ) { indexer_impl_addId       ( pass, 0, node ); }
    413         void indexerAddType     ( const NamedTypeDecl       * node  ) { indexer_impl_addType     ( pass, 0, node ); }
     311        void indexerAddId       ( DeclarationWithType      * node  ) { indexer_impl_addId       ( pass, 0, node ); }
     312        void indexerAddType     ( NamedTypeDecl             * node  ) { indexer_impl_addType     ( pass, 0, node ); }
    414313        void indexerAddStruct   ( const std::string         & id    ) { indexer_impl_addStruct   ( pass, 0, id   ); }
    415         void indexerAddStruct   ( const StructDecl          * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
    416         void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
    417         void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
     314        void indexerAddStruct   ( StructDecl                * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
     315        void indexerAddStructFwd( StructDecl                * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
     316        void indexerAddEnum     ( EnumDecl                  * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
    418317        void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
    419         void indexerAddUnion    ( const UnionDecl           * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
    420         void indexerAddUnionFwd ( const UnionDecl           * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    421         void indexerAddTrait    ( const TraitDecl           * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
    422         void indexerAddWith     ( const std::list< Expression * > & exprs, const Declaration * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
     318        void indexerAddUnion    ( UnionDecl                 * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
     319        void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
     320        void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
     321        void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
    423322
    424323
    425324        template< typename TreeType, typename VisitorType >
    426         friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );
     325        friend inline void indexerScopedAccept( TreeType * tree, VisitorType &visitor );
    427326
    428327        template< typename TreeType, typename VisitorType >
    429         friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor );
    430 
    431         template< typename TreeType, typename VisitorType >
    432         friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor );
     328        friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor );
    433329};
    434330
  • src/Common/PassVisitor.impl.h

    r4eb43fa rf6cc734e  
    8080
    8181template< typename pass_type >
    82 inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) {
    83         SemanticErrorException errors;
    84 
    85         pass_visitor_stats.depth++;
    86         pass_visitor_stats.max->push(pass_visitor_stats.depth);
    87         pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    88         for ( const Declaration * decl : decls ) {
    89                 try {
    90                         // run visitor on declaration
    91                         maybeAccept_impl( decl, visitor );
    92                 }
    93                 catch( SemanticErrorException &e ) {
    94                         errors.append( e );
    95                 }
    96         }
    97         pass_visitor_stats.depth--;
    98         if ( ! errors.isEmpty() ) {
    99                 throw errors;
    100         }
    101 }
    102 
    103 template< typename pass_type >
    10482inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
    10583        DeclList_t* beforeDecls = mutator.get_beforeDecls();
     
    139117}
    140118
    141 template< typename TreeType, typename pass_type >
    142 inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) {
    143         if ( ! visitor.get_visit_children() ) return;
    144         if ( tree ) {
    145                 tree->accept( visitor );
    146         }
    147 }
    148 
    149119template< typename Container, typename pass_type >
    150120inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
     
    159129                        if ( *i ) {
    160130                                (*i)->accept( visitor );
    161                         }
    162                 } catch( SemanticErrorException &e ) {
    163                         errors.append( e );
    164                 }
    165         }
    166         pass_visitor_stats.depth--;
    167         if ( ! errors.isEmpty() ) {
    168                 throw errors;
    169         }
    170 }
    171 
    172 template< typename Container, typename pass_type >
    173 inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) {
    174         if ( ! visitor.get_visit_children() ) return;
    175         SemanticErrorException errors;
    176 
    177         pass_visitor_stats.depth++;
    178         pass_visitor_stats.max->push(pass_visitor_stats.depth);
    179         pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    180         for ( const auto & i : container ) {
    181                 try {
    182                         if ( i ) {
    183                                 i->accept( visitor );
    184131                        }
    185132                } catch( SemanticErrorException &e ) {
     
    280227
    281228template< typename pass_type >
    282 void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) {
    283         if ( ! get_visit_children() ) return;
    284         SemanticErrorException errors;
    285 
    286         pass_visitor_stats.depth++;
    287         pass_visitor_stats.max->push(pass_visitor_stats.depth);
    288         pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    289         for ( const Statement * i : statements ) {
    290                 try {
    291                         maybeAccept_impl( i, *this );
    292                 } catch ( SemanticErrorException &e ) {
    293                         errors.append( e );
    294                 }
    295         }
    296         pass_visitor_stats.depth--;
    297         if ( !errors.isEmpty() ) { throw errors; }
    298 }
    299 
    300 template< typename pass_type >
    301229void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    302230        handleStatementList( statements, [this]( Statement *& stmt) {
     
    347275
    348276template< typename pass_type >
    349 void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) {
    350         if ( ! get_visit_children() ) return;
    351 
    352         // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    353         ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    354 
    355         maybeAccept_impl( stmt, *this );
    356 }
    357 
    358 template< typename pass_type >
    359277Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    360278        return handleStatement( stmt, [this]( Statement * stmt ) {
     
    388306
    389307template< typename pass_type >
    390 void PassVisitor< pass_type >::visitExpression( const Expression * expr ) {
    391         if ( ! get_visit_children() ) return;
    392         if( !expr ) return;
    393 
    394         auto env_ptr = get_env_ptr();
    395         if ( env_ptr && expr->get_env() ) {
    396                 *env_ptr = expr->get_env();
    397         }
    398 
    399         maybeAccept_impl( expr, *this );
    400 }
    401 
    402 template< typename pass_type >
    403308Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
    404309        return handleExpression(expr, [this]( Expression * expr ) {
     
    410315template< typename TreeType, typename VisitorType >
    411316inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
    412         if ( ! visitor.get_visit_children() ) return;
    413         auto guard = makeFuncGuard(
    414                 [&visitor]() { visitor.indexerScopeEnter(); },
    415                 [&visitor]() { visitor.indexerScopeLeave(); }
    416         );
    417         maybeAccept_impl( tree, visitor );
    418 }
    419 
    420 template< typename TreeType, typename VisitorType >
    421 inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) {
    422317        if ( ! visitor.get_visit_children() ) return;
    423318        auto guard = makeFuncGuard(
     
    477372
    478373        indexerAddId( node );
    479 
    480         VISIT_END( node );
    481 }
    482 
    483 template< typename pass_type >
    484 void PassVisitor< pass_type >::visit( const ObjectDecl * node ) {
    485         VISIT_START( node );
    486 
    487         maybeAccept_impl( node->type         , *this );
    488         maybeAccept_impl( node->init         , *this );
    489         maybeAccept_impl( node->bitfieldWidth, *this );
    490         maybeAccept_impl( node->attributes   , *this );
    491374
    492375        VISIT_END( node );
     
    545428
    546429template< typename pass_type >
    547 void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
    548         VISIT_START( node );
    549 
    550         indexerAddId( node );
    551 
    552         maybeAccept_impl( node->withExprs, *this );
    553         {
    554                 // with clause introduces a level of scope (for the with expression members).
    555                 // with clause exprs are added to the indexer before parameters so that parameters
    556                 // shadow with exprs and not the other way around.
    557                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    558                 indexerAddWith( node->withExprs, node );
    559                 {
    560                         auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    561                         // implicit add __func__ identifier as specified in the C manual 6.4.2.2
    562                         static ObjectDecl func(
    563                                 "__func__", noStorageClasses, LinkageSpec::C, nullptr,
    564                                 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
    565                                 nullptr
    566                         );
    567                         indexerAddId( &func );
    568                         maybeAccept_impl( node->type, *this );
    569                         // function body needs to have the same scope as parameters - CompoundStmt will not enter
    570                         // a new scope if inFunction is true
    571                         ValueGuard< bool > oldInFunction( inFunction );
    572                         inFunction = true;
    573                         maybeAccept_impl( node->statements, *this );
    574                         maybeAccept_impl( node->attributes, *this );
    575                 }
    576         }
    577 
    578         VISIT_END( node );
    579 }
    580 
    581 template< typename pass_type >
    582430DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
    583431        MUTATE_START( node );
     
    636484
    637485template< typename pass_type >
    638 void PassVisitor< pass_type >::visit( const StructDecl * node ) {
    639         VISIT_START( node );
     486Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
     487        MUTATE_START( node );
    640488
    641489        // make up a forward declaration and add it before processing the members
    642490        // needs to be on the heap because addStruct saves the pointer
    643491        indexerAddStructFwd( node );
     492
     493        {
     494                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     495                maybeMutate_impl( node->parameters, *this );
     496                maybeMutate_impl( node->members   , *this );
     497        }
     498
     499        // this addition replaces the forward declaration
     500        indexerAddStruct( node );
     501
     502        MUTATE_END( Declaration, node );
     503}
     504
     505//--------------------------------------------------------------------------
     506// UnionDecl
     507template< typename pass_type >
     508void PassVisitor< pass_type >::visit( UnionDecl * node ) {
     509        VISIT_START( node );
     510
     511        // make up a forward declaration and add it before processing the members
     512        indexerAddUnionFwd( node );
    644513
    645514        {
     
    649518        }
    650519
    651         // this addition replaces the forward declaration
    652         indexerAddStruct( node );
    653 
    654         VISIT_END( node );
    655 }
    656 
    657 template< typename pass_type >
    658 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
     520        indexerAddUnion( node );
     521
     522        VISIT_END( node );
     523}
     524
     525template< typename pass_type >
     526Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
    659527        MUTATE_START( node );
    660528
    661529        // make up a forward declaration and add it before processing the members
    662         // needs to be on the heap because addStruct saves the pointer
    663         indexerAddStructFwd( node );
     530        indexerAddUnionFwd( node );
    664531
    665532        {
     
    669536        }
    670537
    671         // this addition replaces the forward declaration
    672         indexerAddStruct( node );
     538        indexerAddUnion( node );
    673539
    674540        MUTATE_END( Declaration, node );
     
    676542
    677543//--------------------------------------------------------------------------
    678 // UnionDecl
    679 template< typename pass_type >
    680 void PassVisitor< pass_type >::visit( UnionDecl * node ) {
    681         VISIT_START( node );
    682 
    683         // make up a forward declaration and add it before processing the members
    684         indexerAddUnionFwd( node );
     544// EnumDecl
     545template< typename pass_type >
     546void PassVisitor< pass_type >::visit( EnumDecl * node ) {
     547        VISIT_START( node );
     548
     549        indexerAddEnum( node );
     550
     551        // unlike structs, traits, and unions, enums inject their members into the global scope
     552        maybeAccept_impl( node->parameters, *this );
     553        maybeAccept_impl( node->members   , *this );
     554
     555        VISIT_END( node );
     556}
     557
     558template< typename pass_type >
     559Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
     560        MUTATE_START( node );
     561
     562        indexerAddEnum( node );
     563
     564        // unlike structs, traits, and unions, enums inject their members into the global scope
     565        maybeMutate_impl( node->parameters, *this );
     566        maybeMutate_impl( node->members   , *this );
     567
     568        MUTATE_END( Declaration, node );
     569}
     570
     571//--------------------------------------------------------------------------
     572// TraitDecl
     573template< typename pass_type >
     574void PassVisitor< pass_type >::visit( TraitDecl * node ) {
     575        VISIT_START( node );
    685576
    686577        {
     
    690581        }
    691582
    692         indexerAddUnion( node );
    693 
    694         VISIT_END( node );
    695 }
    696 template< typename pass_type >
    697 void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
    698         VISIT_START( node );
    699 
    700         // make up a forward declaration and add it before processing the members
    701         indexerAddUnionFwd( node );
    702 
    703         {
    704                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    705                 maybeAccept_impl( node->parameters, *this );
    706                 maybeAccept_impl( node->members   , *this );
    707         }
    708 
    709         indexerAddUnion( node );
    710 
    711         VISIT_END( node );
    712 }
    713 
    714 template< typename pass_type >
    715 Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
    716         MUTATE_START( node );
    717 
    718         // make up a forward declaration and add it before processing the members
    719         indexerAddUnionFwd( node );
     583        indexerAddTrait( node );
     584
     585        VISIT_END( node );
     586}
     587
     588template< typename pass_type >
     589Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
     590        MUTATE_START( node );
    720591
    721592        {
     
    725596        }
    726597
    727         indexerAddUnion( node );
    728 
    729         MUTATE_END( Declaration, node );
    730 }
    731 
    732 //--------------------------------------------------------------------------
    733 // EnumDecl
    734 template< typename pass_type >
    735 void PassVisitor< pass_type >::visit( EnumDecl * node ) {
    736         VISIT_START( node );
    737 
    738         indexerAddEnum( node );
    739 
    740         // unlike structs, traits, and unions, enums inject their members into the global scope
    741         maybeAccept_impl( node->parameters, *this );
    742         maybeAccept_impl( node->members   , *this );
    743 
    744         VISIT_END( node );
    745 }
    746 
    747 template< typename pass_type >
    748 void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
    749         VISIT_START( node );
    750 
    751         indexerAddEnum( node );
    752 
    753         // unlike structs, traits, and unions, enums inject their members into the global scope
    754         maybeAccept_impl( node->parameters, *this );
    755         maybeAccept_impl( node->members   , *this );
    756 
    757         VISIT_END( node );
    758 }
    759 
    760 template< typename pass_type >
    761 Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
    762         MUTATE_START( node );
    763 
    764         indexerAddEnum( node );
    765 
    766         // unlike structs, traits, and unions, enums inject their members into the global scope
    767         maybeMutate_impl( node->parameters, *this );
    768         maybeMutate_impl( node->members   , *this );
    769 
    770         MUTATE_END( Declaration, node );
    771 }
    772 
    773 //--------------------------------------------------------------------------
    774 // TraitDecl
    775 template< typename pass_type >
    776 void PassVisitor< pass_type >::visit( TraitDecl * node ) {
    777         VISIT_START( node );
    778 
    779         {
    780                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    781                 maybeAccept_impl( node->parameters, *this );
    782                 maybeAccept_impl( node->members   , *this );
    783         }
    784 
    785         indexerAddTrait( node );
    786 
    787         VISIT_END( node );
    788 }
    789 
    790 template< typename pass_type >
    791 void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
    792         VISIT_START( node );
    793 
    794         {
    795                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    796                 maybeAccept_impl( node->parameters, *this );
    797                 maybeAccept_impl( node->members   , *this );
    798         }
    799 
    800         indexerAddTrait( node );
    801 
    802         VISIT_END( node );
    803 }
    804 
    805 template< typename pass_type >
    806 Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
    807         MUTATE_START( node );
    808 
    809         {
    810                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    811                 maybeMutate_impl( node->parameters, *this );
    812                 maybeMutate_impl( node->members   , *this );
    813         }
    814 
    815598        indexerAddTrait( node );
    816599
     
    842625}
    843626
    844 
    845 template< typename pass_type >
    846 void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
     627template< typename pass_type >
     628Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     629        MUTATE_START( node );
     630
     631        {
     632                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     633                maybeMutate_impl( node->parameters, *this );
     634                maybeMutate_impl( node->base      , *this );
     635        }
     636
     637        // see A NOTE ON THE ORDER OF TRAVERSAL, above
     638        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
     639        // and may depend on the type itself
     640        indexerAddType( node );
     641
     642        maybeMutate_impl( node->assertions, *this );
     643
     644        indexerScopedMutate( node->init, *this );
     645
     646        MUTATE_END( Declaration, node );
     647}
     648
     649//--------------------------------------------------------------------------
     650// TypedefDecl
     651template< typename pass_type >
     652void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
    847653        VISIT_START( node );
    848654
     
    853659        }
    854660
    855         // see A NOTE ON THE ORDER OF TRAVERSAL, above
    856         // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    857         // and may depend on the type itself
    858661        indexerAddType( node );
    859662
    860663        maybeAccept_impl( node->assertions, *this );
    861664
    862         indexerScopedAccept( node->init, *this );
    863 
    864         VISIT_END( node );
    865 }
    866 
    867 template< typename pass_type >
    868 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     665        VISIT_END( node );
     666}
     667
     668template< typename pass_type >
     669Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
    869670        MUTATE_START( node );
    870671
     
    875676        }
    876677
    877         // see A NOTE ON THE ORDER OF TRAVERSAL, above
    878         // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    879         // and may depend on the type itself
    880678        indexerAddType( node );
    881679
    882680        maybeMutate_impl( node->assertions, *this );
    883681
    884         indexerScopedMutate( node->init, *this );
    885 
    886682        MUTATE_END( Declaration, node );
    887683}
    888684
    889685//--------------------------------------------------------------------------
    890 // TypedefDecl
    891 template< typename pass_type >
    892 void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
    893         VISIT_START( node );
    894 
    895         {
    896                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    897                 maybeAccept_impl( node->parameters, *this );
    898                 maybeAccept_impl( node->base      , *this );
    899         }
    900 
    901         indexerAddType( node );
    902 
    903         maybeAccept_impl( node->assertions, *this );
    904 
    905         VISIT_END( node );
    906 }
    907 
    908 template< typename pass_type >
    909 void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
    910         VISIT_START( node );
    911 
    912         {
    913                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    914                 maybeAccept_impl( node->parameters, *this );
    915                 maybeAccept_impl( node->base      , *this );
    916         }
    917 
    918         indexerAddType( node );
    919 
    920         maybeAccept_impl( node->assertions, *this );
    921 
    922         VISIT_END( node );
    923 }
    924 
    925 template< typename pass_type >
    926 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
    927         MUTATE_START( node );
    928 
    929         {
    930                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    931                 maybeMutate_impl( node->parameters, *this );
    932                 maybeMutate_impl( node->base      , *this );
    933         }
    934 
    935         indexerAddType( node );
    936 
    937         maybeMutate_impl( node->assertions, *this );
    938 
    939         MUTATE_END( Declaration, node );
    940 }
    941 
    942 //--------------------------------------------------------------------------
    943686// AsmDecl
    944687template< typename pass_type >
     
    952695
    953696template< typename pass_type >
    954 void PassVisitor< pass_type >::visit( const AsmDecl * node ) {
    955         VISIT_START( node );
    956 
    957         maybeAccept_impl( node->stmt, *this );
    958 
    959         VISIT_END( node );
    960 }
    961 
    962 template< typename pass_type >
    963697AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
    964698        MUTATE_START( node );
     
    976710
    977711        node->condition = visitExpression( node->condition );
    978         maybeAccept_impl( node->message, *this );
    979 
    980         VISIT_END( node );
    981 }
    982 
    983 template< typename pass_type >
    984 void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) {
    985         VISIT_START( node );
    986 
    987         visitExpression( node->condition );
    988712        maybeAccept_impl( node->message, *this );
    989713
     
    1018742
    1019743template< typename pass_type >
    1020 void PassVisitor< pass_type >::visit( const CompoundStmt * node ) {
    1021         VISIT_START( node );
    1022         {
    1023                 // do not enter a new scope if inFunction is true - needs to check old state before the assignment
    1024                 ValueGuard< bool > oldInFunction( inFunction );
    1025                 auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    1026                 auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
    1027                 inFunction = false;
    1028                 visitStatementList( node->kids );
    1029         }
    1030         VISIT_END( node );
    1031 }
    1032 
    1033 template< typename pass_type >
    1034744CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
    1035745        MUTATE_START( node );
     
    1057767
    1058768template< typename pass_type >
    1059 void PassVisitor< pass_type >::visit( const ExprStmt * node ) {
    1060         VISIT_START( node );
    1061 
    1062         visitExpression( node->expr );
    1063 
    1064         VISIT_END( node );
    1065 }
    1066 
    1067 template< typename pass_type >
    1068769Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
    1069770        MUTATE_START( node );
     
    1089790
    1090791template< typename pass_type >
    1091 void PassVisitor< pass_type >::visit( const AsmStmt * node ) {
    1092         VISIT_START( node )
    1093 
    1094         maybeAccept_impl( node->instruction, *this );
    1095         maybeAccept_impl( node->output, *this );
    1096         maybeAccept_impl( node->input, *this );
    1097         maybeAccept_impl( node->clobber, *this );
    1098 
    1099         VISIT_END( node );
    1100 }
    1101 
    1102 template< typename pass_type >
    1103792Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    1104793        MUTATE_START( node );
     
    1122811
    1123812template< typename pass_type >
    1124 void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) {
    1125         VISIT_START( node )
    1126 
    1127         VISIT_END( node );
    1128 }
    1129 
    1130 template< typename pass_type >
    1131813Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
    1132814        MUTATE_START( node );
     
    1143825                // if statements introduce a level of scope (for the initialization)
    1144826                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1145                 maybeAccept_impl( node->initialization, *this );
     827                maybeAccept_impl( node->get_initialization(), *this );
    1146828                visitExpression ( node->condition );
    1147829                node->thenPart = visitStatement( node->thenPart );
     
    1152834
    1153835template< typename pass_type >
    1154 void PassVisitor< pass_type >::visit( const IfStmt * node ) {
    1155         VISIT_START( node );
     836Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
     837        MUTATE_START( node );
    1156838        {
    1157839                // if statements introduce a level of scope (for the initialization)
    1158840                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1159                 maybeAccept_impl( node->initialization, *this );
    1160                 visitExpression ( node->condition );
    1161                 visitStatement  ( node->thenPart );
    1162                 visitStatement  ( node->elsePart );
    1163         }
    1164         VISIT_END( node );
    1165 }
    1166 
    1167 template< typename pass_type >
    1168 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    1169         MUTATE_START( node );
    1170         {
    1171                 // if statements introduce a level of scope (for the initialization)
    1172                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1173                 maybeMutate_impl( node->initialization, *this );
     841                maybeMutate_impl( node->get_initialization(), *this );
    1174842                node->condition = mutateExpression( node->condition );
    1175843                node->thenPart  = mutateStatement ( node->thenPart  );
     
    1191859                visitExpression ( node->condition );
    1192860                node->body = visitStatement( node->body );
    1193         }
    1194 
    1195         VISIT_END( node );
    1196 }
    1197 
    1198 template< typename pass_type >
    1199 void PassVisitor< pass_type >::visit( const WhileStmt * node ) {
    1200         VISIT_START( node );
    1201 
    1202         {
    1203                 // while statements introduce a level of scope (for the initialization)
    1204                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1205                 maybeAccept_impl( node->initialization, *this );
    1206                 visitExpression ( node->condition );
    1207                 visitStatement  ( node->body );
    1208861        }
    1209862
     
    1244897
    1245898template< typename pass_type >
    1246 void PassVisitor< pass_type >::visit( const ForStmt * node ) {
    1247         VISIT_START( node );
    1248         {
    1249                 // for statements introduce a level of scope (for the initialization)
    1250                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1251                 maybeAccept_impl( node->initialization, *this );
    1252                 visitExpression( node->condition );
    1253                 visitExpression( node->increment );
    1254                 visitStatement ( node->body );
    1255         }
    1256         VISIT_END( node );
    1257 }
    1258 
    1259 template< typename pass_type >
    1260899Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    1261900        MUTATE_START( node );
     
    1284923
    1285924template< typename pass_type >
    1286 void PassVisitor< pass_type >::visit( const SwitchStmt * node ) {
    1287         VISIT_START( node );
    1288 
    1289         visitExpression   ( node->condition  );
    1290         visitStatementList( node->statements );
    1291 
    1292         VISIT_END( node );
    1293 }
    1294 
    1295 template< typename pass_type >
    1296925Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
    1297926        MUTATE_START( node );
     
    1316945
    1317946template< typename pass_type >
    1318 void PassVisitor< pass_type >::visit( const CaseStmt * node ) {
    1319         VISIT_START( node );
    1320 
    1321         visitExpression   ( node->condition );
    1322         visitStatementList( node->stmts     );
    1323 
    1324         VISIT_END( node );
    1325 }
    1326 
    1327 template< typename pass_type >
    1328947Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
    1329948        MUTATE_START( node );
     
    1344963
    1345964template< typename pass_type >
    1346 void PassVisitor< pass_type >::visit( const BranchStmt * node ) {
    1347         VISIT_START( node );
    1348         VISIT_END( node );
    1349 }
    1350 
    1351 template< typename pass_type >
    1352965Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
    1353966        MUTATE_START( node );
     
    1367980
    1368981template< typename pass_type >
    1369 void PassVisitor< pass_type >::visit( const ReturnStmt * node ) {
    1370         VISIT_START( node );
    1371 
    1372         visitExpression( node->expr );
    1373 
    1374         VISIT_END( node );
    1375 }
    1376 
    1377 template< typename pass_type >
    1378982Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
    1379983        MUTATE_START( node );
     
    1386990//--------------------------------------------------------------------------
    1387991// ThrowStmt
     992
    1388993template< typename pass_type >
    1389994void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
     
    13971002
    13981003template< typename pass_type >
    1399 void PassVisitor< pass_type >::visit( const ThrowStmt * node ) {
    1400         VISIT_START( node );
    1401 
    1402         maybeAccept_impl( node->expr, *this );
    1403         maybeAccept_impl( node->target, *this );
    1404 
    1405         VISIT_END( node );
    1406 }
    1407 
    1408 template< typename pass_type >
    14091004Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
    14101005        MUTATE_START( node );
     
    14201015template< typename pass_type >
    14211016void PassVisitor< pass_type >::visit( TryStmt * node ) {
    1422         VISIT_START( node );
    1423 
    1424         maybeAccept_impl( node->block       , *this );
    1425         maybeAccept_impl( node->handlers    , *this );
    1426         maybeAccept_impl( node->finallyBlock, *this );
    1427 
    1428         VISIT_END( node );
    1429 }
    1430 
    1431 template< typename pass_type >
    1432 void PassVisitor< pass_type >::visit( const TryStmt * node ) {
    14331017        VISIT_START( node );
    14341018
     
    14671051
    14681052template< typename pass_type >
    1469 void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
    1470         VISIT_START( node );
    1471         {
    1472                 // catch statements introduce a level of scope (for the caught exception)
    1473                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1474                 maybeAccept_impl( node->decl, *this );
    1475                 visitExpression ( node->cond );
    1476                 visitStatement  ( node->body );
    1477         }
    1478         VISIT_END( node );
    1479 }
    1480 
    1481 template< typename pass_type >
    14821053Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    14831054        MUTATE_START( node );
     
    15041075
    15051076template< typename pass_type >
    1506 void PassVisitor< pass_type >::visit( const FinallyStmt * node ) {
    1507         VISIT_START( node );
    1508 
    1509         maybeAccept_impl( node->block, *this );
    1510 
    1511         VISIT_END( node );
    1512 }
    1513 
    1514 template< typename pass_type >
    15151077Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    15161078        MUTATE_START( node );
     
    15451107
    15461108template< typename pass_type >
    1547 void PassVisitor< pass_type >::visit( const WaitForStmt * node ) {
    1548         VISIT_START( node );
    1549 
    1550         for( auto & clause : node->clauses ) {
    1551                 maybeAccept_impl( clause.target.function, *this );
    1552                 maybeAccept_impl( clause.target.arguments, *this );
    1553 
    1554                 maybeAccept_impl( clause.statement, *this );
    1555                 maybeAccept_impl( clause.condition, *this );
    1556         }
    1557 
    1558         maybeAccept_impl( node->timeout.time, *this );
    1559         maybeAccept_impl( node->timeout.statement, *this );
    1560         maybeAccept_impl( node->timeout.condition, *this );
    1561         maybeAccept_impl( node->orelse.statement, *this );
    1562         maybeAccept_impl( node->orelse.condition, *this );
    1563 
    1564         VISIT_END( node );
    1565 }
    1566 
    1567 template< typename pass_type >
    15681109Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
    15691110        MUTATE_START( node );
     
    15891130
    15901131//--------------------------------------------------------------------------
    1591 // WithStmt
     1132// NullStmt
    15921133template< typename pass_type >
    15931134void PassVisitor< pass_type >::visit( WithStmt * node ) {
     
    16041145
    16051146template< typename pass_type >
    1606 void PassVisitor< pass_type >::visit( const WithStmt * node ) {
    1607         VISIT_START( node );
    1608         maybeAccept_impl( node->exprs, *this );
    1609         {
    1610                 // catch statements introduce a level of scope (for the caught exception)
    1611                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1612                 indexerAddWith( node->exprs, node );
    1613                 maybeAccept_impl( node->stmt, *this );
    1614         }
    1615         VISIT_END( node );
    1616 }
    1617 
    1618 template< typename pass_type >
    1619 Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) {
     1147Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
    16201148        MUTATE_START( node );
    16211149        maybeMutate_impl( node->exprs, *this );
     
    16261154                maybeMutate_impl( node->stmt, *this );
    16271155        }
    1628         MUTATE_END( Declaration, node );
     1156        MUTATE_END( Statement, node );
    16291157}
    16301158
     
    16381166
    16391167template< typename pass_type >
    1640 void PassVisitor< pass_type >::visit( const NullStmt * node ) {
    1641         VISIT_START( node );
    1642         VISIT_END( node );
    1643 }
    1644 
    1645 template< typename pass_type >
    16461168NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
    16471169        MUTATE_START( node );
     
    16611183
    16621184template< typename pass_type >
    1663 void PassVisitor< pass_type >::visit( const DeclStmt * node ) {
    1664         VISIT_START( node );
    1665 
    1666         maybeAccept_impl( node->decl, *this );
    1667 
    1668         VISIT_END( node );
    1669 }
    1670 
    1671 template< typename pass_type >
    16721185Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
    16731186        MUTATE_START( node );
     
    16901203
    16911204template< typename pass_type >
    1692 void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) {
    1693         VISIT_START( node );
    1694 
    1695         maybeAccept_impl( node->callStmt, *this );
    1696 
    1697         VISIT_END( node );
    1698 }
    1699 
    1700 template< typename pass_type >
    17011205Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
    17021206        MUTATE_START( node );
     
    17141218
    17151219        indexerScopedAccept( node->result  , *this );
    1716         maybeAccept_impl   ( node->function, *this );
    1717         maybeAccept_impl   ( node->args    , *this );
    1718 
    1719         VISIT_END( node );
    1720 }
    1721 
    1722 template< typename pass_type >
    1723 void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) {
    1724         VISIT_START( node );
    1725 
    1726         indexerScopedAccept( node->result  , *this );
    1727         maybeAccept_impl   ( node->function, *this );
    1728         maybeAccept_impl   ( node->args    , *this );
     1220        maybeAccept_impl        ( node->function, *this );
     1221        maybeAccept_impl        ( node->args    , *this );
    17291222
    17301223        VISIT_END( node );
     
    17601253
    17611254template< typename pass_type >
    1762 void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
    1763         VISIT_START( node );
    1764 
    1765         indexerScopedAccept( node->result, *this );
    1766 
    1767         for ( auto expr : node->args ) {
    1768                 visitExpression( expr );
    1769         }
    1770 
    1771         VISIT_END( node );
    1772 }
    1773 
    1774 template< typename pass_type >
    17751255Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    17761256        MUTATE_START( node );
     
    17981278
    17991279template< typename pass_type >
    1800 void PassVisitor< pass_type >::visit( const NameExpr * node ) {
     1280Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
     1281        MUTATE_START( node );
     1282
     1283        indexerScopedMutate( node->env   , *this );
     1284        indexerScopedMutate( node->result, *this );
     1285
     1286        MUTATE_END( Expression, node );
     1287}
     1288
     1289//--------------------------------------------------------------------------
     1290// CastExpr
     1291template< typename pass_type >
     1292void PassVisitor< pass_type >::visit( CastExpr * node ) {
    18011293        VISIT_START( node );
    18021294
    18031295        indexerScopedAccept( node->result, *this );
    1804 
    1805         VISIT_END( node );
    1806 }
    1807 
    1808 template< typename pass_type >
    1809 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
     1296        maybeAccept_impl        ( node->arg   , *this );
     1297
     1298        VISIT_END( node );
     1299}
     1300
     1301template< typename pass_type >
     1302Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
    18101303        MUTATE_START( node );
    18111304
    18121305        indexerScopedMutate( node->env   , *this );
    18131306        indexerScopedMutate( node->result, *this );
    1814 
    1815         MUTATE_END( Expression, node );
    1816 }
    1817 
    1818 //--------------------------------------------------------------------------
    1819 // CastExpr
    1820 template< typename pass_type >
    1821 void PassVisitor< pass_type >::visit( CastExpr * node ) {
     1307        maybeMutate_impl   ( node->arg   , *this );
     1308
     1309        MUTATE_END( Expression, node );
     1310}
     1311
     1312//--------------------------------------------------------------------------
     1313// KeywordCastExpr
     1314template< typename pass_type >
     1315void PassVisitor< pass_type >::visit( KeywordCastExpr * node ) {
     1316        VISIT_START( node );
     1317
     1318        indexerScopedAccept( node->result, *this );
     1319        maybeAccept_impl        ( node->arg   , *this );
     1320
     1321        VISIT_END( node );
     1322}
     1323
     1324template< typename pass_type >
     1325Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
     1326        MUTATE_START( node );
     1327
     1328        indexerScopedMutate( node->env   , *this );
     1329        indexerScopedMutate( node->result, *this );
     1330        maybeMutate_impl   ( node->arg   , *this );
     1331
     1332        MUTATE_END( Expression, node );
     1333}
     1334
     1335//--------------------------------------------------------------------------
     1336// VirtualCastExpr
     1337template< typename pass_type >
     1338void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
     1339        VISIT_START( node );
     1340
     1341        indexerScopedAccept( node->result, *this );
     1342        maybeAccept_impl( node->arg, *this );
     1343
     1344        VISIT_END( node );
     1345}
     1346
     1347template< typename pass_type >
     1348Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
     1349        MUTATE_START( node );
     1350
     1351        indexerScopedMutate( node->env   , *this );
     1352        indexerScopedMutate( node->result, *this );
     1353        maybeMutate_impl   ( node->arg   , *this );
     1354
     1355        MUTATE_END( Expression, node );
     1356}
     1357
     1358//--------------------------------------------------------------------------
     1359// AddressExpr
     1360template< typename pass_type >
     1361void PassVisitor< pass_type >::visit( AddressExpr * node ) {
    18221362        VISIT_START( node );
    18231363
     
    18291369
    18301370template< typename pass_type >
    1831 void PassVisitor< pass_type >::visit( const CastExpr * node ) {
     1371Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
     1372        MUTATE_START( node );
     1373
     1374        indexerScopedMutate( node->env   , *this );
     1375        indexerScopedMutate( node->result, *this );
     1376        maybeMutate_impl   ( node->arg   , *this );
     1377
     1378        MUTATE_END( Expression, node );
     1379}
     1380
     1381//--------------------------------------------------------------------------
     1382// LabelAddressExpr
     1383template< typename pass_type >
     1384void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
    18321385        VISIT_START( node );
    18331386
    18341387        indexerScopedAccept( node->result, *this );
    1835         maybeAccept_impl   ( node->arg   , *this );
    1836 
    1837         VISIT_END( node );
    1838 }
    1839 
    1840 template< typename pass_type >
    1841 Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
     1388
     1389        VISIT_END( node );
     1390}
     1391
     1392template< typename pass_type >
     1393Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
    18421394        MUTATE_START( node );
    18431395
    18441396        indexerScopedMutate( node->env   , *this );
    18451397        indexerScopedMutate( node->result, *this );
    1846         maybeMutate_impl   ( node->arg   , *this );
    1847 
    1848         MUTATE_END( Expression, node );
    1849 }
    1850 
    1851 //--------------------------------------------------------------------------
    1852 // KeywordCastExpr
    1853 template< typename pass_type >
    1854 void PassVisitor< pass_type >::visit( KeywordCastExpr * node ) {
    1855         VISIT_START( node );
    1856 
    1857         indexerScopedAccept( node->result, *this );
    1858         maybeAccept_impl        ( node->arg   , *this );
    1859 
    1860         VISIT_END( node );
    1861 }
    1862 
    1863 template< typename pass_type >
    1864 void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
    1865         VISIT_START( node );
    1866 
    1867         indexerScopedAccept( node->result, *this );
    1868         maybeAccept_impl   ( node->arg   , *this );
    1869 
    1870         VISIT_END( node );
    1871 }
    1872 
    1873 template< typename pass_type >
    1874 Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
    1875         MUTATE_START( node );
    1876 
    1877         indexerScopedMutate( node->env   , *this );
    1878         indexerScopedMutate( node->result, *this );
    1879         maybeMutate_impl   ( node->arg   , *this );
    1880 
    1881         MUTATE_END( Expression, node );
    1882 }
    1883 
    1884 //--------------------------------------------------------------------------
    1885 // VirtualCastExpr
    1886 template< typename pass_type >
    1887 void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
    1888         VISIT_START( node );
    1889 
    1890         indexerScopedAccept( node->result, *this );
    1891         maybeAccept_impl   ( node->arg, *this );
    1892 
    1893         VISIT_END( node );
    1894 }
    1895 
    1896 template< typename pass_type >
    1897 void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
    1898         VISIT_START( node );
    1899 
    1900         indexerScopedAccept( node->result, *this );
    1901         maybeAccept_impl   ( node->arg, *this );
    1902 
    1903         VISIT_END( node );
    1904 }
    1905 
    1906 template< typename pass_type >
    1907 Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
    1908         MUTATE_START( node );
    1909 
    1910         indexerScopedMutate( node->env   , *this );
    1911         indexerScopedMutate( node->result, *this );
    1912         maybeMutate_impl   ( node->arg   , *this );
    1913 
    1914         MUTATE_END( Expression, node );
    1915 }
    1916 
    1917 //--------------------------------------------------------------------------
    1918 // AddressExpr
    1919 template< typename pass_type >
    1920 void PassVisitor< pass_type >::visit( AddressExpr * node ) {
    1921         VISIT_START( node );
    1922 
    1923         indexerScopedAccept( node->result, *this );
    1924         maybeAccept_impl   ( node->arg   , *this );
    1925 
    1926         VISIT_END( node );
    1927 }
    1928 
    1929 template< typename pass_type >
    1930 void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
    1931         VISIT_START( node );
    1932 
    1933         indexerScopedAccept( node->result, *this );
    1934         maybeAccept_impl   ( node->arg   , *this );
    1935 
    1936         VISIT_END( node );
    1937 }
    1938 
    1939 template< typename pass_type >
    1940 Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
    1941         MUTATE_START( node );
    1942 
    1943         indexerScopedMutate( node->env   , *this );
    1944         indexerScopedMutate( node->result, *this );
    1945         maybeMutate_impl   ( node->arg   , *this );
    1946 
    1947         MUTATE_END( Expression, node );
    1948 }
    1949 
    1950 //--------------------------------------------------------------------------
    1951 // LabelAddressExpr
    1952 template< typename pass_type >
    1953 void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
    1954         VISIT_START( node );
    1955 
    1956         indexerScopedAccept( node->result, *this );
    1957 
    1958         VISIT_END( node );
    1959 }
    1960 
    1961 template< typename pass_type >
    1962 void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
    1963         VISIT_START( node );
    1964 
    1965         indexerScopedAccept( node->result, *this );
    1966 
    1967         VISIT_END( node );
    1968 }
    1969 
    1970 template< typename pass_type >
    1971 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
    1972         MUTATE_START( node );
    1973 
    1974         indexerScopedMutate( node->env   , *this );
    1975         indexerScopedMutate( node->result, *this );
    19761398
    19771399        MUTATE_END( Expression, node );
     
    19821404template< typename pass_type >
    19831405void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
    1984         VISIT_START( node );
    1985 
    1986         indexerScopedAccept( node->result   , *this );
    1987         maybeAccept_impl   ( node->aggregate, *this );
    1988         maybeAccept_impl   ( node->member   , *this );
    1989 
    1990         VISIT_END( node );
    1991 }
    1992 
    1993 template< typename pass_type >
    1994 void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) {
    19951406        VISIT_START( node );
    19961407
     
    20271438
    20281439template< typename pass_type >
    2029 void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
    2030         VISIT_START( node );
    2031 
    2032         indexerScopedAccept( node->result   , *this );
    2033         maybeAccept_impl   ( node->aggregate, *this );
    2034 
    2035         VISIT_END( node );
    2036 }
    2037 
    2038 template< typename pass_type >
    20391440Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
    20401441        MUTATE_START( node );
     
    20591460
    20601461template< typename pass_type >
    2061 void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
    2062         VISIT_START( node );
    2063 
    2064         indexerScopedAccept( node->result, *this );
    2065 
    2066         VISIT_END( node );
    2067 }
    2068 
    2069 template< typename pass_type >
    20701462Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
    20711463        MUTATE_START( node );
     
    20811473template< typename pass_type >
    20821474void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
    2083         VISIT_START( node );
    2084 
    2085         indexerScopedAccept( node->result   , *this );
    2086         maybeAccept_impl   ( &node->constant, *this );
    2087 
    2088         VISIT_END( node );
    2089 }
    2090 
    2091 template< typename pass_type >
    2092 void PassVisitor< pass_type >::visit( const ConstantExpr * node ) {
    20931475        VISIT_START( node );
    20941476
     
    21291511
    21301512template< typename pass_type >
    2131 void PassVisitor< pass_type >::visit( const SizeofExpr * node ) {
     1513Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
     1514        MUTATE_START( node );
     1515
     1516        indexerScopedMutate( node->env   , *this );
     1517        indexerScopedMutate( node->result, *this );
     1518        if ( node->get_isType() ) {
     1519                maybeMutate_impl( node->type, *this );
     1520        } else {
     1521                maybeMutate_impl( node->expr, *this );
     1522        }
     1523
     1524        MUTATE_END( Expression, node );
     1525}
     1526
     1527//--------------------------------------------------------------------------
     1528// AlignofExpr
     1529template< typename pass_type >
     1530void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
    21321531        VISIT_START( node );
    21331532
     
    21431542
    21441543template< typename pass_type >
    2145 Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
     1544Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
    21461545        MUTATE_START( node );
    21471546
     
    21581557
    21591558//--------------------------------------------------------------------------
    2160 // AlignofExpr
    2161 template< typename pass_type >
    2162 void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
     1559// UntypedOffsetofExpr
     1560template< typename pass_type >
     1561void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
     1562        VISIT_START( node );
     1563
     1564        indexerScopedAccept( node->result, *this );
     1565        maybeAccept_impl   ( node->type  , *this );
     1566
     1567        VISIT_END( node );
     1568}
     1569
     1570template< typename pass_type >
     1571Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
     1572        MUTATE_START( node );
     1573
     1574        indexerScopedMutate( node->env   , *this );
     1575        indexerScopedMutate( node->result, *this );
     1576        maybeMutate_impl   ( node->type  , *this );
     1577
     1578        MUTATE_END( Expression, node );
     1579}
     1580
     1581//--------------------------------------------------------------------------
     1582// OffsetofExpr
     1583template< typename pass_type >
     1584void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
     1585        VISIT_START( node );
     1586
     1587        indexerScopedAccept( node->result, *this );
     1588        maybeAccept_impl   ( node->type  , *this );
     1589
     1590        VISIT_END( node );
     1591}
     1592
     1593template< typename pass_type >
     1594Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
     1595        MUTATE_START( node );
     1596
     1597        indexerScopedMutate( node->env   , *this );
     1598        indexerScopedMutate( node->result, *this );
     1599        maybeMutate_impl   ( node->type  , *this );
     1600
     1601        MUTATE_END( Expression, node );
     1602}
     1603
     1604//--------------------------------------------------------------------------
     1605// OffsetPackExpr
     1606template< typename pass_type >
     1607void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
     1608        VISIT_START( node );
     1609
     1610        indexerScopedAccept( node->result, *this );
     1611        maybeAccept_impl   ( node->type  , *this );
     1612
     1613        VISIT_END( node );
     1614}
     1615
     1616template< typename pass_type >
     1617Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
     1618        MUTATE_START( node );
     1619
     1620        indexerScopedMutate( node->env   , *this );
     1621        indexerScopedMutate( node->result, *this );
     1622        maybeMutate_impl   ( node->type  , *this );
     1623
     1624        MUTATE_END( Expression, node );
     1625}
     1626
     1627//--------------------------------------------------------------------------
     1628// AttrExpr
     1629template< typename pass_type >
     1630void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    21631631        VISIT_START( node );
    21641632
     
    21741642
    21751643template< typename pass_type >
    2176 void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
    2177         VISIT_START( node );
    2178 
    2179         indexerScopedAccept( node->result, *this );
    2180         if ( node->get_isType() ) {
    2181                 maybeAccept_impl( node->type, *this );
    2182         } else {
    2183                 maybeAccept_impl( node->expr, *this );
    2184         }
    2185 
    2186         VISIT_END( node );
    2187 }
    2188 
    2189 template< typename pass_type >
    2190 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
     1644Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
    21911645        MUTATE_START( node );
    21921646
     
    22031657
    22041658//--------------------------------------------------------------------------
    2205 // UntypedOffsetofExpr
    2206 template< typename pass_type >
    2207 void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
    2208         VISIT_START( node );
    2209 
    2210         indexerScopedAccept( node->result, *this );
    2211         maybeAccept_impl   ( node->type  , *this );
    2212 
    2213         VISIT_END( node );
    2214 }
    2215 
    2216 template< typename pass_type >
    2217 void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
    2218         VISIT_START( node );
    2219 
    2220         indexerScopedAccept( node->result, *this );
    2221         maybeAccept_impl   ( node->type  , *this );
    2222 
    2223         VISIT_END( node );
    2224 }
    2225 
    2226 template< typename pass_type >
    2227 Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
    2228         MUTATE_START( node );
    2229 
    2230         indexerScopedMutate( node->env   , *this );
    2231         indexerScopedMutate( node->result, *this );
    2232         maybeMutate_impl   ( node->type  , *this );
    2233 
    2234         MUTATE_END( Expression, node );
    2235 }
    2236 
    2237 //--------------------------------------------------------------------------
    2238 // OffsetofExpr
    2239 template< typename pass_type >
    2240 void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
    2241         VISIT_START( node );
    2242 
    2243         indexerScopedAccept( node->result, *this );
    2244         maybeAccept_impl   ( node->type  , *this );
    2245 
    2246         VISIT_END( node );
    2247 }
    2248 
    2249 template< typename pass_type >
    2250 void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
    2251         VISIT_START( node );
    2252 
    2253         indexerScopedAccept( node->result, *this );
    2254         maybeAccept_impl   ( node->type  , *this );
    2255 
    2256         VISIT_END( node );
    2257 }
    2258 
    2259 template< typename pass_type >
    2260 Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
    2261         MUTATE_START( node );
    2262 
    2263         indexerScopedMutate( node->env   , *this );
    2264         indexerScopedMutate( node->result, *this );
    2265         maybeMutate_impl   ( node->type  , *this );
    2266 
    2267         MUTATE_END( Expression, node );
    2268 }
    2269 
    2270 //--------------------------------------------------------------------------
    2271 // OffsetPackExpr
    2272 template< typename pass_type >
    2273 void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
    2274         VISIT_START( node );
    2275 
    2276         indexerScopedAccept( node->result, *this );
    2277         maybeAccept_impl   ( node->type  , *this );
    2278 
    2279         VISIT_END( node );
    2280 }
    2281 
    2282 template< typename pass_type >
    2283 void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
    2284         VISIT_START( node );
    2285 
    2286         indexerScopedAccept( node->result, *this );
    2287         maybeAccept_impl   ( node->type  , *this );
    2288 
    2289         VISIT_END( node );
    2290 }
    2291 
    2292 template< typename pass_type >
    2293 Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
    2294         MUTATE_START( node );
    2295 
    2296         indexerScopedMutate( node->env   , *this );
    2297         indexerScopedMutate( node->result, *this );
    2298         maybeMutate_impl   ( node->type  , *this );
    2299 
    2300         MUTATE_END( Expression, node );
    2301 }
    2302 
    2303 //--------------------------------------------------------------------------
    2304 // AttrExpr
    2305 template< typename pass_type >
    2306 void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    2307         VISIT_START( node );
    2308 
    2309         indexerScopedAccept( node->result, *this );
    2310         if ( node->get_isType() ) {
    2311                 maybeAccept_impl( node->type, *this );
    2312         } else {
    2313                 maybeAccept_impl( node->expr, *this );
    2314         }
    2315 
    2316         VISIT_END( node );
    2317 }
    2318 
    2319 template< typename pass_type >
    2320 void PassVisitor< pass_type >::visit( const AttrExpr * node ) {
    2321         VISIT_START( node );
    2322 
    2323         indexerScopedAccept( node->result, *this );
    2324         if ( node->get_isType() ) {
    2325                 maybeAccept_impl( node->type, *this );
    2326         } else {
    2327                 maybeAccept_impl( node->expr, *this );
    2328         }
    2329 
    2330         VISIT_END( node );
    2331 }
    2332 
    2333 template< typename pass_type >
    2334 Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
    2335         MUTATE_START( node );
    2336 
    2337         indexerScopedMutate( node->env   , *this );
    2338         indexerScopedMutate( node->result, *this );
    2339         if ( node->get_isType() ) {
    2340                 maybeMutate_impl( node->type, *this );
    2341         } else {
    2342                 maybeMutate_impl( node->expr, *this );
    2343         }
    2344 
    2345         MUTATE_END( Expression, node );
    2346 }
    2347 
    2348 //--------------------------------------------------------------------------
    23491659// LogicalExpr
    23501660template< typename pass_type >
    23511661void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
    2352         VISIT_START( node );
    2353 
    2354         indexerScopedAccept( node->result, *this );
    2355         maybeAccept_impl   ( node->arg1  , *this );
    2356         maybeAccept_impl   ( node->arg2  , *this );
    2357 
    2358         VISIT_END( node );
    2359 }
    2360 
    2361 template< typename pass_type >
    2362 void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
    23631662        VISIT_START( node );
    23641663
     
    23971696
    23981697template< typename pass_type >
    2399 void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) {
     1698Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
     1699        MUTATE_START( node );
     1700
     1701        indexerScopedMutate( node->env   , *this );
     1702        indexerScopedMutate( node->result, *this );
     1703        maybeMutate_impl   ( node->arg1  , *this );
     1704        maybeMutate_impl   ( node->arg2  , *this );
     1705        maybeMutate_impl   ( node->arg3  , *this );
     1706
     1707        MUTATE_END( Expression, node );
     1708}
     1709
     1710//--------------------------------------------------------------------------
     1711// CommaExpr
     1712template< typename pass_type >
     1713void PassVisitor< pass_type >::visit( CommaExpr * node ) {
    24001714        VISIT_START( node );
    24011715
     
    24031717        maybeAccept_impl   ( node->arg1  , *this );
    24041718        maybeAccept_impl   ( node->arg2  , *this );
    2405         maybeAccept_impl   ( node->arg3  , *this );
    2406 
    2407         VISIT_END( node );
    2408 }
    2409 
    2410 template< typename pass_type >
    2411 Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
     1719
     1720        VISIT_END( node );
     1721}
     1722
     1723template< typename pass_type >
     1724Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
    24121725        MUTATE_START( node );
    24131726
     
    24161729        maybeMutate_impl   ( node->arg1  , *this );
    24171730        maybeMutate_impl   ( node->arg2  , *this );
    2418         maybeMutate_impl   ( node->arg3  , *this );
    2419 
    2420         MUTATE_END( Expression, node );
    2421 }
    2422 
    2423 //--------------------------------------------------------------------------
    2424 // CommaExpr
    2425 template< typename pass_type >
    2426 void PassVisitor< pass_type >::visit( CommaExpr * node ) {
    2427         VISIT_START( node );
    2428 
    2429         indexerScopedAccept( node->result, *this );
    2430         maybeAccept_impl   ( node->arg1  , *this );
    2431         maybeAccept_impl   ( node->arg2  , *this );
    2432 
    2433         VISIT_END( node );
    2434 }
    2435 
    2436 template< typename pass_type >
    2437 void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
    2438         VISIT_START( node );
    2439 
    2440         indexerScopedAccept( node->result, *this );
    2441         maybeAccept_impl   ( node->arg1  , *this );
    2442         maybeAccept_impl   ( node->arg2  , *this );
    2443 
    2444         VISIT_END( node );
    2445 }
    2446 
    2447 template< typename pass_type >
    2448 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
    2449         MUTATE_START( node );
    2450 
    2451         indexerScopedMutate( node->env   , *this );
    2452         indexerScopedMutate( node->result, *this );
    2453         maybeMutate_impl   ( node->arg1  , *this );
    2454         maybeMutate_impl   ( node->arg2  , *this );
    24551731
    24561732        MUTATE_END( Expression, node );
     
    24701746
    24711747template< typename pass_type >
    2472 void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
    2473         VISIT_START( node );
    2474 
    2475         indexerScopedAccept( node->result, *this );
    2476         maybeAccept_impl   ( node->type, *this );
    2477 
    2478         VISIT_END( node );
    2479 }
    2480 
    2481 template< typename pass_type >
    24821748Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
    24831749        MUTATE_START( node );
     
    24941760template< typename pass_type >
    24951761void PassVisitor< pass_type >::visit( AsmExpr * node ) {
    2496         VISIT_START( node );
    2497 
    2498         indexerScopedAccept( node->result    , *this );
    2499         maybeAccept_impl   ( node->inout     , *this );
    2500         maybeAccept_impl   ( node->constraint, *this );
    2501         maybeAccept_impl   ( node->operand   , *this );
    2502 
    2503         VISIT_END( node );
    2504 }
    2505 
    2506 template< typename pass_type >
    2507 void PassVisitor< pass_type >::visit( const AsmExpr * node ) {
    25081762        VISIT_START( node );
    25091763
     
    25421796
    25431797template< typename pass_type >
    2544 void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
    2545         VISIT_START( node );
    2546 
    2547         indexerScopedAccept( node->result    , *this );
    2548         maybeAccept_impl   ( node->callExpr  , *this );
    2549 
    2550         VISIT_END( node );
    2551 }
    2552 
    2553 template< typename pass_type >
    25541798Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
    25551799        MUTATE_START( node );
     
    25751819
    25761820template< typename pass_type >
    2577 void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
    2578         VISIT_START( node );
    2579 
    2580         indexerScopedAccept( node->result  , *this );
    2581         maybeAccept_impl   ( node->callExpr, *this );
    2582 
    2583         VISIT_END( node );
    2584 }
    2585 
    2586 template< typename pass_type >
    25871821Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
    25881822        MUTATE_START( node );
     
    26081842
    26091843template< typename pass_type >
    2610 void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
    2611         VISIT_START( node );
    2612 
    2613         indexerScopedAccept( node->result     , *this );
    2614         maybeAccept_impl   ( node->initializer, *this );
    2615 
    2616         VISIT_END( node );
    2617 }
    2618 
    2619 template< typename pass_type >
    26201844Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
    26211845        MUTATE_START( node );
     
    26421866
    26431867template< typename pass_type >
    2644 void PassVisitor< pass_type >::visit( const RangeExpr * node ) {
    2645         VISIT_START( node );
    2646 
    2647         indexerScopedAccept( node->result, *this );
    2648         maybeAccept_impl   ( node->low   , *this );
    2649         maybeAccept_impl   ( node->high  , *this );
    2650 
    2651         VISIT_END( node );
    2652 }
    2653 
    2654 template< typename pass_type >
    26551868Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
    26561869        MUTATE_START( node );
     
    26771890
    26781891template< typename pass_type >
    2679 void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
     1892Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
     1893        MUTATE_START( node );
     1894
     1895        indexerScopedMutate( node->env   , *this );
     1896        indexerScopedMutate( node->result, *this );
     1897        maybeMutate_impl   ( node->exprs , *this );
     1898
     1899        MUTATE_END( Expression, node );
     1900}
     1901
     1902//--------------------------------------------------------------------------
     1903// TupleExpr
     1904template< typename pass_type >
     1905void PassVisitor< pass_type >::visit( TupleExpr * node ) {
    26801906        VISIT_START( node );
    26811907
     
    26871913
    26881914template< typename pass_type >
    2689 Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
    2690         MUTATE_START( node );
    2691 
    2692         indexerScopedMutate( node->env   , *this );
    2693         indexerScopedMutate( node->result, *this );
    2694         maybeMutate_impl   ( node->exprs , *this );
    2695 
    2696         MUTATE_END( Expression, node );
    2697 }
    2698 
    2699 //--------------------------------------------------------------------------
    2700 // TupleExpr
    2701 template< typename pass_type >
    2702 void PassVisitor< pass_type >::visit( TupleExpr * node ) {
    2703         VISIT_START( node );
    2704 
    2705         indexerScopedAccept( node->result, *this );
    2706         maybeAccept_impl   ( node->exprs , *this );
    2707 
    2708         VISIT_END( node );
    2709 }
    2710 
    2711 template< typename pass_type >
    2712 void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
    2713         VISIT_START( node );
    2714 
    2715         indexerScopedAccept( node->result, *this );
    2716         maybeAccept_impl   ( node->exprs , *this );
    2717 
    2718         VISIT_END( node );
    2719 }
    2720 
    2721 template< typename pass_type >
    27221915Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
    27231916        MUTATE_START( node );
     
    27431936
    27441937template< typename pass_type >
    2745 void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
    2746         VISIT_START( node );
    2747 
    2748         indexerScopedAccept( node->result, *this );
    2749         maybeAccept_impl   ( node->tuple , *this );
    2750 
    2751         VISIT_END( node );
    2752 }
    2753 
    2754 template< typename pass_type >
    27551938Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
    27561939        MUTATE_START( node );
     
    27711954        indexerScopedAccept( node->result  , *this );
    27721955        maybeAccept_impl   ( node->stmtExpr, *this );
    2773 
    2774         VISIT_END( node );
    2775 }
    2776 
    2777 template< typename pass_type >
    2778 void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) {
    2779         VISIT_START( node );
    2780 
    2781         indexerScopedAccept( node->result  , *this );
    2782         maybeAccept_impl( node->stmtExpr, *this );
    27831956
    27841957        VISIT_END( node );
     
    28161989
    28171990template< typename pass_type >
    2818 void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
    2819         VISIT_START( node );
     1991Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
     1992        MUTATE_START( node );
    28201993
    28211994        // don't want statements from outer CompoundStmts to be added to this StmtExpr
     
    28241997        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    28251998
    2826         indexerScopedAccept( node->result     , *this );
    2827         maybeAccept_impl   ( node->statements , *this );
    2828         maybeAccept_impl   ( node->returnDecls, *this );
    2829         maybeAccept_impl   ( node->dtors      , *this );
    2830 
    2831         VISIT_END( node );
    2832 }
    2833 
    2834 template< typename pass_type >
    2835 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
    2836         MUTATE_START( node );
    2837 
    2838         // don't want statements from outer CompoundStmts to be added to this StmtExpr
    2839         ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    2840         ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    2841         ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    2842 
    28431999        indexerScopedMutate( node->result     , *this );
    28442000        maybeMutate_impl   ( node->statements , *this );
     
    28622018
    28632019template< typename pass_type >
    2864 void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
    2865         VISIT_START( node );
    2866 
    2867         indexerScopedAccept( node->result, *this );
    2868         maybeAccept_impl   ( node->expr  , *this );
    2869 
    2870         VISIT_END( node );
    2871 }
    2872 
    2873 template< typename pass_type >
    28742020Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
    28752021        MUTATE_START( node );
     
    28962042
    28972043template< typename pass_type >
    2898 void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) {
    2899         VISIT_START( node );
    2900 
    2901         indexerScopedAccept( node->result, *this );
    2902         maybeAccept_impl   ( node->expr  , *this );
    2903         // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
    2904 
    2905         VISIT_END( node );
    2906 }
    2907 
    2908 template< typename pass_type >
    29092044Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) {
    29102045        MUTATE_START( node );
     
    29322067
    29332068template< typename pass_type >
    2934 void PassVisitor< pass_type >::visit( const InitExpr * node ) {
    2935         VISIT_START( node );
    2936 
    2937         indexerScopedAccept( node->result, *this );
    2938         maybeAccept_impl   ( node->expr  , *this );
    2939         maybeAccept_impl   ( node->designation, *this );
    2940 
    2941         VISIT_END( node );
    2942 }
    2943 
    2944 template< typename pass_type >
    29452069Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
    29462070        MUTATE_START( node );
     
    29612085
    29622086        indexerScopedAccept( node->result, *this );
    2963         maybeAccept_impl   ( node->expr, *this );
     2087        maybeAccept_impl( node->expr, *this );
    29642088        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
    29652089
     
    29682092
    29692093template< typename pass_type >
    2970 void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
     2094Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) {
     2095        MUTATE_START( node );
     2096
     2097        indexerScopedMutate( node->env, *this );
     2098        indexerScopedMutate( node->result, *this );
     2099        maybeMutate_impl( node->expr, *this );
     2100
     2101        MUTATE_END( Expression, node );
     2102}
     2103
     2104//--------------------------------------------------------------------------
     2105// DefaultArgExpr
     2106template< typename pass_type >
     2107void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
    29712108        VISIT_START( node );
    29722109
    29732110        indexerScopedAccept( node->result, *this );
    2974         maybeAccept_impl   ( node->expr, *this );
    2975         // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
    2976 
    2977         VISIT_END( node );
    2978 }
    2979 
    2980 template< typename pass_type >
    2981 Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) {
    2982         MUTATE_START( node );
    2983 
    2984         indexerScopedMutate( node->env, *this );
    2985         indexerScopedMutate( node->result, *this );
    2986         maybeMutate_impl( node->expr, *this );
    2987 
    2988         MUTATE_END( Expression, node );
    2989 }
    2990 
    2991 //--------------------------------------------------------------------------
    2992 // DefaultArgExpr
    2993 template< typename pass_type >
    2994 void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
    2995         VISIT_START( node );
    2996 
    2997         indexerScopedAccept( node->result, *this );
    2998         maybeAccept_impl   ( node->expr, *this );
    2999 
    3000         VISIT_END( node );
    3001 }
    3002 
    3003 template< typename pass_type >
    3004 void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
    3005         VISIT_START( node );
    3006 
    3007         indexerScopedAccept( node->result, *this );
    3008         maybeAccept_impl   ( node->expr, *this );
     2111        maybeAccept_impl( node->expr, *this );
    30092112
    30102113        VISIT_END( node );
     
    30392142
    30402143template< typename pass_type >
    3041 void PassVisitor< pass_type >::visit( const GenericExpr * node ) {
    3042         VISIT_START( node );
    3043 
    3044         indexerScopedAccept( node->result, *this );
    3045         maybeAccept_impl( node->control, *this );
    3046         for ( const GenericExpr::Association & assoc : node->associations ) {
    3047                 indexerScopedAccept( assoc.type, *this );
    3048                 maybeAccept_impl( assoc.expr, *this );
    3049         }
    3050 
    3051         VISIT_END( node );
    3052 }
    3053 
    3054 template< typename pass_type >
    30552144Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
    30562145        MUTATE_START( node );
     
    30792168
    30802169template< typename pass_type >
    3081 void PassVisitor< pass_type >::visit( const VoidType * node ) {
    3082         VISIT_START( node );
    3083 
    3084         maybeAccept_impl( node->forall, *this );
    3085 
    3086         VISIT_END( node );
    3087 }
    3088 
    3089 template< typename pass_type >
    30902170Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
    30912171        MUTATE_START( node );
     
    31002180template< typename pass_type >
    31012181void PassVisitor< pass_type >::visit( BasicType * node ) {
    3102         VISIT_START( node );
    3103 
    3104         maybeAccept_impl( node->forall, *this );
    3105 
    3106         VISIT_END( node );
    3107 }
    3108 
    3109 template< typename pass_type >
    3110 void PassVisitor< pass_type >::visit( const BasicType * node ) {
    31112182        VISIT_START( node );
    31122183
     
    31392210
    31402211template< typename pass_type >
    3141 void PassVisitor< pass_type >::visit( const PointerType * node ) {
    3142         VISIT_START( node );
    3143 
    3144         maybeAccept_impl( node->forall, *this );
    3145         // xxx - should PointerType visit/mutate dimension?
    3146         maybeAccept_impl( node->base, *this );
    3147 
    3148         VISIT_END( node );
    3149 }
    3150 
    3151 template< typename pass_type >
    31522212Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
    31532213        MUTATE_START( node );
     
    31742234
    31752235template< typename pass_type >
    3176 void PassVisitor< pass_type >::visit( const ArrayType * node ) {
    3177         VISIT_START( node );
    3178 
    3179         maybeAccept_impl( node->forall, *this );
    3180         maybeAccept_impl( node->dimension, *this );
    3181         maybeAccept_impl( node->base, *this );
    3182 
    3183         VISIT_END( node );
    3184 }
    3185 
    3186 template< typename pass_type >
    31872236Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
    31882237        MUTATE_START( node );
     
    32082257
    32092258template< typename pass_type >
    3210 void PassVisitor< pass_type >::visit( const ReferenceType * node ) {
    3211         VISIT_START( node );
    3212 
    3213         maybeAccept_impl( node->forall, *this );
    3214         maybeAccept_impl( node->base, *this );
    3215 
    3216         VISIT_END( node );
    3217 }
    3218 
    3219 template< typename pass_type >
    32202259Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
    32212260        MUTATE_START( node );
     
    32412280
    32422281template< typename pass_type >
    3243 void PassVisitor< pass_type >::visit( const QualifiedType * node ) {
    3244         VISIT_START( node );
    3245 
    3246         maybeAccept_impl( node->forall, *this );
    3247         maybeAccept_impl( node->parent, *this );
    3248         maybeAccept_impl( node->child, *this );
    3249 
    3250         VISIT_END( node );
    3251 }
    3252 
    3253 template< typename pass_type >
    32542282Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
    32552283        MUTATE_START( node );
     
    32662294template< typename pass_type >
    32672295void PassVisitor< pass_type >::visit( FunctionType * node ) {
    3268         VISIT_START( node );
    3269 
    3270         maybeAccept_impl( node->forall, *this );
    3271         maybeAccept_impl( node->returnVals, *this );
    3272         maybeAccept_impl( node->parameters, *this );
    3273 
    3274         VISIT_END( node );
    3275 }
    3276 
    3277 template< typename pass_type >
    3278 void PassVisitor< pass_type >::visit( const FunctionType * node ) {
    32792296        VISIT_START( node );
    32802297
     
    33152332
    33162333template< typename pass_type >
    3317 void PassVisitor< pass_type >::visit( const StructInstType * node ) {
     2334Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
     2335        MUTATE_START( node );
     2336
     2337        indexerAddStruct( node->name );
     2338
     2339        {
     2340                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     2341                maybeMutate_impl( node->forall    , *this );
     2342                maybeMutate_impl( node->parameters, *this );
     2343        }
     2344
     2345        MUTATE_END( Type, node );
     2346}
     2347
     2348//--------------------------------------------------------------------------
     2349// UnionInstType
     2350template< typename pass_type >
     2351void PassVisitor< pass_type >::visit( UnionInstType * node ) {
    33182352        VISIT_START( node );
    33192353
     
    33302364
    33312365template< typename pass_type >
    3332 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
     2366Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
    33332367        MUTATE_START( node );
    33342368
     
    33452379
    33462380//--------------------------------------------------------------------------
    3347 // UnionInstType
    3348 template< typename pass_type >
    3349 void PassVisitor< pass_type >::visit( UnionInstType * node ) {
    3350         VISIT_START( node );
    3351 
    3352         indexerAddStruct( node->name );
    3353 
    3354         {
    3355                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    3356                 maybeAccept_impl( node->forall    , *this );
    3357                 maybeAccept_impl( node->parameters, *this );
    3358         }
    3359 
    3360         VISIT_END( node );
    3361 }
    3362 
    3363 template< typename pass_type >
    3364 void PassVisitor< pass_type >::visit( const UnionInstType * node ) {
    3365         VISIT_START( node );
    3366 
    3367         indexerAddStruct( node->name );
    3368 
    3369         {
    3370                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    3371                 maybeAccept_impl( node->forall    , *this );
    3372                 maybeAccept_impl( node->parameters, *this );
    3373         }
    3374 
    3375         VISIT_END( node );
    3376 }
    3377 
    3378 template< typename pass_type >
    3379 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
    3380         MUTATE_START( node );
    3381 
    3382         indexerAddStruct( node->name );
    3383 
    3384         {
    3385                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    3386                 maybeMutate_impl( node->forall    , *this );
    3387                 maybeMutate_impl( node->parameters, *this );
    3388         }
    3389 
    3390         MUTATE_END( Type, node );
    3391 }
    3392 
    3393 //--------------------------------------------------------------------------
    33942381// EnumInstType
    33952382template< typename pass_type >
     
    34042391
    34052392template< typename pass_type >
    3406 void PassVisitor< pass_type >::visit( const EnumInstType * node ) {
    3407         VISIT_START( node );
    3408 
    3409         maybeAccept_impl( node->forall, *this );
    3410         maybeAccept_impl( node->parameters, *this );
    3411 
    3412         VISIT_END( node );
    3413 }
    3414 
    3415 template< typename pass_type >
    34162393Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
    34172394        MUTATE_START( node );
     
    34362413
    34372414template< typename pass_type >
    3438 void PassVisitor< pass_type >::visit( const TraitInstType * node ) {
    3439         VISIT_START( node );
    3440 
    3441         maybeAccept_impl( node->forall    , *this );
    3442         maybeAccept_impl( node->parameters, *this );
    3443 
    3444         VISIT_END( node );
    3445 }
    3446 
    3447 template< typename pass_type >
    34482415Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
    34492416        MUTATE_START( node );
     
    34592426template< typename pass_type >
    34602427void PassVisitor< pass_type >::visit( TypeInstType * node ) {
    3461         VISIT_START( node );
    3462 
    3463         maybeAccept_impl( node->forall    , *this );
    3464         maybeAccept_impl( node->parameters, *this );
    3465 
    3466         VISIT_END( node );
    3467 }
    3468 
    3469 template< typename pass_type >
    3470 void PassVisitor< pass_type >::visit( const TypeInstType * node ) {
    34712428        VISIT_START( node );
    34722429
     
    35012458
    35022459template< typename pass_type >
    3503 void PassVisitor< pass_type >::visit( const TupleType * node ) {
    3504         VISIT_START( node );
    3505 
    3506         maybeAccept_impl( node->forall, *this );
    3507         maybeAccept_impl( node->types, *this );
    3508         maybeAccept_impl( node->members, *this );
    3509 
    3510         VISIT_END( node );
    3511 }
    3512 
    3513 template< typename pass_type >
    35142460Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
    35152461        MUTATE_START( node );
     
    35262472template< typename pass_type >
    35272473void PassVisitor< pass_type >::visit( TypeofType * node ) {
    3528         VISIT_START( node );
    3529 
    3530         assert( node->expr );
    3531         maybeAccept_impl( node->expr, *this );
    3532 
    3533         VISIT_END( node );
    3534 }
    3535 
    3536 template< typename pass_type >
    3537 void PassVisitor< pass_type >::visit( const TypeofType * node ) {
    35382474        VISIT_START( node );
    35392475
     
    35722508
    35732509template< typename pass_type >
    3574 void PassVisitor< pass_type >::visit( const AttrType * node ) {
    3575         VISIT_START( node );
    3576 
    3577         if ( node->isType ) {
    3578                 assert( node->type );
    3579                 maybeAccept_impl( node->type, *this );
    3580         } else {
    3581                 assert( node->expr );
    3582                 maybeAccept_impl( node->expr, *this );
    3583         } // if
    3584 
    3585         VISIT_END( node );
    3586 }
    3587 
    3588 template< typename pass_type >
    35892510Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
    35902511        MUTATE_START( node );
     
    36132534
    36142535template< typename pass_type >
    3615 void PassVisitor< pass_type >::visit( const VarArgsType * node ) {
     2536Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
     2537        MUTATE_START( node );
     2538
     2539        maybeMutate_impl( node->forall, *this );
     2540
     2541        MUTATE_END( Type, node );
     2542}
     2543
     2544//--------------------------------------------------------------------------
     2545// ZeroType
     2546template< typename pass_type >
     2547void PassVisitor< pass_type >::visit( ZeroType * node ) {
    36162548        VISIT_START( node );
    36172549
     
    36222554
    36232555template< typename pass_type >
    3624 Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
     2556Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
    36252557        MUTATE_START( node );
    36262558
     
    36312563
    36322564//--------------------------------------------------------------------------
    3633 // ZeroType
    3634 template< typename pass_type >
    3635 void PassVisitor< pass_type >::visit( ZeroType * node ) {
     2565// OneType
     2566template< typename pass_type >
     2567void PassVisitor< pass_type >::visit( OneType * node ) {
    36362568        VISIT_START( node );
    36372569
     
    36422574
    36432575template< typename pass_type >
    3644 void PassVisitor< pass_type >::visit( const ZeroType * node ) {
     2576Type * PassVisitor< pass_type >::mutate( OneType * node ) {
     2577        MUTATE_START( node );
     2578
     2579        maybeMutate_impl( node->forall, *this );
     2580
     2581        MUTATE_END( Type, node );
     2582}
     2583
     2584//--------------------------------------------------------------------------
     2585// GlobalScopeType
     2586template< typename pass_type >
     2587void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
    36452588        VISIT_START( node );
    36462589
     
    36512594
    36522595template< typename pass_type >
    3653 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
     2596Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
    36542597        MUTATE_START( node );
    36552598
     
    36602603
    36612604//--------------------------------------------------------------------------
    3662 // OneType
    3663 template< typename pass_type >
    3664 void PassVisitor< pass_type >::visit( OneType * node ) {
    3665         VISIT_START( node );
    3666 
    3667         maybeAccept_impl( node->forall, *this );
    3668 
    3669         VISIT_END( node );
    3670 }
    3671 
    3672 template< typename pass_type >
    3673 void PassVisitor< pass_type >::visit( const OneType * node ) {
    3674         VISIT_START( node );
    3675 
    3676         maybeAccept_impl( node->forall, *this );
    3677 
    3678         VISIT_END( node );
    3679 }
    3680 
    3681 template< typename pass_type >
    3682 Type * PassVisitor< pass_type >::mutate( OneType * node ) {
    3683         MUTATE_START( node );
    3684 
    3685         maybeMutate_impl( node->forall, *this );
    3686 
    3687         MUTATE_END( Type, node );
    3688 }
    3689 
    3690 //--------------------------------------------------------------------------
    3691 // GlobalScopeType
    3692 template< typename pass_type >
    3693 void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
    3694         VISIT_START( node );
    3695 
    3696         maybeAccept_impl( node->forall, *this );
    3697 
    3698         VISIT_END( node );
    3699 }
    3700 
    3701 template< typename pass_type >
    3702 void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) {
    3703         VISIT_START( node );
    3704 
    3705         maybeAccept_impl( node->forall, *this );
    3706 
    3707         VISIT_END( node );
    3708 }
    3709 
    3710 template< typename pass_type >
    3711 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
    3712         MUTATE_START( node );
    3713 
    3714         maybeMutate_impl( node->forall, *this );
    3715 
    3716         MUTATE_END( Type, node );
    3717 }
    3718 
    3719 //--------------------------------------------------------------------------
    37202605// Designation
    37212606template< typename pass_type >
     
    37292614
    37302615template< typename pass_type >
    3731 void PassVisitor< pass_type >::visit( const Designation * node ) {
    3732         VISIT_START( node );
    3733 
    3734         maybeAccept_impl( node->designators, *this );
    3735 
    3736         VISIT_END( node );
    3737 }
    3738 
    3739 template< typename pass_type >
    37402616Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
    37412617        MUTATE_START( node );
     
    37582634
    37592635template< typename pass_type >
    3760 void PassVisitor< pass_type >::visit( const SingleInit * node ) {
    3761         VISIT_START( node );
    3762 
    3763         visitExpression( node->value );
    3764 
    3765         VISIT_END( node );
    3766 }
    3767 
    3768 template< typename pass_type >
    37692636Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
    37702637        MUTATE_START( node );
     
    37792646template< typename pass_type >
    37802647void PassVisitor< pass_type >::visit( ListInit * node ) {
    3781         VISIT_START( node );
    3782 
    3783         maybeAccept_impl( node->designations, *this );
    3784         maybeAccept_impl( node->initializers, *this );
    3785 
    3786         VISIT_END( node );
    3787 }
    3788 
    3789 template< typename pass_type >
    3790 void PassVisitor< pass_type >::visit( const ListInit * node ) {
    37912648        VISIT_START( node );
    37922649
     
    38212678
    38222679template< typename pass_type >
    3823 void PassVisitor< pass_type >::visit( const ConstructorInit * node ) {
    3824         VISIT_START( node );
    3825 
    3826         maybeAccept_impl( node->ctor, *this );
    3827         maybeAccept_impl( node->dtor, *this );
    3828         maybeAccept_impl( node->init, *this );
    3829 
    3830         VISIT_END( node );
    3831 }
    3832 
    3833 template< typename pass_type >
    38342680Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
    38352681        MUTATE_START( node );
     
    38522698
    38532699template< typename pass_type >
    3854 void PassVisitor< pass_type >::visit( const Constant * node ) {
    3855         VISIT_START( node );
    3856 
    3857         VISIT_END( node );
    3858 }
    3859 
    3860 template< typename pass_type >
    38612700Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
    38622701        MUTATE_START( node );
     
    38692708template< typename pass_type >
    38702709void PassVisitor< pass_type >::visit( Attribute * node ) {
    3871         VISIT_START( node );
    3872 
    3873         maybeAccept_impl( node->parameters, *this );
    3874 
    3875         VISIT_END( node );
    3876 }
    3877 
    3878 template< typename pass_type >
    3879 void PassVisitor< pass_type >::visit( const Attribute * node ) {
    38802710        VISIT_START( node );
    38812711
  • src/Common/PassVisitor.proto.h

    r4eb43fa rf6cc734e  
    118118static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
    119119
    120 template<typename pass_type, typename node_type>
    121 static inline auto previsit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
    122         pass.previsit( node );
    123 }
    124 
    125 template<typename pass_type, typename node_type>
    126 static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
    127 
    128 
    129 template<typename pass_type, typename node_type>
    130 static inline auto postvisit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
    131         pass.postvisit( node );
    132 }
    133 
    134 template<typename pass_type, typename node_type>
    135 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
    136 
    137120//---------------------------------------------------------
    138121// Mutate
     
    217200        pass.indexer.func( arg );                                                                                                \
    218201}                                                                                                                              \
    219 template<typename pass_type>                                                                                                   \
    220 static inline void indexer_impl_##func ( pass_type &, long, type ) { }
     202                                                                                                                               \
     203template<typename pass_type>                                                                                                   \
     204static inline void indexer_impl_##func ( pass_type &, long, type ) { }                                                          \
    221205
    222206#define INDEXER_FUNC2( func, type1, type2 )                                                                                             \
     
    225209        pass.indexer.func( arg1, arg2 );                                                                                                \
    226210}                                                                                                                              \
     211                                                                                                                               \
    227212template<typename pass_type>                                                                                                   \
    228213static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { }
    229214
    230215
    231 INDEXER_FUNC1( addId     , const DeclarationWithType *       );
    232 INDEXER_FUNC1( addType   , const NamedTypeDecl *             );
    233 INDEXER_FUNC1( addStruct , const StructDecl *                );
    234 INDEXER_FUNC1( addEnum   , const EnumDecl *                  );
    235 INDEXER_FUNC1( addUnion  , const UnionDecl *                 );
    236 INDEXER_FUNC1( addTrait  , const TraitDecl *                 );
    237 INDEXER_FUNC2( addWith   , const std::list< Expression * > &, const Declaration * );
     216INDEXER_FUNC1( addId     , DeclarationWithType *       );
     217INDEXER_FUNC1( addType   , NamedTypeDecl *             );
     218INDEXER_FUNC1( addStruct , StructDecl *                );
     219INDEXER_FUNC1( addEnum   , EnumDecl *                  );
     220INDEXER_FUNC1( addUnion  , UnionDecl *                 );
     221INDEXER_FUNC1( addTrait  , TraitDecl *                 );
     222INDEXER_FUNC2( addWith   , std::list< Expression * > &, BaseSyntaxNode * );
    238223
    239224#undef INDEXER_FUNC1
     
    241226
    242227template<typename pass_type>
    243 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
     228static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
    244229        StructDecl * fwd = new StructDecl( decl->name );
    245230        cloneAll( decl->parameters, fwd->parameters );
     
    248233
    249234template<typename pass_type>
    250 static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {}
    251 
    252 template<typename pass_type>
    253 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
     235static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}
     236
     237template<typename pass_type>
     238static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
    254239        UnionDecl * fwd = new UnionDecl( decl->name );
    255240        cloneAll( decl->parameters, fwd->parameters );
     
    258243
    259244template<typename pass_type>
    260 static inline auto indexer_impl_addUnionFwd( pass_type &, long, const UnionDecl * ) {}
     245static inline auto indexer_impl_addUnionFwd( pass_type &, long, UnionDecl * ) {}
    261246
    262247template<typename pass_type>
  • src/InitTweak/InitTweak.cc

    r4eb43fa rf6cc734e  
    318318        virtual ~ExpanderImpl() = default;
    319319        virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0;
    320         virtual ast::ptr< ast::Stmt > buildListInit(
     320        virtual ast::ptr< ast::Stmt > buildListInit( 
    321321                ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
    322322};
     
    324324namespace {
    325325        template< typename Out >
    326         void buildCallExpr(
    327                 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension,
     326        void buildCallExpr( 
     327                ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 
    328328                const ast::Init * init, Out & out
    329329        ) {
    330330                const CodeLocation & loc = init->location;
    331331
    332                 auto cond = new ast::UntypedExpr{
     332                auto cond = new ast::UntypedExpr{ 
    333333                        loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } };
    334 
     334               
    335335                std::vector< ast::ptr< ast::Expr > > args = makeInitList( init );
    336336                splice( callExpr->args, args );
     
    338338                out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } );
    339339
    340                 out.emplace_back( new ast::ExprStmt{
     340                out.emplace_back( new ast::ExprStmt{ 
    341341                        loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } );
    342342        }
     
    344344        template< typename Out >
    345345        void build(
    346                 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices,
     346                ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 
    347347                const ast::Init * init, Out & out
    348348        ) {
     
    371371
    372372                        static UniqueName targetLabel( "L__autogen__" );
    373                         ast::Label switchLabel{
     373                        ast::Label switchLabel{ 
    374374                                loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } };
    375 
     375                       
    376376                        std::vector< ast::ptr< ast::Stmt > > branches;
    377377                        for ( const ast::Init * init : *listInit ) {
     
    381381                                std::vector< ast::ptr< ast::Stmt > > stmts;
    382382                                build( callExpr, indices, init, stmts );
    383                                 stmts.emplace_back(
     383                                stmts.emplace_back( 
    384384                                        new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } );
    385385                                branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } );
     
    398398                        return makeInitList( init );
    399399                }
    400 
    401                 ast::ptr< ast::Stmt > buildListInit(
    402                         ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices
     400               
     401                ast::ptr< ast::Stmt > buildListInit( 
     402                        ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 
    403403                ) override {
    404                         // If array came with an initializer list, initialize each element. We may have more
    405                         // initializers than elements of the array; need to check at each index that we have
    406                         // not exceeded size. We may have fewer initializers than elements in the array; need
    407                         // to default-construct remaining elements. To accomplish this, generate switch
     404                        // If array came with an initializer list, initialize each element. We may have more 
     405                        // initializers than elements of the array; need to check at each index that we have 
     406                        // not exceeded size. We may have fewer initializers than elements in the array; need 
     407                        // to default-construct remaining elements. To accomplish this, generate switch 
    408408                        // statement consuming all of expander's elements
    409409
     
    427427                ExprImpl_new( const ast::Expr * a ) : arg( a ) {}
    428428
    429                 std::vector< ast::ptr< ast::Expr > > next(
    430                         InitExpander_new::IndexList & indices
     429                std::vector< ast::ptr< ast::Expr > > next( 
     430                        InitExpander_new::IndexList & indices 
    431431                ) override {
    432432                        if ( ! arg ) return {};
     
    437437                                // go through indices and layer on subscript exprs ?[?]
    438438                                ++it;
    439                                 expr = new ast::UntypedExpr{
     439                                expr = new ast::UntypedExpr{ 
    440440                                        loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } };
    441441                        }
    442442                        return { expr };
    443443                }
    444 
    445                 ast::ptr< ast::Stmt > buildListInit(
    446                         ast::UntypedExpr *, InitExpander_new::IndexList &
    447                 ) override {
     444               
     445                ast::ptr< ast::Stmt > buildListInit( 
     446                        ast::UntypedExpr *, InitExpander_new::IndexList & 
     447                ) override { 
    448448                        return {};
    449449                }
     
    464464}
    465465
    466 /// builds statement which has the same semantics as a C-style list initializer (for array
     466/// builds statement which has the same semantics as a C-style list initializer (for array 
    467467/// initializers) using callExpr as the base expression to perform initialization
    468468ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) {
     
    668668
    669669                const ast::DeclWithType * func = getCalledFunction( appExpr->func );
    670                 assertf( func,
     670                assertf( func, 
    671671                        "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );
    672 
    673                 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because
    674                 // autogenerated ctor/dtor will call all member dtors, and some members may have a
     672               
     673                // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 
     674                // autogenerated ctor/dtor will call all member dtors, and some members may have a 
    675675                // user-defined dtor
    676676                return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;
     
    707707                return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){
    708708                        if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
    709                                 const ast::FunctionType * funcType =
     709                                const ast::FunctionType * funcType = 
    710710                                        GenPoly::getFunctionType( appExpr->func->result );
    711711                                assert( funcType );
     
    997997        bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); }
    998998
    999         const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) {
    1000                 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl );
     999        FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) {
     1000                FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl );
    10011001                if ( ! function ) return nullptr;
    10021002                if ( function->name != fname ) return nullptr;
     
    10221022                if ( ! t1 ) return false;
    10231023                const ast::Type * t2 = ftype->params.back()->get_type();
    1024 
     1024               
    10251025                return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
    10261026        }
    10271027
    1028         const FunctionDecl * isAssignment( const Declaration * decl ) {
     1028        FunctionDecl * isAssignment( Declaration * decl ) {
    10291029                return isCopyFunction( decl, "?=?" );
    10301030        }
    1031         const FunctionDecl * isDestructor( const Declaration * decl ) {
    1032                 if ( isDestructor( decl->name ) ) {
    1033                         return dynamic_cast< const FunctionDecl * >( decl );
     1031        FunctionDecl * isDestructor( Declaration * decl ) {
     1032                if ( isDestructor( decl->get_name() ) ) {
     1033                        return dynamic_cast< FunctionDecl * >( decl );
    10341034                }
    10351035                return nullptr;
    10361036        }
    1037         const FunctionDecl * isDefaultConstructor( const Declaration * decl ) {
     1037        FunctionDecl * isDefaultConstructor( Declaration * decl ) {
    10381038                if ( isConstructor( decl->name ) ) {
    1039                         if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
     1039                        if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
    10401040                                if ( func->type->parameters.size() == 1 ) {
    10411041                                        return func;
     
    10451045                return nullptr;
    10461046        }
    1047         const FunctionDecl * isCopyConstructor( const Declaration * decl ) {
     1047        FunctionDecl * isCopyConstructor( Declaration * decl ) {
    10481048                return isCopyFunction( decl, "?{}" );
    10491049        }
  • src/InitTweak/InitTweak.h

    r4eb43fa rf6cc734e  
    2626// helper functions for initialization
    2727namespace InitTweak {
    28         const FunctionDecl * isAssignment( const Declaration * decl );
    29         const FunctionDecl * isDestructor( const Declaration * decl );
    30         const FunctionDecl * isDefaultConstructor( const Declaration * decl );
    31         const FunctionDecl * isCopyConstructor( const Declaration * decl );
    32         const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname );
     28        FunctionDecl * isAssignment( Declaration * decl );
     29        FunctionDecl * isDestructor( Declaration * decl );
     30        FunctionDecl * isDefaultConstructor( Declaration * decl );
     31        FunctionDecl * isCopyConstructor( Declaration * decl );
     32        FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname );
    3333        bool isCopyFunction( const ast::FunctionDecl * decl );
    3434
     
    153153                InitExpander_new & operator++ ();
    154154
    155                 /// builds statement which has the same semantics as a C-style list initializer (for array
    156                 /// initializers) using callExpr as the base expression to perform initialization.
     155                /// builds statement which has the same semantics as a C-style list initializer (for array 
     156                /// initializers) using callExpr as the base expression to perform initialization. 
    157157                /// Mutates callExpr
    158158                ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr );
  • src/Parser/LinkageSpec.h

    r4eb43fa rf6cc734e  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:24:28 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 10 16:02:34 2019
    13 // Update Count     : 18
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Spt 13 15:59:00 2018
     13// Update Count     : 17
    1414//
    1515
     
    3535                constexpr Spec( unsigned int val ) : val( val ) {}
    3636                constexpr Spec( Spec const & other ) : val( other.val ) {}
    37                 constexpr Spec & operator=( const Spec & ) = default;
    3837                // Operators may go here.
    3938                // Supports == and !=
  • src/Parser/ParseNode.h

    r4eb43fa rf6cc734e  
    437437WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
    438438WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
    439 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
     439WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
    440440
    441441//##############################################################################
  • src/Parser/StatementNode.cc

    r4eb43fa rf6cc734e  
    317317} // build_waitfor_timeout
    318318
    319 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
     319WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    320320        std::list< Expression * > e;
    321321        buildMoveList( exprs, e );
    322322        Statement * s = maybeMoveBuild<Statement>( stmt );
    323         return new DeclStmt( new WithStmt( e, s ) );
     323        return new WithStmt( e, s );
    324324} // build_with
    325325
  • src/Parser/parser.yy

    r4eb43fa rf6cc734e  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 07:54:30 2019
    13 // Update Count     : 4355
     12// Last Modified On : Tue May 28 17:06:37 2019
     13// Update Count     : 4354
    1414//
    1515
     
    678678
    679679argument_expression_list:
     680        argument_expression
     681        | argument_expression_list ',' argument_expression
     682                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     683        ;
     684
     685argument_expression:
    680686        // empty
    681687                { $$ = nullptr; }
    682         | argument_expression
    683         | argument_expression_list ',' argument_expression
    684                 { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
    685         ;
    686 
    687 argument_expression:
    688         '@'                                                                                                     // CFA, default parameter
     688        | '@'                                                                                           // CFA, default parameter
    689689                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    690690                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
  • src/ResolvExpr/AdjustExprType.cc

    r4eb43fa rf6cc734e  
    4747                void premutate( OneType * ) { visit_children = false; }
    4848
    49                 Type * postmutate( ArrayType * arrayType );
    50                 Type * postmutate( FunctionType * functionType );
    51                 Type * postmutate( TypeInstType * aggregateUseType );
     49                Type * postmutate( ArrayType *arrayType );
     50                Type * postmutate( FunctionType *functionType );
     51                Type * postmutate( TypeInstType *aggregateUseType );
    5252
    5353                private:
     
    6161
    6262        Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) {
    63                 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
     63                PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
    6464                arrayType->base = nullptr;
    6565                delete arrayType;
     
    7272
    7373        Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) {
    74                 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
     74                if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
    7575                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    7676                                return new PointerType{ Type::Qualifiers(), typeInst };
    7777                        }
    78                 } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    79                         if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) {
     78                } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     79                        if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    8080                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
    8181                                        return new PointerType{ Type::Qualifiers(), typeInst };
     
    8989void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    9090        PassVisitor<AdjustExprType_old> adjuster( env, indexer );
    91         Type * newType = type->acceptMutator( adjuster );
     91        Type *newType = type->acceptMutator( adjuster );
    9292        type = newType;
    9393}
     
    149149} // anonymous namespace
    150150
    151 const ast::Type * adjustExprType(
    152         const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     151const ast::Type * adjustExprType( 
     152        const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
    153153) {
    154154        ast::Pass<AdjustExprType_new> adjuster{ env, symtab };
  • src/ResolvExpr/AlternativeFinder.cc

    r4eb43fa rf6cc734e  
    336336                }
    337337
    338                 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
     338                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    339339                        addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    340                 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
     340                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    341341                        addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    342342                } // if
     
    344344
    345345        template< typename StructOrUnionType >
    346         void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
     346        void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
    347347                std::list< Declaration* > members;
    348348                aggInst->lookup( name, members );
    349349
    350350                for ( Declaration * decl : members ) {
    351                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     351                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
    352352                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    353353                                // can't construct in place and use vector::back
     
    362362        }
    363363
    364         void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) {
     364        void AlternativeFinder::Finder::addTupleMembers( TupleType *tupleType, Expression *expr,                        const Alternative &alt, const Cost &newCost, Expression *member ) {
    365365                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    366366                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
     
    368368                        std::string tmp;
    369369                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    370                                 alternatives.push_back( Alternative{
     370                                alternatives.push_back( Alternative{ 
    371371                                        alt, new TupleIndexExpr( expr->clone(), val ), newCost } );
    372372                        } // if
     
    374374        }
    375375
    376         void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {
     376        void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
    377377                alternatives.push_back( Alternative{ applicationExpr->clone(), env } );
    378378        }
     
    475475                }
    476476
    477                 // specialization cost of return types can't be accounted for directly, it disables
     477                // specialization cost of return types can't be accounted for directly, it disables 
    478478                // otherwise-identical calls, like this example based on auto-newline in the I/O lib:
    479479                //
     
    12261226                                // count one safe conversion for each value that is thrown away
    12271227                                thisCost.incSafe( discardedValues );
    1228                                 Alternative newAlt{
    1229                                         restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
     1228                                Alternative newAlt{ 
     1229                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 
    12301230                                        alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost };
    12311231                                inferParameters( newAlt, back_inserter( candidates ) );
     
    13281328                if ( sizeofExpr->get_isType() ) {
    13291329                        Type * newType = sizeofExpr->get_type()->clone();
    1330                         alternatives.push_back( Alternative{
     1330                        alternatives.push_back( Alternative{ 
    13311331                                new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } );
    13321332                } else {
     
    13431343                        Alternative &choice = winners.front();
    13441344                        referenceToRvalueConversion( choice.expr, choice.cost );
    1345                         alternatives.push_back( Alternative{
     1345                        alternatives.push_back( Alternative{ 
    13461346                                choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } );
    13471347                } // if
     
    13511351                if ( alignofExpr->get_isType() ) {
    13521352                        Type * newType = alignofExpr->get_type()->clone();
    1353                         alternatives.push_back( Alternative{
     1353                        alternatives.push_back( Alternative{ 
    13541354                                new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } );
    13551355                } else {
     
    13661366                        Alternative &choice = winners.front();
    13671367                        referenceToRvalueConversion( choice.expr, choice.cost );
    1368                         alternatives.push_back( Alternative{
     1368                        alternatives.push_back( Alternative{ 
    13691369                                choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } );
    13701370                } // if
     
    13771377                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    13781378                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    1379                                 alternatives.push_back( Alternative{
     1379                                alternatives.push_back( Alternative{ 
    13801380                                        new OffsetofExpr{ aggInst->clone(), dwt }, env } );
    13811381                                renameTypes( alternatives.back().expr );
     
    14051405
    14061406        namespace {
    1407                 void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
     1407                void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
    14081408                        // assume no polymorphism
    14091409                        // assume no implicit conversions
    1410                         assert( function->parameters.size() == 1 );
     1410                        assert( function->get_parameters().size() == 1 );
    14111411                        PRINT(
    14121412                                std::cerr << "resolvAttr: funcDecl is ";
     
    14181418                        const SymTab::Indexer & indexer = finder.get_indexer();
    14191419                        AltList & alternatives = finder.get_alternatives();
    1420                         if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) {
     1420                        if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
    14211421                                Cost cost = Cost::zero;
    14221422                                Expression * newExpr = data.combine( cost );
    1423                                 alternatives.push_back( Alternative{
    1424                                         new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{},
     1423                                alternatives.push_back( Alternative{ 
     1424                                        new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 
    14251425                                        AssertionList{}, Cost::zero, cost } );
    14261426                                for ( DeclarationWithType * retVal : function->returnVals ) {
     
    14311431        }
    14321432
    1433         void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {
     1433        void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) {
    14341434                // assume no 'pointer-to-attribute'
    1435                 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
     1435                NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    14361436                assert( nameExpr );
    14371437                std::list< SymTab::Indexer::IdData > attrList;
     
    14391439                if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    14401440                        for ( auto & data : attrList ) {
    1441                                 const DeclarationWithType * id = data.id;
     1441                                DeclarationWithType * id = data.id;
    14421442                                // check if the type is function
    1443                                 if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) {
     1443                                if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
    14441444                                        // assume exactly one parameter
    1445                                         if ( function->parameters.size() == 1 ) {
     1445                                        if ( function->get_parameters().size() == 1 ) {
    14461446                                                if ( attrExpr->get_isType() ) {
    14471447                                                        resolveAttr( data, function, attrExpr->get_type(), env, altFinder);
     
    14621462                                Cost cost = Cost::zero;
    14631463                                Expression * newExpr = data.combine( cost );
    1464                                 alternatives.push_back( Alternative{
     1464                                alternatives.push_back( Alternative{ 
    14651465                                        newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } );
    14661466                                renameTypes( alternatives.back().expr );
     
    14691469        }
    14701470
    1471         void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {
     1471        void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) {
    14721472                AlternativeFinder firstFinder( indexer, env );
    14731473                firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
     
    14861486                                cloneAll( second.need, need );
    14871487
    1488                                 LogicalExpr *newExpr = new LogicalExpr{
     1488                                LogicalExpr *newExpr = new LogicalExpr{ 
    14891489                                        first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() };
    1490                                 alternatives.push_back( Alternative{
    1491                                         newExpr, std::move(compositeEnv), std::move(openVars),
     1490                                alternatives.push_back( Alternative{ 
     1491                                        newExpr, std::move(compositeEnv), std::move(openVars), 
    14921492                                        AssertionList( need.begin(), need.end() ), first.cost + second.cost } );
    14931493                        }
     
    15221522                                        cloneAll( third.need, need );
    15231523                                        AssertionSet have;
    1524 
     1524                                       
    15251525                                        // unify true and false types, then infer parameters to produce new alternatives
    15261526                                        Type* commonType = nullptr;
    1527                                         if ( unify( second.expr->result, third.expr->result, compositeEnv,
     1527                                        if ( unify( second.expr->result, third.expr->result, compositeEnv, 
    15281528                                                        need, have, openVars, indexer, commonType ) ) {
    1529                                                 ConditionalExpr *newExpr = new ConditionalExpr{
     1529                                                ConditionalExpr *newExpr = new ConditionalExpr{ 
    15301530                                                        first.expr->clone(), second.expr->clone(), third.expr->clone() };
    15311531                                                newExpr->result = commonType ? commonType : second.expr->result->clone();
    15321532                                                // convert both options to the conditional result type
    15331533                                                Cost cost = first.cost + second.cost + third.cost;
    1534                                                 cost += computeExpressionConversionCost(
     1534                                                cost += computeExpressionConversionCost( 
    15351535                                                        newExpr->arg2, newExpr->result, indexer, compositeEnv );
    1536                                                 cost += computeExpressionConversionCost(
     1536                                                cost += computeExpressionConversionCost( 
    15371537                                                        newExpr->arg3, newExpr->result, indexer, compositeEnv );
    15381538                                                // output alternative
    1539                                                 Alternative newAlt{
    1540                                                         newExpr, std::move(compositeEnv), std::move(openVars),
     1539                                                Alternative newAlt{ 
     1540                                                        newExpr, std::move(compositeEnv), std::move(openVars), 
    15411541                                                        AssertionList( need.begin(), need.end() ), cost };
    15421542                                                inferParameters( newAlt, back_inserter( alternatives ) );
     
    15531553                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    15541554                for ( const Alternative & alt : secondFinder.alternatives ) {
    1555                         alternatives.push_back( Alternative{
     1555                        alternatives.push_back( Alternative{ 
    15561556                                alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } );
    15571557                } // for
     
    15791579
    15801580                                Type* commonType = nullptr;
    1581                                 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have,
     1581                                if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 
    15821582                                                openVars, indexer, commonType ) ) {
    1583                                         RangeExpr * newExpr =
     1583                                        RangeExpr * newExpr = 
    15841584                                                new RangeExpr{ first.expr->clone(), second.expr->clone() };
    15851585                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    1586                                         Alternative newAlt{
    1587                                                 newExpr, std::move(compositeEnv), std::move(openVars),
     1586                                        Alternative newAlt{ 
     1587                                                newExpr, std::move(compositeEnv), std::move(openVars), 
    15881588                                                AssertionList( need.begin(), need.end() ), first.cost + second.cost };
    15891589                                        inferParameters( newAlt, back_inserter( alternatives ) );
     
    16121612                                cloneAll( alt.need, need );
    16131613                        }
    1614 
    1615                         alternatives.push_back( Alternative{
    1616                                 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars),
     1614                       
     1615                        alternatives.push_back( Alternative{ 
     1616                                new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 
    16171617                                AssertionList( need.begin(), need.end() ), sumCost( alts ) } );
    16181618                } // for
     
    16331633                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    16341634                for ( Alternative & alt : finder.alternatives ) {
    1635                         alternatives.push_back( Alternative{
     1635                        alternatives.push_back( Alternative{ 
    16361636                                alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } );
    16371637                }
     
    16851685                                cloneAll( alt.need, need );
    16861686                                AssertionSet have;
    1687                                 OpenVarSet openVars( alt.openVars );
    1688                                 // xxx - find things in env that don't have a "representative type" and claim
     1687                                OpenVarSet openVars( alt.openVars ); 
     1688                                // xxx - find things in env that don't have a "representative type" and claim 
    16891689                                // those are open vars?
    16901690                                PRINT(
    16911691                                        std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
    16921692                                )
    1693                                 // It's possible that a cast can throw away some values in a multiply-valued
    1694                                 // expression. (An example is a cast-to-void, which casts from one value to
    1695                                 // zero.)  Figure out the prefix of the subexpression results that are cast
    1696                                 // directly.  The candidate is invalid if it has fewer results than there are
     1693                                // It's possible that a cast can throw away some values in a multiply-valued 
     1694                                // expression. (An example is a cast-to-void, which casts from one value to 
     1695                                // zero.)  Figure out the prefix of the subexpression results that are cast 
     1696                                // directly.  The candidate is invalid if it has fewer results than there are 
    16971697                                // types to cast to.
    16981698                                int discardedValues = alt.expr->result->size() - toType->size();
    16991699                                if ( discardedValues < 0 ) continue;
    1700                                 // xxx - may need to go into tuple types and extract relevant types and use
    1701                                 // unifyList. Note that currently, this does not allow casting a tuple to an
     1700                                // xxx - may need to go into tuple types and extract relevant types and use 
     1701                                // unifyList. Note that currently, this does not allow casting a tuple to an 
    17021702                                // atomic type (e.g. (int)([1, 2, 3]))
    1703 
     1703                               
    17041704                                // unification run for side-effects
    17051705                                unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer );
     
    17101710                                        // count one safe conversion for each value that is thrown away
    17111711                                        thisCost.incSafe( discardedValues );
    1712                                         Alternative newAlt{
    1713                                                 new InitExpr{
    1714                                                         restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() },
    1715                                                 std::move(newEnv), std::move(openVars),
     1712                                        Alternative newAlt{ 
     1713                                                new InitExpr{ 
     1714                                                        restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 
     1715                                                std::move(newEnv), std::move(openVars), 
    17161716                                                AssertionList( need.begin(), need.end() ), alt.cost, thisCost };
    17171717                                        inferParameters( newAlt, back_inserter( candidates ) );
  • src/ResolvExpr/CastCost.cc

    r4eb43fa rf6cc734e  
    3737        struct CastCost_old : public ConversionCost {
    3838          public:
    39                 CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     39                CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    4040
    4141                using ConversionCost::previsit;
    4242                using ConversionCost::postvisit;
    43                 void postvisit( const BasicType * basicType );
    44                 void postvisit( const PointerType * pointerType );
     43                void postvisit( BasicType * basicType );
     44                void postvisit( PointerType * pointerType );
    4545        };
    4646
    47         Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    48                 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    49                         if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
     47        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     48                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     49                        if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    5050                                if ( eqvClass->type ) {
    5151                                        return castCost( src, eqvClass->type, indexer, env );
     
    5353                                        return Cost::infinity;
    5454                                }
    55                         } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     55                        } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
    5656                                // all typedefs should be gone by this point
    57                                 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
     57                                TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
    5858                                if ( type->base ) {
    5959                                        return castCost( src, type->base, indexer, env ) + Cost::safe;
     
    7474                        PRINT( std::cerr << "compatible!" << std::endl; )
    7575                        return Cost::zero;
    76                 } else if ( dynamic_cast< const VoidType * >( dest ) ) {
     76                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    7777                        return Cost::safe;
    78                 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
     78                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    7979                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    80                         return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     80                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    8181                                return ptrsCastable( t1, t2, env, indexer );
    8282                        });
    8383                } else {
    84                         PassVisitor<CastCost_old> converter(
    85                                 dest, indexer, env,
    86                                 (Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
     84                        PassVisitor<CastCost_old> converter( 
     85                                dest, indexer, env, 
     86                                (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
    8787                                        castCost );
    8888                        src->accept( converter );
     
    9696        }
    9797
    98         CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     98        CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    9999                : ConversionCost( dest, indexer, env, costFunc ) {
    100100        }
    101101
    102         void CastCost_old::postvisit( const BasicType * basicType ) {
    103                 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest );
     102        void CastCost_old::postvisit( BasicType *basicType ) {
     103                PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
    104104                if ( destAsPointer && basicType->isInteger() ) {
    105                         // necessary for, e.g. unsigned long => void *
     105                        // necessary for, e.g. unsigned long => void*
    106106                        cost = Cost::unsafe;
    107107                } else {
     
    110110        }
    111111
    112         void CastCost_old::postvisit( const PointerType * pointerType ) {
    113                 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
    114                         if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     112        void CastCost_old::postvisit( PointerType *pointerType ) {
     113                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     114                        if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    115115                                cost = Cost::safe;
    116116                        } else {
     
    125125                                } // if
    126126                        } // if
    127                 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     127                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    128128                        if ( destAsBasic->isInteger() ) {
    129                                 // necessary for, e.g. void * => unsigned long
     129                                // necessary for, e.g. void* => unsigned long
    130130                                cost = Cost::unsafe;
    131131                        } // if
     
    138138                using ConversionCost_new::postvisit;
    139139
    140                 CastCost_new(
    141                         const ast::Type * dst, const ast::SymbolTable & symtab,
     140                CastCost_new( 
     141                        const ast::Type * dst, const ast::SymbolTable & symtab, 
    142142                        const ast::TypeEnvironment & env, CostCalculation costFunc )
    143143                : ConversionCost_new( dst, symtab, env, costFunc ) {}
     
    182182} // anonymous namespace
    183183
    184 Cost castCost(
    185         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    186         const ast::TypeEnvironment & env
     184Cost castCost( 
     185        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
     186        const ast::TypeEnvironment & env 
    187187) {
    188188        if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     
    220220                PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    221221                #warning cast on ptrsCastable artifact of having two functions, remove when port done
    222                 return convertToReferenceCost(
    223                         src, refType, symtab, env,
    224                         ( int (*)(
    225                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     222                return convertToReferenceCost( 
     223                        src, refType, symtab, env, 
     224                        ( int (*)( 
     225                                const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
    226226                                const ast::TypeEnvironment & )
    227227                        ) ptrsCastable );
     
    229229                #warning cast on castCost artifact of having two functions, remove when port done
    230230                ast::Pass< CastCost_new > converter{
    231                         dst, symtab, env,
    232                         ( Cost (*)(
    233                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     231                        dst, symtab, env, 
     232                        ( Cost (*)( 
     233                                const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
    234234                                const ast::TypeEnvironment & )
    235235                        ) castCost };
  • src/ResolvExpr/CommonType.cc

    r4eb43fa rf6cc734e  
    3838namespace ResolvExpr {
    3939        struct CommonType_old : public WithShortCircuiting {
    40                 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    41                 Type * get_result() const { return result; }
     40                CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     41                Type *get_result() const { return result; }
    4242
    4343                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     
    6060
    6161          private:
    62                 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer );
    63                 template< typename RefType > void handleRefType( RefType * inst, Type * other );
    64 
    65                 Type * result;
    66                 Type * type2;                           // inherited
     62                template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
     63                template< typename RefType > void handleRefType( RefType *inst, Type *other );
     64
     65                Type *result;
     66                Type *type2;                            // inherited
    6767                bool widenFirst, widenSecond;
    6868                const SymTab::Indexer &indexer;
     
    8080                                std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
    8181                        )
    82                         if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) {
     82                        if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
    8383                                PRINT(
    8484                                        std::cerr << "widen okay" << std::endl;
    8585                                )
    86                                 common->tq |= t1->tq;
    87                                 common->tq |= t2->tq;
     86                                common->get_qualifiers() |= t1->get_qualifiers();
     87                                common->get_qualifiers() |= t2->get_qualifiers();
    8888                                return common;
    8989                        }
     
    9595        }
    9696
    97         Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
     97        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
    9898                PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    9999
     
    127127                                                std::cerr << "formal is reference; result should be reference" << std::endl;
    128128                                        )
    129                                         result = new ReferenceType( ref1->tq, result );
     129                                        result = new ReferenceType( ref1->get_qualifiers(), result );
    130130                                }
    131131                                PRINT(
     
    138138
    139139                type1->accept( visitor );
    140                 Type * result = visitor.pass.get_result();
     140                Type *result = visitor.pass.get_result();
    141141                if ( ! result ) {
    142142                        // this appears to be handling for opaque type declarations
    143143                        if ( widenSecond ) {
    144                                 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) {
    145                                         if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) {
    146                                                 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
     144                                if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {
     145                                        if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {
     146                                                TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
    147147                                                if ( type->get_base() ) {
    148                                                         Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq;
     148                                                        Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
    149149                                                        AssertionSet have, need;
    150150                                                        OpenVarSet newOpen( openVars );
    151                                                         type1->tq = Type::Qualifiers();
    152                                                         type->get_base()->tq = tq1;
     151                                                        type1->get_qualifiers() = Type::Qualifiers();
     152                                                        type->get_base()->get_qualifiers() = tq1;
    153153                                                        if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
    154154                                                                result = type1->clone();
    155                                                                 result->tq = tq1 | tq2;
     155                                                                result->get_qualifiers() = tq1 | tq2;
    156156                                                        } // if
    157                                                         type1->tq = tq1;
    158                                                         type->get_base()->tq = Type::Qualifiers();
     157                                                        type1->get_qualifiers() = tq1;
     158                                                        type->get_base()->get_qualifiers() = Type::Qualifiers();
    159159                                                } // if
    160160                                        } // if
     
    190190                                 */
    191191                                  {
    192                 /*     B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     192                /*     B*/                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    193193                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    194194                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    198198                                  },
    199199                                  {
    200                 /*     C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     200                /*     C*/                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    201201                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    202202                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    206206                                  },
    207207                                  {
    208                 /*    SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     208                /*    SC*/          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    209209                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    210210                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    214214                                  },
    215215                                  {
    216                 /*    UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     216                /*    UC*/        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    217217                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    218218                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    222222                                  },
    223223                                  {
    224                 /*    SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
     224                /*    SI*/      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
    225225                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    226226                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    230230                                  },
    231231                                  {
    232                 /*   SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
     232                /*   SUI*/    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
    233233                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    234234                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    238238                                  },
    239239                                  {
    240                 /*     I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
     240                /*     I*/           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
    241241                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    242242                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    246246                                  },
    247247                                  {
    248                 /*    UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
     248                /*    UI*/         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
    249249                                           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    250250                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    254254                                  },
    255255                                  {
    256                 /*    LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
     256                /*    LI*/       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
    257257                                         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    258258                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    262262                                  },
    263263                                  {
    264                 /*   LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
     264                /*   LUI*/     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
    265265                                       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    266266                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    270270                                  },
    271271                                  {
    272                 /*   LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
     272                /*   LLI*/   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
    273273                                     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    274274                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    278278                                  },
    279279                                  {
    280                 /*  LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     280                /*  LLUI*/ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
    281281                                   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
    282282                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    286286                                  },
    287287                                  {
    288                 /*    IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     288                /*    IB*/        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
    289289                                          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
    290290                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    294294                                  },
    295295                                  {
    296                 /*   UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     296                /*   UIB*/      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
    297297                                        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
    298298                                        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    302302                                  },
    303303                                  {
    304                 /*   _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     304                /*   _FH*/            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
    305305                                              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
    306306                                              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    310310                                  },
    311311                                  {
    312                 /*   _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     312                /*   _FH*/     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
    313313                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
    314314                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     
    318318                                  },
    319319                                  {
    320                 /*    _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     320                /*    _F*/            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
    321321                                              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
    322322                                              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
     
    326326                                  },
    327327                                  {
    328                 /*   _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     328                /*   _FC*/     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
    329329                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
    330330                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     
    334334                                  },
    335335                                  {
    336                 /*     F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     336                /*     F*/               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
    337337                                                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
    338338                                                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
     
    342342                                  },
    343343                                  {
    344                 /*    FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     344                /*    FC*/        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
    345345                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
    346346                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     
    350350                                  },
    351351                                  {
    352                 /*   _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     352                /*   _FX*/           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
    353353                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
    354354                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
     
    358358                                  },
    359359                                  {
    360                 /*  _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     360                /*  _FXC*/    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
    361361                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
    362362                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     
    366366                                  },
    367367                                  {
    368                 /*    FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     368                /*    FD*/            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
    369369                                              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
    370370                                              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     
    374374                                  },
    375375                                  {
    376                 /*  _FDC */     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     376                /*  _FDC*/     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
    377377                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
    378378                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     
    382382                                  },
    383383                                  {
    384                 /*     D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     384                /*     D*/              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
    385385                                                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
    386386                                                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     
    390390                                  },
    391391                                  {
    392                 /*    DC */       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     392                /*    DC*/       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
    393393                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
    394394                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     
    398398                                  },
    399399                                  {
    400                 /*  F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     400                /*  F80X*/           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
    401401                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
    402402                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     
    406406                                  },
    407407                                  {
    408                 /* _FDXC */    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     408                /* _FDXC*/    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
    409409                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
    410410                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     
    422422                                  },
    423423                                  {
    424                 /*   _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     424                /*   _FB*/           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
    425425                                             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
    426426                                             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     
    430430                                  },
    431431                                  {
    432                 /* _FLDC */    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     432                /* _FLDC*/    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
    433433                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
    434434                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     
    438438                                  },
    439439                                  {
    440                 /*    FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     440                /*    FB*/          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
    441441                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
    442442                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     
    446446                                  },
    447447                                  {
    448                 /*    LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     448                /*    LD*/          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
    449449                                            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
    450450                                            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     
    454454                                  },
    455455                                  {
    456                 /*   LDC */   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     456                /*   LDC*/   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
    457457                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
    458458                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     
    462462                                  },
    463463                                  {
    464                 /*  _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     464                /*  _FBX*/          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
    465465                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
    466466                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     
    470470                                  },
    471471                                  {
    472                 /* _FLDXC */   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     472                /*_FLDXC*/   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
    473473                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
    474474                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     
    481481        // GENERATED END
    482482        static_assert(
    483                 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
     483                sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
    484484                "Each basic type kind should have a corresponding row in the combined type matrix"
    485485        );
    486486
    487         CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
     487        CommonType_old::CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
    488488                : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
    489489        }
     
    491491        void CommonType_old::postvisit( VoidType * ) {}
    492492
    493         void CommonType_old::postvisit( BasicType * basicType ) {
    494                 if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) {
     493        void CommonType_old::postvisit( BasicType *basicType ) {
     494                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    495495                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
    496                         if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) {
    497                                 result = new BasicType( basicType->tq | otherBasic->tq, newType );
     496                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
     497                                result = new BasicType( basicType->get_qualifiers() | otherBasic->get_qualifiers(), newType );
    498498                        } // if
    499                 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
     499                } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
    500500                        // use signed int in lieu of the enum/zero/one type
    501501                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
    502                         if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
    503                                 result = new BasicType( basicType->tq | type2->tq, newType );
     502                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
     503                                result = new BasicType( basicType->get_qualifiers() | type2->get_qualifiers(), newType );
    504504                        } // if
    505505                } // if
     
    507507
    508508        template< typename Pointer >
    509         void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) {
    510                 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) {
     509        void CommonType_old::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
     510                if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
    511511                        OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
    512512                        if ( entry != openVars.end() ) {
     
    517517                }
    518518                result = voidPointer->clone();
    519                 result->tq |= otherPointer->tq;
    520         }
    521 
    522         void CommonType_old::postvisit( PointerType * pointerType ) {
    523                 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) {
     519                result->get_qualifiers() |= otherPointer->get_qualifiers();
     520        }
     521
     522        void CommonType_old::postvisit( PointerType *pointerType ) {
     523                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    524524                        // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
    525                         if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
     525                        if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
    526526                                getCommonWithVoidPointer( otherPointer, pointerType );
    527                         } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
     527                        } else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
    528528                                getCommonWithVoidPointer( pointerType, otherPointer );
    529                         } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst )
    530                                            && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) {
     529                        } else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
     530                                           && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
    531531                                // std::cerr << "middle case" << std::endl;
    532                                 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq;
    533                                 pointerType->get_base()->tq = Type::Qualifiers();
    534                                 otherPointer->get_base()->tq = Type::Qualifiers();
     532                                Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
     533                                pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
     534                                otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
    535535                                AssertionSet have, need;
    536536                                OpenVarSet newOpen( openVars );
     
    542542                                                result = otherPointer->clone();
    543543                                        } // if
    544                                         strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2;
     544                                        strict_dynamic_cast<PointerType*>(result)->base->get_qualifiers() = tq1 | tq2;
    545545                                } else {
    546546                                        /// std::cerr << "place for ptr-to-type" << std::endl;
    547547                                } // if
    548                                 pointerType->get_base()->tq = tq1;
    549                                 otherPointer->get_base()->tq = tq2;
     548                                pointerType->get_base()->get_qualifiers() = tq1;
     549                                otherPointer->get_base()->get_qualifiers() = tq2;
    550550                        } // if
    551                 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
     551                } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
    552552                        result = pointerType->clone();
    553                         result->tq |= type2->tq;
     553                        result->get_qualifiers() |= type2->get_qualifiers();
    554554                } // if
    555555        }
     
    557557        void CommonType_old::postvisit( ArrayType * ) {}
    558558
    559         void CommonType_old::postvisit( ReferenceType * refType ) {
    560                 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) {
     559        void CommonType_old::postvisit( ReferenceType *refType ) {
     560                if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
    561561                        // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
    562                         // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl;
    563                         if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
     562                        // std::cerr << ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond) << std::endl;
     563                        if ( widenFirst && dynamic_cast< VoidType* >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
    564564                                getCommonWithVoidPointer( otherRef, refType );
    565                         } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
     565                        } else if ( widenSecond && dynamic_cast< VoidType* >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
    566566                                getCommonWithVoidPointer( refType, otherRef );
    567                         } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst )
    568                                            && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) {
     567                        } else if ( ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst )
     568                                           && ( refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond ) ) {
    569569                                // std::cerr << "middle case" << std::endl;
    570                                 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq;
    571                                 refType->get_base()->tq = Type::Qualifiers();
    572                                 otherRef->get_base()->tq = Type::Qualifiers();
     570                                Type::Qualifiers tq1 = refType->get_base()->get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();
     571                                refType->get_base()->get_qualifiers() = Type::Qualifiers();
     572                                otherRef->get_base()->get_qualifiers() = Type::Qualifiers();
    573573                                AssertionSet have, need;
    574574                                OpenVarSet newOpen( openVars );
     
    579579                                                result = otherRef->clone();
    580580                                        } // if
    581                                         strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2;
     581                                        strict_dynamic_cast<ReferenceType*>(result)->base->get_qualifiers() = tq1 | tq2;
    582582                                } else {
    583583                                        /// std::cerr << "place for ptr-to-type" << std::endl;
    584584                                } // if
    585                                 refType->get_base()->tq = tq1;
    586                                 otherRef->get_base()->tq = tq2;
     585                                refType->get_base()->get_qualifiers() = tq1;
     586                                otherRef->get_base()->get_qualifiers() = tq2;
    587587                        } // if
    588                 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
     588                } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
    589589                        result = refType->clone();
    590                         result->tq |= type2->tq;
     590                        result->get_qualifiers() |= type2->get_qualifiers();
    591591                } // if
    592592        }
     
    596596        void CommonType_old::postvisit( UnionInstType * ) {}
    597597
    598         void CommonType_old::postvisit( EnumInstType * enumInstType ) {
    599                 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
     598        void CommonType_old::postvisit( EnumInstType *enumInstType ) {
     599                if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
    600600                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
    601601                        result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
     
    606606        }
    607607
    608         void CommonType_old::postvisit( TypeInstType * inst ) {
     608        void CommonType_old::postvisit( TypeInstType *inst ) {
    609609                if ( widenFirst ) {
    610                         const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() );
     610                        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
    611611                        if ( nt ) {
    612                                 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
     612                                TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
    613613                                if ( type->get_base() ) {
    614                                         Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq;
     614                                        Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
    615615                                        AssertionSet have, need;
    616616                                        OpenVarSet newOpen( openVars );
    617                                         type2->tq = Type::Qualifiers();
    618                                         type->get_base()->tq = tq1;
     617                                        type2->get_qualifiers() = Type::Qualifiers();
     618                                        type->get_base()->get_qualifiers() = tq1;
    619619                                        if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
    620620                                                result = type2->clone();
    621                                                 result->tq = tq1 | tq2;
     621                                                result->get_qualifiers() = tq1 | tq2;
    622622                                        } // if
    623                                         type2->tq = tq2;
    624                                         type->get_base()->tq = Type::Qualifiers();
     623                                        type2->get_qualifiers() = tq2;
     624                                        type->get_base()->get_qualifiers() = Type::Qualifiers();
    625625                                } // if
    626626                        } // if
     
    631631        void CommonType_old::postvisit( VarArgsType * ) {}
    632632
    633         void CommonType_old::postvisit( ZeroType * zeroType ) {
     633        void CommonType_old::postvisit( ZeroType *zeroType ) {
    634634                if ( widenFirst ) {
    635                         if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
    636                                 if ( widenSecond || zeroType->tq <= type2->tq ) {
     635                        if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
     636                                if ( widenSecond || zeroType->get_qualifiers() <= type2->get_qualifiers() ) {
    637637                                        result = type2->clone();
    638                                         result->tq |= zeroType->tq;
    639                                 }
    640                         } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {
    641                                 result = new BasicType( zeroType->tq, BasicType::SignedInt );
    642                                 result->tq |= type2->tq;
    643                         }
    644                 }
    645         }
    646 
    647         void CommonType_old::postvisit( OneType * oneType ) {
     638                                        result->get_qualifiers() |= zeroType->get_qualifiers();
     639                                }
     640                        } else if ( widenSecond && dynamic_cast< OneType* >( type2 ) ) {
     641                                result = new BasicType( zeroType->get_qualifiers(), BasicType::SignedInt );
     642                                result->get_qualifiers() |= type2->get_qualifiers();
     643                        }
     644                }
     645        }
     646
     647        void CommonType_old::postvisit( OneType *oneType ) {
    648648                if ( widenFirst ) {
    649                         if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
    650                                 if ( widenSecond || oneType->tq <= type2->tq ) {
     649                        if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
     650                                if ( widenSecond || oneType->get_qualifiers() <= type2->get_qualifiers() ) {
    651651                                        result = type2->clone();
    652                                         result->tq |= oneType->tq;
    653                                 }
    654                         } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
    655                                 result = new BasicType( oneType->tq, BasicType::SignedInt );
    656                                 result->tq |= type2->tq;
     652                                        result->get_qualifiers() |= oneType->get_qualifiers();
     653                                }
     654                        } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
     655                                result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt );
     656                                result->get_qualifiers() |= type2->get_qualifiers();
    657657                        }
    658658                }
     
    668668                ast::ptr< ast::Type > result;
    669669
    670                 CommonType_new(
    671                         const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
     670                CommonType_new( 
     671                        const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 
    672672                        ast::TypeEnvironment & env, const ast::OpenVarSet & o )
    673673                : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
     
    681681                                #warning remove casts when `commonTypes` moved to new AST
    682682                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
    683                                 if (
    684                                         ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
    685                                                 || widen.first )
    686                                         && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
    687                                                 || widen.second )
     683                                if ( 
     684                                        ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 
     685                                                || widen.first ) 
     686                                        && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 
     687                                                || widen.second ) 
    688688                                ) {
    689689                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
    690690                                }
    691                         } else if (
    692                                 dynamic_cast< const ast::EnumInstType * >( type2 )
     691                        } else if ( 
     692                                dynamic_cast< const ast::EnumInstType * >( type2 ) 
    693693                                || dynamic_cast< const ast::ZeroType * >( type2 )
    694694                                || dynamic_cast< const ast::OneType * >( type2 )
     
    696696                                #warning remove casts when `commonTypes` moved to new AST
    697697                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
    698                                 if (
    699                                         ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
    700                                                 || widen.first )
    701                                         && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
    702                                                 || widen.second )
     698                                if ( 
     699                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 
     700                                                || widen.first ) 
     701                                        && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 
     702                                                || widen.second ) 
    703703                                ) {
    704704                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
     
    715715                                if ( entry != open.end() ) {
    716716                                        ast::AssertionSet need, have;
    717                                         if ( ! tenv.bindVar(
    718                                                 var, voidPtr->base, entry->second, need, have, open, widen, symtab )
     717                                        if ( ! tenv.bindVar( 
     718                                                var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 
    719719                                        ) return;
    720720                                }
     
    727727                void postvisit( const ast::PointerType * pointer ) {
    728728                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
    729                                 if (
    730                                         widen.first
    731                                         && pointer2->base.as< ast::VoidType >()
    732                                         && ! ast::isFtype( pointer->base )
     729                                if ( 
     730                                        widen.first 
     731                                        && pointer2->base.as< ast::VoidType >() 
     732                                        && ! ast::isFtype( pointer->base ) 
    733733                                ) {
    734734                                        getCommonWithVoidPointer( pointer2, pointer );
    735                                 } else if (
    736                                         widen.second
    737                                         && pointer->base.as< ast::VoidType >()
    738                                         && ! ast::isFtype( pointer2->base )
     735                                } else if ( 
     736                                        widen.second 
     737                                        && pointer->base.as< ast::VoidType >() 
     738                                        && ! ast::isFtype( pointer2->base ) 
    739739                                ) {
    740740                                        getCommonWithVoidPointer( pointer, pointer2 );
     
    746746                                        ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
    747747
    748                                         // force t{1,2} to be cloned if their qualifiers must be stripped, so that
     748                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that 
    749749                                        // pointer{,2}->base are unchanged
    750750                                        ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
    751751                                        reset_qualifiers( t1 );
    752752                                        reset_qualifiers( t2 );
    753 
     753                                       
    754754                                        ast::AssertionSet have, need;
    755755                                        ast::OpenVarSet newOpen{ open };
     
    758758                                                if ( q1.val != q2.val ) {
    759759                                                        // reset result->base->qualifiers to be union of two base qualifiers
    760                                                         strict_dynamic_cast< ast::PointerType * >(
    761                                                                 result.get_and_mutate()
     760                                                        strict_dynamic_cast< ast::PointerType * >( 
     761                                                                result.get_and_mutate() 
    762762                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
    763763                                                }
     
    775775                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    776776                                if (
    777                                         widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
     777                                        widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 
    778778                                ) {
    779779                                        getCommonWithVoidPointer( ref2, ref );
    780                                 } else if (
    781                                         widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
     780                                } else if ( 
     781                                        widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 
    782782                                ) {
    783783                                        getCommonWithVoidPointer( ref, ref2 );
     
    788788                                        ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
    789789
    790                                         // force t{1,2} to be cloned if their qualifiers must be stripped, so that
     790                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that 
    791791                                        // ref{,2}->base are unchanged
    792792                                        ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
     
    800800                                                if ( q1.val != q2.val ) {
    801801                                                        // reset result->base->qualifiers to be union of two base qualifiers
    802                                                         strict_dynamic_cast< ast::ReferenceType * >(
    803                                                                 result.get_and_mutate()
     802                                                        strict_dynamic_cast< ast::ReferenceType * >( 
     803                                                                result.get_and_mutate() 
    804804                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
    805805                                                }
     
    819819
    820820                void postvisit( const ast::EnumInstType * enumInst ) {
    821                         if (
    822                                 dynamic_cast< const ast::BasicType * >( type2 )
     821                        if ( 
     822                                dynamic_cast< const ast::BasicType * >( type2 ) 
    823823                                || dynamic_cast< const ast::ZeroType * >( type2 )
    824824                                || dynamic_cast< const ast::OneType * >( type2 )
     
    834834                        if ( ! widen.first ) return;
    835835                        if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
    836                                 if ( const ast::Type * base =
    837                                                 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
     836                                if ( const ast::Type * base = 
     837                                                strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 
    838838                                ) {
    839839                                        ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
     
    860860                void postvisit( const ast::ZeroType * zero ) {
    861861                        if ( ! widen.first ) return;
    862                         if (
     862                        if ( 
    863863                                dynamic_cast< const ast::BasicType * >( type2 )
    864864                                || dynamic_cast< const ast::PointerType * >( type2 )
     
    870870                                }
    871871                        } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
    872                                 result = new ast::BasicType{
     872                                result = new ast::BasicType{ 
    873873                                        ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
    874874                        }
     
    877877                void postvisit( const ast::OneType * one ) {
    878878                        if ( ! widen.first ) return;
    879                         if (
     879                        if ( 
    880880                                dynamic_cast< const ast::BasicType * >( type2 )
    881881                                || dynamic_cast< const ast::EnumInstType * >( type2 )
     
    886886                                }
    887887                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
    888                                 result = new ast::BasicType{
     888                                result = new ast::BasicType{ 
    889889                                        ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
    890890                        }
     
    894894
    895895        namespace {
    896                 ast::ptr< ast::Type > handleReference(
    897                         const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
    898                         const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
    899                         const ast::OpenVarSet & open
     896                ast::ptr< ast::Type > handleReference( 
     897                        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 
     898                        const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 
     899                        const ast::OpenVarSet & open 
    900900                ) {
    901901                        ast::ptr<ast::Type> common;
     
    926926
    927927        ast::ptr< ast::Type > commonType(
    928                         const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
    929                         WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
    930                         const ast::OpenVarSet & open
     928                        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 
     929                        WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 
     930                        const ast::OpenVarSet & open 
    931931        ) {
    932932                unsigned depth1 = type1->referenceDepth();
     
    940940                        const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
    941941                        const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
    942 
     942                       
    943943                        if ( depth1 > depth2 ) {
    944944                                assert( ref1 );
     
    978978                                                ast::OpenVarSet newOpen{ open };
    979979
    980                                                 // force t{1,2} to be cloned if its qualifiers must be stripped, so that
    981                                                 // type1 and type->base are left unchanged; calling convention forces
     980                                                // force t{1,2} to be cloned if its qualifiers must be stripped, so that 
     981                                                // type1 and type->base are left unchanged; calling convention forces 
    982982                                                // {type1,type->base}->strong_ref >= 1
    983983                                                ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
    984984                                                reset_qualifiers( t1 );
    985985                                                reset_qualifiers( t2, q1 );
    986 
     986                                               
    987987                                                if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
    988988                                                        result = t1;
  • src/ResolvExpr/ConversionCost.cc

    r4eb43fa rf6cc734e  
    4646#endif
    4747
    48         Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    49                 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
     48        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     49                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    5050                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
    51                         if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
     51                        if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
    5252                                if ( eqvClass->type ) {
    5353                                        return conversionCost( src, eqvClass->type, indexer, env );
     
    5555                                        return Cost::infinity;
    5656                                }
    57                         } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     57                        } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5858                                PRINT( std::cerr << " found" << std::endl; )
    59                                 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
     59                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    6060                                // all typedefs should be gone by this point
    6161                                assert( type );
     
    7777                        PRINT( std::cerr << "compatible!" << std::endl; )
    7878                        return Cost::zero;
    79                 } else if ( dynamic_cast< const VoidType * >( dest ) ) {
     79                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    8080                        return Cost::safe;
    81                 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
     81                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    8282                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    83                         return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
     83                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8484                                return ptrsAssignable( t1, t2, env );
    8585                        });
    8686                } else {
    87                         PassVisitor<ConversionCost> converter(
    88                                 dest, indexer, env,
    89                                 (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
     87                        PassVisitor<ConversionCost> converter( 
     88                                dest, indexer, env, 
     89                                (Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
    9090                                        conversionCost );
    9191                        src->accept( converter );
     
    9898        }
    9999
    100         Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     100        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    101101                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    102102                if ( diff > 0 ) {
    103103                        // TODO: document this
    104                         Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
     104                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
    105105                        cost.incReference();
    106106                        return cost;
    107107                } else if ( diff < -1 ) {
    108108                        // TODO: document this
    109                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
     109                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
    110110                        cost.incReference();
    111111                        return cost;
    112112                } else if ( diff == 0 ) {
    113                         const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
    114                         const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
     113                        ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
     114                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
    115115                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    116116                                PRINT( std::cerr << "converting between references" << std::endl; )
    117                                 Type::Qualifiers tq1 = srcAsRef->base->tq;
    118                                 Type::Qualifiers tq2 = destAsRef->base->tq;
     117                                Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
     118                                Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
    119119                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
    120120                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    137137                        } else {
    138138                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    139                                 PassVisitor<ConversionCost> converter(
    140                                         dest, indexer, env,
    141                                         (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
     139                                PassVisitor<ConversionCost> converter( 
     140                                        dest, indexer, env, 
     141                                        (Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
    142142                                                conversionCost );
    143143                                src->accept( converter );
     
    145145                        } // if
    146146                } else {
    147                         const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
     147                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
    148148                        assert( diff == -1 && destAsRef );
    149149                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
     
    156156                                        )
    157157                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    158                                         if ( src->tq == destAsRef->base->tq ) {
     158                                        if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
    159159                                                return Cost::reference; // cost needs to be non-zero to add cast
    160                                         } if ( src->tq < destAsRef->base->tq ) {
     160                                        } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
    161161                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    162162                                        } else {
     
    178178        }
    179179
    180         Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     180        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    181181                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    182182                Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
     
    185185        }
    186186
    187         ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     187        ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    188188                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    189189        }
     
    193193        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
    194194                                 _Bool
    195         char                signed char         unsigned char
    196                   signed short int         unsigned short int
    197                   signed int               unsigned int
    198                   signed long int          unsigned long int
    199                   signed long long int     unsigned long long int
    200                   __int128                 unsigned __int128
    201                   _Float16                 _Float16 _Complex
    202                   _Float32                 _Float32 _Complex
    203                   float                    float _Complex
    204                   _Float32x                _Float32x _Complex
    205                   _Float64                 _Float64 _Complex
    206                   double                   double _Complex
    207                   _Float64x                _Float64x _Complex
     195        char                signed char         unsigned char       
     196                  signed short int         unsigned short int       
     197                  signed int               unsigned int             
     198                  signed long int          unsigned long int       
     199                  signed long long int     unsigned long long int   
     200                  __int128                 unsigned __int128       
     201                  _Float16                 _Float16 _Complex       
     202                  _Float32                 _Float32 _Complex       
     203                  float                    float _Complex           
     204                  _Float32x                _Float32x _Complex       
     205                  _Float64                 _Float64 _Complex       
     206                  double                   double _Complex         
     207                  _Float64x                _Float64x _Complex       
    208208                             __float80
    209                   _Float128                _Float128 _Complex
     209                  _Float128                _Float128 _Complex       
    210210                            __float128
    211                   long double              long double _Complex
    212                   _Float128x               _Float128x _Complex
     211                  long double              long double _Complex     
     212                  _Float128x               _Float128x _Complex     
    213213        */
    214214        // GENERATED END
     
    218218        static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
    219219                /*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    220                 /*     B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
    221                 /*     C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    222                 /*    SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    223                 /*    UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    224                 /*    SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
    225                 /*   SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
    226                 /*     I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
    227                 /*    UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
    228                 /*    LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
    229                 /*   LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
    230                 /*   LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
    231                 /*  LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
    232                 /*    IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
    233                 /*   UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
    234                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
    235                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
    236                 /*    _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
    237                 /*   _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
    238                 /*     F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
    239                 /*    FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
    240                 /*   _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
    241                 /*  _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
    242                 /*    FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
    243                 /*  _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
    244                 /*     D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
    245                 /*    DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
    246                 /*  F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
    247                 /* _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
     220                /*     B*/ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
     221                /*     C*/ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     222                /*    SC*/ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     223                /*    UC*/ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     224                /*    SI*/ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
     225                /*   SUI*/ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
     226                /*     I*/ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
     227                /*    UI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
     228                /*    LI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
     229                /*   LUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
     230                /*   LLI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
     231                /*  LLUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
     232                /*    IB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
     233                /*   UIB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
     234                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
     235                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
     236                /*    _F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
     237                /*   _FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
     238                /*     F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
     239                /*    FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
     240                /*   _FX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
     241                /*  _FXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
     242                /*    FD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
     243                /*  _FDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
     244                /*     D*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
     245                /*    DC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
     246                /*  F80X*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
     247                /* _FDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
    248248                /*   F80*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3,   3,   4,   4, },
    249                 /*   _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
    250                 /* _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
    251                 /*    FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
    252                 /*    LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
    253                 /*   LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
    254                 /*  _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
    255                 /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
     249                /*   _FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
     250                /* _FLDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
     251                /*    FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
     252                /*    LD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
     253                /*   LDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
     254                /*  _FBX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
     255                /*_FLDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
    256256        }; // costMatrix
    257257        static const int maxIntCost = 15;
    258258        // GENERATED END
    259259        static_assert(
    260                 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
     260                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
    261261                "Missing row in the cost matrix"
    262262        );
     
    266266        static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
    267267                /*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    268                 /*     B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    269                 /*     C */ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    270                 /*    SC */ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    271                 /*    UC */ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    272                 /*    SI */ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    273                 /*   SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    274                 /*     I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    275                 /*    UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    276                 /*    LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    277                 /*   LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    278                 /*   LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    279                 /*  LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    280                 /*    IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    281                 /*   UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    282                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    283                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    284                 /*    _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    285                 /*   _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    286                 /*     F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    287                 /*    FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    288                 /*   _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    289                 /*  _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    290                 /*    FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    291                 /*  _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    292                 /*     D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    293                 /*    DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    294                 /*  F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    295                 /* _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     268                /*     B*/ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     269                /*     C*/ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     270                /*    SC*/ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     271                /*    UC*/ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     272                /*    SI*/ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     273                /*   SUI*/ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     274                /*     I*/ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     275                /*    UI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     276                /*    LI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     277                /*   LUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     278                /*   LLI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     279                /*  LLUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     280                /*    IB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     281                /*   UIB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     282                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     283                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     284                /*    _F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     285                /*   _FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     286                /*     F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     287                /*    FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     288                /*   _FX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     289                /*  _FXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     290                /*    FD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     291                /*  _FDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     292                /*     D*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     293                /*    DC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     294                /*  F80X*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     295                /* _FDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    296296                /*   F80*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    297                 /*   _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
    298                 /* _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    299                 /*    FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
    300                 /*    LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
    301                 /*   LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
    302                 /*  _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
    303                 /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
     297                /*   _FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
     298                /* _FLDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     299                /*    FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
     300                /*    LD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
     301                /*   LDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
     302                /*  _FBX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
     303                /*_FLDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
    304304        }; // signMatrix
    305305        // GENERATED END
    306306        static_assert(
    307                 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
     307                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
    308308                "Missing row in the sign matrix"
    309309        );
    310310
    311         void ConversionCost::postvisit( const VoidType * ) {
     311        void ConversionCost::postvisit( VoidType * ) {
    312312                cost = Cost::infinity;
    313313        }
    314314
    315         void ConversionCost::postvisit(const BasicType * basicType) {
    316                 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    317                         int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ];
     315        void ConversionCost::postvisit(BasicType *basicType) {
     316                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     317                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
    318318                        if ( tableResult == -1 ) {
    319319                                cost = Cost::unsafe;
     
    321321                                cost = Cost::zero;
    322322                                cost.incSafe( tableResult );
    323                                 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
    324                         } // if
    325                 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
     323                                cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
     324                        } // if
     325                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
    326326                        // xxx - not positive this is correct, but appears to allow casting int => enum
    327327                        cost = Cost::unsafe;
     
    330330        }
    331331
    332         void ConversionCost::postvisit( const PointerType * pointerType ) {
    333                 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
     332        void ConversionCost::postvisit( PointerType * pointerType ) {
     333                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    334334                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    335                         Type::Qualifiers tq1 = pointerType->base->tq;
    336                         Type::Qualifiers tq2 = destAsPtr->base->tq;
     335                        Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
     336                        Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
    337337                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    338338                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    363363        }
    364364
    365         void ConversionCost::postvisit( const ArrayType * ) {}
    366 
    367         void ConversionCost::postvisit( const ReferenceType * refType ) {
     365        void ConversionCost::postvisit( ArrayType * ) {}
     366
     367        void ConversionCost::postvisit( ReferenceType * refType ) {
    368368                // Note: dest can never be a reference, since it would have been caught in an earlier check
    369                 assert( ! dynamic_cast< const ReferenceType * >( dest ) );
     369                assert( ! dynamic_cast< ReferenceType * >( dest ) );
    370370                // convert reference to rvalue: cv T1 & => T2
    371371                // recursively compute conversion cost from T1 to T2.
    372372                // cv can be safely dropped because of 'implicit dereference' behavior.
    373373                cost = costFunc( refType->base, dest, indexer, env );
    374                 if ( refType->base->tq == dest->tq ) {
     374                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    375375                        cost.incReference();  // prefer exact qualifiers
    376                 } else if ( refType->base->tq < dest->tq ) {
     376                } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
    377377                        cost.incSafe(); // then gaining qualifiers
    378378                } else {
     
    382382        }
    383383
    384         void ConversionCost::postvisit( const FunctionType * ) {}
    385 
    386         void ConversionCost::postvisit( const StructInstType * inst ) {
    387                 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
     384        void ConversionCost::postvisit( FunctionType * ) {}
     385
     386        void ConversionCost::postvisit( StructInstType * inst ) {
     387                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    388388                        if ( inst->name == destAsInst->name ) {
    389389                                cost = Cost::zero;
     
    392392        }
    393393
    394         void ConversionCost::postvisit( const UnionInstType * inst ) {
    395                 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
     394        void ConversionCost::postvisit( UnionInstType * inst ) {
     395                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    396396                        if ( inst->name == destAsInst->name ) {
    397397                                cost = Cost::zero;
     
    400400        }
    401401
    402         void ConversionCost::postvisit( const EnumInstType * ) {
     402        void ConversionCost::postvisit( EnumInstType * ) {
    403403                static Type::Qualifiers q;
    404404                static BasicType integer( q, BasicType::SignedInt );
     
    409409        }
    410410
    411         void ConversionCost::postvisit( const TraitInstType * ) {}
    412 
    413         void ConversionCost::postvisit( const TypeInstType * inst ) {
    414                 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
     411        void ConversionCost::postvisit( TraitInstType * ) {}
     412
     413        void ConversionCost::postvisit( TypeInstType *inst ) {
     414                if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
    415415                        cost = costFunc( eqvClass->type, dest, indexer, env );
    416                 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
     416                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    417417                        if ( inst->name == destAsInst->name ) {
    418418                                cost = Cost::zero;
    419419                        }
    420                 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
    421                         const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
     420                } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
     421                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    422422                        // all typedefs should be gone by this point
    423423                        assert( type );
     
    428428        }
    429429
    430         void ConversionCost::postvisit( const TupleType * tupleType ) {
     430        void ConversionCost::postvisit( TupleType * tupleType ) {
    431431                Cost c = Cost::zero;
    432                 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
     432                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
    433433                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
    434434                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
    435435                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
    436                                 Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env );
     436                                Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
    437437                                if ( newCost == Cost::infinity ) {
    438438                                        return;
     
    448448        }
    449449
    450         void ConversionCost::postvisit( const VarArgsType * ) {
    451                 if ( dynamic_cast< const VarArgsType * >( dest ) ) {
    452                         cost = Cost::zero;
    453                 }
    454         }
    455 
    456         void ConversionCost::postvisit( const ZeroType * ) {
    457                 if ( dynamic_cast< const ZeroType * >( dest ) ) {
    458                         cost = Cost::zero;
    459                 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    460                         // copied from visit(BasicType *) for signed int, but +1 for safe conversions
    461                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
     450        void ConversionCost::postvisit( VarArgsType * ) {
     451                if ( dynamic_cast< VarArgsType* >( dest ) ) {
     452                        cost = Cost::zero;
     453                }
     454        }
     455
     456        void ConversionCost::postvisit( ZeroType * ) {
     457                if ( dynamic_cast< ZeroType * >( dest ) ) {
     458                        cost = Cost::zero;
     459                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     460                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
     461                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
    462462                        if ( tableResult == -1 ) {
    463463                                cost = Cost::unsafe;
     
    465465                                cost = Cost::zero;
    466466                                cost.incSafe( tableResult + 1 );
    467                                 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
    468                         } // if
    469                 } else if ( dynamic_cast< const PointerType * >( dest ) ) {
     467                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
     468                        } // if
     469                } else if ( dynamic_cast< PointerType* >( dest ) ) {
    470470                        cost = Cost::zero;
    471471                        cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
     
    473473        }
    474474
    475         void ConversionCost::postvisit( const OneType * ) {
    476                 if ( dynamic_cast< const OneType * >( dest ) ) {
    477                         cost = Cost::zero;
    478                 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    479                         // copied from visit(BasicType *) for signed int, but +1 for safe conversions
    480                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
     475        void ConversionCost::postvisit( OneType * ) {
     476                if ( dynamic_cast< OneType * >( dest ) ) {
     477                        cost = Cost::zero;
     478                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     479                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
     480                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
    481481                        if ( tableResult == -1 ) {
    482482                                cost = Cost::unsafe;
     
    484484                                cost = Cost::zero;
    485485                                cost.incSafe( tableResult + 1 );
    486                                 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
     486                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
    487487                        } // if
    488488                } // if
     
    729729                auto dstEnd = dstAsTuple->types.end();
    730730                while ( srcIt != srcEnd && dstIt != dstEnd ) {
    731                         Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env );
     731                        Cost newCost = costCalc( *srcIt++, *dstIt++, symtab, env );
    732732                        if ( newCost == Cost::infinity ) {
    733733                                return;
  • src/ResolvExpr/ConversionCost.h

    r4eb43fa rf6cc734e  
    3333        class TypeEnvironment;
    3434
    35         typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
     35        typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
    3636        struct ConversionCost : public WithShortCircuiting {
    3737          public:
    38                 ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
     38                ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
    3939
    4040                Cost get_cost() const { return cost; }
    4141
    42                 void previsit( const BaseSyntaxNode * ) { visit_children = false; }
     42                void previsit( BaseSyntaxNode * ) { visit_children = false; }
    4343
    44                 void postvisit( const VoidType * voidType );
    45                 void postvisit( const BasicType * basicType );
    46                 void postvisit( const PointerType * pointerType );
    47                 void postvisit( const ArrayType * arrayType );
    48                 void postvisit( const ReferenceType * refType );
    49                 void postvisit( const FunctionType * functionType );
    50                 void postvisit( const StructInstType * aggregateUseType );
    51                 void postvisit( const UnionInstType * aggregateUseType );
    52                 void postvisit( const EnumInstType * aggregateUseType );
    53                 void postvisit( const TraitInstType * aggregateUseType );
    54                 void postvisit( const TypeInstType * aggregateUseType );
    55                 void postvisit( const TupleType * tupleType );
    56                 void postvisit( const VarArgsType * varArgsType );
    57                 void postvisit( const ZeroType * zeroType );
    58                 void postvisit( const OneType * oneType );
     44                void postvisit( VoidType * voidType );
     45                void postvisit( BasicType * basicType );
     46                void postvisit( PointerType * pointerType );
     47                void postvisit( ArrayType * arrayType );
     48                void postvisit( ReferenceType * refType );
     49                void postvisit( FunctionType * functionType );
     50                void postvisit( StructInstType * aggregateUseType );
     51                void postvisit( UnionInstType * aggregateUseType );
     52                void postvisit( EnumInstType * aggregateUseType );
     53                void postvisit( TraitInstType * aggregateUseType );
     54                void postvisit( TypeInstType * aggregateUseType );
     55                void postvisit( TupleType * tupleType );
     56                void postvisit( VarArgsType * varArgsType );
     57                void postvisit( ZeroType * zeroType );
     58                void postvisit( OneType * oneType );
    5959          protected:
    60                 const Type * dest;
     60                Type *dest;
    6161                const SymTab::Indexer &indexer;
    6262                Cost cost;
     
    6565        };
    6666
    67         typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
    68         Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
     67        typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
     68        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
    6969
    7070// Some function pointer types, differ in return type.
  • src/ResolvExpr/PtrsAssignable.cc

    r4eb43fa rf6cc734e  
    2727namespace ResolvExpr {
    2828        struct PtrsAssignable : public WithShortCircuiting {
    29                 PtrsAssignable( const Type * dest, const TypeEnvironment &env );
     29                PtrsAssignable( Type *dest, const TypeEnvironment &env );
    3030
    3131                int get_result() const { return result; }
    3232
    33                 void previsit( const Type * ) { visit_children = false; }
    34 
    35                 void postvisit( const VoidType * voidType );
    36                 void postvisit( const BasicType * basicType );
    37                 void postvisit( const PointerType * pointerType );
    38                 void postvisit( const ArrayType * arrayType );
    39                 void postvisit( const FunctionType * functionType );
    40                 void postvisit( const StructInstType * inst );
    41                 void postvisit( const UnionInstType * inst );
    42                 void postvisit( const EnumInstType * inst );
    43                 void postvisit( const TraitInstType * inst );
    44                 void postvisit( const TypeInstType * inst );
    45                 void postvisit( const TupleType * tupleType );
    46                 void postvisit( const VarArgsType * varArgsType );
    47                 void postvisit( const ZeroType * zeroType );
    48                 void postvisit( const OneType * oneType );
     33                void previsit( Type * ) { visit_children = false; }
     34
     35                void postvisit( VoidType * voidType );
     36                void postvisit( BasicType * basicType );
     37                void postvisit( PointerType * pointerType );
     38                void postvisit( ArrayType * arrayType );
     39                void postvisit( FunctionType * functionType );
     40                void postvisit( StructInstType * inst );
     41                void postvisit( UnionInstType * inst );
     42                void postvisit( EnumInstType * inst );
     43                void postvisit( TraitInstType * inst );
     44                void postvisit( TypeInstType * inst );
     45                void postvisit( TupleType * tupleType );
     46                void postvisit( VarArgsType * varArgsType );
     47                void postvisit( ZeroType * zeroType );
     48                void postvisit( OneType * oneType );
    4949          private:
    50                 const Type * dest;
     50                Type *dest;
    5151                int result;
    5252                const TypeEnvironment &env;
    5353        };
    5454
    55         int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
     55        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
    5656                // std::cerr << "assignable: " << src << " | " << dest << std::endl;
    57                 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
    58                         if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     57                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     58                        if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    5959                                return ptrsAssignable( src, eqvClass->type, env );
    6060                        } // if
    6161                } // if
    62                 if ( dynamic_cast< const VoidType* >( dest ) ) {
     62                if ( dynamic_cast< VoidType* >( dest ) ) {
    6363                        // void * = T * for any T is unsafe
    6464                        // xxx - this should be safe, but that currently breaks the build
     
    7171        }
    7272
    73         PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
    74 
    75         void PtrsAssignable::postvisit( const VoidType * ) {
     73        PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
     74
     75        void PtrsAssignable::postvisit( VoidType * ) {
    7676                // T * = void * is disallowed - this is a change from C, where any
    7777                // void * can be assigned or passed to a non-void pointer without a cast.
    7878        }
    7979
    80         void PtrsAssignable::postvisit( const BasicType * ) {}
    81         void PtrsAssignable::postvisit( const PointerType * ) {}
    82         void PtrsAssignable::postvisit( const ArrayType * ) {}
    83         void PtrsAssignable::postvisit( const FunctionType * ) {}
    84 
    85         void PtrsAssignable::postvisit( const StructInstType * ) {}
    86         void PtrsAssignable::postvisit( const UnionInstType * ) {}
    87 
    88         void PtrsAssignable::postvisit( const EnumInstType * ) {
    89                 if ( dynamic_cast< const BasicType* >( dest ) ) {
     80        void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
     81        void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
     82        void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
     83        void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
     84
     85        void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
     86        void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
     87
     88        void PtrsAssignable::postvisit( EnumInstType * ) {
     89                if ( dynamic_cast< BasicType* >( dest ) ) {
    9090                        // int * = E *, etc. is safe. This isn't technically correct, as each
    9191                        // enum has one basic type that it is compatible with, an that type can
     
    9797        }
    9898
    99         void PtrsAssignable::postvisit(  const TraitInstType * ) {}
    100         void PtrsAssignable::postvisit( const TypeInstType * inst ) {
    101                 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
     99        void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
     100        void PtrsAssignable::postvisit( TypeInstType *inst ) {
     101                if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
    102102                        if ( eqvClass->type ) {
    103103                                // T * = S * for any S depends on the type bound to T
     
    107107        }
    108108
    109         void PtrsAssignable::postvisit( const TupleType * ) {}
    110         void PtrsAssignable::postvisit( const VarArgsType * ) {}
    111         void PtrsAssignable::postvisit( const ZeroType * ) {}
    112         void PtrsAssignable::postvisit( const OneType * ) {}
     109        void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
     110        void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
     111        void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
     112        void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
    113113
    114114// TODO: Get rid of the `_new` suffix when the old version is removed.
  • src/ResolvExpr/PtrsCastable.cc

    r4eb43fa rf6cc734e  
    2929        struct PtrsCastable_old : public WithShortCircuiting  {
    3030          public:
    31                 PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     31                PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    3232
    3333                int get_result() const { return result; }
    3434
    35                 void previsit( const Type * ) { visit_children = false; }
    36 
    37                 void postvisit( const VoidType * voidType );
    38                 void postvisit( const BasicType * basicType );
    39                 void postvisit( const PointerType * pointerType );
    40                 void postvisit( const ArrayType * arrayType );
    41                 void postvisit( const FunctionType * functionType );
    42                 void postvisit( const StructInstType * inst );
    43                 void postvisit( const UnionInstType * inst );
    44                 void postvisit( const EnumInstType * inst );
    45                 void postvisit( const TraitInstType * inst );
    46                 void postvisit( const TypeInstType * inst );
    47                 void postvisit( const TupleType * tupleType );
    48                 void postvisit( const VarArgsType * varArgsType );
    49                 void postvisit( const ZeroType * zeroType );
    50                 void postvisit( const OneType * oneType );
     35                void previsit( Type * ) { visit_children = false; }
     36
     37                void postvisit( VoidType * voidType );
     38                void postvisit( BasicType * basicType );
     39                void postvisit( PointerType * pointerType );
     40                void postvisit( ArrayType * arrayType );
     41                void postvisit( FunctionType * functionType );
     42                void postvisit( StructInstType * inst );
     43                void postvisit( UnionInstType * inst );
     44                void postvisit( EnumInstType * inst );
     45                void postvisit( TraitInstType * inst );
     46                void postvisit( TypeInstType * inst );
     47                void postvisit( TupleType * tupleType );
     48                void postvisit( VarArgsType * varArgsType );
     49                void postvisit( ZeroType * zeroType );
     50                void postvisit( OneType * oneType );
    5151          private:
    52                 const Type * dest;
     52                Type *dest;
    5353                int result;
    5454                const TypeEnvironment &env;
     
    5757
    5858        namespace {
    59                 int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    60                         if ( dynamic_cast< const FunctionType* >( src ) ) {
     59                int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     60                        if ( dynamic_cast< FunctionType* >( src ) ) {
    6161                                return -1;
    62                         } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
    63                                 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
    64                                         if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
    65                                                 if ( tyDecl->kind == TypeDecl::Ftype ) {
     62                        } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
     63                                if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     64                                        if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     65                                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
    6666                                                        return -1;
    6767                                                } // if
    6868                                        } //if
    69                                 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
     69                                } else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
    7070                                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    7171                                                return -1;
     
    7575                        return 1;
    7676                }
    77                 int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     77                int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    7878                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
    7979                }
    8080        }
    8181
    82         int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    83                 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
    84                         if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     82        int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     83                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     84                        if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    8585                                // xxx - should this be ptrsCastable?
    8686                                return ptrsAssignable( src, eqvClass->type, env );
    8787                        } // if
    8888                } // if
    89                 if ( dynamic_cast< const VoidType* >( dest ) ) {
     89                if ( dynamic_cast< VoidType* >( dest ) ) {
    9090                        return objectCast( src, env, indexer );
    9191                } else {
     
    9696        }
    9797
    98         PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
     98        PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    9999                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
    100100        }
    101101
    102         void PtrsCastable_old::postvisit( const VoidType * ) {
    103                 result = objectCast( dest, env, indexer );
    104         }
    105 
    106         void PtrsCastable_old::postvisit( const BasicType * ) {
    107                 result = objectCast( dest, env, indexer );
    108         }
    109 
    110         void PtrsCastable_old::postvisit( const PointerType * ) {
    111                 result = objectCast( dest, env, indexer );
    112         }
    113 
    114         void PtrsCastable_old::postvisit( const ArrayType * ) {
    115                 result = objectCast( dest, env, indexer );
    116         }
    117 
    118         void PtrsCastable_old::postvisit( const FunctionType * ) {
     102        void PtrsCastable_old::postvisit( VoidType * ) {
     103                result = objectCast( dest, env, indexer );
     104        }
     105
     106        void PtrsCastable_old::postvisit( BasicType * ) {
     107                result = objectCast( dest, env, indexer );
     108        }
     109
     110        void PtrsCastable_old::postvisit( PointerType * ) {
     111                result = objectCast( dest, env, indexer );
     112        }
     113
     114        void PtrsCastable_old::postvisit( ArrayType * ) {
     115                result = objectCast( dest, env, indexer );
     116        }
     117
     118        void PtrsCastable_old::postvisit( FunctionType * ) {
    119119                // result = -1;
    120120                result = functionCast( dest, env, indexer );
    121121        }
    122122
    123         void PtrsCastable_old::postvisit( const StructInstType * ) {
    124                 result = objectCast( dest, env, indexer );
    125         }
    126 
    127         void PtrsCastable_old::postvisit( const UnionInstType * ) {
    128                 result = objectCast( dest, env, indexer );
    129         }
    130 
    131         void PtrsCastable_old::postvisit( const EnumInstType * ) {
    132                 if ( dynamic_cast< const EnumInstType * >( dest ) ) {
     123        void PtrsCastable_old::postvisit( StructInstType * ) {
     124                result = objectCast( dest, env, indexer );
     125        }
     126
     127        void PtrsCastable_old::postvisit( UnionInstType * ) {
     128                result = objectCast( dest, env, indexer );
     129        }
     130
     131        void PtrsCastable_old::postvisit( EnumInstType * ) {
     132                if ( dynamic_cast< EnumInstType* >( dest ) ) {
    133133                        result = 1;
    134                 } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
    135                         if ( bt->kind == BasicType::SignedInt ) {
     134                } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
     135                        if ( bt->get_kind() == BasicType::SignedInt ) {
    136136                                result = 0;
    137137                        } else {
     
    143143        }
    144144
    145         void PtrsCastable_old::postvisit( const TraitInstType * ) {}
    146 
    147         void PtrsCastable_old::postvisit( const TypeInstType *inst ) {
     145        void PtrsCastable_old::postvisit( TraitInstType * ) {}
     146
     147        void PtrsCastable_old::postvisit(TypeInstType *inst ) {
    148148                //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
    149149                result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
    150150        }
    151151
    152         void PtrsCastable_old::postvisit( const TupleType * ) {
    153                 result = objectCast( dest, env, indexer );
    154         }
    155 
    156         void PtrsCastable_old::postvisit( const VarArgsType * ) {
    157                 result = objectCast( dest, env, indexer );
    158         }
    159 
    160         void PtrsCastable_old::postvisit( const ZeroType * ) {
    161                 result = objectCast( dest, env, indexer );
    162         }
    163 
    164         void PtrsCastable_old::postvisit( const OneType * ) {
     152        void PtrsCastable_old::postvisit( TupleType * ) {
     153                result = objectCast( dest, env, indexer );
     154        }
     155
     156        void PtrsCastable_old::postvisit( VarArgsType * ) {
     157                result = objectCast( dest, env, indexer );
     158        }
     159
     160        void PtrsCastable_old::postvisit( ZeroType * ) {
     161                result = objectCast( dest, env, indexer );
     162        }
     163
     164        void PtrsCastable_old::postvisit( OneType * ) {
    165165                result = objectCast( dest, env, indexer );
    166166        }
     
    168168namespace {
    169169        // can this type be cast to an object (1 for yes, -1 for no)
    170         int objectCast(
    171                 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     170        int objectCast( 
     171                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
    172172        ) {
    173173                if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
     
    191191
    192192        // can this type be cast to a function (inverse of objectCast)
    193         int functionCast(
    194                 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     193        int functionCast( 
     194                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
    195195        ) {
    196196                return -1 * objectCast( src, env, symtab );
     
    204204                int result;
    205205
    206                 PtrsCastable_new(
     206                PtrsCastable_new( 
    207207                        const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
    208208                : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
     
    278278} // anonymous namespace
    279279
    280 int ptrsCastable(
    281         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    282         const ast::TypeEnvironment & env
     280int ptrsCastable( 
     281        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
     282        const ast::TypeEnvironment & env 
    283283) {
    284284        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
  • src/ResolvExpr/ResolveAssertions.cc

    r4eb43fa rf6cc734e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Fri Oct 05 13:46:00 2018
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 10 16:10:37 2019
    13 // Update Count     : 2
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Fri Oct 05 13:46:00 2018
     13// Update Count     : 1
    1414//
    1515
     
    197197                        }
    198198                        if ( i == b.size() /* && i < a.size() */ ) return 1;
    199 
     199                       
    200200                        int c = a[i].compare( b[i] );
    201201                        if ( c != 0 ) return c;
     
    220220
    221221                /// Initial resolution state for an alternative
    222                 ResnState( Alternative & a, SymTab::Indexer & indexer )
     222                ResnState( Alternative& a, SymTab::Indexer& indexer )
    223223                : alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) {
    224224                        need.swap( a.need );
     
    226226
    227227                /// Updated resolution state with new need-list
    228                 ResnState( ResnState && o, IterateFlag )
     228                ResnState( ResnState&& o, IterateFlag )
    229229                : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(),
    230230                  inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) {
     
    234234
    235235        /// Binds a single assertion, updating resolution state
    236         void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative & alt,
    237                         AssnCandidate & match, InferCache & inferred ) {
    238 
    239                 const DeclarationWithType * candidate = match.cdata.id;
    240                 assertf( candidate->uniqueId, "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    241 
    242                 Expression * varExpr = match.cdata.combine( alt.cvtCost );
     236        void bindAssertion( const DeclarationWithType* decl, AssertionSetValue info, Alternative& alt,
     237                        AssnCandidate& match, InferCache& inferred ) {
     238
     239                DeclarationWithType* candidate = match.cdata.id;
     240                assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
     241
     242                Expression* varExpr = match.cdata.combine( alt.cvtCost );
    243243                delete varExpr->result;
    244244                varExpr->result = match.adjType->clone();
     
    247247                // place newly-inferred assertion in proper place in cache
    248248                inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{
    249                                 candidate->uniqueId, candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),
     249                                candidate->get_uniqueId(), candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),
    250250                                varExpr };
    251251        }
    252252
    253253        /// Adds a captured assertion to the symbol table
    254         void addToIndexer( AssertionSet & assertSet, SymTab::Indexer & indexer ) {
     254        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    255255                for ( auto&  i : assertSet ) {
    256256                        if ( i.second.isUsed ) {
     
    264264
    265265        /// Resolve a single assertion, in context
    266         bool resolveAssertion( AssertionItem & assn, ResnState & resn ) {
     266        bool resolveAssertion( AssertionItem& assn, ResnState& resn ) {
    267267                // skip unused assertions
    268268                if ( ! assn.info.isUsed ) return true;
     
    274274                // find the candidates that unify with the desired type
    275275                CandidateList matches;
    276                 for ( const auto & cdata : candidates ) {
    277                         const DeclarationWithType * candidate = cdata.id;
     276                for ( const auto& cdata : candidates ) {
     277                        DeclarationWithType* candidate = cdata.id;
    278278
    279279                        // build independent unification context for candidate
     
    281281                        TypeEnvironment newEnv{ resn.alt.env };
    282282                        OpenVarSet newOpenVars{ resn.alt.openVars };
    283                         Type * adjType = candidate->get_type()->clone();
     283                        Type* adjType = candidate->get_type()->clone();
    284284                        adjustExprType( adjType, newEnv, resn.indexer );
    285285                        renameTyVars( adjType );
     
    368368                std::string resKey = SymTab::Mangler::mangleType( resType );
    369369                delete resType;
    370                 return resKey;
    371         }
    372 
    373         /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning
     370                return std::move( resKey );
     371        }
     372       
     373        /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 
    374374        /// threshold.
    375375        void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) {
     
    406406                ResnList resns{ ResnState{ alt, root_indexer } };
    407407                ResnList new_resns{};
    408 
     408               
    409409                // Pruning thresholds by result type of the output alternatives.
    410410                // Alternatives *should* be generated in sorted order, so no need to retroactively prune
  • src/ResolvExpr/Resolver.cc

    r4eb43fa rf6cc734e  
    562562                // TODO: Replace *exception type with &exception type.
    563563                if ( throwStmt->get_expr() ) {
    564                         const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     564                        StructDecl * exception_decl =
     565                                indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    565566                        assert( exception_decl );
    566                         Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) );
     567                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
    567568                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    568569                }
     
    971972                /// Calls the CandidateFinder and finds the single best candidate
    972973                CandidateRef findUnfinishedKindExpression(
    973                         const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     974                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 
    974975                        std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
    975976                ) {
     
    993994                        // produce invalid error if no candidates
    994995                        if ( candidates.empty() ) {
    995                                 SemanticError( untyped,
    996                                         toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
     996                                SemanticError( untyped, 
     997                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 
    997998                                        "expression: ") );
    998999                        }
     
    10301031                        if ( winners.size() != 1 ) {
    10311032                                std::ostringstream stream;
    1032                                 stream << "Cannot choose between " << winners.size() << " alternatives for "
     1033                                stream << "Cannot choose between " << winners.size() << " alternatives for " 
    10331034                                        << kind << (kind != "" ? " " : "") << "expression\n";
    10341035                                ast::print( stream, untyped );
     
    10531054                struct StripCasts_new final {
    10541055                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
    1055                                 if (
    1056                                         castExpr->isGenerated
    1057                                         && typesCompatible( castExpr->arg->result, castExpr->result )
     1056                                if ( 
     1057                                        castExpr->isGenerated 
     1058                                        && typesCompatible( castExpr->arg->result, castExpr->result ) 
    10581059                                ) {
    10591060                                        // generated cast is the same type as its argument, remove it after keeping env
    1060                                         return ast::mutate_field(
     1061                                        return ast::mutate_field( 
    10611062                                                castExpr->arg.get(), &ast::Expr::env, castExpr->env );
    10621063                                }
     
    10871088
    10881089                /// Establish post-resolver invariants for expressions
    1089                 void finishExpr(
    1090                         ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
     1090                void finishExpr( 
     1091                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 
    10911092                        const ast::TypeSubstitution * oldenv = nullptr
    10921093                ) {
    10931094                        // set up new type substitution for expression
    1094                         ast::ptr< ast::TypeSubstitution > newenv =
     1095                        ast::ptr< ast::TypeSubstitution > newenv = 
    10951096                                 oldenv ? oldenv : new ast::TypeSubstitution{};
    10961097                        env.writeToSubstitution( *newenv.get_and_mutate() );
     
    11011102        } // anonymous namespace
    11021103
    1103 
     1104               
    11041105        ast::ptr< ast::Expr > resolveInVoidContext(
    11051106                const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
    11061107        ) {
    11071108                assertf( expr, "expected a non-null expression" );
    1108 
     1109               
    11091110                // set up and resolve expression cast to void
    11101111                ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
    1111                 CandidateRef choice = findUnfinishedKindExpression(
     1112                CandidateRef choice = findUnfinishedKindExpression( 
    11121113                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
    1113 
     1114               
    11141115                // a cast expression has either 0 or 1 interpretations (by language rules);
    11151116                // if 0, an exception has already been thrown, and this code will not run
     
    11211122
    11221123        namespace {
    1123                 /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
     1124                /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 
    11241125                /// context.
    1125                 ast::ptr< ast::Expr > findVoidExpression(
     1126                ast::ptr< ast::Expr > findVoidExpression( 
    11261127                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11271128                ) {
     
    11331134                }
    11341135
    1135                 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     1136                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 
    11361137                /// lowest cost, returning the resolved version
    11371138                ast::ptr< ast::Expr > findKindExpression(
    1138                         const ast::Expr * untyped, const ast::SymbolTable & symtab,
    1139                         std::function<bool(const Candidate &)> pred = anyCandidate,
     1139                        const ast::Expr * untyped, const ast::SymbolTable & symtab, 
     1140                        std::function<bool(const Candidate &)> pred = anyCandidate, 
    11401141                        const std::string & kind = "", ResolvMode mode = {}
    11411142                ) {
    11421143                        if ( ! untyped ) return {};
    1143                         CandidateRef choice =
     1144                        CandidateRef choice = 
    11441145                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
    11451146                        finishExpr( choice->expr, choice->env, untyped->env );
     
    11481149
    11491150                /// Resolve `untyped` to the single expression whose candidate is the best match
    1150                 ast::ptr< ast::Expr > findSingleExpression(
    1151                         const ast::Expr * untyped, const ast::SymbolTable & symtab
     1151                ast::ptr< ast::Expr > findSingleExpression( 
     1152                        const ast::Expr * untyped, const ast::SymbolTable & symtab 
    11521153                ) {
    11531154                        return findKindExpression( untyped, symtab );
     
    11691170                bool hasIntegralType( const Candidate & i ) {
    11701171                        const ast::Type * type = i.expr->result;
    1171 
     1172                       
    11721173                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
    11731174                                return bt->isInteger();
    1174                         } else if (
    1175                                 dynamic_cast< const ast::EnumInstType * >( type )
     1175                        } else if ( 
     1176                                dynamic_cast< const ast::EnumInstType * >( type ) 
    11761177                                || dynamic_cast< const ast::ZeroType * >( type )
    11771178                                || dynamic_cast< const ast::OneType * >( type )
     
    11821183
    11831184                /// Resolve `untyped` as an integral expression, returning the resolved version
    1184                 ast::ptr< ast::Expr > findIntegralExpression(
    1185                         const ast::Expr * untyped, const ast::SymbolTable & symtab
     1185                ast::ptr< ast::Expr > findIntegralExpression( 
     1186                        const ast::Expr * untyped, const ast::SymbolTable & symtab 
    11861187                ) {
    11871188                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
     
    11911192                bool isCharType( const ast::Type * t ) {
    11921193                        if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {
    1193                                 return bt->kind == ast::BasicType::Char
    1194                                         || bt->kind == ast::BasicType::SignedChar
     1194                                return bt->kind == ast::BasicType::Char 
     1195                                        || bt->kind == ast::BasicType::SignedChar 
    11951196                                        || bt->kind == ast::BasicType::UnsignedChar;
    11961197                        }
     
    12521253        }
    12531254
    1254         ast::ptr< ast::Init > resolveCtorInit(
    1255                 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab
     1255        ast::ptr< ast::Init > resolveCtorInit( 
     1256                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 
    12561257        ) {
    12571258                assert( ctorInit );
     
    12601261        }
    12611262
    1262         ast::ptr< ast::Expr > resolveStmtExpr(
    1263                 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
     1263        ast::ptr< ast::Expr > resolveStmtExpr( 
     1264                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 
    12641265        ) {
    12651266                assert( stmtExpr );
     
    13021303
    13031304        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    1304                 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    1305                 // class-variable `initContext` is changed multiple times because the LHS is analyzed
    1306                 // twice. The second analysis changes `initContext` because a function type can contain
    1307                 // object declarations in the return and parameter types. Therefore each value of
    1308                 // `initContext` is retained so the type on the first analysis is preserved and used for
     1305                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 
     1306                // class-variable `initContext` is changed multiple times because the LHS is analyzed 
     1307                // twice. The second analysis changes `initContext` because a function type can contain 
     1308                // object declarations in the return and parameter types. Therefore each value of 
     1309                // `initContext` is retained so the type on the first analysis is preserved and used for 
    13091310                // selecting the RHS.
    13101311                GuardValue( currentObject );
    13111312                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    13121313                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    1313                         // enumerator initializers should not use the enum type to initialize, since the
     1314                        // enumerator initializers should not use the enum type to initialize, since the 
    13141315                        // enum type is still incomplete at this point. Use `int` instead.
    1315                         currentObject = ast::CurrentObject{
     1316                        currentObject = ast::CurrentObject{ 
    13161317                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    13171318                }
     
    13241325        }
    13251326
    1326         const ast::StaticAssertDecl * Resolver_new::previsit(
    1327                 const ast::StaticAssertDecl * assertDecl
     1327        const ast::StaticAssertDecl * Resolver_new::previsit( 
     1328                const ast::StaticAssertDecl * assertDecl 
    13281329        ) {
    1329                 return ast::mutate_field(
    1330                         assertDecl, &ast::StaticAssertDecl::cond,
     1330                return ast::mutate_field( 
     1331                        assertDecl, &ast::StaticAssertDecl::cond, 
    13311332                        findIntegralExpression( assertDecl->cond, symtab ) );
    13321333        }
     
    13371338                        #warning should use new equivalent to Validate::SizeType rather than sizeType here
    13381339                        ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
    1339                         ast::mutate_field(
    1340                                 type, &PtrType::dimension,
     1340                        ast::mutate_field( 
     1341                                type, &PtrType::dimension, 
    13411342                                findSingleExpression( type->dimension, sizeType, symtab ) );
    13421343                }
     
    13551356                visit_children = false;
    13561357                assertf( exprStmt->expr, "ExprStmt has null expression in resolver" );
    1357 
    1358                 return ast::mutate_field(
     1358               
     1359                return ast::mutate_field( 
    13591360                        exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
    13601361        }
     
    13631364                visit_children = false;
    13641365
    1365                 asmExpr = ast::mutate_field(
     1366                asmExpr = ast::mutate_field( 
    13661367                        asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
    1367 
     1368               
    13681369                if ( asmExpr->inout ) {
    13691370                        asmExpr = ast::mutate_field(
    13701371                                asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
    13711372                }
    1372 
     1373               
    13731374                return asmExpr;
    13741375        }
     
    13871388
    13881389        const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    1389                 return ast::mutate_field(
     1390                return ast::mutate_field( 
    13901391                        whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) );
    13911392        }
     
    14081409                GuardValue( currentObject );
    14091410                switchStmt = ast::mutate_field(
    1410                         switchStmt, &ast::SwitchStmt::cond,
     1411                        switchStmt, &ast::SwitchStmt::cond, 
    14111412                        findIntegralExpression( switchStmt->cond, symtab ) );
    14121413                currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
     
    14191420                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    14201421                                "expression." );
    1421 
    1422                         ast::ptr< ast::Expr > untyped =
     1422                       
     1423                        ast::ptr< ast::Expr > untyped = 
    14231424                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
    14241425                        ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
    1425 
    1426                         // case condition cannot have a cast in C, so it must be removed here, regardless of
     1426                       
     1427                        // case condition cannot have a cast in C, so it must be removed here, regardless of 
    14271428                        // whether it would perform a conversion.
    14281429                        if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
    14291430                                swap_and_save_env( newExpr, castExpr->arg );
    14301431                        }
    1431 
     1432                       
    14321433                        caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
    14331434                }
     
    14421443                        ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
    14431444                        branchStmt = ast::mutate_field(
    1444                                 branchStmt, &ast::BranchStmt::computedTarget,
     1445                                branchStmt, &ast::BranchStmt::computedTarget, 
    14451446                                findSingleExpression( branchStmt->computedTarget, target, symtab ) );
    14461447                }
     
    14521453                if ( returnStmt->expr ) {
    14531454                        returnStmt = ast::mutate_field(
    1454                                 returnStmt, &ast::ReturnStmt::expr,
     1455                                returnStmt, &ast::ReturnStmt::expr, 
    14551456                                findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
    14561457                }
     
    14611462                visit_children = false;
    14621463                if ( throwStmt->expr ) {
    1463                         const ast::StructDecl * exceptionDecl =
     1464                        const ast::StructDecl * exceptionDecl = 
    14641465                                symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    14651466                        assert( exceptionDecl );
    1466                         ast::ptr< ast::Type > exceptType =
     1467                        ast::ptr< ast::Type > exceptType = 
    14671468                                new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
    14681469                        throwStmt = ast::mutate_field(
    1469                                 throwStmt, &ast::ThrowStmt::expr,
     1470                                throwStmt, &ast::ThrowStmt::expr, 
    14701471                                findSingleExpression( throwStmt->expr, exceptType, symtab ) );
    14711472                }
     
    14761477                if ( catchStmt->cond ) {
    14771478                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
    1478                         catchStmt = ast::mutate_field(
    1479                                 catchStmt, &ast::CatchStmt::cond,
     1479                        catchStmt = ast::mutate_field( 
     1480                                catchStmt, &ast::CatchStmt::cond, 
    14801481                                findSingleExpression( catchStmt->cond, boolType, symtab ) );
    14811482                }
     
    15051506
    15061507                        if ( clause.target.args.empty() ) {
    1507                                 SemanticError( stmt->location,
     1508                                SemanticError( stmt->location, 
    15081509                                        "Waitfor clause must have at least one mutex parameter");
    15091510                        }
    15101511
    15111512                        // Find all alternatives for all arguments in canonical form
    1512                         std::vector< CandidateFinder > argFinders =
     1513                        std::vector< CandidateFinder > argFinders = 
    15131514                                funcFinder.findSubExprs( clause.target.args );
    1514 
     1515                       
    15151516                        // List all combinations of arguments
    15161517                        std::vector< CandidateList > possibilities;
     
    15181519
    15191520                        // For every possible function:
    1520                         // * try matching the arguments to the parameters, not the other way around because
     1521                        // * try matching the arguments to the parameters, not the other way around because 
    15211522                        //   more arguments than parameters
    15221523                        CandidateList funcCandidates;
     
    15251526                        for ( CandidateRef & func : funcFinder.candidates ) {
    15261527                                try {
    1527                                         auto pointerType = dynamic_cast< const ast::PointerType * >(
     1528                                        auto pointerType = dynamic_cast< const ast::PointerType * >( 
    15281529                                                func->expr->result->stripReferences() );
    15291530                                        if ( ! pointerType ) {
    1530                                                 SemanticError( stmt->location, func->expr->result.get(),
     1531                                                SemanticError( stmt->location, func->expr->result.get(), 
    15311532                                                        "candidate not viable: not a pointer type\n" );
    15321533                                        }
     
    15341535                                        auto funcType = pointerType->base.as< ast::FunctionType >();
    15351536                                        if ( ! funcType ) {
    1536                                                 SemanticError( stmt->location, func->expr->result.get(),
     1537                                                SemanticError( stmt->location, func->expr->result.get(), 
    15371538                                                        "candidate not viable: not a function type\n" );
    15381539                                        }
     
    15431544
    15441545                                                if( ! nextMutex( param, paramEnd ) ) {
    1545                                                         SemanticError( stmt->location, funcType,
     1546                                                        SemanticError( stmt->location, funcType, 
    15461547                                                                "candidate function not viable: no mutex parameters\n");
    15471548                                                }
     
    15591560                                                        ast::AssertionSet need, have;
    15601561                                                        ast::TypeEnvironment resultEnv{ func->env };
    1561                                                         // Add all type variables as open so that those not used in the
     1562                                                        // Add all type variables as open so that those not used in the 
    15621563                                                        // parameter list are still considered open
    15631564                                                        resultEnv.add( funcType->forall );
     
    15791580                                                        unsigned n_mutex_param = 0;
    15801581
    1581                                                         // For every argument of its set, check if it matches one of the
     1582                                                        // For every argument of its set, check if it matches one of the 
    15821583                                                        // parameters. The order is important
    15831584                                                        for ( auto & arg : argsList ) {
     
    15861587                                                                        // We ran out of parameters but still have arguments.
    15871588                                                                        // This function doesn't match
    1588                                                                         SemanticError( stmt->location, funcType,
     1589                                                                        SemanticError( stmt->location, funcType, 
    15891590                                                                                toString("candidate function not viable: too many mutex "
    15901591                                                                                "arguments, expected ", n_mutex_param, "\n" ) );
     
    15931594                                                                ++n_mutex_param;
    15941595
    1595                                                                 // Check if the argument matches the parameter type in the current
     1596                                                                // Check if the argument matches the parameter type in the current 
    15961597                                                                // scope
    15971598                                                                ast::ptr< ast::Type > paramType = (*param)->get_type();
    1598                                                                 if (
    1599                                                                         ! unify(
    1600                                                                                 arg->expr->result, paramType, resultEnv, need, have, open,
    1601                                                                                 symtab )
     1599                                                                if ( 
     1600                                                                        ! unify( 
     1601                                                                                arg->expr->result, paramType, resultEnv, need, have, open, 
     1602                                                                                symtab ) 
    16021603                                                                ) {
    16031604                                                                        // Type doesn't match
     
    16261627                                                                } while ( nextMutex( param, paramEnd ) );
    16271628
    1628                                                                 // We ran out of arguments but still have parameters left; this
     1629                                                                // We ran out of arguments but still have parameters left; this 
    16291630                                                                // function doesn't match
    1630                                                                 SemanticError( stmt->location, funcType,
     1631                                                                SemanticError( stmt->location, funcType, 
    16311632                                                                        toString( "candidate function not viable: too few mutex "
    16321633                                                                        "arguments, expected ", n_mutex_param, "\n" ) );
     
    16561657                        // Make sure correct number of arguments
    16571658                        if( funcCandidates.empty() ) {
    1658                                 SemanticErrorException top( stmt->location,
     1659                                SemanticErrorException top( stmt->location, 
    16591660                                        "No alternatives for function in call to waitfor" );
    16601661                                top.append( errors );
     
    16631664
    16641665                        if( argsCandidates.empty() ) {
    1665                                 SemanticErrorException top( stmt->location,
    1666                                         "No alternatives for arguments in call to waitfor" );
     1666                                SemanticErrorException top( stmt->location, 
     1667                                        "No alternatives for arguments in call to waitfor" ); 
    16671668                                top.append( errors );
    16681669                                throw top;
     
    16701671
    16711672                        if( funcCandidates.size() > 1 ) {
    1672                                 SemanticErrorException top( stmt->location,
     1673                                SemanticErrorException top( stmt->location, 
    16731674                                        "Ambiguous function in call to waitfor" );
    16741675                                top.append( errors );
     
    16851686                        // build new clause
    16861687                        ast::WaitForStmt::Clause clause2;
    1687 
     1688                       
    16881689                        clause2.target.func = funcCandidates.front()->expr;
    1689 
     1690                       
    16901691                        clause2.target.args.reserve( clause.target.args.size() );
    16911692                        for ( auto arg : argsCandidates.front() ) {
     
    17071708                        ast::WaitForStmt::Timeout timeout2;
    17081709
    1709                         ast::ptr< ast::Type > target =
     1710                        ast::ptr< ast::Type > target = 
    17101711                                new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
    17111712                        timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
     
    17391740        const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) {
    17401741                visit_children = false;
    1741                 // resolve initialization using the possibilities as determined by the `currentObject`
     1742                // resolve initialization using the possibilities as determined by the `currentObject` 
    17421743                // cursor.
    1743                 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
     1744                ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 
    17441745                        singleInit->location, singleInit->value, currentObject.getOptions() };
    17451746                ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
     
    17501751
    17511752                // discard InitExpr wrapper and retain relevant pieces.
    1752                 // `initExpr` may have inferred params in the case where the expression specialized a
    1753                 // function pointer, and newExpr may already have inferParams of its own, so a simple
     1753                // `initExpr` may have inferred params in the case where the expression specialized a 
     1754                // function pointer, and newExpr may already have inferParams of its own, so a simple 
    17541755                // swap is not sufficient
    17551756                ast::Expr::InferUnion inferred = initExpr->inferred;
     
    17571758                newExpr.get_and_mutate()->inferred.splice( std::move(inferred) );
    17581759
    1759                 // get the actual object's type (may not exactly match what comes back from the resolver
     1760                // get the actual object's type (may not exactly match what comes back from the resolver 
    17601761                // due to conversions)
    17611762                const ast::Type * initContext = currentObject.getCurrentType();
     
    17691770                                if ( auto pt = newExpr->result.as< ast::PointerType >() ) {
    17701771                                        if ( isCharType( pt->base ) ) {
    1771                                                 // strip cast if we're initializing a char[] with a char*
     1772                                                // strip cast if we're initializing a char[] with a char* 
    17721773                                                // e.g. char x[] = "hello"
    17731774                                                if ( auto ce = newExpr.as< ast::CastExpr >() ) {
     
    17921793                assert( listInit->designations.size() == listInit->initializers.size() );
    17931794                for ( unsigned i = 0; i < listInit->designations.size(); ++i ) {
    1794                         // iterate designations and initializers in pairs, moving the cursor to the current
     1795                        // iterate designations and initializers in pairs, moving the cursor to the current 
    17951796                        // designated object and resolving the initializer against that object
    17961797                        listInit = ast::mutate_field_index(
    1797                                 listInit, &ast::ListInit::designations, i,
     1798                                listInit, &ast::ListInit::designations, i, 
    17981799                                currentObject.findNext( listInit->designations[i] ) );
    17991800                        listInit = ast::mutate_field_index(
     
    18171818                ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
    18181819
    1819                 // intrinsic single-parameter constructors and destructors do nothing. Since this was
    1820                 // implicitly generated, there's no way for it to have side effects, so get rid of it to
     1820                // intrinsic single-parameter constructors and destructors do nothing. Since this was 
     1821                // implicitly generated, there's no way for it to have side effects, so get rid of it to 
    18211822                // clean up generated code
    18221823                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
  • src/ResolvExpr/Unify.cc

    r4eb43fa rf6cc734e  
    9797        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
    9898
    99         bool unifyExact(
    100                 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    101                 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     99        bool unifyExact( 
     100                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
     101                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
    102102                WidenMode widen, const ast::SymbolTable & symtab );
    103103
    104         bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     104        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    105105                TypeEnvironment newEnv;
    106106                OpenVarSet openVars, closedVars; // added closedVars
    107107                AssertionSet needAssertions, haveAssertions;
    108                 Type * newFirst = first->clone(), * newSecond = second->clone();
     108                Type *newFirst = first->clone(), *newSecond = second->clone();
    109109                env.apply( newFirst );
    110110                env.apply( newSecond );
     
    121121        }
    122122
    123         bool typesCompatible(
    124                         const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
     123        bool typesCompatible( 
     124                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
    125125                        const ast::TypeEnvironment & env ) {
    126126                ast::TypeEnvironment newEnv;
     
    135135                findOpenVars( newSecond, open, closed, need, have, FirstOpen );
    136136
    137                 return unifyExact(
     137                return unifyExact( 
    138138                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    139139        }
    140140
    141         bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     141        bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    142142                TypeEnvironment newEnv;
    143143                OpenVarSet openVars;
     
    163163        }
    164164
    165         bool typesCompatibleIgnoreQualifiers(
    166                         const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
     165        bool typesCompatibleIgnoreQualifiers( 
     166                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
    167167                        const ast::TypeEnvironment & env ) {
    168168                ast::TypeEnvironment newEnv;
    169169                ast::OpenVarSet open;
    170170                ast::AssertionSet need, have;
    171 
     171               
    172172                ast::ptr<ast::Type> newFirst{ first }, newSecond{ second };
    173173                env.apply( newFirst );
     
    176176                reset_qualifiers( newSecond );
    177177
    178                 return unifyExact(
     178                return unifyExact( 
    179179                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    180180        }
     
    490490
    491491                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
    492                         if (
    493                                         (flatFunc->parameters.size() == flatOther->parameters.size() &&
    494                                                 flatFunc->returnVals.size() == flatOther->returnVals.size())
    495                                         || flatFunc->isTtype()
    496                                         || flatOther->isTtype()
     492                        if ( 
     493                                        (flatFunc->parameters.size() == flatOther->parameters.size() && 
     494                                                flatFunc->returnVals.size() == flatOther->returnVals.size()) 
     495                                        || flatFunc->isTtype() 
     496                                        || flatOther->isTtype() 
    497497                        ) {
    498498                                if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     
    711711                bool result;
    712712
    713                 Unify_new(
    714                         const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
    715                         ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
     713                Unify_new( 
     714                        const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 
     715                        ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 
    716716                        const ast::SymbolTable & symtab )
    717                 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
     717                : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 
    718718                  symtab(symtab), result(false) {}
    719719
    720720                void previsit( const ast::Node * ) { visit_children = false; }
    721 
     721               
    722722                void postvisit( const ast::VoidType * ) {
    723723                        result = dynamic_cast< const ast::VoidType * >( type2 );
     
    732732                void postvisit( const ast::PointerType * pointer ) {
    733733                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
    734                                 result = unifyExact(
    735                                         pointer->base, pointer2->base, tenv, need, have, open,
     734                                result = unifyExact( 
     735                                        pointer->base, pointer2->base, tenv, need, have, open, 
    736736                                        noWiden(), symtab );
    737737                        }
     
    742742                        if ( ! array2 ) return;
    743743
    744                         // to unify, array types must both be VLA or both not VLA and both must have a
     744                        // to unify, array types must both be VLA or both not VLA and both must have a 
    745745                        // dimension expression or not have a dimension
    746746                        if ( array->isVarLen != array2->isVarLen ) return;
    747                         if ( ! array->isVarLen && ! array2->isVarLen
     747                        if ( ! array->isVarLen && ! array2->isVarLen 
    748748                                        && array->dimension && array2->dimension ) {
    749749                                auto ce1 = array->dimension.as< ast::ConstantExpr >();
     
    751751
    752752                                // see C11 Reference Manual 6.7.6.2.6
    753                                 // two array types with size specifiers that are integer constant expressions are
     753                                // two array types with size specifiers that are integer constant expressions are 
    754754                                // compatible if both size specifiers have the same constant value
    755755                                if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return;
    756756                        }
    757757
    758                         result = unifyExact(
    759                                 array->base, array2->base, tenv, need, have, open, noWiden(),
     758                        result = unifyExact( 
     759                                array->base, array2->base, tenv, need, have, open, noWiden(), 
    760760                                symtab );
    761761                }
     
    763763                void postvisit( const ast::ReferenceType * ref ) {
    764764                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    765                                 result = unifyExact(
    766                                         ref->base, ref2->base, tenv, need, have, open, noWiden(),
     765                                result = unifyExact( 
     766                                        ref->base, ref2->base, tenv, need, have, open, noWiden(), 
    767767                                        symtab );
    768768                        }
     
    771771        private:
    772772                /// Replaces ttype variables with their bound types.
    773                 /// If this isn't done when satifying ttype assertions, then argument lists can have
     773                /// If this isn't done when satifying ttype assertions, then argument lists can have 
    774774                /// different size and structure when they should be compatible.
    775775                struct TtypeExpander_new : public ast::WithShortCircuiting {
     
    800800                                auto types = flatten( d->get_type() );
    801801                                for ( ast::ptr< ast::Type > & t : types ) {
    802                                         // outermost const, volatile, _Atomic qualifiers in parameters should not play
    803                                         // a role in the unification of function types, since they do not determine
     802                                        // outermost const, volatile, _Atomic qualifiers in parameters should not play 
     803                                        // a role in the unification of function types, since they do not determine 
    804804                                        // whether a function is callable.
    805                                         // NOTE: **must** consider at least mutex qualifier, since functions can be
    806                                         // overloaded on outermost mutex and a mutex function has different
     805                                        // NOTE: **must** consider at least mutex qualifier, since functions can be 
     806                                        // overloaded on outermost mutex and a mutex function has different 
    807807                                        // requirements than a non-mutex function
    808808                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
     
    818818                        std::vector< ast::ptr< ast::Type > > types;
    819819                        while ( crnt != end ) {
    820                                 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
     820                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
    821821                                // that this results in a flat tuple
    822822                                flatten( (*crnt)->get_type(), types );
     
    829829
    830830                template< typename Iter >
    831                 static bool unifyDeclList(
    832                         Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
    833                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     831                static bool unifyDeclList( 
     832                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 
     833                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
    834834                        const ast::SymbolTable & symtab
    835835                ) {
     
    843843                                if ( isTuple1 && ! isTuple2 ) {
    844844                                        // combine remainder of list2, then unify
    845                                         return unifyExact(
    846                                                 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     845                                        return unifyExact( 
     846                                                t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
    847847                                                noWiden(), symtab );
    848848                                } else if ( ! isTuple1 && isTuple2 ) {
    849849                                        // combine remainder of list1, then unify
    850                                         return unifyExact(
    851                                                 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     850                                        return unifyExact( 
     851                                                tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
    852852                                                noWiden(), symtab );
    853853                                }
    854854
    855                                 if ( ! unifyExact(
    856                                         t1, t2, env, need, have, open, noWiden(), symtab )
     855                                if ( ! unifyExact( 
     856                                        t1, t2, env, need, have, open, noWiden(), symtab ) 
    857857                                ) return false;
    858858
     
    860860                        }
    861861
    862                         // May get to the end of one argument list before the other. This is only okay if the
     862                        // May get to the end of one argument list before the other. This is only okay if the 
    863863                        // other is a ttype
    864864                        if ( crnt1 != end1 ) {
     
    866866                                const ast::Type * t1 = (*crnt1)->get_type();
    867867                                if ( ! Tuples::isTtype( t1 ) ) return false;
    868                                 return unifyExact(
    869                                         t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     868                                return unifyExact( 
     869                                        t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
    870870                                        noWiden(), symtab );
    871871                        } else if ( crnt2 != end2 ) {
     
    873873                                const ast::Type * t2 = (*crnt2)->get_type();
    874874                                if ( ! Tuples::isTtype( t2 ) ) return false;
    875                                 return unifyExact(
    876                                         tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     875                                return unifyExact( 
     876                                        tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
    877877                                        noWiden(), symtab );
    878878                        }
     
    881881                }
    882882
    883                 static bool unifyDeclList(
    884                         const std::vector< ast::ptr< ast::DeclWithType > > & list1,
    885                         const std::vector< ast::ptr< ast::DeclWithType > > & list2,
    886                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     883                static bool unifyDeclList( 
     884                        const std::vector< ast::ptr< ast::DeclWithType > > & list1, 
     885                        const std::vector< ast::ptr< ast::DeclWithType > > & list2, 
     886                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
    887887                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
    888888                ) {
    889                         return unifyDeclList(
    890                                 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
     889                        return unifyDeclList( 
     890                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 
    891891                                symtab );
    892892                }
     
    900900
    901901                /// mark all assertions in `type` used in both `assn1` and `assn2`
    902                 static void markAssertions(
    903                         ast::AssertionSet & assn1, ast::AssertionSet & assn2,
    904                         const ast::ParameterizedType * type
     902                static void markAssertions( 
     903                        ast::AssertionSet & assn1, ast::AssertionSet & assn2, 
     904                        const ast::ParameterizedType * type 
    905905                ) {
    906906                        for ( const auto & tyvar : type->forall ) {
     
    918918
    919919                        if ( func->isVarArgs != func2->isVarArgs ) return;
    920 
    921                         // Flatten the parameter lists for both functions so that tuple structure does not
     920                       
     921                        // Flatten the parameter lists for both functions so that tuple structure does not 
    922922                        // affect unification. Does not actually mutate function parameters.
    923923                        auto params = flattenList( func->params, tenv );
    924924                        auto params2 = flattenList( func2->params, tenv );
    925925
    926                         // sizes don't have to match if ttypes are involved; need to be more precise w.r.t.
     926                        // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 
    927927                        // where the ttype is to prevent errors
    928                         if (
     928                        if ( 
    929929                                ( params.size() != params2.size() || func->returns.size() != func2->returns.size() )
    930930                                && ! func->isTtype()
     
    933933
    934934                        if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
    935                         if ( ! unifyDeclList(
     935                        if ( ! unifyDeclList( 
    936936                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
    937 
     937                       
    938938                        markAssertions( have, need, func );
    939939                        markAssertions( have, need, func2 );
     
    941941                        result = true;
    942942                }
    943 
     943       
    944944        private:
    945945                template< typename RefType >
     
    953953                /// Creates a tuple type based on a list of TypeExpr
    954954                template< typename Iter >
    955                 static const ast::Type * tupleFromExprs(
     955                static const ast::Type * tupleFromExprs( 
    956956                        const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs
    957957                ) {
     
    973973                        const RefType * inst2 = handleRefType( inst, other );
    974974                        if ( ! inst2 ) return;
    975 
     975                       
    976976                        // check that parameters of types unify, if any
    977977                        const std::vector< ast::ptr< ast::Expr > > & params = inst->params;
     
    10021002                                }
    10031003
    1004                                 if ( ! unifyExact(
     1004                                if ( ! unifyExact( 
    10051005                                                pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
    10061006                                        result = false;
     
    10381038        private:
    10391039                /// Creates a tuple type based on a list of Type
    1040                 static ast::ptr< ast::Type > tupleFromTypes(
     1040                static ast::ptr< ast::Type > tupleFromTypes( 
    10411041                        const std::vector< ast::ptr< ast::Type > > & tys
    10421042                ) {
    10431043                        std::vector< ast::ptr< ast::Type > > out;
    10441044                        for ( const ast::Type * ty : tys ) {
    1045                                 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
     1045                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
    10461046                                // that this results in a flat tuple
    10471047                                flatten( ty, out );
     
    10511051                }
    10521052
    1053                 static bool unifyList(
    1054                         const std::vector< ast::ptr< ast::Type > > & list1,
    1055                         const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
    1056                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     1053                static bool unifyList( 
     1054                        const std::vector< ast::ptr< ast::Type > > & list1, 
     1055                        const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 
     1056                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
    10571057                        const ast::SymbolTable & symtab
    10581058                ) {
     
    10681068                                if ( isTuple1 && ! isTuple2 ) {
    10691069                                        // combine entirety of list2, then unify
    1070                                         return unifyExact(
    1071                                                 t1, tupleFromTypes( list2 ), env, need, have, open,
     1070                                        return unifyExact( 
     1071                                                t1, tupleFromTypes( list2 ), env, need, have, open, 
    10721072                                                noWiden(), symtab );
    10731073                                } else if ( ! isTuple1 && isTuple2 ) {
    10741074                                        // combine entirety of list1, then unify
    10751075                                        return unifyExact(
    1076                                                 tupleFromTypes( list1 ), t2, env, need, have, open,
     1076                                                tupleFromTypes( list1 ), t2, env, need, have, open, 
    10771077                                                noWiden(), symtab );
    10781078                                }
    10791079
    1080                                 if ( ! unifyExact(
    1081                                         t1, t2, env, need, have, open, noWiden(), symtab )
     1080                                if ( ! unifyExact( 
     1081                                        t1, t2, env, need, have, open, noWiden(), symtab ) 
    10821082                                ) return false;
    10831083
     
    10891089                                const ast::Type * t1 = *crnt1;
    10901090                                if ( ! Tuples::isTtype( t1 ) ) return false;
    1091                                 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported
     1091                                // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
    10921092                                // from Rob's code
    1093                                 return unifyExact(
    1094                                                 t1, tupleFromTypes( list2 ), env, need, have, open,
     1093                                return unifyExact( 
     1094                                                t1, tupleFromTypes( list2 ), env, need, have, open, 
    10951095                                                noWiden(), symtab );
    10961096                        } else if ( crnt2 != list2.end() ) {
     
    10981098                                const ast::Type * t2 = *crnt2;
    10991099                                if ( ! Tuples::isTtype( t2 ) ) return false;
    1100                                 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported
     1100                                // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
    11011101                                // from Rob's code
    11021102                                return unifyExact(
    1103                                                 tupleFromTypes( list1 ), t2, env, need, have, open,
     1103                                                tupleFromTypes( list1 ), t2, env, need, have, open, 
    11041104                                                noWiden(), symtab );
    11051105                        }
     
    11331133                void postvisit( const ast::OneType * ) {
    11341134                        result = dynamic_cast< const ast::OneType * >( type2 );
    1135                 }
     1135                }       
    11361136
    11371137          private:
     
    11401140        };
    11411141
    1142         bool unify(
    1143                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    1144                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1142        bool unify( 
     1143                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
     1144                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
    11451145                        ast::OpenVarSet & open, const ast::SymbolTable & symtab
    11461146        ) {
     
    11491149        }
    11501150
    1151         bool unify(
    1152                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    1153                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1154                         ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
     1151        bool unify( 
     1152                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
     1153                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
     1154                        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 
    11551155        ) {
    11561156                ast::OpenVarSet closed;
    11571157                findOpenVars( type1, open, closed, need, have, FirstClosed );
    11581158                findOpenVars( type2, open, closed, need, have, FirstOpen );
    1159                 return unifyInexact(
     1159                return unifyInexact( 
    11601160                        type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
    11611161        }
    11621162
    1163         bool unifyExact(
    1164                         const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    1165                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     1163        bool unifyExact( 
     1164                        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
     1165                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
    11661166                        WidenMode widen, const ast::SymbolTable & symtab
    11671167        ) {
     
    11701170                auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
    11711171                auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
    1172                 ast::OpenVarSet::const_iterator
    1173                         entry1 = var1 ? open.find( var1->name ) : open.end(),
     1172                ast::OpenVarSet::const_iterator 
     1173                        entry1 = var1 ? open.find( var1->name ) : open.end(), 
    11741174                        entry2 = var2 ? open.find( var2->name ) : open.end();
    11751175                bool isopen1 = entry1 != open.end();
     
    11781178                if ( isopen1 && isopen2 ) {
    11791179                        if ( entry1->second.kind != entry2->second.kind ) return false;
    1180                         return env.bindVarToVar(
    1181                                 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have,
     1180                        return env.bindVarToVar( 
     1181                                var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 
    11821182                                open, widen, symtab );
    11831183                } else if ( isopen1 ) {
     
    11921192        }
    11931193
    1194         bool unifyInexact(
    1195                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    1196                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1197                         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
    1198                         ast::ptr<ast::Type> & common
     1194        bool unifyInexact( 
     1195                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
     1196                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
     1197                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 
     1198                        ast::ptr<ast::Type> & common 
    11991199        ) {
    12001200                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
    1201 
    1202                 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and
     1201               
     1202                // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 
    12031203                // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
    12041204                ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
    12051205                reset_qualifiers( t1 );
    12061206                reset_qualifiers( t2 );
    1207 
     1207               
    12081208                if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
    12091209                        t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones
  • src/ResolvExpr/typeops.h

    r4eb43fa rf6cc734e  
    2828#include "SynTree/SynTree.h"
    2929#include "SynTree/Type.h"
    30 
    31 namespace SymTab {
    32         class Indexer;
    33 }
     30#include "SymTab/Indexer.h"
    3431
    3532namespace ResolvExpr {
     
    6360        // in AdjustExprType.cc
    6461        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
    65         void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     62        void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    6663
    6764        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
     
    6966
    7067        template< typename ForwardIterator >
    71         void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
     68        void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    7269                while ( begin != end ) {
    7370                        adjustExprType( *begin++, env, indexer );
     
    7673
    7774        /// Replaces array types with equivalent pointer, and function types with a pointer-to-function
    78         const ast::Type * adjustExprType(
     75        const ast::Type * adjustExprType( 
    7976                const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
    8077
    8178        // in CastCost.cc
    82         Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    83         Cost castCost(
    84                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     79        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     80        Cost castCost( 
     81                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
    8582                const ast::TypeEnvironment & env );
    8683
    8784        // in ConversionCost.cc
    88         Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    89         Cost conversionCost(
    90                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     85        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     86        Cost conversionCost( 
     87                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
    9188                const ast::TypeEnvironment & env );
    9289
    9390        // in AlternativeFinder.cc
    94         Cost computeConversionCost( Type * actualType, Type * formalType,
    95                 const SymTab::Indexer & indexer, const TypeEnvironment & env );
     91        Cost computeConversionCost( Type *actualType, Type *formalType,
     92                const SymTab::Indexer &indexer, const TypeEnvironment &env );
    9693
    9794        // in PtrsAssignable.cc
    98         int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
     95        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
    9996        int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
    10097                const ast::TypeEnvironment & env );
    10198
    10299        // in PtrsCastable.cc
    103         int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    104         int ptrsCastable(
    105                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     100        int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     101        int ptrsCastable( 
     102                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
    106103                const ast::TypeEnvironment & env );
    107104
    108105        // in Unify.cc
    109         bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    110         bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    111 
    112         inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
     106        bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     107        bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     108
     109        inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
    113110                TypeEnvironment env;
    114111                return typesCompatible( t1, t2, indexer, env );
    115112        }
    116113
    117         inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
     114        inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
    118115                TypeEnvironment env;
    119116                return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
    120117        }
    121118
    122         bool typesCompatible(
    123                 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
     119        bool typesCompatible( 
     120                const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 
    124121                const ast::TypeEnvironment & env = {} );
    125 
     122       
    126123        bool typesCompatibleIgnoreQualifiers(
    127                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     124                const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
    128125                const ast::TypeEnvironment & env = {} );
    129126
     
    134131
    135132        // in CommonType.cc
    136         Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
     133        Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    137134        ast::ptr< ast::Type > commonType(
    138                 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen,
     135                const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 
    139136                const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open );
    140137
    141138        // in PolyCost.cc
    142         int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    143         int polyCost(
     139        int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     140        int polyCost( 
    144141                const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    145142
    146143        // in SpecCost.cc
    147         int specCost( Type * type );
     144        int specCost( Type *type );
    148145        int specCost( const ast::Type * type );
    149146
    150147        // in Occurs.cc
    151         bool occurs( Type * type, std::string varName, const TypeEnvironment & env );
     148        bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
    152149        // new AST version in TypeEnvironment.cpp (only place it was used in old AST)
    153150
    154         template<typename Iter>
    155         bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {
     151        template<typename Iter> 
     152        bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) {
    156153                while ( begin != end ) {
    157154                        if ( occurs( ty, *begin, env ) ) return true;
     
    179176
    180177        /// flatten tuple type into existing list of types
    181         static inline void flatten(
    182                 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out
     178        static inline void flatten( 
     179                const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 
    183180        ) {
    184                 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {
     181                if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {       
    185182                        for ( const ast::Type * t : tupleType->types ) {
    186183                                flatten( t, out );
     
    200197
    201198        // in TypeEnvironment.cc
    202         bool isFtype( Type * type );
     199        bool isFtype( Type *type );
    203200} // namespace ResolvExpr
    204201
  • src/SymTab/Indexer.cc

    r4eb43fa rf6cc734e  
    7474        }
    7575
    76         Indexer::Indexer()
    77         : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
    78           prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }
     76        Indexer::Indexer() 
     77        : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
     78          prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
    7979
    8080        Indexer::~Indexer() {
     
    8484        void Indexer::lazyInitScope() {
    8585                if ( repScope < scope ) {
    86                         ++* stats().lazy_scopes;
     86                        ++*stats().lazy_scopes;
    8787                        // create rollback
    88                         prevScope = std::make_shared<Indexer>( * this );
     88                        prevScope = std::make_shared<Indexer>( *this );
    8989                        // update repScope
    9090                        repScope = scope;
     
    9595                ++scope;
    9696
    97                 ++* stats().new_scopes;
     97                ++*stats().new_scopes;
    9898                stats().avg_scope_depth->push( scope );
    9999                stats().max_scope_depth->push( scope );
     
    103103                if ( repScope == scope ) {
    104104                        Ptr prev = prevScope;           // make sure prevScope stays live
    105                         * this = std::move(* prevScope);  // replace with previous scope
     105                        *this = std::move(*prevScope);  // replace with previous scope
    106106                }
    107107
     
    109109        }
    110110
    111         void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const {
    112                 ++* stats().lookup_calls;
     111        void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
     112                ++*stats().lookup_calls;
    113113                if ( ! idTable ) return;
    114114
    115                 ++* stats().map_lookups;
     115                ++*stats().map_lookups;
    116116                auto decls = idTable->find( id );
    117117                if ( decls == idTable->end() ) return;
     
    122122        }
    123123
    124         const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const {
    125                 ++* stats().lookup_calls;
     124        NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
     125                ++*stats().lookup_calls;
    126126                if ( ! typeTable ) return nullptr;
    127                 ++* stats().map_lookups;
     127                ++*stats().map_lookups;
    128128                auto it = typeTable->find( id );
    129129                return it == typeTable->end() ? nullptr : it->second.decl;
    130130        }
    131131
    132         const StructDecl * Indexer::lookupStruct( const std::string & id ) const {
    133                 ++* stats().lookup_calls;
     132        StructDecl *Indexer::lookupStruct( const std::string &id ) const {
     133                ++*stats().lookup_calls;
    134134                if ( ! structTable ) return nullptr;
    135                 ++* stats().map_lookups;
     135                ++*stats().map_lookups;
    136136                auto it = structTable->find( id );
    137137                return it == structTable->end() ? nullptr : it->second.decl;
    138138        }
    139139
    140         const EnumDecl * Indexer::lookupEnum( const std::string & id ) const {
    141                 ++* stats().lookup_calls;
     140        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
     141                ++*stats().lookup_calls;
    142142                if ( ! enumTable ) return nullptr;
    143                 ++* stats().map_lookups;
     143                ++*stats().map_lookups;
    144144                auto it = enumTable->find( id );
    145145                return it == enumTable->end() ? nullptr : it->second.decl;
    146146        }
    147147
    148         const UnionDecl * Indexer::lookupUnion( const std::string & id ) const {
    149                 ++* stats().lookup_calls;
     148        UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
     149                ++*stats().lookup_calls;
    150150                if ( ! unionTable ) return nullptr;
    151                 ++* stats().map_lookups;
     151                ++*stats().map_lookups;
    152152                auto it = unionTable->find( id );
    153153                return it == unionTable->end() ? nullptr : it->second.decl;
    154154        }
    155155
    156         const TraitDecl * Indexer::lookupTrait( const std::string & id ) const {
    157                 ++* stats().lookup_calls;
     156        TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
     157                ++*stats().lookup_calls;
    158158                if ( ! traitTable ) return nullptr;
    159                 ++* stats().map_lookups;
     159                ++*stats().map_lookups;
    160160                auto it = traitTable->find( id );
    161161                return it == traitTable->end() ? nullptr : it->second.decl;
    162162        }
    163163
    164         const Indexer * Indexer::atScope( unsigned long target ) const {
     164        const Indexer* Indexer::atScope( unsigned long target ) const {
    165165                // by lazy construction, final indexer in list has repScope 0, cannot be > target
    166166                // otherwise, will find first scope representing the target
    167                 const Indexer * indexer = this;
     167                const Indexer* indexer = this;
    168168                while ( indexer->repScope > target ) {
    169169                        indexer = indexer->prevScope.get();
     
    172172        }
    173173
    174         const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const {
     174        NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
    175175                return atScope( 0 )->lookupType( id );
    176176        }
    177177
    178         const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const {
     178        StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
    179179                return atScope( 0 )->lookupStruct( id );
    180180        }
    181181
    182         const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const {
     182        UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {
    183183                return atScope( 0 )->lookupUnion( id );
    184184        }
    185185
    186         const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const {
     186        EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {
    187187                return atScope( 0 )->lookupEnum( id );
    188188        }
    189189
    190         bool isFunction( const DeclarationWithType * decl ) {
     190        bool isFunction( DeclarationWithType * decl ) {
    191191                return GenPoly::getFunctionType( decl->get_type() );
    192192        }
    193193
    194         bool isObject( const DeclarationWithType * decl ) {
     194        bool isObject( DeclarationWithType * decl ) {
    195195                return ! isFunction( decl );
    196196        }
    197197
    198         bool isDefinition( const DeclarationWithType * decl ) {
    199                 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
     198        bool isDefinition( DeclarationWithType * decl ) {
     199                if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
    200200                        // a function is a definition if it has a body
    201201                        return func->statements;
     
    207207        }
    208208
    209 
    210         bool Indexer::addedIdConflicts(
    211                         const Indexer::IdData & existing, const DeclarationWithType * added,
    212                         Indexer::OnConflict handleConflicts, const Declaration * deleteStmt ) {
    213                 // if we're giving the same name mangling to things of different types then there is
     209       
     210        bool Indexer::addedIdConflicts( 
     211                        const Indexer::IdData & existing, DeclarationWithType *added,
     212                        Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) {
     213                // if we're giving the same name mangling to things of different types then there is 
    214214                // something wrong
    215215                assert( (isObject( added ) && isObject( existing.id ) )
     
    219219                        // new definition shadows the autogenerated one, even at the same scope
    220220                        return false;
    221                 } else if ( LinkageSpec::isMangled( added->linkage )
    222                                 || ResolvExpr::typesCompatible(
     221                } else if ( LinkageSpec::isMangled( added->linkage ) 
     222                                || ResolvExpr::typesCompatible( 
    223223                                        added->get_type(), existing.id->get_type(), Indexer() ) ) {
    224224
     
    238238                        if ( isDefinition( added ) && isDefinition( existing.id ) ) {
    239239                                if ( handleConflicts.mode == OnConflict::Error ) {
    240                                         SemanticError( added,
    241                                                 isFunction( added ) ?
    242                                                         "duplicate function definition for " :
     240                                        SemanticError( added, 
     241                                                isFunction( added ) ? 
     242                                                        "duplicate function definition for " : 
    243243                                                        "duplicate object definition for " );
    244244                                }
     
    255255        }
    256256
    257         bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const {
     257        bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
    258258                if ( ! idTable ) return false;
    259259
    260                 ++* stats().map_lookups;
     260                ++*stats().map_lookups;
    261261                auto decls = idTable->find( id );
    262262                if ( decls == idTable->end() ) return false;
     
    270270                        }
    271271                }
    272 
     272               
    273273                return false;
    274274        }
    275275
    276         bool Indexer::hasIncompatibleCDecl(const std::string & id, const std::string &mangleName ) const {
     276        bool Indexer::hasIncompatibleCDecl(
     277                        const std::string &id, const std::string &mangleName ) const {
    277278                if ( ! idTable ) return false;
    278279
    279                 ++* stats().map_lookups;
     280                ++*stats().map_lookups;
    280281                auto decls = idTable->find( id );
    281282                if ( decls == idTable->end() ) return false;
     
    294295
    295296        /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
    296         std::string getOtypeKey( const FunctionDecl * function ) {
     297        std::string getOtypeKey( FunctionDecl* function ) {
    297298                auto& params = function->type->parameters;
    298299                assert( ! params.empty() );
    299300                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    300                 Type * base = InitTweak::getPointerBase( params.front()->get_type() );
     301                Type* base = InitTweak::getPointerBase( params.front()->get_type() );
    301302                assert( base );
    302303                return Mangler::mangle( base );
    303304        }
    304305
    305         /// gets the declaration for the function acting on a type specified by otype key,
     306        /// gets the declaration for the function acting on a type specified by otype key, 
    306307        /// nullptr if none such
    307         const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) {
    308                 const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl );
     308        FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) {
     309                FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl );
    309310                if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
    310311                return func;
    311312        }
    312313
    313         bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
    314                 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which
    315                 // determinethe set of ctor/dtor/assign that can be used  by the requester. In particular,
    316                 // if the user defines a default ctor, then the generated default ctor is unavailable,
    317                 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
    318                 // field ctors are available. If the user defines any ctor then the generated default ctor
    319                 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
    320                 // anything that looks like a copy constructor, then the generated copy constructor is
     314        bool Indexer::removeSpecialOverrides(
     315                        Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
     316                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which
     317                // determinethe set of ctor/dtor/assign that can be used  by the requester. In particular,
     318                // if the user defines a default ctor, then the generated default ctor is unavailable,
     319                // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
     320                // field ctors are available. If the user defines any ctor then the generated default ctor
     321                // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
     322                // anything that looks like a copy constructor, then the generated copy constructor is
    321323                // unavailable, and likewise for the assignment operator.
    322324
    323325                // only relevant on function declarations
    324                 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id );
     326                FunctionDecl * function = dynamic_cast< FunctionDecl * >( data.id );
    325327                if ( ! function ) return true;
    326328                // only need to perform this check for constructors, destructors, and assignment functions
     
    338340                        std::vector< MangleTable::value_type > deleted;
    339341                        bool alreadyUserDefinedFunc = false;
    340 
    341                         for ( const auto& entry : * mangleTable ) {
     342                       
     343                        for ( const auto& entry : *mangleTable ) {
    342344                                // skip decls that aren't functions or are for the wrong type
    343                                 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     345                                FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
    344346                                if ( ! decl ) continue;
    345347
     
    366368                        // perform removals from mangle table, and deletions if necessary
    367369                        for ( const auto& key : removed ) {
    368                                 ++* stats().map_mutations;
     370                                ++*stats().map_mutations;
    369371                                mangleTable = mangleTable->erase( key );
    370372                        }
    371373                        if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
    372                                 ++* stats().map_mutations;
     374                                ++*stats().map_mutations;
    373375                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
    374376                        }
     
    377379                        // if this is the first user-defined function, delete non-user-defined overloads
    378380                        std::vector< MangleTable::value_type > deleted;
    379 
    380                         for ( const auto& entry : * mangleTable ) {
     381                       
     382                        for ( const auto& entry : *mangleTable ) {
    381383                                // skip decls that aren't functions or are for the wrong type
    382                                 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     384                                FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
    383385                                if ( ! decl ) continue;
    384386
     
    400402                        // this needs to be a separate loop because of iterator invalidation
    401403                        for ( const auto& entry : deleted ) {
    402                                 ++* stats().map_mutations;
     404                                ++*stats().map_mutations;
    403405                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
    404406                        }
     
    406408                        // this is an overridable generated function
    407409                        // if there already exists a matching user-defined function, delete this appropriately
    408                         for ( const auto& entry : * mangleTable ) {
     410                        for ( const auto& entry : *mangleTable ) {
    409411                                // skip decls that aren't functions or are for the wrong type
    410                                 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     412                                FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
    411413                                if ( ! decl ) continue;
    412414
     
    416418                                if ( dataIsCopyFunc ) {
    417419                                        // remove current function if exists a user-defined copy function
    418                                         // since the signatures for copy functions don't need to match exactly, using
     420                                        // since the signatures for copy functions don't need to match exactly, using 
    419421                                        // a delete statement is the wrong approach
    420422                                        if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false;
     
    426428                        }
    427429                }
    428 
     430               
    429431                // nothing (more) to fix, return true
    430432                return true;
    431433        }
    432434
    433         void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr,
    434                         const Declaration * deleteStmt ) {
    435                 ++* stats().add_calls;
     435        void Indexer::addId(
     436                        DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr,
     437                        BaseSyntaxNode * deleteStmt ) {
     438                ++*stats().add_calls;
    436439                const std::string &name = decl->name;
    437440                if ( name == "" ) return;
    438 
     441               
    439442                std::string mangleName;
    440443                if ( LinkageSpec::isOverridable( decl->linkage ) ) {
    441                         // mangle the name without including the appropriate suffix, so overridable routines
     444                        // mangle the name without including the appropriate suffix, so overridable routines 
    442445                        // are placed into the same "bucket" as their user defined versions.
    443446                        mangleName = Mangler::mangle( decl, false );
     
    446449                } // if
    447450
    448                 // this ensures that no two declarations with the same unmangled name at the same scope
     451                // this ensures that no two declarations with the same unmangled name at the same scope 
    449452                // both have C linkage
    450453                if ( LinkageSpec::isMangled( decl->linkage ) ) {
     
    454457                        }
    455458                } else {
    456                         // NOTE: only correct if name mangling is completely isomorphic to C
     459                        // NOTE: only correct if name mangling is completely isomorphic to C 
    457460                        // type-compatibility, which it may not be.
    458461                        if ( hasIncompatibleCDecl( name, mangleName ) ) {
     
    467470                        mangleTable = MangleTable::new_ptr();
    468471                } else {
    469                         ++* stats().map_lookups;
     472                        ++*stats().map_lookups;
    470473                        auto decls = idTable->find( name );
    471474                        if ( decls == idTable->end() ) {
     
    474477                                mangleTable = decls->second;
    475478                                // skip in-scope repeat declarations of same identifier
    476                                 ++* stats().map_lookups;
     479                                ++*stats().map_lookups;
    477480                                auto existing = mangleTable->find( mangleName );
    478481                                if ( existing != mangleTable->end()
     
    483486                                                        // set delete expression for conflicting identifier
    484487                                                        lazyInitScope();
    485                                                         * stats().map_mutations += 2;
     488                                                        *stats().map_mutations += 2;
    486489                                                        idTable = idTable->set(
    487490                                                                name,
    488                                                                 mangleTable->set(
    489                                                                         mangleName,
     491                                                                mangleTable->set( 
     492                                                                        mangleName, 
    490493                                                                        IdData{ existing->second, handleConflicts.deleteStmt } ) );
    491494                                                }
     
    501504                // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
    502505                if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
    503                 * stats().map_mutations += 2;
     506                *stats().map_mutations += 2;
    504507                idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
    505508        }
    506509
    507         void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) {
     510        void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
    508511                // default handling of conflicts is to raise an error
    509512                addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
    510513        }
    511514
    512         void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ) {
     515        void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
    513516                // default handling of conflicts is to raise an error
    514517                addId( decl, OnConflict::error(), nullptr, deleteStmt );
    515518        }
    516519
    517         bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) {
     520        bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
    518521                if ( existing->base == nullptr ) {
    519522                        return false;
     
    527530                        }
    528531                }
    529                 // does not need to be added to the table if both existing and added have a base that are
     532                // does not need to be added to the table if both existing and added have a base that are 
    530533                // the same
    531534                return true;
    532535        }
    533536
    534         void Indexer::addType( const NamedTypeDecl * decl ) {
    535                 ++* stats().add_calls;
    536                 const std::string & id = decl->name;
    537 
    538                 if ( ! typeTable ) {
     537        void Indexer::addType( NamedTypeDecl *decl ) {
     538                ++*stats().add_calls;
     539                const std::string &id = decl->name;
     540
     541                if ( ! typeTable ) { 
    539542                        typeTable = TypeTable::new_ptr();
    540543                } else {
    541                         ++* stats().map_lookups;
     544                        ++*stats().map_lookups;
    542545                        auto existing = typeTable->find( id );
    543                         if ( existing != typeTable->end()
    544                                 && existing->second.scope == scope
     546                        if ( existing != typeTable->end() 
     547                                && existing->second.scope == scope 
    545548                                && addedTypeConflicts( existing->second.decl, decl ) ) return;
    546549                }
    547 
     550               
    548551                lazyInitScope();
    549                 ++* stats().map_mutations;
     552                ++*stats().map_mutations;
    550553                typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } );
    551554        }
    552555
    553         bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) {
     556        bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
    554557                if ( ! existing->body ) {
    555558                        return false;
     
    560563        }
    561564
    562         void Indexer::addStruct( const std::string & id ) {
     565        void Indexer::addStruct( const std::string &id ) {
    563566                addStruct( new StructDecl( id ) );
    564567        }
    565568
    566         void Indexer::addStruct( const StructDecl * decl ) {
    567                 ++* stats().add_calls;
    568                 const std::string & id = decl->name;
     569        void Indexer::addStruct( StructDecl *decl ) {
     570                ++*stats().add_calls;
     571                const std::string &id = decl->name;
    569572
    570573                if ( ! structTable ) {
    571574                        structTable = StructTable::new_ptr();
    572575                } else {
    573                         ++* stats().map_lookups;
     576                        ++*stats().map_lookups;
    574577                        auto existing = structTable->find( id );
    575                         if ( existing != structTable->end()
    576                                 && existing->second.scope == scope
     578                        if ( existing != structTable->end() 
     579                                && existing->second.scope == scope 
    577580                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
    578581                }
    579582
    580583                lazyInitScope();
    581                 ++* stats().map_mutations;
     584                ++*stats().map_mutations;
    582585                structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } );
    583586        }
    584587
    585         void Indexer::addEnum( const EnumDecl * decl ) {
    586                 ++* stats().add_calls;
    587                 const std::string & id = decl->name;
     588        void Indexer::addEnum( EnumDecl *decl ) {
     589                ++*stats().add_calls;
     590                const std::string &id = decl->name;
    588591
    589592                if ( ! enumTable ) {
    590593                        enumTable = EnumTable::new_ptr();
    591594                } else {
    592                         ++* stats().map_lookups;
     595                        ++*stats().map_lookups;
    593596                        auto existing = enumTable->find( id );
    594                         if ( existing != enumTable->end()
    595                                 && existing->second.scope == scope
     597                        if ( existing != enumTable->end() 
     598                                && existing->second.scope == scope 
    596599                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
    597600                }
    598 
     601               
    599602                lazyInitScope();
    600                 ++* stats().map_mutations;
     603                ++*stats().map_mutations;
    601604                enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } );
    602605        }
    603606
    604         void Indexer::addUnion( const std::string & id ) {
     607        void Indexer::addUnion( const std::string &id ) {
    605608                addUnion( new UnionDecl( id ) );
    606609        }
    607610
    608         void Indexer::addUnion( const UnionDecl * decl ) {
    609                 ++* stats().add_calls;
    610                 const std::string & id = decl->name;
     611        void Indexer::addUnion( UnionDecl *decl ) {
     612                ++*stats().add_calls;
     613                const std::string &id = decl->name;
    611614
    612615                if ( ! unionTable ) {
    613616                        unionTable = UnionTable::new_ptr();
    614617                } else {
    615                         ++* stats().map_lookups;
     618                        ++*stats().map_lookups;
    616619                        auto existing = unionTable->find( id );
    617                         if ( existing != unionTable->end()
    618                                 && existing->second.scope == scope
     620                        if ( existing != unionTable->end() 
     621                                && existing->second.scope == scope 
    619622                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
    620623                }
    621624
    622625                lazyInitScope();
    623                 ++* stats().map_mutations;
     626                ++*stats().map_mutations;
    624627                unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } );
    625628        }
    626629
    627         void Indexer::addTrait( const TraitDecl * decl ) {
    628                 ++* stats().add_calls;
    629                 const std::string & id = decl->name;
     630        void Indexer::addTrait( TraitDecl *decl ) {
     631                ++*stats().add_calls;
     632                const std::string &id = decl->name;
    630633
    631634                if ( ! traitTable ) {
    632635                        traitTable = TraitTable::new_ptr();
    633636                } else {
    634                         ++* stats().map_lookups;
     637                        ++*stats().map_lookups;
    635638                        auto existing = traitTable->find( id );
    636                         if ( existing != traitTable->end()
    637                                 && existing->second.scope == scope
     639                        if ( existing != traitTable->end() 
     640                                && existing->second.scope == scope 
    638641                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
    639642                }
    640643
    641644                lazyInitScope();
    642                 ++* stats().map_mutations;
     645                ++*stats().map_mutations;
    643646                traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } );
    644647        }
    645648
    646         void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) {
     649        void Indexer::addMembers( AggregateDecl * aggr, Expression * expr,
     650                        OnConflict handleConflicts ) {
    647651                for ( Declaration * decl : aggr->members ) {
    648652                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    649653                                addId( dwt, handleConflicts, expr );
    650654                                if ( dwt->name == "" ) {
    651                                         const Type * t = dwt->get_type()->stripReferences();
    652                                         if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) {
     655                                        Type * t = dwt->get_type()->stripReferences();
     656                                        if ( dynamic_cast<StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {
    653657                                                Expression * base = expr->clone();
    654658                                                ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
     
    661665        }
    662666
    663         void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ) {
    664                 for ( const Expression * expr : withExprs ) {
     667        void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) {
     668                for ( Expression * expr : withExprs ) {
    665669                        if ( expr->result ) {
    666670                                AggregateDecl * aggr = expr->result->stripReferences()->getAggr();
     
    685689        }
    686690
    687         void Indexer::addFunctionType( const FunctionType * ftype ) {
     691        void Indexer::addFunctionType( FunctionType * ftype ) {
    688692                addTypes( ftype->forall );
    689693                addIds( ftype->returnVals );
     
    696700                        Expression * base = baseExpr->clone();
    697701                        ResolvExpr::referenceToRvalueConversion( base, cost );
    698                         ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base );
     702                        ret = new MemberExpr( id, base );
    699703                        // xxx - this introduces hidden environments, for now remove them.
    700704                        // std::swap( base->env, ret->env );
     
    702706                        base->env = nullptr;
    703707                } else {
    704                         ret = new VariableExpr( const_cast<DeclarationWithType *>(id) );
    705                 }
    706                 if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<Declaration *>(deleteStmt) );
     708                        ret = new VariableExpr( id );
     709                }
     710                if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt );
    707711                return ret;
    708712        }
  • src/SymTab/Indexer.h

    r4eb43fa rf6cc734e  
    3434                virtual ~Indexer();
    3535
    36                 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to
     36                // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
    3737                // tell the indexer explicitly when scopes begin and end
    3838                void enterScope();
     
    4040
    4141                struct IdData {
    42                         const DeclarationWithType * id = nullptr;
    43                         const Expression * baseExpr = nullptr; // WithExpr
     42                        DeclarationWithType * id = nullptr;
     43                        Expression * baseExpr = nullptr; // WithExpr
    4444
    4545                        /// non-null if this declaration is deleted
    46                         const Declaration * deleteStmt = nullptr;
     46                        BaseSyntaxNode * deleteStmt = nullptr;
    4747                        /// scope of identifier
    4848                        unsigned long scope = 0;
     
    5050                        // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
    5151                        IdData() = default;
    52                         IdData(
    53                                 const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt,
    54                                 unsigned long scope )
     52                        IdData( 
     53                                DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt,
     54                                unsigned long scope ) 
    5555                                : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
    56                         IdData( const IdData& o, const Declaration * deleteStmt )
     56                        IdData( const IdData& o, BaseSyntaxNode * deleteStmt )
    5757                                : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {}
    5858
     
    6161
    6262                /// Gets all declarations with the given ID
    63                 void lookupId( const std::string & id, std::list< IdData > &out ) const;
     63                void lookupId( const std::string &id, std::list< IdData > &out ) const;
    6464                /// Gets the top-most type declaration with the given ID
    65                 const NamedTypeDecl * lookupType( const std::string & id ) const;
     65                NamedTypeDecl *lookupType( const std::string &id ) const;
    6666                /// Gets the top-most struct declaration with the given ID
    67                 const StructDecl * lookupStruct( const std::string & id ) const;
     67                StructDecl *lookupStruct( const std::string &id ) const;
    6868                /// Gets the top-most enum declaration with the given ID
    69                 const EnumDecl * lookupEnum( const std::string & id ) const;
     69                EnumDecl *lookupEnum( const std::string &id ) const;
    7070                /// Gets the top-most union declaration with the given ID
    71                 const UnionDecl * lookupUnion( const std::string & id ) const;
     71                UnionDecl *lookupUnion( const std::string &id ) const;
    7272                /// Gets the top-most trait declaration with the given ID
    73                 const TraitDecl * lookupTrait( const std::string & id ) const;
     73                TraitDecl *lookupTrait( const std::string &id ) const;
    7474
    7575                /// Gets the type declaration with the given ID at global scope
    76                 const NamedTypeDecl * globalLookupType( const std::string & id ) const;
     76                NamedTypeDecl *globalLookupType( const std::string &id ) const;
    7777                /// Gets the struct declaration with the given ID at global scope
    78                 const StructDecl * globalLookupStruct( const std::string & id ) const;
     78                StructDecl *globalLookupStruct( const std::string &id ) const;
    7979                /// Gets the union declaration with the given ID at global scope
    80                 const UnionDecl * globalLookupUnion( const std::string & id ) const;
     80                UnionDecl *globalLookupUnion( const std::string &id ) const;
    8181                /// Gets the enum declaration with the given ID at global scope
    82                 const EnumDecl * globalLookupEnum( const std::string & id ) const;
     82                EnumDecl *globalLookupEnum( const std::string &id ) const;
    8383
    84                 void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr );
    85                 void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt );
     84                void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
     85                void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
    8686
    87                 void addType( const NamedTypeDecl * decl );
    88                 void addStruct( const std::string & id );
    89                 void addStruct( const StructDecl * decl );
    90                 void addEnum( const EnumDecl * decl );
    91                 void addUnion( const std::string & id );
    92                 void addUnion( const UnionDecl * decl );
    93                 void addTrait( const TraitDecl * decl );
     87                void addType( NamedTypeDecl *decl );
     88                void addStruct( const std::string &id );
     89                void addStruct( StructDecl *decl );
     90                void addEnum( EnumDecl *decl );
     91                void addUnion( const std::string &id );
     92                void addUnion( UnionDecl *decl );
     93                void addTrait( TraitDecl *decl );
    9494
    9595                /// adds all of the IDs from WithStmt exprs
    96                 void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt );
     96                void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
    9797
    9898                /// convenience function for adding a list of Ids to the indexer
     
    103103
    104104                /// convenience function for adding all of the declarations in a function type to the indexer
    105                 void addFunctionType( const FunctionType * ftype );
     105                void addFunctionType( FunctionType * ftype );
    106106
    107107          private:
    108                 /// Wraps a Decl * with a scope
     108                /// Wraps a Decl* with a scope
    109109                template<typename Decl>
    110110                struct Scoped {
    111                         const Decl * decl;           ///< declaration
     111                        Decl* decl;           ///< declaration
    112112                        unsigned long scope;  ///< scope of this declaration
    113113
    114                         Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {}
     114                        Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {}
    115115                };
    116116
     
    140140
    141141                /// Gets the indexer at the given scope
    142                 const Indexer * atScope( unsigned long scope ) const;
     142                const Indexer* atScope( unsigned long scope ) const;
    143143
    144                 /// Removes matching autogenerated constructors and destructors so that they will not be
     144                /// Removes matching autogenerated constructors and destructors so that they will not be 
    145145                /// selected. If returns false, passed decl should not be added.
    146                 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
     146                bool removeSpecialOverrides( IdData& decl, MangleTable::Ptr& mangleTable );
    147147
    148148                /// Options for handling identifier conflicts
     
    152152                                Delete  ///< Delete the earlier version with the delete statement
    153153                        } mode;
    154                         const Declaration * deleteStmt;  ///< Statement that deletes this expression
     154                        BaseSyntaxNode * deleteStmt;  ///< Statement that deletes this expression
    155155
    156156                private:
    157157                        OnConflict() : mode(Error), deleteStmt(nullptr) {}
    158                         OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {}
     158                        OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {}
    159159                public:
    160160                        OnConflict( const OnConflict& ) = default;
    161161
    162162                        static OnConflict error() { return {}; }
    163                         static OnConflict deleteWith( const Declaration * d ) { return { d }; }
     163                        static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; }
    164164                };
    165165
    166166                /// true if the existing identifier conflicts with the added identifier
    167167                bool addedIdConflicts(
    168                         const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts,
    169                         const Declaration * deleteStmt );
     168                        const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts,
     169                        BaseSyntaxNode * deleteStmt );
    170170
    171171                /// common code for addId, addDeletedId, etc.
    172                 void addId(const DeclarationWithType * decl, OnConflict handleConflicts,
    173                         const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr );
     172                void addId(
     173                        DeclarationWithType * decl, OnConflict handleConflicts,
     174                        Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
    174175
    175176                /// adds all of the members of the Aggregate (addWith helper)
    176                 void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts );
     177                void addMembers( AggregateDecl * aggr, Expression * expr, OnConflict handleConflicts );
    177178
    178179                /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
    179                 bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
     180                bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
    180181                /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
    181                 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
     182                bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
    182183        };
    183184} // namespace SymTab
  • src/SymTab/Mangler.cc

    r4eb43fa rf6cc734e  
    4242                                Mangler_old( const Mangler_old & ) = delete;
    4343
    44                                 void previsit( const BaseSyntaxNode * ) { visit_children = false; }
    45 
    46                                 void postvisit( const ObjectDecl * declaration );
    47                                 void postvisit( const FunctionDecl * declaration );
    48                                 void postvisit( const TypeDecl * declaration );
    49 
    50                                 void postvisit( const VoidType * voidType );
    51                                 void postvisit( const BasicType * basicType );
    52                                 void postvisit( const PointerType * pointerType );
    53                                 void postvisit( const ArrayType * arrayType );
    54                                 void postvisit( const ReferenceType * refType );
    55                                 void postvisit( const FunctionType * functionType );
    56                                 void postvisit( const StructInstType * aggregateUseType );
    57                                 void postvisit( const UnionInstType * aggregateUseType );
    58                                 void postvisit( const EnumInstType * aggregateUseType );
    59                                 void postvisit( const TypeInstType * aggregateUseType );
    60                                 void postvisit( const TraitInstType * inst );
    61                                 void postvisit( const TupleType * tupleType );
    62                                 void postvisit( const VarArgsType * varArgsType );
    63                                 void postvisit( const ZeroType * zeroType );
    64                                 void postvisit( const OneType * oneType );
    65                                 void postvisit( const QualifiedType * qualType );
     44                                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     45
     46                                void postvisit( ObjectDecl * declaration );
     47                                void postvisit( FunctionDecl * declaration );
     48                                void postvisit( TypeDecl * declaration );
     49
     50                                void postvisit( VoidType * voidType );
     51                                void postvisit( BasicType * basicType );
     52                                void postvisit( PointerType * pointerType );
     53                                void postvisit( ArrayType * arrayType );
     54                                void postvisit( ReferenceType * refType );
     55                                void postvisit( FunctionType * functionType );
     56                                void postvisit( StructInstType * aggregateUseType );
     57                                void postvisit( UnionInstType * aggregateUseType );
     58                                void postvisit( EnumInstType * aggregateUseType );
     59                                void postvisit( TypeInstType * aggregateUseType );
     60                                void postvisit( TraitInstType * inst );
     61                                void postvisit( TupleType * tupleType );
     62                                void postvisit( VarArgsType * varArgsType );
     63                                void postvisit( ZeroType * zeroType );
     64                                void postvisit( OneType * oneType );
     65                                void postvisit( QualifiedType * qualType );
    6666
    6767                                std::string get_mangleName() { return mangleName.str(); }
     
    7979
    8080                          public:
    81                                 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     81                                Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
    8282                                        int nextVarNum, const VarMapType& varNums );
    8383
    8484                          private:
    85                                 void mangleDecl( const DeclarationWithType * declaration );
    86                                 void mangleRef( const ReferenceToType * refType, std::string prefix );
    87 
    88                                 void printQualifiers( const Type *type );
     85                                void mangleDecl( DeclarationWithType *declaration );
     86                                void mangleRef( ReferenceToType *refType, std::string prefix );
     87
     88                                void printQualifiers( Type *type );
    8989                        }; // Mangler_old
    9090                } // namespace
    9191
    92                 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
     92                std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
    9393                        PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );
    9494                        maybeAccept( decl, mangler );
     
    9696                }
    9797
    98                 std::string mangleType( const Type * ty ) {
     98                std::string mangleType( Type * ty ) {
    9999                        PassVisitor<Mangler_old> mangler( false, true, true );
    100100                        maybeAccept( ty, mangler );
     
    102102                }
    103103
    104                 std::string mangleConcrete( const Type * ty ) {
     104                std::string mangleConcrete( Type * ty ) {
    105105                        PassVisitor<Mangler_old> mangler( false, false, false );
    106106                        maybeAccept( ty, mangler );
     
    110110                namespace {
    111111                        Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
    112                                 : nextVarNum( 0 ), isTopLevel( true ),
    113                                 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     112                                : nextVarNum( 0 ), isTopLevel( true ), 
     113                                mangleOverridable( mangleOverridable ), typeMode( typeMode ), 
    114114                                mangleGenericParams( mangleGenericParams ) {}
    115 
    116                         Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     115                       
     116                        Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
    117117                                int nextVarNum, const VarMapType& varNums )
    118                                 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
    119                                 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     118                                : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 
     119                                mangleOverridable( mangleOverridable ), typeMode( typeMode ), 
    120120                                mangleGenericParams( mangleGenericParams ) {}
    121121
    122                         void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {
     122                        void Mangler_old::mangleDecl( DeclarationWithType * declaration ) {
    123123                                bool wasTopLevel = isTopLevel;
    124124                                if ( isTopLevel ) {
     
    150150                        }
    151151
    152                         void Mangler_old::postvisit( const ObjectDecl * declaration ) {
     152                        void Mangler_old::postvisit( ObjectDecl * declaration ) {
    153153                                mangleDecl( declaration );
    154154                        }
    155155
    156                         void Mangler_old::postvisit( const FunctionDecl * declaration ) {
     156                        void Mangler_old::postvisit( FunctionDecl * declaration ) {
    157157                                mangleDecl( declaration );
    158158                        }
    159159
    160                         void Mangler_old::postvisit( const VoidType * voidType ) {
     160                        void Mangler_old::postvisit( VoidType * voidType ) {
    161161                                printQualifiers( voidType );
    162162                                mangleName << Encoding::void_t;
    163163                        }
    164164
    165                         void Mangler_old::postvisit( const BasicType * basicType ) {
     165                        void Mangler_old::postvisit( BasicType * basicType ) {
    166166                                printQualifiers( basicType );
    167                                 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
    168                                 mangleName << Encoding::basicTypes[ basicType->kind ];
    169                         }
    170 
    171                         void Mangler_old::postvisit( const PointerType * pointerType ) {
     167                                assertf( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind() );
     168                                mangleName << Encoding::basicTypes[ basicType->get_kind() ];
     169                        }
     170
     171                        void Mangler_old::postvisit( PointerType * pointerType ) {
    172172                                printQualifiers( pointerType );
    173173                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
     
    176176                        }
    177177
    178                         void Mangler_old::postvisit( const ArrayType * arrayType ) {
     178                        void Mangler_old::postvisit( ArrayType * arrayType ) {
    179179                                // TODO: encode dimension
    180180                                printQualifiers( arrayType );
     
    183183                        }
    184184
    185                         void Mangler_old::postvisit( const ReferenceType * refType ) {
     185                        void Mangler_old::postvisit( ReferenceType * refType ) {
    186186                                // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
    187187                                // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     
    202202                        }
    203203
    204                         void Mangler_old::postvisit( const FunctionType * functionType ) {
     204                        void Mangler_old::postvisit( FunctionType * functionType ) {
    205205                                printQualifiers( functionType );
    206206                                mangleName << Encoding::function;
     
    219219                        }
    220220
    221                         void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {
     221                        void Mangler_old::mangleRef( ReferenceToType * refType, std::string prefix ) {
    222222                                printQualifiers( refType );
    223223
     
    225225
    226226                                if ( mangleGenericParams ) {
    227                                         const std::list< Expression* > & params = refType->parameters;
     227                                        std::list< Expression* >& params = refType->parameters;
    228228                                        if ( ! params.empty() ) {
    229229                                                mangleName << "_";
    230                                                 for ( const Expression * param : params ) {
    231                                                         const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );
    232                                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
     230                                                for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
     231                                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     232                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
    233233                                                        maybeAccept( paramType->type, *visitor );
    234234                                                }
     
    238238                        }
    239239
    240                         void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {
     240                        void Mangler_old::postvisit( StructInstType * aggregateUseType ) {
    241241                                mangleRef( aggregateUseType, Encoding::struct_t );
    242242                        }
    243243
    244                         void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {
     244                        void Mangler_old::postvisit( UnionInstType * aggregateUseType ) {
    245245                                mangleRef( aggregateUseType, Encoding::union_t );
    246246                        }
    247247
    248                         void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {
     248                        void Mangler_old::postvisit( EnumInstType * aggregateUseType ) {
    249249                                mangleRef( aggregateUseType, Encoding::enum_t );
    250250                        }
    251251
    252                         void Mangler_old::postvisit( const TypeInstType * typeInst ) {
     252                        void Mangler_old::postvisit( TypeInstType * typeInst ) {
    253253                                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    254254                                if ( varNum == varNums.end() ) {
     
    266266                        }
    267267
    268                         void Mangler_old::postvisit( const TraitInstType * inst ) {
     268                        void Mangler_old::postvisit( TraitInstType * inst ) {
    269269                                printQualifiers( inst );
    270270                                mangleName << inst->name.size() << inst->name;
    271271                        }
    272272
    273                         void Mangler_old::postvisit( const TupleType * tupleType ) {
     273                        void Mangler_old::postvisit( TupleType * tupleType ) {
    274274                                printQualifiers( tupleType );
    275275                                mangleName << Encoding::tuple << tupleType->types.size();
     
    277277                        }
    278278
    279                         void Mangler_old::postvisit( const VarArgsType * varArgsType ) {
     279                        void Mangler_old::postvisit( VarArgsType * varArgsType ) {
    280280                                printQualifiers( varArgsType );
    281281                                static const std::string vargs = "__builtin_va_list";
     
    283283                        }
    284284
    285                         void Mangler_old::postvisit( const ZeroType * ) {
     285                        void Mangler_old::postvisit( ZeroType * ) {
    286286                                mangleName << Encoding::zero;
    287287                        }
    288288
    289                         void Mangler_old::postvisit( const OneType * ) {
     289                        void Mangler_old::postvisit( OneType * ) {
    290290                                mangleName << Encoding::one;
    291291                        }
    292292
    293                         void Mangler_old::postvisit( const QualifiedType * qualType ) {
     293                        void Mangler_old::postvisit( QualifiedType * qualType ) {
    294294                                bool inqual = inQualifiedType;
    295295                                if (! inqual ) {
     
    307307                        }
    308308
    309                         void Mangler_old::postvisit( const TypeDecl * decl ) {
     309                        void Mangler_old::postvisit( TypeDecl * decl ) {
    310310                                // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
    311311                                // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     
    314314                                // aside from the assert false.
    315315                                assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl));
    316                                 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
    317                                 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
     316                                assertf( decl->get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind() );
     317                                mangleName << Encoding::typeVariables[ decl->get_kind() ] << ( decl->name.length() ) << decl->name;
    318318                        }
    319319
     
    324324                        }
    325325
    326                         void Mangler_old::printQualifiers( const Type * type ) {
     326                        void Mangler_old::printQualifiers( Type * type ) {
    327327                                // skip if not including qualifiers
    328328                                if ( typeMode ) return;
    329                                 if ( ! type->forall.empty() ) {
     329                                if ( ! type->get_forall().empty() ) {
    330330                                        std::list< std::string > assertionNames;
    331331                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
    332332                                        mangleName << Encoding::forall;
    333                                         for ( const TypeDecl * i : type->forall ) {
    334                                                 switch ( i->kind ) {
     333                                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
     334                                                switch ( (*i)->get_kind() ) {
    335335                                                  case TypeDecl::Dtype:
    336336                                                        dcount++;
     
    345345                                                        assert( false );
    346346                                                } // switch
    347                                                 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
    348                                                 for ( const DeclarationWithType * assert : i->assertions ) {
    349                                                         PassVisitor<Mangler_old> sub_mangler(
     347                                                varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->get_kind() );
     348                                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
     349                                                        PassVisitor<Mangler_old> sub_mangler( 
    350350                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
    351                                                         assert->accept( sub_mangler );
     351                                                        (*assert)->accept( sub_mangler );
    352352                                                        assertionNames.push_back( sub_mangler.pass.get_mangleName() );
    353353                                                        acount++;
     
    436436
    437437                  private:
    438                         Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     438                        Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
    439439                                int nextVarNum, const VarMapType& varNums );
    440440                        friend class ast::Pass<Mangler_new>;
     
    457457        namespace {
    458458                Mangler_new::Mangler_new( Mangle::Mode mode )
    459                         : nextVarNum( 0 ), isTopLevel( true ),
     459                        : nextVarNum( 0 ), isTopLevel( true ), 
    460460                        mangleOverridable  ( ! mode.no_overrideable   ),
    461                         typeMode           (   mode.type              ),
     461                        typeMode           (   mode.type              ), 
    462462                        mangleGenericParams( ! mode.no_generic_params ) {}
    463 
    464                 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     463               
     464                Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
    465465                        int nextVarNum, const VarMapType& varNums )
    466                         : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
    467                         mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     466                        : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 
     467                        mangleOverridable( mangleOverridable ), typeMode( typeMode ), 
    468468                        mangleGenericParams( mangleGenericParams ) {}
    469469
     
    693693                                                varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
    694694                                                for ( const ast::DeclWithType * assert : decl->assertions ) {
    695                                                         ast::Pass<Mangler_new> sub_mangler(
     695                                                        ast::Pass<Mangler_new> sub_mangler( 
    696696                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
    697697                                                        assert->accept( sub_mangler );
  • src/SymTab/Mangler.h

    r4eb43fa rf6cc734e  
    4040        namespace Mangler {
    4141                /// Mangle syntax tree object; primary interface to clients
    42                 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
     42                std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
    4343
    4444                /// Mangle a type name; secondary interface
    45                 std::string mangleType( const Type * ty );
     45                std::string mangleType( Type* ty );
    4646                /// Mangle ignoring generic type parameters
    47                 std::string mangleConcrete( const Type * ty );
     47                std::string mangleConcrete( Type* ty );
    4848
    4949                namespace Encoding {
  • src/SymTab/Validate.cc

    r4eb43fa rf6cc734e  
    119119
    120120          private:
    121                 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );
     121                template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    122122
    123123                AggregateDecl * parentAggr = nullptr;
     
    134134        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    135135        struct EnumAndPointerDecay_old {
    136                 void previsit( EnumDecl * aggregateDecl );
    137                 void previsit( FunctionType * func );
     136                void previsit( EnumDecl *aggregateDecl );
     137                void previsit( FunctionType *func );
    138138        };
    139139
    140140        /// Associates forward declarations of aggregates with their definitions
    141141        struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {
    142                 LinkReferenceToTypes_old( const Indexer * indexer );
    143                 void postvisit( TypeInstType * typeInst );
    144 
    145                 void postvisit( EnumInstType * enumInst );
    146                 void postvisit( StructInstType * structInst );
    147                 void postvisit( UnionInstType * unionInst );
    148                 void postvisit( TraitInstType * traitInst );
     142                LinkReferenceToTypes_old( const Indexer *indexer );
     143                void postvisit( TypeInstType *typeInst );
     144
     145                void postvisit( EnumInstType *enumInst );
     146                void postvisit( StructInstType *structInst );
     147                void postvisit( UnionInstType *unionInst );
     148                void postvisit( TraitInstType *traitInst );
    149149                void previsit( QualifiedType * qualType );
    150150                void postvisit( QualifiedType * qualType );
    151151
    152                 void postvisit( EnumDecl * enumDecl );
    153                 void postvisit( StructDecl * structDecl );
    154                 void postvisit( UnionDecl * unionDecl );
     152                void postvisit( EnumDecl *enumDecl );
     153                void postvisit( StructDecl *structDecl );
     154                void postvisit( UnionDecl *unionDecl );
    155155                void postvisit( TraitDecl * traitDecl );
    156156
    157                 void previsit( StructDecl * structDecl );
    158                 void previsit( UnionDecl * unionDecl );
     157                void previsit( StructDecl *structDecl );
     158                void previsit( UnionDecl *unionDecl );
    159159
    160160                void renameGenericParams( std::list< TypeDecl * > & params );
    161161
    162162          private:
    163                 const Indexer * local_indexer;
     163                const Indexer *local_indexer;
    164164
    165165                typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
     
    239239
    240240                template<typename AggDecl>
    241                 void handleAggregate( AggDecl * aggregateDecl );
     241                void handleAggregate( AggDecl *aggregateDecl );
    242242
    243243                void previsit( StructDecl * aggregateDecl );
     
    252252                static void verify( std::list< Declaration * > &translationUnit );
    253253
    254                 void previsit( FunctionDecl * funcDecl );
     254                void previsit( FunctionDecl *funcDecl );
    255255        };
    256256
     
    287287                Type::StorageClasses storageClasses;
    288288
    289                 void premutate( ObjectDecl * objectDecl );
    290                 Expression * postmutate( CompoundLiteralExpr * compLitExpr );
     289                void premutate( ObjectDecl *objectDecl );
     290                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    291291        };
    292292
     
    393393        }
    394394
    395         void validateType( Type * type, const Indexer * indexer ) {
     395        void validateType( Type *type, const Indexer *indexer ) {
    396396                PassVisitor<EnumAndPointerDecay_old> epc;
    397397                PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
     
    496496        }
    497497
    498         bool shouldHoist( Declaration * decl ) {
     498        bool shouldHoist( Declaration *decl ) {
    499499                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl );
    500500        }
     
    515515
    516516        template< typename AggDecl >
    517         void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {
     517        void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
    518518                if ( parentAggr ) {
    519519                        aggregateDecl->parent = parentAggr;
     
    560560
    561561
    562         bool isTypedef( Declaration * decl ) {
     562        bool isTypedef( Declaration *decl ) {
    563563                return dynamic_cast< TypedefDecl * >( decl );
    564564        }
     
    571571
    572572        template< typename AggDecl >
    573         void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {
     573        void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) {
    574574                filter( aggregateDecl->members, isTypedef, true );
    575575        }
     
    586586                // remove and delete decl stmts
    587587                filter( compoundStmt->kids, [](Statement * stmt) {
    588                         if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     588                        if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    589589                                if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {
    590590                                        return true;
     
    595595        }
    596596
    597         void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {
     597        void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) {
    598598                // Set the type of each member of the enumeration to be EnumConstant
    599599                for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
    600                         ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );
     600                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    601601                        assert( obj );
    602602                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) );
     
    627627        }
    628628
    629         void EnumAndPointerDecay_old::previsit( FunctionType * func ) {
     629        void EnumAndPointerDecay_old::previsit( FunctionType *func ) {
    630630                // Fix up parameters and return types
    631631                fixFunctionList( func->parameters, func->isVarArgs, func );
     
    633633        }
    634634
    635         LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {
     635        LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) {
    636636                if ( other_indexer ) {
    637637                        local_indexer = other_indexer;
     
    641641        }
    642642
    643         void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {
    644                 const EnumDecl * st = local_indexer->lookupEnum( enumInst->name );
     643        void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) {
     644                EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
    645645                // it's not a semantic error if the enum is not found, just an implicit forward declaration
    646646                if ( st ) {
    647                         enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node
     647                        enumInst->baseEnum = st;
    648648                } // if
    649649                if ( ! st || ! st->body ) {
     
    661661        }
    662662
    663         void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {
    664                 const StructDecl * st = local_indexer->lookupStruct( structInst->name );
     663        void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) {
     664                StructDecl *st = local_indexer->lookupStruct( structInst->name );
    665665                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    666666                if ( st ) {
    667                         structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node
     667                        structInst->baseStruct = st;
    668668                } // if
    669669                if ( ! st || ! st->body ) {
     
    674674        }
    675675
    676         void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {
    677                 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name );
     676        void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) {
     677                UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
    678678                // it's not a semantic error if the union is not found, just an implicit forward declaration
    679679                if ( un ) {
    680                         unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node
     680                        unionInst->baseUnion = un;
    681681                } // if
    682682                if ( ! un || ! un->body ) {
     
    693693        void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) {
    694694                // linking only makes sense for the 'oldest ancestor' of the qualified type
    695                 qualType->parent->accept( * visitor );
     695                qualType->parent->accept( *visitor );
    696696        }
    697697
     
    762762        void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) {
    763763                // handle other traits
    764                 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name );
     764                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
    765765                if ( ! traitDecl ) {
    766766                        SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
     
    769769                        SemanticError( traitInst, "incorrect number of trait parameters: " );
    770770                } // if
    771                 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node
     771                traitInst->baseTrait = traitDecl;
    772772
    773773                // need to carry over the 'sized' status of each decl in the instance
     
    786786        }
    787787
    788         void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {
     788        void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) {
    789789                // visit enum members first so that the types of self-referencing members are updated properly
    790790                if ( enumDecl->body ) {
     
    792792                        if ( fwds != forwardEnums.end() ) {
    793793                                for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    794                                         (* inst)->baseEnum = enumDecl;
     794                                        (*inst)->baseEnum = enumDecl;
    795795                                } // for
    796796                                forwardEnums.erase( fwds );
     
    834834        }
    835835
    836         void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {
     836        void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) {
    837837                // visit struct members first so that the types of self-referencing members are updated properly
    838838                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
     
    841841                        if ( fwds != forwardStructs.end() ) {
    842842                                for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    843                                         (* inst)->baseStruct = structDecl;
     843                                        (*inst)->baseStruct = structDecl;
    844844                                } // for
    845845                                forwardStructs.erase( fwds );
     
    848848        }
    849849
    850         void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {
     850        void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) {
    851851                if ( unionDecl->body ) {
    852852                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
    853853                        if ( fwds != forwardUnions.end() ) {
    854854                                for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    855                                         (* inst)->baseUnion = unionDecl;
     855                                        (*inst)->baseUnion = unionDecl;
    856856                                } // for
    857857                                forwardUnions.erase( fwds );
     
    860860        }
    861861
    862         void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {
     862        void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) {
    863863                // ensure generic parameter instances are renamed like the base type
    864864                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
    865                 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
    866                         if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) {
    867                                 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype );
     865                if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
     866                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
     867                                typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
    868868                        } // if
    869869                } // if
     
    877877                        // expand trait instances into their members
    878878                        for ( DeclarationWithType * assertion : asserts ) {
    879                                 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     879                                if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
    880880                                        // expand trait instance into all of its members
    881881                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     
    897897        }
    898898
    899         void ForallPointerDecay_old::previsit( ObjectDecl * object ) {
     899        void ForallPointerDecay_old::previsit( ObjectDecl *object ) {
    900900                // ensure that operator names only apply to functions or function pointers
    901901                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     
    905905        }
    906906
    907         void ForallPointerDecay_old::previsit( FunctionDecl * func ) {
     907        void ForallPointerDecay_old::previsit( FunctionDecl *func ) {
    908908                func->fixUniqueId();
    909909        }
     
    961961        Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) {
    962962                // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type
    963                 qualType->parent = qualType->parent->acceptMutator( * visitor );
     963                qualType->parent = qualType->parent->acceptMutator( *visitor );
    964964                return qualType;
    965965        }
     
    970970                TypedefMap::const_iterator def = typedefNames.find( typeInst->name );
    971971                if ( def != typedefNames.end() ) {
    972                         Type * ret = def->second.first->base->clone();
     972                        Type *ret = def->second.first->base->clone();
    973973                        ret->location = typeInst->location;
    974974                        ret->get_qualifiers() |= typeInst->get_qualifiers();
     
    982982                        // place instance parameters on the typedef'd type
    983983                        if ( ! typeInst->parameters.empty() ) {
    984                                 ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret);
     984                                ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
    985985                                if ( ! rtt ) {
    986986                                        SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
     
    988988                                rtt->parameters.clear();
    989989                                cloneAll( typeInst->parameters, rtt->parameters );
    990                                 mutateAll( rtt->parameters, * visitor );  // recursively fix typedefs on parameters
     990                                mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
    991991                        } // if
    992992                        delete typeInst;
     
    10431043                //    struct screen;
    10441044                // because the expansion of the typedef is:
    1045                 //    void rtn( SCREEN * p ) => void rtn( struct screen * p )
     1045                //    void rtn( SCREEN *p ) => void rtn( struct screen *p )
    10461046                // hence the type-name "screen" must be defined.
    10471047                // Note, qualifiers on the typedef are superfluous for the forward declaration.
    10481048
    1049                 Type * designatorType = tyDecl->base->stripDeclarator();
    1050                 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
     1049                Type *designatorType = tyDecl->base->stripDeclarator();
     1050                if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    10511051                        declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
    1052                 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
     1052                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    10531053                        declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
    1054                 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
     1054                } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
    10551055                        declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
    10561056                } // if
     
    10781078
    10791079        DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) {
    1080                 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
     1080                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
    10811081                        // replace the current object declaration with a function declaration
    10821082                        FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );
     
    11041104        void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
    11051105                if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
    1106                         Type * type = nullptr;
     1106                        Type *type = nullptr;
    11071107                        if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) {
    11081108                                type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() );
     
    11301130                GuardScope( typedefNames );
    11311131                GuardScope( typedeclNames );
    1132                 mutateAll( aggr->parameters, * visitor );
     1132                mutateAll( aggr->parameters, *visitor );
    11331133
    11341134                // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body.
     
    11371137
    11381138                        try {
    1139                                 * i = maybeMutate( * i, * visitor );
     1139                                *i = maybeMutate( *i, *visitor );
    11401140                        } catch ( SemanticErrorException &e ) {
    11411141                                errors.append( e );
     
    12171217                        for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) {
    12181218                                if ( i < args.size() ) {
    1219                                         TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );
    1220                                         sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );
     1219                                        TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) );
     1220                                        sub.add( (*paramIter)->get_name(), expr->get_type()->clone() );
    12211221                                } else if ( i == args.size() ) {
    1222                                         Type * defaultType = (* paramIter)->get_init();
     1222                                        Type * defaultType = (*paramIter)->get_init();
    12231223                                        if ( defaultType ) {
    12241224                                                args.push_back( new TypeExpr( defaultType->clone() ) );
    1225                                                 sub.add( (* paramIter)->get_name(), defaultType->clone() );
     1225                                                sub.add( (*paramIter)->get_name(), defaultType->clone() );
    12261226                                        }
    12271227                                }
     
    12421242        }
    12431243
    1244         void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {
     1244        void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
    12451245                storageClasses = objectDecl->get_storageClasses();
    12461246        }
    12471247
    1248         Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) {
     1248        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    12491249                // transform [storage_class] ... (struct S){ 3, ... };
    12501250                // into [storage_class] struct S temp =  { 3, ... };
    12511251                static UniqueName indexName( "_compLit" );
    12521252
    1253                 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     1253                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
    12541254                compLitExpr->set_result( nullptr );
    12551255                compLitExpr->set_initializer( nullptr );
     
    12891289                        TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
    12901290                        // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
    1291                         ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );
     1291                        ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
    12921292                        deleteAll( retVals );
    12931293                        retVals.clear();
     
    13021302
    13031303        void FixObjectType::previsit( ObjectDecl * objDecl ) {
    1304                 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
     1304                Type *new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
    13051305                new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
    13061306                objDecl->set_type( new_type );
     
    13081308
    13091309        void FixObjectType::previsit( FunctionDecl * funcDecl ) {
    1310                 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
     1310                Type *new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
    13111311                new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
    13121312                funcDecl->set_type( new_type );
    13131313        }
    13141314
    1315         void FixObjectType::previsit( TypeDecl * typeDecl ) {
     1315        void FixObjectType::previsit( TypeDecl *typeDecl ) {
    13161316                if ( typeDecl->get_base() ) {
    1317                         Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
     1317                        Type *new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
    13181318                        new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
    13191319                        typeDecl->set_base( new_type );
     
    13781378
    13791379namespace {
    1380         /// Replaces enum types by int, and function/array types in function parameter and return
     1380        /// Replaces enum types by int, and function/array types in function parameter and return 
    13811381        /// lists by appropriate pointers
    13821382        struct EnumAndPointerDecay_new {
     
    13851385                        for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
    13861386                                // build new version of object with EnumConstant
    1387                                 ast::ptr< ast::ObjectDecl > obj =
     1387                                ast::ptr< ast::ObjectDecl > obj = 
    13881388                                        enumDecl->members[i].strict_as< ast::ObjectDecl >();
    1389                                 obj.get_and_mutate()->type =
     1389                                obj.get_and_mutate()->type = 
    13901390                                        new ast::EnumInstType{ enumDecl->name, ast::CV::Const };
    1391 
     1391                               
    13921392                                // set into decl
    13931393                                ast::EnumDecl * mut = mutate( enumDecl );
     
    13991399
    14001400                static const ast::FunctionType * fixFunctionList(
    1401                         const ast::FunctionType * func,
     1401                        const ast::FunctionType * func, 
    14021402                        std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,
    14031403                        ast::ArgumentFlag isVarArgs = ast::FixedArgs
    14041404                ) {
    1405                         const auto & dwts = func->* field;
     1405                        const auto & dwts = func->*field;
    14061406                        unsigned nvals = dwts.size();
    14071407                        bool hasVoid = false;
     
    14091409                                func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );
    14101410                        }
    1411 
     1411                       
    14121412                        // the only case in which "void" is valid is where it is the only one in the list
    14131413                        if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {
    1414                                 SemanticError(
     1414                                SemanticError( 
    14151415                                        dwts.front()->location, func, "invalid type void in function type" );
    14161416                        }
     
    14181418                        // one void is the only thing in the list, remove it
    14191419                        if ( hasVoid ) {
    1420                                 func = ast::mutate_field(
     1420                                func = ast::mutate_field( 
    14211421                                        func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );
    14221422                        }
     
    14321432
    14331433        /// expand assertions from a trait instance, performing appropriate type variable substitutions
    1434         void expandAssertions(
    1435                 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out
     1434        void expandAssertions( 
     1435                const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 
    14361436        ) {
    14371437                assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) );
    14381438
    14391439                // build list of trait members, substituting trait decl parameters for instance parameters
    1440                 ast::TypeSubstitution sub{
     1440                ast::TypeSubstitution sub{ 
    14411441                        inst->base->params.begin(), inst->base->params.end(), inst->params.begin() };
    14421442                // deliberately take ast::ptr by-value to ensure this does not mutate inst->base
     
    14491449
    14501450        /// Associates forward declarations of aggregates with their definitions
    1451         class LinkReferenceToTypes_new final
    1452         : public ast::WithSymbolTable, public ast::WithGuards, public
     1451        class LinkReferenceToTypes_new final 
     1452        : public ast::WithSymbolTable, public ast::WithGuards, public 
    14531453          ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
    1454 
    1455                 // these maps of uses of forward declarations of types need to have the actual type
    1456                 // declaration switched in * after * they have been traversed. To enable this in the
    1457                 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it
    1458                 // before it is placed in the map, properly updating its parents in the usual traversal,
     1454               
     1455                // these maps of uses of forward declarations of types need to have the actual type 
     1456                // declaration switched in *after* they have been traversed. To enable this in the
     1457                // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 
     1458                // before it is placed in the map, properly updating its parents in the usual traversal, 
    14591459                // then can have the actual mutation applied later
    14601460                using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >;
    14611461                using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >;
    14621462                using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >;
    1463 
     1463               
    14641464                const CodeLocation & location;
    14651465                const ast::SymbolTable * localSymtab;
    1466 
     1466               
    14671467                ForwardEnumsType forwardEnums;
    14681468                ForwardStructsType forwardStructs;
    14691469                ForwardUnionsType forwardUnions;
    14701470
    1471                 /// true if currently in a generic type body, so that type parameter instances can be
     1471                /// true if currently in a generic type body, so that type parameter instances can be 
    14721472                /// renamed appropriately
    14731473                bool inGeneric = false;
     
    14751475        public:
    14761476                /// contstruct using running symbol table
    1477                 LinkReferenceToTypes_new( const CodeLocation & loc )
     1477                LinkReferenceToTypes_new( const CodeLocation & loc ) 
    14781478                : location( loc ), localSymtab( &symtab ) {}
    1479 
     1479               
    14801480                /// construct using provided symbol table
    1481                 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms )
     1481                LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 
    14821482                : location( loc ), localSymtab( &syms ) {}
    14831483
     
    14851485                        // ensure generic parameter instances are renamed like the base type
    14861486                        if ( inGeneric && typeInst->base ) {
    1487                                 typeInst = ast::mutate_field(
     1487                                typeInst = ast::mutate_field( 
    14881488                                        typeInst, &ast::TypeInstType::name, typeInst->base->name );
    14891489                        }
    14901490
    1491                         if (
    1492                                 auto typeDecl = dynamic_cast< const ast::TypeDecl * >(
    1493                                         localSymtab->lookupType( typeInst->name ) )
     1491                        if ( 
     1492                                auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 
     1493                                        localSymtab->lookupType( typeInst->name ) ) 
    14941494                        ) {
    14951495                                typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind );
     
    15171517                        for ( const ast::Expr * param : inst->params ) {
    15181518                                if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) {
    1519                                         SemanticError(
     1519                                        SemanticError( 
    15201520                                                location, inst, "Expression parameters for generic types are currently "
    15211521                                                "unsupported: " );
     
    15711571                                auto expr = traitInst->params[i].as< ast::TypeExpr >();
    15721572                                if ( ! expr ) {
    1573                                         SemanticError(
     1573                                        SemanticError( 
    15741574                                                traitInst->params[i].get(), "Expression parameters for trait instances "
    15751575                                                "are currently unsupported: " );
     
    15931593                        return traitInst;
    15941594                }
    1595 
     1595               
    15961596                void previsit( const ast::QualifiedType * ) { visit_children = false; }
    1597 
     1597               
    15981598                const ast::Type * postvisit( const ast::QualifiedType * qualType ) {
    15991599                        // linking only makes sense for the "oldest ancestor" of the qualified type
    1600                         return ast::mutate_field(
    1601                                 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );
     1600                        return ast::mutate_field( 
     1601                                qualType, &ast::QualifiedType::parent, qualType->parent->accept( *visitor ) );
    16021602                }
    16031603
    16041604                const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) {
    1605                         // visit enum members first so that the types of self-referencing members are updated
     1605                        // visit enum members first so that the types of self-referencing members are updated 
    16061606                        // properly
    16071607                        if ( ! enumDecl->body ) return enumDecl;
     
    16121612                                auto inst = fwds.first;
    16131613                                do {
    1614                                         // forward decl is stored * mutably * in map, can thus be updated
     1614                                        // forward decl is stored *mutably* in map, can thus be updated
    16151615                                        inst->second->base = enumDecl;
    16161616                                } while ( ++inst != fwds.second );
    16171617                                forwardEnums.erase( fwds.first, fwds.second );
    16181618                        }
    1619 
     1619                       
    16201620                        // ensure that enumerator initializers are properly set
    16211621                        for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
    16221622                                auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >();
    16231623                                if ( field->init ) {
    1624                                         // need to resolve enumerator initializers early so that other passes that
     1624                                        // need to resolve enumerator initializers early so that other passes that 
    16251625                                        // determine if an expression is constexpr have appropriate information
    16261626                                        auto init = field->init.strict_as< ast::SingleInit >();
    1627 
    1628                                         enumDecl = ast::mutate_field_index(
    1629                                                 enumDecl, &ast::EnumDecl::members, i,
    1630                                                 ast::mutate_field( field, &ast::ObjectDecl::init,
     1627                                       
     1628                                        enumDecl = ast::mutate_field_index( 
     1629                                                enumDecl, &ast::EnumDecl::members, i, 
     1630                                                ast::mutate_field( field, &ast::ObjectDecl::init, 
    16311631                                                        ast::mutate_field( init, &ast::SingleInit::value,
    1632                                                                 ResolvExpr::findSingleExpression(
     1632                                                                ResolvExpr::findSingleExpression( 
    16331633                                                                        init->value, new ast::BasicType{ ast::BasicType::SignedInt },
    16341634                                                                        symtab ) ) ) );
     
    16391639                }
    16401640
    1641                 /// rename generic type parameters uniquely so that they do not conflict with user defined
     1641                /// rename generic type parameters uniquely so that they do not conflict with user defined 
    16421642                /// function forall parameters, e.g. the T in Box and the T in f, below
    16431643                ///   forall(otype T)
     
    16571657                                const ast::TypeDecl * td = aggr->params[i];
    16581658
    1659                                 aggr = ast::mutate_field_index(
    1660                                         aggr, &AggrDecl::params, i,
     1659                                aggr = ast::mutate_field_index( 
     1660                                        aggr, &AggrDecl::params, i, 
    16611661                                        ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) );
    16621662                        }
     
    16691669
    16701670                void postvisit( const ast::StructDecl * structDecl ) {
    1671                         // visit struct members first so that the types of self-referencing members are
     1671                        // visit struct members first so that the types of self-referencing members are 
    16721672                        // updated properly
    16731673                        if ( ! structDecl->body ) return;
     
    16781678                                auto inst = fwds.first;
    16791679                                do {
    1680                                         // forward decl is stored * mutably * in map, can thus be updated
     1680                                        // forward decl is stored *mutably* in map, can thus be updated
    16811681                                        inst->second->base = structDecl;
    16821682                                } while ( ++inst != fwds.second );
     
    16901690
    16911691                void postvisit( const ast::UnionDecl * unionDecl ) {
    1692                         // visit union members first so that the types of self-referencing members are updated
     1692                        // visit union members first so that the types of self-referencing members are updated 
    16931693                        // properly
    16941694                        if ( ! unionDecl->body ) return;
     
    16991699                                auto inst = fwds.first;
    17001700                                do {
    1701                                         // forward decl is stored * mutably * in map, can thus be updated
     1701                                        // forward decl is stored *mutably* in map, can thus be updated
    17021702                                        inst->second->base = unionDecl;
    17031703                                } while ( ++inst != fwds.second );
     
    17121712                                        "number of parameters: %zd", traitDecl->params.size() );
    17131713
    1714                                 traitDecl = ast::mutate_field_index(
    1715                                         traitDecl, &ast::TraitDecl::params, 0,
    1716                                         ast::mutate_field(
     1714                                traitDecl = ast::mutate_field_index( 
     1715                                        traitDecl, &ast::TraitDecl::params, 0, 
     1716                                        ast::mutate_field( 
    17171717                                                traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) );
    17181718                        }
     
    17371737                                traitDecl = mut;
    17381738                        }
    1739 
     1739                       
    17401740                        return traitDecl;
    17411741                }
    17421742        };
    17431743
    1744         /// Replaces array and function types in forall lists by appropriate pointer type and assigns
     1744        /// Replaces array and function types in forall lists by appropriate pointer type and assigns 
    17451745        /// each object and function declaration a unique ID
    17461746        class ForallPointerDecay_new {
     
    17511751                const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) {
    17521752                        // ensure that operator names only apply to functions or function pointers
    1753                         if (
    1754                                 CodeGen::isOperator( obj->name )
     1753                        if ( 
     1754                                CodeGen::isOperator( obj->name ) 
    17551755                                && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() )
    17561756                        ) {
     
    17761776                /// Fix up assertions -- flattens assertion lists, removing all trait instances
    17771777                template< typename node_t, typename parent_t >
    1778                 static const node_t * forallFixer(
    1779                         const CodeLocation & loc, const node_t * node,
     1778                static const node_t * forallFixer( 
     1779                        const CodeLocation & loc, const node_t * node, 
    17801780                        ast::ParameterizedType::ForallList parent_t::* forallField
    17811781                ) {
    1782                         for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {
    1783                                 const ast::TypeDecl * type = (node->* forallField)[i];
     1782                        for ( unsigned i = 0; i < (node->*forallField).size(); ++i ) {
     1783                                const ast::TypeDecl * type = (node->*forallField)[i];
    17841784                                if ( type->assertions.empty() ) continue;
    17851785
     
    17891789                                // expand trait instances into their members
    17901790                                for ( const ast::DeclWithType * assn : type->assertions ) {
    1791                                         auto traitInst =
    1792                                                 dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
     1791                                        auto traitInst = 
     1792                                                dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 
    17931793                                        if ( traitInst ) {
    17941794                                                // expand trait instance to all its members
     
    18311831} // anonymous namespace
    18321832
    1833 const ast::Type * validateType(
     1833const ast::Type * validateType( 
    18341834                const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
    18351835        ast::Pass< EnumAndPointerDecay_new > epc;
  • src/SymTab/Validate.h

    r4eb43fa rf6cc734e  
    1919#include <list>  // for list
    2020
    21 struct CodeLocation;
    22 class  Declaration;
    23 class  Type;
     21class CodeLocation;
     22class Declaration;
     23class Type;
    2424
    2525namespace ast {
     
    3535        void validateType( Type *type, const Indexer *indexer );
    3636
    37         const ast::Type * validateType(
     37        const ast::Type * validateType( 
    3838                const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab );
    3939} // namespace SymTab
  • src/SynTree/Attribute.h

    r4eb43fa rf6cc734e  
    5050        Attribute * clone() const override { return new Attribute( *this ); }
    5151        virtual void accept( Visitor & v ) override { v.visit( this ); }
    52         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    5352        virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    5453        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
  • src/SynTree/BaseSyntaxNode.h

    r4eb43fa rf6cc734e  
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Feb 14 07:44:20 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 10 16:13:49 2019
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 17 13:44:00
     13// Update Count     : 1
    1414//
    1515
     
    2525class BaseSyntaxNode {
    2626  public:
    27         static Stats::Counters::SimpleCounter* new_nodes;
     27  static Stats::Counters::SimpleCounter* new_nodes;
    2828
    2929        CodeLocation location;
    3030
    31         BaseSyntaxNode() { ++*new_nodes; }
    32         BaseSyntaxNode( const BaseSyntaxNode & o ) : location(o.location) { ++*new_nodes; }
    33         BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default;
     31  BaseSyntaxNode() { ++*new_nodes; }
     32  BaseSyntaxNode( const BaseSyntaxNode& o ) : location(o.location) { ++*new_nodes; }
    3433
    3534        virtual ~BaseSyntaxNode() {}
     
    3736        virtual BaseSyntaxNode * clone() const = 0;
    3837        virtual void accept( Visitor & v ) = 0;
    39         virtual void accept( Visitor & v ) const = 0;
    4038        virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0;
    41         /// Notes:
    42         /// * each node is responsible for indenting its children.
    43         /// * Expressions should not finish with a newline, since the expression's parent has better information.
     39  /// Notes:
     40  /// * each node is responsible for indenting its children.
     41  /// * Expressions should not finish with a newline, since the expression's parent has better information.
    4442        virtual void print( std::ostream & os, Indenter indent = {} ) const = 0;
    4543};
  • src/SynTree/Constant.h

    r4eb43fa rf6cc734e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 10 15:57:38 2019
    13 // Update Count     : 19
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Spt 28 14:48:00 2018
     13// Update Count     : 18
    1414//
    1515
     
    3030        Constant( Type * type, std::string rep, std::optional<unsigned long long> i );
    3131        Constant( const Constant & other );
    32         Constant & operator=( const Constant & ) = default;
    3332        virtual ~Constant();
    3433
    35         virtual Constant * clone() const override { return new Constant( *this ); }
     34        virtual Constant * clone() const { return new Constant( *this ); }
    3635
    3736        Type * get_type() { return type; }
     
    5150        static Constant null( Type * ptrtype = nullptr );
    5251
    53         virtual void accept( Visitor & v ) override { v.visit( this ); }
    54         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    55         virtual Constant * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    56         virtual void print( std::ostream & os, Indenter indent = 0 ) const override;
    57 
     52        virtual void accept( Visitor & v ) { v.visit( this ); }
     53        virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     54        virtual void print( std::ostream & os, Indenter indent = 0 ) const;
     55  private:
    5856        Type * type;
    5957        std::string rep;
    6058        std::optional<unsigned long long> ival;
     59
     60        friend class ConverterOldToNew;
    6161};
    6262
  • src/SynTree/Declaration.h

    r4eb43fa rf6cc734e  
    6363        void fixUniqueId( void );
    6464        virtual Declaration *clone() const override = 0;
    65         virtual void accept( Visitor & v ) override = 0;
    66         virtual void accept( Visitor & v ) const override = 0;
     65        virtual void accept( Visitor &v ) override = 0;
    6766        virtual Declaration *acceptMutator( Mutator &m ) override = 0;
    6867        virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
     
    140139
    141140        virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); }
    142         virtual void accept( Visitor & v ) override { v.visit( this ); }
    143         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     141        virtual void accept( Visitor &v ) override { v.visit( this ); }
    144142        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    145143        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    171169
    172170        virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); }
    173         virtual void accept( Visitor & v ) override { v.visit( this ); }
    174         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     171        virtual void accept( Visitor &v ) override { v.visit( this ); }
    175172        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    176173        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    241238
    242239        virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
    243         virtual void accept( Visitor & v ) override { v.visit( this ); }
    244         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     240        virtual void accept( Visitor &v ) override { v.visit( this ); }
    245241        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    246242        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    260256
    261257        virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
    262         virtual void accept( Visitor & v ) override { v.visit( this ); }
    263         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     258        virtual void accept( Visitor &v ) override { v.visit( this ); }
    264259        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    265260  private:
     
    305300
    306301        virtual StructDecl *clone() const override { return new StructDecl( *this ); }
    307         virtual void accept( Visitor & v ) override { v.visit( this ); }
    308         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     302        virtual void accept( Visitor &v ) override { v.visit( this ); }
    309303        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    310304        DeclarationNode::Aggregate kind;
     
    320314
    321315        virtual UnionDecl *clone() const override { return new UnionDecl( *this ); }
    322         virtual void accept( Visitor & v ) override { v.visit( this ); }
    323         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     316        virtual void accept( Visitor &v ) override { v.visit( this ); }
    324317        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    325318  private:
     
    336329
    337330        virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
    338         virtual void accept( Visitor & v ) override { v.visit( this ); }
    339         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     331        virtual void accept( Visitor &v ) override { v.visit( this ); }
    340332        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    341333  private:
     
    353345
    354346        virtual TraitDecl *clone() const override { return new TraitDecl( *this ); }
    355         virtual void accept( Visitor & v ) override { v.visit( this ); }
    356         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    357         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    358   private:
    359         virtual std::string typeString() const override;
    360 };
    361 
    362 class WithStmt : public Declaration {
    363 public:
    364         std::list< Expression * > exprs;
    365         Statement * stmt;
    366 
    367         WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
    368         WithStmt( const WithStmt & other );
    369         virtual ~WithStmt();
    370 
    371         virtual WithStmt * clone() const override { return new WithStmt( *this ); }
    372         virtual void accept( Visitor & v ) override { v.visit( this ); }
    373         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    374         virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    375         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    376         virtual void printShort( std::ostream & os, Indenter indent = {} ) const override { print(os, indent); }
     347        virtual void accept( Visitor &v ) override { v.visit( this ); }
     348        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     349  private:
     350        virtual std::string typeString() const override;
    377351};
    378352
     
    389363
    390364        virtual AsmDecl *clone() const override { return new AsmDecl( *this ); }
    391         virtual void accept( Visitor & v ) override { v.visit( this ); }
    392         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     365        virtual void accept( Visitor &v ) override { v.visit( this ); }
    393366        virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    394367        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    406379
    407380        virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
    408         virtual void accept( Visitor & v ) override { v.visit( this ); }
    409         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     381        virtual void accept( Visitor &v ) override { v.visit( this ); }
    410382        virtual StaticAssertDecl * acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    411383        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
  • src/SynTree/Expression.cc

    r4eb43fa rf6cc734e  
    724724}
    725725
    726 DeletedExpr::DeletedExpr( Expression * expr, Declaration * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {
     726DeletedExpr::DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {
    727727        assert( expr->result );
    728728        result = expr->result->clone();
  • src/SynTree/Expression.h

    r4eb43fa rf6cc734e  
    8282        virtual Expression * clone() const override = 0;
    8383        virtual void accept( Visitor & v ) override = 0;
    84         virtual void accept( Visitor & v ) const override = 0;
    8584        virtual Expression * acceptMutator( Mutator & m ) override = 0;
    8685        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    102101        std::list<Expression *>& get_args() { return args; }
    103102
    104         virtual ApplicationExpr * clone() const override { return new ApplicationExpr( * this ); }
    105         virtual void accept( Visitor & v ) override { v.visit( this ); }
    106         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    107         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    108         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     103        virtual ApplicationExpr * clone() const { return new ApplicationExpr( * this ); }
     104        virtual void accept( Visitor & v ) { v.visit( this ); }
     105        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     106        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    109107};
    110108
     
    131129        static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 );
    132130
    133         virtual UntypedExpr * clone() const override { return new UntypedExpr( * this ); }
    134         virtual void accept( Visitor & v ) override { v.visit( this ); }
    135         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    136         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    137         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     131        virtual UntypedExpr * clone() const { return new UntypedExpr( * this ); }
     132        virtual void accept( Visitor & v ) { v.visit( this ); }
     133        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     134        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    138135};
    139136
     
    150147        void set_name( std::string newValue ) { name = newValue; }
    151148
    152         virtual NameExpr * clone() const override { return new NameExpr( * this ); }
    153         virtual void accept( Visitor & v ) override { v.visit( this ); }
    154         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    155         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    156         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     149        virtual NameExpr * clone() const { return new NameExpr( * this ); }
     150        virtual void accept( Visitor & v ) { v.visit( this ); }
     151        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     152        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    157153};
    158154
     
    172168        void set_arg(Expression * newValue ) { arg = newValue; }
    173169
    174         virtual AddressExpr * clone() const override { return new AddressExpr( * this ); }
    175         virtual void accept( Visitor & v ) override { v.visit( this ); }
    176         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    177         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    178         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     170        virtual AddressExpr * clone() const { return new AddressExpr( * this ); }
     171        virtual void accept( Visitor & v ) { v.visit( this ); }
     172        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     173        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    179174};
    180175
     
    189184        virtual ~LabelAddressExpr();
    190185
    191         virtual LabelAddressExpr * clone() const override { return new LabelAddressExpr( * this ); }
    192         virtual void accept( Visitor & v ) override { v.visit( this ); }
    193         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    194         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    195         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     186        virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
     187        virtual void accept( Visitor & v ) { v.visit( this ); }
     188        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     189        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    196190};
    197191
     
    211205        void set_arg( Expression * newValue ) { arg = newValue; }
    212206
    213         virtual CastExpr * clone() const override { return new CastExpr( * this ); }
    214         virtual void accept( Visitor & v ) override { v.visit( this ); }
    215         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    216         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    217         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     207        virtual CastExpr * clone() const { return new CastExpr( * this ); }
     208        virtual void accept( Visitor & v ) { v.visit( this ); }
     209        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     210        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    218211};
    219212
     
    232225        const std::string & targetString() const;
    233226
    234         virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); }
    235         virtual void accept( Visitor & v ) override { v.visit( this ); }
    236         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    237         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    238         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     227        virtual KeywordCastExpr * clone() const { return new KeywordCastExpr( * this ); }
     228        virtual void accept( Visitor & v ) { v.visit( this ); }
     229        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     230        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    239231};
    240232
     
    251243        void set_arg( Expression * newValue ) { arg = newValue; }
    252244
    253         virtual VirtualCastExpr * clone() const override { return new VirtualCastExpr( * this ); }
    254         virtual void accept( Visitor & v ) override { v.visit( this ); }
    255         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    256         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    257         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     245        virtual VirtualCastExpr * clone() const { return new VirtualCastExpr( * this ); }
     246        virtual void accept( Visitor & v ) { v.visit( this ); }
     247        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     248        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    258249};
    259250
     
    273264        void set_aggregate( Expression * newValue ) { aggregate = newValue; }
    274265
    275         virtual UntypedMemberExpr * clone() const override { return new UntypedMemberExpr( * this ); }
    276         virtual void accept( Visitor & v ) override { v.visit( this ); }
    277         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    278         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    279         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     266        virtual UntypedMemberExpr * clone() const { return new UntypedMemberExpr( * this ); }
     267        virtual void accept( Visitor & v ) { v.visit( this ); }
     268        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     269        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    280270};
    281271
     
    296286        void set_aggregate( Expression * newValue ) { aggregate = newValue; }
    297287
    298         virtual MemberExpr * clone() const override { return new MemberExpr( * this ); }
    299         virtual void accept( Visitor & v ) override { v.visit( this ); }
    300         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    301         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    302         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     288        virtual MemberExpr * clone() const { return new MemberExpr( * this ); }
     289        virtual void accept( Visitor & v ) { v.visit( this ); }
     290        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     291        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    303292};
    304293
     
    319308        static VariableExpr * functionPointer( FunctionDecl * decl );
    320309
    321         virtual VariableExpr * clone() const override { return new VariableExpr( * this ); }
    322         virtual void accept( Visitor & v ) override { v.visit( this ); }
    323         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    324         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    325         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     310        virtual VariableExpr * clone() const { return new VariableExpr( * this ); }
     311        virtual void accept( Visitor & v ) { v.visit( this ); }
     312        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     313        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    326314};
    327315
     
    341329        long long int intValue() const;
    342330
    343         virtual ConstantExpr * clone() const override { return new ConstantExpr( * this ); }
    344         virtual void accept( Visitor & v ) override { v.visit( this ); }
    345         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    346         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    347         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     331        virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); }
     332        virtual void accept( Visitor & v ) { v.visit( this ); }
     333        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     334        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    348335};
    349336
     
    367354        void set_isType( bool newValue ) { isType = newValue; }
    368355
    369         virtual SizeofExpr * clone() const override { return new SizeofExpr( * this ); }
    370         virtual void accept( Visitor & v ) override { v.visit( this ); }
    371         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    372         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    373         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     356        virtual SizeofExpr * clone() const { return new SizeofExpr( * this ); }
     357        virtual void accept( Visitor & v ) { v.visit( this ); }
     358        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     359        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    374360};
    375361
     
    393379        void set_isType( bool newValue ) { isType = newValue; }
    394380
    395         virtual AlignofExpr * clone() const override { return new AlignofExpr( * this ); }
    396         virtual void accept( Visitor & v ) override { v.visit( this ); }
    397         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    398         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    399         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     381        virtual AlignofExpr * clone() const { return new AlignofExpr( * this ); }
     382        virtual void accept( Visitor & v ) { v.visit( this ); }
     383        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     384        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    400385};
    401386
     
    415400        void set_type( Type * newValue ) { type = newValue; }
    416401
    417         virtual UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr( * this ); }
    418         virtual void accept( Visitor & v ) override { v.visit( this ); }
    419         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    420         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    421         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     402        virtual UntypedOffsetofExpr * clone() const { return new UntypedOffsetofExpr( * this ); }
     403        virtual void accept( Visitor & v ) { v.visit( this ); }
     404        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     405        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    422406};
    423407
     
    437421        void set_member( DeclarationWithType * newValue ) { member = newValue; }
    438422
    439         virtual OffsetofExpr * clone() const override { return new OffsetofExpr( * this ); }
    440         virtual void accept( Visitor & v ) override { v.visit( this ); }
    441         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    442         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    443         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     423        virtual OffsetofExpr * clone() const { return new OffsetofExpr( * this ); }
     424        virtual void accept( Visitor & v ) { v.visit( this ); }
     425        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     426        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    444427};
    445428
     
    456439        void set_type( StructInstType * newValue ) { type = newValue; }
    457440
    458         virtual OffsetPackExpr * clone() const override { return new OffsetPackExpr( * this ); }
    459         virtual void accept( Visitor & v ) override { v.visit( this ); }
    460         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    461         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    462         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     441        virtual OffsetPackExpr * clone() const { return new OffsetPackExpr( * this ); }
     442        virtual void accept( Visitor & v ) { v.visit( this ); }
     443        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     444        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    463445};
    464446
     
    485467        void set_isType( bool newValue ) { isType = newValue; }
    486468
    487         virtual AttrExpr * clone() const override { return new AttrExpr( * this ); }
    488         virtual void accept( Visitor & v ) override { v.visit( this ); }
    489         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    490         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    491         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     469        virtual AttrExpr * clone() const { return new AttrExpr( * this ); }
     470        virtual void accept( Visitor & v ) { v.visit( this ); }
     471        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     472        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    492473};
    493474
     
    508489        void set_arg2( Expression * newValue ) { arg2 = newValue; }
    509490
    510         virtual LogicalExpr * clone() const override { return new LogicalExpr( * this ); }
    511         virtual void accept( Visitor & v ) override { v.visit( this ); }
    512         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    513         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    514         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     491        virtual LogicalExpr * clone() const { return new LogicalExpr( * this ); }
     492        virtual void accept( Visitor & v ) { v.visit( this ); }
     493        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     494        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    515495
    516496  private:
     
    536516        void set_arg3( Expression * newValue ) { arg3 = newValue; }
    537517
    538         virtual ConditionalExpr * clone() const override { return new ConditionalExpr( * this ); }
    539         virtual void accept( Visitor & v ) override { v.visit( this ); }
    540         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    541         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    542         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     518        virtual ConditionalExpr * clone() const { return new ConditionalExpr( * this ); }
     519        virtual void accept( Visitor & v ) { v.visit( this ); }
     520        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     521        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    543522};
    544523
     
    558537        void set_arg2( Expression * newValue ) { arg2 = newValue; }
    559538
    560         virtual CommaExpr * clone() const override { return new CommaExpr( * this ); }
    561         virtual void accept( Visitor & v ) override { v.visit( this ); }
    562         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    563         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    564         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     539        virtual CommaExpr * clone() const { return new CommaExpr( * this ); }
     540        virtual void accept( Visitor & v ) { v.visit( this ); }
     541        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     542        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    565543};
    566544
     
    577555        void set_type( Type * newValue ) { type = newValue; }
    578556
    579         virtual TypeExpr * clone() const override { return new TypeExpr( * this ); }
    580         virtual void accept( Visitor & v ) override { v.visit( this ); }
    581         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    582         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    583         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     557        virtual TypeExpr * clone() const { return new TypeExpr( * this ); }
     558        virtual void accept( Visitor & v ) { v.visit( this ); }
     559        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     560        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    584561};
    585562
     
    604581        void set_operand( Expression * newValue ) { operand = newValue; }
    605582
    606         virtual AsmExpr * clone() const override { return new AsmExpr( * this ); }
    607         virtual void accept( Visitor & v ) override { v.visit( this ); }
    608         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    609         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    610         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     583        virtual AsmExpr * clone() const { return new AsmExpr( * this ); }
     584        virtual void accept( Visitor & v ) { v.visit( this ); }
     585        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     586        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    611587
    612588        // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints
     
    623599        virtual ~ImplicitCopyCtorExpr();
    624600
    625         virtual ImplicitCopyCtorExpr * clone() const override { return new ImplicitCopyCtorExpr( * this ); }
    626         virtual void accept( Visitor & v ) override { v.visit( this ); }
    627         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    628         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    629         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     601        virtual ImplicitCopyCtorExpr * clone() const { return new ImplicitCopyCtorExpr( * this ); }
     602        virtual void accept( Visitor & v ) { v.visit( this ); }
     603        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     604        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    630605};
    631606
     
    642617        void set_callExpr( Expression * newValue ) { callExpr = newValue; }
    643618
    644         virtual ConstructorExpr * clone() const override { return new ConstructorExpr( * this ); }
    645         virtual void accept( Visitor & v ) override { v.visit( this ); }
    646         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    647         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    648         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     619        virtual ConstructorExpr * clone() const { return new ConstructorExpr( * this ); }
     620        virtual void accept( Visitor & v ) { v.visit( this ); }
     621        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     622        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    649623};
    650624
     
    661635        void set_initializer( Initializer * i ) { initializer = i; }
    662636
    663         virtual CompoundLiteralExpr * clone() const override { return new CompoundLiteralExpr( * this ); }
    664         virtual void accept( Visitor & v ) override { v.visit( this ); }
    665         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    666         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    667         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     637        virtual CompoundLiteralExpr * clone() const { return new CompoundLiteralExpr( * this ); }
     638        virtual void accept( Visitor & v ) { v.visit( this ); }
     639        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     640        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    668641};
    669642
     
    681654        RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; }
    682655
    683         virtual RangeExpr * clone() const override { return new RangeExpr( * this ); }
    684         virtual void accept( Visitor & v ) override { v.visit( this ); }
    685         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    686         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    687         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     656        virtual RangeExpr * clone() const { return new RangeExpr( * this ); }
     657        virtual void accept( Visitor & v ) { v.visit( this ); }
     658        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     659        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    688660};
    689661
     
    699671        std::list<Expression*>& get_exprs() { return exprs; }
    700672
    701         virtual UntypedTupleExpr * clone() const override { return new UntypedTupleExpr( * this ); }
    702         virtual void accept( Visitor & v ) override { v.visit( this ); }
    703         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    704         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    705         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     673        virtual UntypedTupleExpr * clone() const { return new UntypedTupleExpr( * this ); }
     674        virtual void accept( Visitor & v ) { v.visit( this ); }
     675        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     676        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    706677};
    707678
     
    717688        std::list<Expression*>& get_exprs() { return exprs; }
    718689
    719         virtual TupleExpr * clone() const override { return new TupleExpr( * this ); }
    720         virtual void accept( Visitor & v ) override { v.visit( this ); }
    721         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    722         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    723         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     690        virtual TupleExpr * clone() const { return new TupleExpr( * this ); }
     691        virtual void accept( Visitor & v ) { v.visit( this ); }
     692        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     693        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    724694};
    725695
     
    739709        TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; }
    740710
    741         virtual TupleIndexExpr * clone() const override { return new TupleIndexExpr( * this ); }
    742         virtual void accept( Visitor & v ) override { v.visit( this ); }
    743         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    744         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    745         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     711        virtual TupleIndexExpr * clone() const { return new TupleIndexExpr( * 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, Indenter indent = {} ) const;
    746715};
    747716
     
    758727        StmtExpr * get_stmtExpr() const { return stmtExpr; }
    759728
    760         virtual TupleAssignExpr * clone() const override { return new TupleAssignExpr( * this ); }
    761         virtual void accept( Visitor & v ) override { v.visit( this ); }
    762         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    763         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    764         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     729        virtual TupleAssignExpr * clone() const { return new TupleAssignExpr( * this ); }
     730        virtual void accept( Visitor & v ) { v.visit( this ); }
     731        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     732        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    765733
    766734        friend class ConverterNewToOld;
     
    792760        std::list< Expression * > & get_dtors() { return dtors; }
    793761
    794         virtual StmtExpr * clone() const override { return new StmtExpr( * this ); }
    795         virtual void accept( Visitor & v ) override { v.visit( this ); }
    796         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    797         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    798         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     762        virtual StmtExpr * clone() const { return new StmtExpr( * this ); }
     763        virtual void accept( Visitor & v ) { v.visit( this ); }
     764        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     765        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    799766};
    800767
     
    820787        int get_id() const { return id; }
    821788
    822         virtual UniqueExpr * clone() const override { return new UniqueExpr( * this ); }
    823         virtual void accept( Visitor & v ) override { v.visit( this ); }
    824         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    825         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    826         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     789        virtual UniqueExpr * clone() const { return new UniqueExpr( * this ); }
     790        virtual void accept( Visitor & v ) { v.visit( this ); }
     791        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     792        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    827793
    828794private:
     
    855821        std::list<InitAlternative> & get_initAlts() { return initAlts; }
    856822
    857         virtual UntypedInitExpr * clone() const override { return new UntypedInitExpr( * this ); }
    858         virtual void accept( Visitor & v ) override { v.visit( this ); }
    859         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    860         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    861         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     823        virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); }
     824        virtual void accept( Visitor & v ) { v.visit( this ); }
     825        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     826        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    862827};
    863828
     
    877842        InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; }
    878843
    879         virtual InitExpr * clone() const override { return new InitExpr( * this ); }
    880         virtual void accept( Visitor & v ) override { v.visit( this ); }
    881         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    882         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    883         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     844        virtual InitExpr * clone() const { return new InitExpr( * this ); }
     845        virtual void accept( Visitor & v ) { v.visit( this ); }
     846        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     847        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    884848};
    885849
     
    888852public:
    889853        Expression * expr;
    890         Declaration * deleteStmt;
    891 
    892         DeletedExpr( Expression * expr, Declaration * deleteStmt );
     854        BaseSyntaxNode * deleteStmt;
     855
     856        DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt );
    893857        DeletedExpr( const DeletedExpr & other );
    894858        ~DeletedExpr();
    895859
    896         virtual DeletedExpr * clone() const override { return new DeletedExpr( * this ); }
    897         virtual void accept( Visitor & v ) override { v.visit( this ); }
    898         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    899         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    900         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     860        virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); }
     861        virtual void accept( Visitor & v ) { v.visit( this ); }
     862        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     863        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    901864};
    902865
     
    910873        ~DefaultArgExpr();
    911874
    912         virtual DefaultArgExpr * clone() const override { return new DefaultArgExpr( * this ); }
    913         virtual void accept( Visitor & v ) override { v.visit( this ); }
    914         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    915         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    916         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     875        virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); }
     876        virtual void accept( Visitor & v ) { v.visit( this ); }
     877        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     878        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    917879};
    918880
     
    939901        virtual ~GenericExpr();
    940902
    941         virtual GenericExpr * clone() const override { return new GenericExpr( * this ); }
    942         virtual void accept( Visitor & v ) override { v.visit( this ); }
    943         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    944         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    945         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     903        virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
     904        virtual void accept( Visitor & v ) { v.visit( this ); }
     905        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     906        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    946907};
    947908
  • src/SynTree/Initializer.h

    r4eb43fa rf6cc734e  
    3838
    3939        virtual Designation * clone() const override { return new Designation( *this ); };
    40         virtual void accept( Visitor & v ) override { v.visit( this ); }
    41         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     40        virtual void accept( Visitor &v ) override { v.visit( this ); }
    4241        virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); }
    4342        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    5352        virtual ~Initializer();
    5453
    55         bool get_maybeConstructed() const { return maybeConstructed; }
     54        bool get_maybeConstructed() { return maybeConstructed; }
    5655
    5756        virtual Initializer *clone() const override = 0;
    58         virtual void accept( Visitor & v ) override = 0;
    59         virtual void accept( Visitor & v ) const override = 0;
     57        virtual void accept( Visitor &v ) override = 0;
    6058        virtual Initializer *acceptMutator( Mutator &m ) override = 0;
    6159        virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
     
    7876
    7977        virtual SingleInit *clone() const override { return new SingleInit( *this); }
    80         virtual void accept( Visitor & v ) override { v.visit( this ); }
    81         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     78        virtual void accept( Visitor &v ) override { v.visit( this ); }
    8279        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    8380        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    107104
    108105        virtual ListInit *clone() const override { return new ListInit( *this ); }
    109         virtual void accept( Visitor & v ) override { v.visit( this ); }
    110         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     106        virtual void accept( Visitor &v ) override { v.visit( this ); }
    111107        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    112108        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    137133
    138134        ConstructorInit *clone() const override { return new ConstructorInit( *this ); }
    139         virtual void accept( Visitor & v ) override { v.visit( this ); }
    140         virtual void accept( Visitor & v ) const override { v.visit( this ); }
     135        virtual void accept( Visitor &v ) override { v.visit( this ); }
    141136        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    142137        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
  • src/SynTree/Mutator.h

    r4eb43fa rf6cc734e  
    5252        virtual Statement * mutate( FinallyStmt * catchStmt ) = 0;
    5353        virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0;
    54         virtual Declaration * mutate( WithStmt * withStmt ) = 0;
     54        virtual Statement * mutate( WithStmt * withStmt ) = 0;
    5555        virtual NullStmt * mutate( NullStmt * nullStmt ) = 0;
    5656        virtual Statement * mutate( DeclStmt * declStmt ) = 0;
  • src/SynTree/Statement.cc

    r4eb43fa rf6cc734e  
    493493
    494494
    495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Declaration("", noStorageClasses, LinkageSpec::Cforall), exprs( exprs ), stmt( stmt ) {}
    496 WithStmt::WithStmt( const WithStmt & other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) {
     495WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}
     496WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
    497497        cloneAll( other.exprs, exprs );
    498498}
  • src/SynTree/Statement.h

    r4eb43fa rf6cc734e  
    4545        virtual Statement * clone() const override = 0;
    4646        virtual void accept( Visitor & v ) override = 0;
    47         virtual void accept( Visitor & v ) const override = 0;
    4847        virtual Statement * acceptMutator( Mutator & m ) override = 0;
    4948        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    6564        virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); }
    6665        virtual void accept( Visitor & v ) override { v.visit( this ); }
    67         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    6866        virtual CompoundStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    6967        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    7674        virtual NullStmt * clone() const override { return new NullStmt( *this ); }
    7775        virtual void accept( Visitor & v ) override { v.visit( this ); }
    78         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    7976        virtual NullStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    8077        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    9491        virtual ExprStmt * clone() const override { return new ExprStmt( *this ); }
    9592        virtual void accept( Visitor & v ) override { v.visit( this ); }
    96         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    9793        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    9894        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    124120        void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; }
    125121
    126         virtual AsmStmt * clone() const override { return new AsmStmt( *this ); }
    127         virtual void accept( Visitor & v ) override { v.visit( this ); }
    128         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    129         virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    130         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     122        virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
     123        virtual void accept( Visitor & v ) { v.visit( this ); }
     124        virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     125        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    131126};
    132127
     
    138133        virtual ~DirectiveStmt(){}
    139134
    140         virtual DirectiveStmt * clone() const override { return new DirectiveStmt( *this ); }
    141         virtual void accept( Visitor & v ) override { v.visit( this ); }
    142         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    143         virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    144         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     135        virtual DirectiveStmt * clone() const { return new DirectiveStmt( *this ); }
     136        virtual void accept( Visitor & v ) { v.visit( this ); }
     137        virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     138        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    145139};
    146140
     
    167161        virtual IfStmt * clone() const override { return new IfStmt( *this ); }
    168162        virtual void accept( Visitor & v ) override { v.visit( this ); }
    169         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    170163        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    171164        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    187180
    188181        virtual void accept( Visitor & v ) override { v.visit( this ); }
    189         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    190182        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    191183
     
    216208
    217209        virtual void accept( Visitor & v ) override { v.visit( this ); }
    218         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    219210        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    220211
     
    245236        virtual WhileStmt * clone() const override { return new WhileStmt( *this ); }
    246237        virtual void accept( Visitor & v ) override { v.visit( this ); }
    247         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    248238        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    249239        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    271261        virtual ForStmt * clone() const override { return new ForStmt( *this ); }
    272262        virtual void accept( Visitor & v ) override { v.visit( this ); }
    273         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    274263        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    275264        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    301290        virtual BranchStmt * clone() const override { return new BranchStmt( *this ); }
    302291        virtual void accept( Visitor & v ) override { v.visit( this ); }
    303         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    304292        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    305293        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    321309        virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); }
    322310        virtual void accept( Visitor & v ) override { v.visit( this ); }
    323         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    324311        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    325312        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    346333        virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); }
    347334        virtual void accept( Visitor & v ) override { v.visit( this ); }
    348         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    349335        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    350336        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    370356        virtual TryStmt * clone() const override { return new TryStmt( *this ); }
    371357        virtual void accept( Visitor & v ) override { v.visit( this ); }
    372         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    373358        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    374359        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    399384        virtual CatchStmt * clone() const override { return new CatchStmt( *this ); }
    400385        virtual void accept( Visitor & v ) override { v.visit( this ); }
    401         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    402386        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    403387        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    417401        virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); }
    418402        virtual void accept( Visitor & v ) override { v.visit( this ); }
    419         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    420403        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    421404        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    455438        virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); }
    456439        virtual void accept( Visitor & v ) override { v.visit( this ); }
    457         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    458         virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    459         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    460 
    461 };
    462 
    463 // class WithStmt : public Statement {
    464 // public:
    465 //      std::list< Expression * > exprs;
    466 //      Statement * stmt;
    467 
    468 //      WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
    469 //      WithStmt( const WithStmt & other );
    470 //      virtual ~WithStmt();
    471 
    472 //      virtual WithStmt * clone() const override { return new WithStmt( *this ); }
    473 //      virtual void accept( Visitor & v ) override { v.visit( this ); }
    474 //      virtual void accept( Visitor & v ) const override { v.visit( this ); }
    475 //      virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    476 //      virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    477 // };
     440        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     441        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     442
     443};
     444
     445class WithStmt : public Statement {
     446public:
     447        std::list< Expression * > exprs;
     448        Statement * stmt;
     449
     450        WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
     451        WithStmt( const WithStmt & other );
     452        virtual ~WithStmt();
     453
     454        virtual WithStmt * clone() const override { return new WithStmt( *this ); }
     455        virtual void accept( Visitor & v ) override { v.visit( this ); }
     456        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     457        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     458};
    478459
    479460
     
    492473        virtual DeclStmt * clone() const override { return new DeclStmt( *this ); }
    493474        virtual void accept( Visitor & v ) override { v.visit( this ); }
    494         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    495475        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    496476        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    514494        virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); }
    515495        virtual void accept( Visitor & v ) override { v.visit( this ); }
    516         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    517496        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    518497        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
  • src/SynTree/Type.h

    r4eb43fa rf6cc734e  
    144144
    145145        Qualifiers & get_qualifiers() { return tq; }
    146         bool get_const() const { return tq.is_const; }
    147         bool get_volatile() const { return tq.is_volatile; }
    148         bool get_restrict() const { return tq.is_restrict; }
    149         bool get_lvalue() const { return tq.is_lvalue; }
    150         bool get_mutex() const { return tq.is_mutex; }
    151         bool get_atomic() const { return tq.is_atomic; }
     146        bool get_const() { return tq.is_const; }
     147        bool get_volatile() { return tq.is_volatile; }
     148        bool get_restrict() { return tq.is_restrict; }
     149        bool get_lvalue() { return tq.is_lvalue; }
     150        bool get_mutex() { return tq.is_mutex; }
     151        bool get_atomic() { return tq.is_atomic; }
    152152        void set_const( bool newValue ) { tq.is_const = newValue; }
    153153        void set_volatile( bool newValue ) { tq.is_volatile = newValue; }
     
    184184        virtual Type *clone() const = 0;
    185185        virtual void accept( Visitor & v ) = 0;
    186         virtual void accept( Visitor & v ) const = 0;
    187186        virtual Type *acceptMutator( Mutator & m ) = 0;
    188187        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     
    202201        virtual VoidType *clone() const override { return new VoidType( *this ); }
    203202        virtual void accept( Visitor & v ) override { v.visit( this ); }
    204         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    205203        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    206204        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    261259        virtual BasicType *clone() const override { return new BasicType( *this ); }
    262260        virtual void accept( Visitor & v ) override { v.visit( this ); }
    263         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    264261        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    265262        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    297294        virtual PointerType *clone() const override { return new PointerType( *this ); }
    298295        virtual void accept( Visitor & v ) override { v.visit( this ); }
    299         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    300296        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    301297        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    329325        virtual ArrayType *clone() const override { return new ArrayType( *this ); }
    330326        virtual void accept( Visitor & v ) override { v.visit( this ); }
    331         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    332327        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    333328        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    345340        virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }
    346341        virtual void accept( Visitor & v ) override { v.visit( this ); }
    347         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    348342        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    349343        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    372366        virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
    373367        virtual void accept( Visitor & v ) override { v.visit( this ); }
    374         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    375368        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    376369        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    402395        virtual FunctionType *clone() const override { return new FunctionType( *this ); }
    403396        virtual void accept( Visitor & v ) override { v.visit( this ); }
    404         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    405397        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    406398        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    463455        virtual StructInstType *clone() const override { return new StructInstType( *this ); }
    464456        virtual void accept( Visitor & v ) override { v.visit( this ); }
    465         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    466457        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    467458
     
    501492        virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
    502493        virtual void accept( Visitor & v ) override { v.visit( this ); }
    503         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    504494        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    505495
     
    529519        virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
    530520        virtual void accept( Visitor & v ) override { v.visit( this ); }
    531         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    532521        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    533522
     
    553542        virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
    554543        virtual void accept( Visitor & v ) override { v.visit( this ); }
    555         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    556544        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    557545  private:
     
    581569        virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
    582570        virtual void accept( Visitor & v ) override { v.visit( this ); }
    583         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    584571        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    585572        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    619606        virtual TupleType *clone() const override { return new TupleType( *this ); }
    620607        virtual void accept( Visitor & v ) override { v.visit( this ); }
    621         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    622608        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    623609        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    630616
    631617        TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    632         TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof,
     618        TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 
    633619                const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    634620        TypeofType( const TypeofType& );
     
    642628        virtual TypeofType *clone() const override { return new TypeofType( *this ); }
    643629        virtual void accept( Visitor & v ) override { v.visit( this ); }
    644         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    645630        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    646631        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    672657        virtual AttrType *clone() const override { return new AttrType( *this ); }
    673658        virtual void accept( Visitor & v ) override { v.visit( this ); }
    674         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    675659        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    676660        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    687671        virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
    688672        virtual void accept( Visitor & v ) override { v.visit( this ); }
    689         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    690673        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    691674        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    700683        virtual ZeroType *clone() const override { return new ZeroType( *this ); }
    701684        virtual void accept( Visitor & v ) override { v.visit( this ); }
    702         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    703685        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    704686        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    713695        virtual OneType *clone() const override { return new OneType( *this ); }
    714696        virtual void accept( Visitor & v ) override { v.visit( this ); }
    715         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    716697        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    717698        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    724705        virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }
    725706        virtual void accept( Visitor & v ) override { v.visit( this ); }
    726         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    727707        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    728708        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
  • src/SynTree/Visitor.h

    r4eb43fa rf6cc734e  
    2727        // of the given syntax node, but performs no other action.
    2828
    29         virtual void visit( ObjectDecl * node ) { visit( const_cast<const ObjectDecl *>(node) ); }
    30         virtual void visit( const ObjectDecl * objectDecl ) = 0;
    31         virtual void visit( FunctionDecl * node ) { visit( const_cast<const FunctionDecl *>(node) ); }
    32         virtual void visit( const FunctionDecl * functionDecl ) = 0;
    33         virtual void visit( StructDecl * node ) { visit( const_cast<const StructDecl *>(node) ); }
    34         virtual void visit( const StructDecl * aggregateDecl ) = 0;
    35         virtual void visit( UnionDecl * node ) { visit( const_cast<const UnionDecl *>(node) ); }
    36         virtual void visit( const UnionDecl * aggregateDecl ) = 0;
    37         virtual void visit( EnumDecl * node ) { visit( const_cast<const EnumDecl *>(node) ); }
    38         virtual void visit( const EnumDecl * aggregateDecl ) = 0;
    39         virtual void visit( TraitDecl * node ) { visit( const_cast<const TraitDecl *>(node) ); }
    40         virtual void visit( const TraitDecl * aggregateDecl ) = 0;
    41         virtual void visit( TypeDecl * node ) { visit( const_cast<const TypeDecl *>(node) ); }
    42         virtual void visit( const TypeDecl * typeDecl ) = 0;
    43         virtual void visit( TypedefDecl * node ) { visit( const_cast<const TypedefDecl *>(node) ); }
    44         virtual void visit( const TypedefDecl * typeDecl ) = 0;
    45         virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); }
    46         virtual void visit( const AsmDecl * asmDecl ) = 0;
    47         virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); }
    48         virtual void visit( const StaticAssertDecl * assertDecl ) = 0;
     29        virtual void visit( ObjectDecl * objectDecl ) = 0;
     30        virtual void visit( FunctionDecl * functionDecl ) = 0;
     31        virtual void visit( StructDecl * aggregateDecl ) = 0;
     32        virtual void visit( UnionDecl * aggregateDecl ) = 0;
     33        virtual void visit( EnumDecl * aggregateDecl ) = 0;
     34        virtual void visit( TraitDecl * aggregateDecl ) = 0;
     35        virtual void visit( TypeDecl * typeDecl ) = 0;
     36        virtual void visit( TypedefDecl * typeDecl ) = 0;
     37        virtual void visit( AsmDecl * asmDecl ) = 0;
     38        virtual void visit( StaticAssertDecl * assertDecl ) = 0;
    4939
    50         virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); }
    51         virtual void visit( const CompoundStmt * compoundStmt ) = 0;
    52         virtual void visit( ExprStmt * node ) { visit( const_cast<const ExprStmt *>(node) ); }
    53         virtual void visit( const ExprStmt * exprStmt ) = 0;
    54         virtual void visit( AsmStmt * node ) { visit( const_cast<const AsmStmt *>(node) ); }
    55         virtual void visit( const AsmStmt * asmStmt ) = 0;
    56         virtual void visit( DirectiveStmt * node ) { visit( const_cast<const DirectiveStmt *>(node) ); }
    57         virtual void visit( const DirectiveStmt * directiveStmt ) = 0;
    58         virtual void visit( IfStmt * node ) { visit( const_cast<const IfStmt *>(node) ); }
    59         virtual void visit( const IfStmt * ifStmt ) = 0;
    60         virtual void visit( WhileStmt * node ) { visit( const_cast<const WhileStmt *>(node) ); }
    61         virtual void visit( const WhileStmt * whileStmt ) = 0;
    62         virtual void visit( ForStmt * node ) { visit( const_cast<const ForStmt *>(node) ); }
    63         virtual void visit( const ForStmt * forStmt ) = 0;
    64         virtual void visit( SwitchStmt * node ) { visit( const_cast<const SwitchStmt *>(node) ); }
    65         virtual void visit( const SwitchStmt * switchStmt ) = 0;
    66         virtual void visit( CaseStmt * node ) { visit( const_cast<const CaseStmt *>(node) ); }
    67         virtual void visit( const CaseStmt * caseStmt ) = 0;
    68         virtual void visit( BranchStmt * node ) { visit( const_cast<const BranchStmt *>(node) ); }
    69         virtual void visit( const BranchStmt * branchStmt ) = 0;
    70         virtual void visit( ReturnStmt * node ) { visit( const_cast<const ReturnStmt *>(node) ); }
    71         virtual void visit( const ReturnStmt * returnStmt ) = 0;
    72         virtual void visit( ThrowStmt * node ) { visit( const_cast<const ThrowStmt *>(node) ); }
    73         virtual void visit( const ThrowStmt * throwStmt ) = 0;
    74         virtual void visit( TryStmt * node ) { visit( const_cast<const TryStmt *>(node) ); }
    75         virtual void visit( const TryStmt * tryStmt ) = 0;
    76         virtual void visit( CatchStmt * node ) { visit( const_cast<const CatchStmt *>(node) ); }
    77         virtual void visit( const CatchStmt * catchStmt ) = 0;
    78         virtual void visit( FinallyStmt * node ) { visit( const_cast<const FinallyStmt *>(node) ); }
    79         virtual void visit( const FinallyStmt * finallyStmt ) = 0;
    80         virtual void visit( WaitForStmt * node ) { visit( const_cast<const WaitForStmt *>(node) ); }
    81         virtual void visit( const WaitForStmt * waitforStmt ) = 0;
    82         virtual void visit( WithStmt * node ) { visit( const_cast<const WithStmt *>(node) ); }
    83         virtual void visit( const WithStmt * withStmt ) = 0;
    84         virtual void visit( NullStmt * node ) { visit( const_cast<const NullStmt *>(node) ); }
    85         virtual void visit( const NullStmt * nullStmt ) = 0;
    86         virtual void visit( DeclStmt * node ) { visit( const_cast<const DeclStmt *>(node) ); }
    87         virtual void visit( const DeclStmt * declStmt ) = 0;
    88         virtual void visit( ImplicitCtorDtorStmt * node ) { visit( const_cast<const ImplicitCtorDtorStmt *>(node) ); }
    89         virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0;
     40        virtual void visit( CompoundStmt * compoundStmt ) = 0;
     41        virtual void visit( ExprStmt * exprStmt ) = 0;
     42        virtual void visit( AsmStmt * asmStmt ) = 0;
     43        virtual void visit( DirectiveStmt * directiveStmt ) = 0;
     44        virtual void visit( IfStmt * ifStmt ) = 0;
     45        virtual void visit( WhileStmt * whileStmt ) = 0;
     46        virtual void visit( ForStmt * forStmt ) = 0;
     47        virtual void visit( SwitchStmt * switchStmt ) = 0;
     48        virtual void visit( CaseStmt * caseStmt ) = 0;
     49        virtual void visit( BranchStmt * branchStmt ) = 0;
     50        virtual void visit( ReturnStmt * returnStmt ) = 0;
     51        virtual void visit( ThrowStmt * throwStmt ) = 0;
     52        virtual void visit( TryStmt * tryStmt ) = 0;
     53        virtual void visit( CatchStmt * catchStmt ) = 0;
     54        virtual void visit( FinallyStmt * finallyStmt ) = 0;
     55        virtual void visit( WaitForStmt * waitforStmt ) = 0;
     56        virtual void visit( WithStmt * withStmt ) = 0;
     57        virtual void visit( NullStmt * nullStmt ) = 0;
     58        virtual void visit( DeclStmt * declStmt ) = 0;
     59        virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0;
    9060
    91         virtual void visit( ApplicationExpr * node ) { visit( const_cast<const ApplicationExpr *>(node) ); }
    92         virtual void visit( const ApplicationExpr * applicationExpr ) = 0;
    93         virtual void visit( UntypedExpr * node ) { visit( const_cast<const UntypedExpr *>(node) ); }
    94         virtual void visit( const UntypedExpr * untypedExpr ) = 0;
    95         virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); }
    96         virtual void visit( const NameExpr * nameExpr ) = 0;
    97         virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); }
    98         virtual void visit( const CastExpr * castExpr ) = 0;
    99         virtual void visit( KeywordCastExpr * node ) { visit( const_cast<const KeywordCastExpr *>(node) ); }
    100         virtual void visit( const KeywordCastExpr * castExpr ) = 0;
    101         virtual void visit( VirtualCastExpr * node ) { visit( const_cast<const VirtualCastExpr *>(node) ); }
    102         virtual void visit( const VirtualCastExpr * castExpr ) = 0;
    103         virtual void visit( AddressExpr * node ) { visit( const_cast<const AddressExpr *>(node) ); }
    104         virtual void visit( const AddressExpr * addressExpr ) = 0;
    105         virtual void visit( LabelAddressExpr * node ) { visit( const_cast<const LabelAddressExpr *>(node) ); }
    106         virtual void visit( const LabelAddressExpr * labAddressExpr ) = 0;
    107         virtual void visit( UntypedMemberExpr * node ) { visit( const_cast<const UntypedMemberExpr *>(node) ); }
    108         virtual void visit( const UntypedMemberExpr * memberExpr ) = 0;
    109         virtual void visit( MemberExpr * node ) { visit( const_cast<const MemberExpr *>(node) ); }
    110         virtual void visit( const MemberExpr * memberExpr ) = 0;
    111         virtual void visit( VariableExpr * node ) { visit( const_cast<const VariableExpr *>(node) ); }
    112         virtual void visit( const VariableExpr * variableExpr ) = 0;
    113         virtual void visit( ConstantExpr * node ) { visit( const_cast<const ConstantExpr *>(node) ); }
    114         virtual void visit( const ConstantExpr * constantExpr ) = 0;
    115         virtual void visit( SizeofExpr * node ) { visit( const_cast<const SizeofExpr *>(node) ); }
    116         virtual void visit( const SizeofExpr * sizeofExpr ) = 0;
    117         virtual void visit( AlignofExpr * node ) { visit( const_cast<const AlignofExpr *>(node) ); }
    118         virtual void visit( const AlignofExpr * alignofExpr ) = 0;
    119         virtual void visit( UntypedOffsetofExpr * node ) { visit( const_cast<const UntypedOffsetofExpr *>(node) ); }
    120         virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) = 0;
    121         virtual void visit( OffsetofExpr * node ) { visit( const_cast<const OffsetofExpr *>(node) ); }
    122         virtual void visit( const OffsetofExpr * offsetofExpr ) = 0;
    123         virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); }
    124         virtual void visit( const OffsetPackExpr * offsetPackExpr ) = 0;
    125         virtual void visit( AttrExpr * node ) { visit( const_cast<const AttrExpr *>(node) ); }
    126         virtual void visit( const AttrExpr * attrExpr ) = 0;
    127         virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); }
    128         virtual void visit( const LogicalExpr * logicalExpr ) = 0;
    129         virtual void visit( ConditionalExpr * node ) { visit( const_cast<const ConditionalExpr *>(node) ); }
    130         virtual void visit( const ConditionalExpr * conditionalExpr ) = 0;
    131         virtual void visit( CommaExpr * node ) { visit( const_cast<const CommaExpr *>(node) ); }
    132         virtual void visit( const CommaExpr * commaExpr ) = 0;
    133         virtual void visit( TypeExpr * node ) { visit( const_cast<const TypeExpr *>(node) ); }
    134         virtual void visit( const TypeExpr * typeExpr ) = 0;
    135         virtual void visit( AsmExpr * node ) { visit( const_cast<const AsmExpr *>(node) ); }
    136         virtual void visit( const AsmExpr * asmExpr ) = 0;
    137         virtual void visit( ImplicitCopyCtorExpr * node ) { visit( const_cast<const ImplicitCopyCtorExpr *>(node) ); }
    138         virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) = 0;
    139         virtual void visit( ConstructorExpr * node ) { visit( const_cast<const ConstructorExpr *>(node) ); }
    140         virtual void visit( const ConstructorExpr *  ctorExpr ) = 0;
    141         virtual void visit( CompoundLiteralExpr * node ) { visit( const_cast<const CompoundLiteralExpr *>(node) ); }
    142         virtual void visit( const CompoundLiteralExpr * compLitExpr ) = 0;
    143         virtual void visit( RangeExpr * node ) { visit( const_cast<const RangeExpr *>(node) ); }
    144         virtual void visit( const RangeExpr * rangeExpr ) = 0;
    145         virtual void visit( UntypedTupleExpr * node ) { visit( const_cast<const UntypedTupleExpr *>(node) ); }
    146         virtual void visit( const UntypedTupleExpr * tupleExpr ) = 0;
    147         virtual void visit( TupleExpr * node ) { visit( const_cast<const TupleExpr *>(node) ); }
    148         virtual void visit( const TupleExpr * tupleExpr ) = 0;
    149         virtual void visit( TupleIndexExpr * node ) { visit( const_cast<const TupleIndexExpr *>(node) ); }
    150         virtual void visit( const TupleIndexExpr * tupleExpr ) = 0;
    151         virtual void visit( TupleAssignExpr * node ) { visit( const_cast<const TupleAssignExpr *>(node) ); }
    152         virtual void visit( const TupleAssignExpr * assignExpr ) = 0;
    153         virtual void visit( StmtExpr * node ) { visit( const_cast<const StmtExpr *>(node) ); }
    154         virtual void visit( const StmtExpr *  stmtExpr ) = 0;
    155         virtual void visit( UniqueExpr * node ) { visit( const_cast<const UniqueExpr *>(node) ); }
    156         virtual void visit( const UniqueExpr *  uniqueExpr ) = 0;
    157         virtual void visit( UntypedInitExpr * node ) { visit( const_cast<const UntypedInitExpr *>(node) ); }
    158         virtual void visit( const UntypedInitExpr *  initExpr ) = 0;
    159         virtual void visit( InitExpr * node ) { visit( const_cast<const InitExpr *>(node) ); }
    160         virtual void visit( const InitExpr *  initExpr ) = 0;
    161         virtual void visit( DeletedExpr * node ) { visit( const_cast<const DeletedExpr *>(node) ); }
    162         virtual void visit( const DeletedExpr * delExpr ) = 0;
    163         virtual void visit( DefaultArgExpr * node ) { visit( const_cast<const DefaultArgExpr *>(node) ); }
    164         virtual void visit( const DefaultArgExpr * argExpr ) = 0;
    165         virtual void visit( GenericExpr * node ) { visit( const_cast<const GenericExpr *>(node) ); }
    166         virtual void visit( const GenericExpr * genExpr ) = 0;
     61        virtual void visit( ApplicationExpr * applicationExpr ) = 0;
     62        virtual void visit( UntypedExpr * untypedExpr ) = 0;
     63        virtual void visit( NameExpr * nameExpr ) = 0;
     64        virtual void visit( CastExpr * castExpr ) = 0;
     65        virtual void visit( KeywordCastExpr * castExpr ) = 0;
     66        virtual void visit( VirtualCastExpr * castExpr ) = 0;
     67        virtual void visit( AddressExpr * addressExpr ) = 0;
     68        virtual void visit( LabelAddressExpr * labAddressExpr ) = 0;
     69        virtual void visit( UntypedMemberExpr * memberExpr ) = 0;
     70        virtual void visit( MemberExpr * memberExpr ) = 0;
     71        virtual void visit( VariableExpr * variableExpr ) = 0;
     72        virtual void visit( ConstantExpr * constantExpr ) = 0;
     73        virtual void visit( SizeofExpr * sizeofExpr ) = 0;
     74        virtual void visit( AlignofExpr * alignofExpr ) = 0;
     75        virtual void visit( UntypedOffsetofExpr * offsetofExpr ) = 0;
     76        virtual void visit( OffsetofExpr * offsetofExpr ) = 0;
     77        virtual void visit( OffsetPackExpr * offsetPackExpr ) = 0;
     78        virtual void visit( AttrExpr * attrExpr ) = 0;
     79        virtual void visit( LogicalExpr * logicalExpr ) = 0;
     80        virtual void visit( ConditionalExpr * conditionalExpr ) = 0;
     81        virtual void visit( CommaExpr * commaExpr ) = 0;
     82        virtual void visit( TypeExpr * typeExpr ) = 0;
     83        virtual void visit( AsmExpr * asmExpr ) = 0;
     84        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) = 0;
     85        virtual void visit( ConstructorExpr *  ctorExpr ) = 0;
     86        virtual void visit( CompoundLiteralExpr * compLitExpr ) = 0;
     87        virtual void visit( RangeExpr * rangeExpr ) = 0;
     88        virtual void visit( UntypedTupleExpr * tupleExpr ) = 0;
     89        virtual void visit( TupleExpr * tupleExpr ) = 0;
     90        virtual void visit( TupleIndexExpr * tupleExpr ) = 0;
     91        virtual void visit( TupleAssignExpr * assignExpr ) = 0;
     92        virtual void visit( StmtExpr *  stmtExpr ) = 0;
     93        virtual void visit( UniqueExpr *  uniqueExpr ) = 0;
     94        virtual void visit( UntypedInitExpr *  initExpr ) = 0;
     95        virtual void visit( InitExpr *  initExpr ) = 0;
     96        virtual void visit( DeletedExpr * delExpr ) = 0;
     97        virtual void visit( DefaultArgExpr * argExpr ) = 0;
     98        virtual void visit( GenericExpr * genExpr ) = 0;
    16799
    168         virtual void visit( VoidType * node ) { visit( const_cast<const VoidType *>(node) ); }
    169         virtual void visit( const VoidType * basicType ) = 0;
    170         virtual void visit( BasicType * node ) { visit( const_cast<const BasicType *>(node) ); }
    171         virtual void visit( const BasicType * basicType ) = 0;
    172         virtual void visit( PointerType * node ) { visit( const_cast<const PointerType *>(node) ); }
    173         virtual void visit( const PointerType * pointerType ) = 0;
    174         virtual void visit( ArrayType * node ) { visit( const_cast<const ArrayType *>(node) ); }
    175         virtual void visit( const ArrayType * arrayType ) = 0;
    176         virtual void visit( ReferenceType * node ) { visit( const_cast<const ReferenceType *>(node) ); }
    177         virtual void visit( const ReferenceType * refType ) = 0;
    178         virtual void visit( QualifiedType * node ) { visit( const_cast<const QualifiedType *>(node) ); }
    179         virtual void visit( const QualifiedType * qualType ) = 0;
    180         virtual void visit( FunctionType * node ) { visit( const_cast<const FunctionType *>(node) ); }
    181         virtual void visit( const FunctionType * functionType ) = 0;
    182         virtual void visit( StructInstType * node ) { visit( const_cast<const StructInstType *>(node) ); }
    183         virtual void visit( const StructInstType * aggregateUseType ) = 0;
    184         virtual void visit( UnionInstType * node ) { visit( const_cast<const UnionInstType *>(node) ); }
    185         virtual void visit( const UnionInstType * aggregateUseType ) = 0;
    186         virtual void visit( EnumInstType * node ) { visit( const_cast<const EnumInstType *>(node) ); }
    187         virtual void visit( const EnumInstType * aggregateUseType ) = 0;
    188         virtual void visit( TraitInstType * node ) { visit( const_cast<const TraitInstType *>(node) ); }
    189         virtual void visit( const TraitInstType * aggregateUseType ) = 0;
    190         virtual void visit( TypeInstType * node ) { visit( const_cast<const TypeInstType *>(node) ); }
    191         virtual void visit( const TypeInstType * aggregateUseType ) = 0;
    192         virtual void visit( TupleType * node ) { visit( const_cast<const TupleType *>(node) ); }
    193         virtual void visit( const TupleType * tupleType ) = 0;
    194         virtual void visit( TypeofType * node ) { visit( const_cast<const TypeofType *>(node) ); }
    195         virtual void visit( const TypeofType * typeofType ) = 0;
    196         virtual void visit( AttrType * node ) { visit( const_cast<const AttrType *>(node) ); }
    197         virtual void visit( const AttrType * attrType ) = 0;
    198         virtual void visit( VarArgsType * node ) { visit( const_cast<const VarArgsType *>(node) ); }
    199         virtual void visit( const VarArgsType * varArgsType ) = 0;
    200         virtual void visit( ZeroType * node ) { visit( const_cast<const ZeroType *>(node) ); }
    201         virtual void visit( const ZeroType * zeroType ) = 0;
    202         virtual void visit( OneType * node ) { visit( const_cast<const OneType *>(node) ); }
    203         virtual void visit( const OneType * oneType ) = 0;
    204         virtual void visit( GlobalScopeType * node ) { visit( const_cast<const GlobalScopeType *>(node) ); }
    205         virtual void visit( const GlobalScopeType * globalType ) = 0;
     100        virtual void visit( VoidType * basicType ) = 0;
     101        virtual void visit( BasicType * basicType ) = 0;
     102        virtual void visit( PointerType * pointerType ) = 0;
     103        virtual void visit( ArrayType * arrayType ) = 0;
     104        virtual void visit( ReferenceType * refType ) = 0;
     105        virtual void visit( QualifiedType * qualType ) = 0;
     106        virtual void visit( FunctionType * functionType ) = 0;
     107        virtual void visit( StructInstType * aggregateUseType ) = 0;
     108        virtual void visit( UnionInstType * aggregateUseType ) = 0;
     109        virtual void visit( EnumInstType * aggregateUseType ) = 0;
     110        virtual void visit( TraitInstType * aggregateUseType ) = 0;
     111        virtual void visit( TypeInstType * aggregateUseType ) = 0;
     112        virtual void visit( TupleType * tupleType ) = 0;
     113        virtual void visit( TypeofType * typeofType ) = 0;
     114        virtual void visit( AttrType * attrType ) = 0;
     115        virtual void visit( VarArgsType * varArgsType ) = 0;
     116        virtual void visit( ZeroType * zeroType ) = 0;
     117        virtual void visit( OneType * oneType ) = 0;
     118        virtual void visit( GlobalScopeType * globalType ) = 0;
    206119
    207         virtual void visit( Designation * node ) { visit( const_cast<const Designation *>(node) ); }
    208         virtual void visit( const Designation * designation ) = 0;
    209         virtual void visit( SingleInit * node ) { visit( const_cast<const SingleInit *>(node) ); }
    210         virtual void visit( const SingleInit * singleInit ) = 0;
    211         virtual void visit( ListInit * node ) { visit( const_cast<const ListInit *>(node) ); }
    212         virtual void visit( const ListInit * listInit ) = 0;
    213         virtual void visit( ConstructorInit * node ) { visit( const_cast<const ConstructorInit *>(node) ); }
    214         virtual void visit( const ConstructorInit * ctorInit ) = 0;
     120        virtual void visit( Designation * designation ) = 0;
     121        virtual void visit( SingleInit * singleInit ) = 0;
     122        virtual void visit( ListInit * listInit ) = 0;
     123        virtual void visit( ConstructorInit * ctorInit ) = 0;
    215124
    216         virtual void visit( Constant * node ) { visit( const_cast<const Constant *>(node) ); }
    217         virtual void visit( const Constant * constant ) = 0;
     125        virtual void visit( Constant * constant ) = 0;
    218126
    219         virtual void visit( Attribute * node ) { visit( const_cast<const Attribute *>(node) ); }
    220         virtual void visit( const Attribute * attribute ) = 0;
     127        virtual void visit( Attribute * attribute ) = 0;
    221128};
    222129
    223130template< typename TreeType, typename VisitorType >
    224 inline void maybeAccept( TreeType * tree, VisitorType & visitor ) {
    225         if ( tree ) {
    226                 tree->accept( visitor );
    227         }
    228 }
    229 
    230 template< typename TreeType, typename VisitorType >
    231 inline void maybeAccept( const TreeType * tree, VisitorType & visitor ) {
     131inline void maybeAccept( TreeType *tree, VisitorType &visitor ) {
    232132        if ( tree ) {
    233133                tree->accept( visitor );
     
    236136
    237137template< typename Container, typename VisitorType >
    238 inline void acceptAll( Container & container, VisitorType & visitor ) {
     138inline void acceptAll( Container &container, VisitorType &visitor ) {
    239139        SemanticErrorException errors;
    240         for ( auto * i : container ) {
     140        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    241141                try {
    242                         if ( i ) {
    243                                 i->accept( visitor );
    244                         }
    245                 } catch( SemanticErrorException & e ) {
    246                         errors.append( e );
    247                 }
    248         }
    249         if ( ! errors.isEmpty() ) {
    250                 throw errors;
    251         }
    252 }
    253 
    254 template< typename Container, typename VisitorType >
    255 inline void acceptAll( const Container & container, VisitorType & visitor ) {
    256         SemanticErrorException errors;
    257         for ( const auto * i : container ) {
    258                 try {
    259                         if ( i ) {
    260                                 i->accept( visitor );
     142                        if ( *i ) {
     143                                (*i)->accept( visitor );
    261144                        }
    262145                } catch( SemanticErrorException &e ) {
  • src/Tuples/Explode.h

    r4eb43fa rf6cc734e  
    5151        template<typename OutputIterator>
    5252        void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
    53                         const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need,
     53                        const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 
    5454                        const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
    5555                *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost };
     
    5858        /// Append alternative to an ExplodedActual
    5959        static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
    60                         const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&,
     60                        const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 
    6161                        const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
    6262                ea.exprs.emplace_back( expr );
     
    111111                } else {
    112112                        // atomic (non-tuple) type - output a clone of the expression in a new alternative
    113                         append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,
     113                        append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 
    114114                                alt.cost, alt.cvtCost );
    115115                }
     
    174174template< typename Output >
    175175void explodeRecursive(
    176         const ast::CastExpr *, const ResolvExpr::Candidate &,
    177         const ast::SymbolTable &, Output &&
     176        const ast::CastExpr * expr, const ResolvExpr::Candidate & arg,
     177        const ast::SymbolTable & symtab, Output && out
    178178) {
    179179}
     
    239239/// explode list of candidates into flattened list of candidates
    240240template< typename Output >
    241 void explode(
    242         const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out,
     241void explode( 
     242        const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 
    243243        bool isTupleAssign = false
    244244) {
  • src/Tuples/TupleAssignment.cc

    r4eb43fa rf6cc734e  
    6767                struct Matcher {
    6868                  public:
    69                         Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs,
     69                        Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 
    7070                                const ResolvExpr::AltList& rhs );
    7171                        virtual ~Matcher() {}
    72 
     72                       
    7373                        virtual void match( std::list< Expression * > &out ) = 0;
    7474                        ObjectDecl * newObject( UniqueName & namer, Expression * expr );
     
    8383                                for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); }
    8484                        }
    85 
     85                       
    8686                        ResolvExpr::AltList lhs, rhs;
    8787                        TupleAssignSpotter_old &spotter;
     
    264264                }
    265265
    266                 // extract expressions from the assignment alternatives to produce a list of assignments
     266                // extract expressions from the assignment alternatives to produce a list of assignments 
    267267                // that together form a single alternative
    268268                std::list< Expression *> solved_assigns;
     
    271271                        matcher->combineState( alt );
    272272                }
    273 
     273               
    274274                // xxx -- was push_front
    275275                currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{
    276                         new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv,
    277                         matcher->openVars,
    278                         ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ),
     276                        new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 
     277                        matcher->openVars, 
     278                        ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 
    279279                        ResolvExpr::sumCost( current ) + matcher->baseCost } );
    280280        }
     
    284284        : lhs(lhs), rhs(rhs), spotter(spotter),
    285285          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
    286                 combineState( lhs );
     286                combineState( lhs ); 
    287287                combineState( rhs );
    288288        }
     
    390390                return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() );
    391391        }
    392 
     392       
    393393        /// true if `expr` is of tuple type or a reference to one
    394394        bool refToTuple( const ast::Expr * expr ) {
     
    421421                        }
    422422
    423                         Matcher(
     423                        Matcher( 
    424424                                TupleAssignSpotter_new & s, const CodeLocation & loc,
    425425                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    426                         : lhs( l ), rhs( r ), spotter( s ), location( loc ),
    427                           baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(),
     426                        : lhs( l ), rhs( r ), spotter( s ), location( loc ), 
     427                          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 
    428428                          env(), open(), need() {
    429429                                for ( auto & cand : lhs ) combineState( *cand );
    430430                                for ( auto & cand : rhs ) combineState( *cand );
    431431                        }
    432                         virtual ~Matcher() = default;
    433432
    434433                        virtual std::vector< ast::ptr< ast::Expr > > match() = 0;
    435434
    436                         /// removes environments from subexpressions within statement expressions, which could
    437                         /// throw off later passes like those in Box which rely on PolyMutator, and adds the
     435                        /// removes environments from subexpressions within statement expressions, which could 
     436                        /// throw off later passes like those in Box which rely on PolyMutator, and adds the 
    438437                        /// bindings to the env
    439438                        struct EnvRemover {
     
    456455                        ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) {
    457456                                assert( expr->result && ! expr->result->isVoid() );
    458 
    459                                 ast::ObjectDecl * ret = new ast::ObjectDecl{
    460                                         location, namer.newName(), expr->result, new ast::SingleInit{ location, expr },
     457                               
     458                                ast::ObjectDecl * ret = new ast::ObjectDecl{ 
     459                                        location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 
    461460                                        ast::Storage::Classes{}, ast::Linkage::Cforall };
    462 
     461                               
    463462                                // if expression type is a reference, just need an initializer, otherwise construct
    464463                                if ( ! expr->result.as< ast::ReferenceType >() ) {
    465464                                        // resolve ctor/dtor for the new object
    466                                         ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
     465                                        ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 
    467466                                                        InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms );
    468467                                        // remove environments from subexpressions of stmtExpr
     
    475474                        }
    476475
    477                         ast::UntypedExpr * createFunc(
    478                                 const std::string & fname, const ast::ObjectDecl * left,
    479                                 const ast::ObjectDecl * right
     476                        ast::UntypedExpr * createFunc( 
     477                                const std::string & fname, const ast::ObjectDecl * left, 
     478                                const ast::ObjectDecl * right 
    480479                        ) {
    481480                                assert( left );
     
    487486                                        args.front() = new ast::AddressExpr{ location, args.front() };
    488487                                        if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; }
    489                                         return new ast::UntypedExpr{
     488                                        return new ast::UntypedExpr{ 
    490489                                                location, new ast::NameExpr{ location, "?=?" }, std::move(args) };
    491490                                } else {
    492                                         return new ast::UntypedExpr{
     491                                        return new ast::UntypedExpr{ 
    493492                                                location, new ast::NameExpr{ location, fname }, std::move(args) };
    494493                                }
     
    499498                struct MassAssignMatcher final : public Matcher {
    500499                        MassAssignMatcher(
    501                                 TupleAssignSpotter_new & s, const CodeLocation & loc,
     500                                TupleAssignSpotter_new & s, const CodeLocation & loc, 
    502501                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    503502                        : Matcher( s, loc, l, r ) {}
     
    509508                                assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 );
    510509
    511                                 ast::ptr< ast::ObjectDecl > rtmp =
     510                                ast::ptr< ast::ObjectDecl > rtmp = 
    512511                                        rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr;
    513512
    514513                                std::vector< ast::ptr< ast::Expr > > out;
    515514                                for ( ResolvExpr::CandidateRef & lhsCand : lhs ) {
    516                                         // create a temporary object for each value in the LHS and create a call
     515                                        // create a temporary object for each value in the LHS and create a call 
    517516                                        // involving the RHS
    518517                                        ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr );
     
    529528                struct MultipleAssignMatcher final : public Matcher {
    530529                        MultipleAssignMatcher(
    531                                 TupleAssignSpotter_new & s, const CodeLocation & loc,
     530                                TupleAssignSpotter_new & s, const CodeLocation & loc, 
    532531                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    533532                        : Matcher( s, loc, l, r ) {}
     
    539538                                if ( lhs.size() != rhs.size() ) return {};
    540539
    541                                 // produce a new temporary object for each value in the LHS and RHS and pairwise
     540                                // produce a new temporary object for each value in the LHS and RHS and pairwise 
    542541                                // create the calls
    543542                                std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp;
     
    548547                                        ResolvExpr::CandidateRef & rhsCand = rhs[i];
    549548
    550                                         // convert RHS to LHS type minus one reference -- important for case where LHS
     549                                        // convert RHS to LHS type minus one reference -- important for case where LHS 
    551550                                        // is && and RHS is lvalue
    552551                                        auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
     
    558557                                        rtmp.emplace_back( std::move( robj ) );
    559558
    560                                         // resolve the cast expression so that rhsCand return type is bound by the cast
     559                                        // resolve the cast expression so that rhsCand return type is bound by the cast 
    561560                                        // type as needed, and transfer the resulting environment
    562561                                        ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env };
     
    565564                                        env = std::move( finder.candidates.front()->env );
    566565                                }
    567 
     566                               
    568567                                splice( tmpDecls, ltmp );
    569568                                splice( tmpDecls, rtmp );
    570 
     569                               
    571570                                return out;
    572571                        }
     
    576575                std::string fname;
    577576                std::unique_ptr< Matcher > matcher;
    578 
     577       
    579578        public:
    580                 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f )
     579                TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 
    581580                : crntFinder( f ), fname(), matcher() {}
    582581
    583582                // find left- and right-hand-sides for mass or multiple assignment
    584                 void spot(
    585                         const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args
     583                void spot( 
     584                        const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 
    586585                ) {
    587586                        if ( auto op = expr->func.as< ast::NameExpr >() ) {
     
    600599                                        if ( ! refToTuple( lhsCand->expr ) ) continue;
    601600
    602                                         // explode is aware of casts - ensure every LHS is sent into explode with a
     601                                        // explode is aware of casts - ensure every LHS is sent into explode with a 
    603602                                        // reference cast
    604603                                        if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
    605                                                 lhsCand->expr = new ast::CastExpr{
     604                                                lhsCand->expr = new ast::CastExpr{ 
    606605                                                        lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
    607606                                        }
     
    611610                                        explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true );
    612611                                        for ( ResolvExpr::CandidateRef & cand : lhs ) {
    613                                                 // each LHS value must be a reference - some come in with a cast, if not
     612                                                // each LHS value must be a reference - some come in with a cast, if not 
    614613                                                // just cast to reference here
    615614                                                if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
     
    630629                                                                // multiple assignment
    631630                                                                explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
    632                                                                 matcher.reset(
     631                                                                matcher.reset( 
    633632                                                                        new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
    634633                                                        } else {
    635634                                                                // mass assignment
    636635                                                                rhs.emplace_back( rhsCand );
    637                                                                 matcher.reset(
     636                                                                matcher.reset( 
    638637                                                                        new MassAssignMatcher{ *this, expr->location, lhs, rhs } );
    639638                                                        }
     
    643642                                                // expand all possible RHS possibilities
    644643                                                std::vector< ResolvExpr::CandidateList > rhsCands;
    645                                                 combos(
     644                                                combos( 
    646645                                                        std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) );
    647646                                                for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) {
     
    649648                                                        ResolvExpr::CandidateList rhs;
    650649                                                        explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
    651                                                         matcher.reset(
     650                                                        matcher.reset( 
    652651                                                                new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
    653652                                                        match();
     
    664663
    665664                        if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) {
    666                                 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's
    667                                 // okay for newAssigns to be empty. Otherwise, return early so that no new
     665                                // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 
     666                                // okay for newAssigns to be empty. Otherwise, return early so that no new 
    668667                                // candidates are generated
    669668                                if ( newAssigns.empty() ) return;
     
    693692                        }
    694693
    695                         // extract expressions from the assignment candidates to produce a list of assignments
     694                        // extract expressions from the assignment candidates to produce a list of assignments 
    696695                        // that together form a sigle candidate
    697696                        std::vector< ast::ptr< ast::Expr > > solved;
     
    702701
    703702                        crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >(
    704                                 new ast::TupleAssignExpr{
    705                                         matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) },
    706                                 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ),
     703                                new ast::TupleAssignExpr{ 
     704                                        matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 
     705                                std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 
    707706                                ResolvExpr::sumCost( crnt ) + matcher->baseCost ) );
    708707                }
     
    710709} // anonymous namespace
    711710
    712 void handleTupleAssignment(
    713         ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
     711void handleTupleAssignment( 
     712        ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 
    714713        std::vector< ResolvExpr::CandidateFinder > & args
    715714) {
  • src/main.cc

    r4eb43fa rf6cc734e  
    460460        const char * descript;
    461461} printopts[] = {
    462         { "ascodegen", codegenp, true, "print AST as codegen rather than AST" },
    463         { "asterr", errorp, true, "print AST on error" },
     462        { "altexpr", expraltp, true, "alternatives for expressions" },
     463        { "ascodegen", codegenp, true, "as codegen rather than AST" },
     464        { "ast", astp, true, "AST after parsing" },
     465        { "astdecl", validp, true, "AST after declaration validation pass" },
     466        { "asterr", errorp, true, "AST on error" },
     467        { "astexpr", exprp, true, "AST after expression analysis" },
     468        { "astgen", genericsp, true, "AST after instantiate generics" },
     469        { "box", bboxp, true, "before box step" },
     470        { "ctordtor", ctorinitp, true, "after ctor/dtor are replaced" },
     471        { "codegen", bcodegenp, true, "before code generation" },
    464472        { "declstats", declstatsp, true, "code property statistics" },
    465473        { "parse", yydebug, true, "yacc (parsing) debug information" },
    466474        { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" },
     475        { "resolver", bresolvep, true, "before resolver step" },
    467476        { "rproto", resolvprotop, true, "resolver-proto instance" },
    468         { "rsteps", resolvep, true, "print resolver steps" },
    469         { "tree", parsep, true, "print parse tree" },
    470         // code dumps
    471         { "ast", astp, true, "print AST after parsing" },
    472         { "symevt", symtabp, true, "print AST after symbol table events" },
    473         { "altexpr", expraltp, true, "print alternatives for expressions" },
    474         { "astdecl", validp, true, "print AST after declaration validation pass" },
    475         { "resolver", bresolvep, true, "print AST before resolver step" },
    476         { "astexpr", exprp, true, "print AST after expression analysis" },
    477         { "ctordtor", ctorinitp, true, "print AST after ctor/dtor are replaced" },
    478         { "tuple", tuplep, true, "print AST after tuple expansion" },
    479         { "astgen", genericsp, true, "print AST after instantiate generics" },
    480         { "box", bboxp, true, "print AST before box step" },
    481         { "codegen", bcodegenp, true, "print AST before code generation" },
     477        { "rsteps", resolvep, true, "resolver steps" },
     478        { "symevt", symtabp, true, "symbol table events" },
     479        { "tree", parsep, true, "parse tree" },
     480        { "tuple", tuplep, true, "after tuple expansion" },
    482481};
    483482enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
  • tests/.expect/completeTypeError.txt

    r4eb43fa rf6cc734e  
    2727    void
    2828  )
    29   Environment:( _83_4_DT ) -> instance of struct A with body 0 (no widening)
     29  Environment:( _82_4_DT ) -> instance of struct A with body 0 (no widening)
    3030
    3131
     
    5050    void
    5151  )
    52   Environment:( _83_4_DT ) -> instance of struct B with body 1 (no widening)
     52  Environment:( _82_4_DT ) -> instance of struct B with body 1 (no widening)
    5353
    5454
     
    127127          void
    128128        )
    129         Environment:( _102_0_T ) -> instance of type T (not function type) (no widening)
     129        Environment:( _101_0_T ) -> instance of type T (not function type) (no widening)
    130130
    131131      Could not satisfy assertion:
    132132?=?: pointer to function
    133133        ... with parameters
    134           reference to instance of type _102_0_T (not function type)
    135           instance of type _102_0_T (not function type)
     134          reference to instance of type _101_0_T (not function type)
     135          instance of type _101_0_T (not function type)
    136136        ... returning
    137           _retval__operator_assign: instance of type _102_0_T (not function type)
     137          _retval__operator_assign: instance of type _101_0_T (not function type)
    138138          ... with attributes:
    139139            Attribute with name: unused
  • tests/loopctrl.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed Aug  8 18:32:59 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 12:05:05 2019
    13 // Update Count     : 106
     12// Last Modified On : Sat Apr 13 11:03:09 2019
     13// Update Count     : 104
    1414//
    1515
     
    3232S ?-=?( S & t, one_t ) { t.i -= 1; t.j -= 1; return t; }
    3333ofstream & ?|?( ofstream & os, S v ) { return os | '(' | v.i | v.j | ')'; }
    34 void & ?|?( ofstream & os, S v ) { (ofstream &)(os | v); ends( os ); }
     34void & ?|?( ofstream & os, S v ) { (ofstream &)(os | v); nl( os ); }
    3535
    3636int main() {
  • tests/math1.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Fri Apr 22 14:59:21 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 10:16:45 2019
    13 // Update Count     : 112
     12// Last Modified On : Mon Mar 25 22:56:47 2019
     13// Update Count     : 109
    1414//
    1515
     
    3333        sout | quot | l;
    3434        sout | "div:" | div( 3.6F, 0.5F ) | div( 3.6D, 0.5D ) | div( 3.6L, 0.5L );
    35         sout | "fma:" | fma( 3.0F, -1.0F, 1.0F ) | fma( 3.0D, -1.0D, 1.0D ) | fma( 3.0L, -1.0L, 1.0L );
     35        sout | "fma:" | fma( 3.0F, -1.0F, 1.0F ) | fma( 3.0D, -1.0D, 1.0D ) | fma( 3.0L, -1.0L, , 1.0L );
    3636        sout | "fdim:" | fdim( 1.0F, -1.0F ) | fdim( 1.0D, -1.0D ) | fdim( 1.0L, -1.0L );
    3737        sout | "nan:" | (float)nan( "" ) | (double)nan( "" ) | (long double)nan( "" );
     
    5959        S ?\?( S s, unsigned long y ) { return (S){ s.i \ y }; }
    6060        ofstream & ?|?( ofstream & os, S s ) { return os | s.i; }
    61         void ?|?( ofstream & os, S s ) { (ofstream &)(os | s); ends( os ); }
     61        void ?|?( ofstream & os, S s ) { (ofstream &)(os | s); nl( os ); }
    6262        S s = { 4 };
    6363        S x = s \ 2;
  • tests/pybin/tools.py

    r4eb43fa rf6cc734e  
    179179                        os.chdir(cwd)
    180180
    181 def killgroup():
    182         try:
    183                 os.killpg(os.getpgrp(), signal.SIGINT)
    184         except KeyboardInterrupt:
    185                 pass # expected
    186         except Exception as exc:
    187                 print("Unexpected exception", file=sys.stderr)
    188                 print(exc, file=sys.stderr)
    189                 sys.stderr.flush()
    190                 sys.exit(2)
    191 
    192181################################################################################
    193182#               file handling
     
    312301        self.end = time.time()
    313302        self.duration = self.end - self.start
    314 
    315 def timed(src, timeout):
    316         expire = time.time() + timeout
    317         i = iter(src)
    318         while True:
    319                 yield i.next(max(expire - time.time(), 0))
  • tests/sum.cfa

    r4eb43fa rf6cc734e  
    1111// Created On       : Wed May 27 17:56:53 2015
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Tue Jul 16 09:51:37 2019
    14 // Update Count     : 336
     13// Last Modified On : Thu Jun  6 16:18:22 2019
     14// Update Count     : 333
    1515//
    1616
     
    9797        S ?++( S & t ) { S temp = t; t += (S){1}; return temp; }
    9898        ofstream & ?|?( ofstream & os, S v ) { return os | v.i | v.j; }
    99         void ?|?( ofstream & os, S v ) { (ofstream &)(os | v); ends( os ); }
     99        void ?|?( ofstream & os, S v ) { (ofstream &)(os | v); nl( os ); }
    100100
    101101        S s = (S){0}, a[size], v = { low, low };
     
    184184        S ?++( S & t ) { S temp = t; t += (S){1}; return temp; }
    185185        ofstream & ?|?( ofstream & os, S v ) { return os | v.i | v.j; }
    186         void ?|?( ofstream & os, S v ) { (ofstream &)(os | v); ends( os ); }
    187 
    188         S s = 0, a[size], v = { low, low };
     186        void ?|?( ofstream & os, S v ) { (ofstream &)(os | v); nl( os ); }
     187
     188        S s = (S){0}, a[size], v = { low, low };
    189189        for ( int i = 0; i < size; i += 1, v += (S){1} ) {
    190190                s += (S)v;
  • tests/swap.cfa

    r4eb43fa rf6cc734e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 12:05:26 2019
    13 // Update Count     : 79
     12// Last Modified On : Sun Dec 23 23:00:49 2018
     13// Update Count     : 77
    1414//
    1515
     
    8585        struct S { int i, j; } s1 = { 1, 2 }, s2 = { 2, 1 };
    8686        ofstream & ?|?( ofstream & os, S s ) { return os | s.i | s.j; }
    87         void ?|?( ofstream & os, S s ) { (ofstream &)(os | s.i | s.j); ends( os ); }
     87        void ?|?( ofstream & os, S s ) { (ofstream &)(os | s.i | s.j); nl( os ); }
    8888        sout | "struct S\t\t" | s1 | "," | s2 | "\t\tswap " | nonl;
    8989        swap( s1, s2 );
  • tests/test.py

    r4eb43fa rf6cc734e  
    202202                if error :
    203203                        text = text + '\n' + error
    204 
    205                 return retcode == TestResult.SUCCESS, text
     204                        out = sys.stderr
     205
     206                print(text, file = out)
     207                sys.stdout.flush()
     208                sys.stderr.flush()
     209
     210                return retcode != TestResult.SUCCESS
    206211        except KeyboardInterrupt:
    207                 return False, ""
    208         except:
    209                 print("Unexpected error in worker thread", file=sys.stderr)
    210                 sys.stderr.flush()
    211                 return False, ""
    212 
     212                False
    213213
    214214# run the given list of tests with the given parameters
     
    220220        pool = multiprocessing.Pool(jobs)
    221221
    222         failed = False
    223 
    224222        # for each test to run
    225223        try :
    226                 num = len(tests)
    227                 fancy = sys.stdout.isatty()
    228                 results = pool.imap_unordered(
     224                results = pool.map_async(
    229225                        run_test_worker,
    230226                        tests,
    231227                        chunksize = 1
    232                 )
    233 
    234                 for i, (succ, txt) in enumerate(timed(results, timeout = settings.timeout.total), 1) :
    235                         if not succ :
    236                                 failed = True
    237 
    238                         print("       " + txt)
    239 
    240                         if(fancy and i != num):
    241                                 print("%d/%d" % (i, num), end='\r')
    242                                 sys.stdout.flush()
    243 
     228                ).get(settings.timeout.total)
    244229        except KeyboardInterrupt:
    245                 print("Tests interrupted by user", file=sys.stderr)
    246230                pool.terminate()
    247                 pool.join()
    248                 failed = True
    249         except multiprocessing.TimeoutError:
    250                 print("ERROR: Test suite timed out", file=sys.stderr)
    251                 pool.terminate()
    252                 pool.join()
    253                 failed = True
    254                 killgroup() # needed to cleanly kill all children
    255 
     231                print("Tests interrupted by user")
     232                sys.exit(1)
    256233
    257234        # clean the workspace
    258235        make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
    259236
    260         return 1 if failed else 0
     237        for failed in results:
     238                if failed :
     239                        return 1
     240
     241        return 0
    261242
    262243
Note: See TracChangeset for help on using the changeset viewer.