Changes in / [4eb43fa:f6cc734e]
- Files:
-
- 3 added
- 9 deleted
- 95 edited
-
Jenkinsfile_disabled (modified) (10 diffs)
-
Makefile.am (modified) (1 diff)
-
Makefile.in (modified) (1 diff)
-
benchmark/Makefile.am (modified) (7 diffs)
-
benchmark/creation/qthreads.c (added)
-
benchmark/ctxswitch/qthreads.c (added)
-
doc/bibliography/pl.bib (modified) (1 diff)
-
doc/papers/concurrency/Paper.tex (modified) (10 diffs)
-
doc/papers/concurrency/mail2 (deleted)
-
doc/user/user.tex (modified) (15 diffs)
-
driver/cfa.cc (modified) (2 diffs)
-
libcfa/prelude/builtins.c (modified) (3 diffs)
-
libcfa/src/Makefile.am (modified) (6 diffs)
-
libcfa/src/Makefile.in (modified) (13 diffs)
-
libcfa/src/bits/containers.hfa (modified) (8 diffs)
-
libcfa/src/bits/debug.cfa (modified) (2 diffs)
-
libcfa/src/bits/defs.hfa (modified) (1 diff)
-
libcfa/src/bits/locks.hfa (modified) (1 diff)
-
libcfa/src/concurrency/alarm.cfa (modified) (1 diff)
-
libcfa/src/concurrency/coroutine.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/invoke.c (modified) (2 diffs)
-
libcfa/src/concurrency/invoke.h (modified) (1 diff)
-
libcfa/src/concurrency/kernel.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel_private.hfa (modified) (1 diff)
-
libcfa/src/concurrency/monitor.cfa (modified) (1 diff)
-
libcfa/src/concurrency/mutex.cfa (modified) (1 diff)
-
libcfa/src/concurrency/preemption.cfa (modified) (1 diff)
-
libcfa/src/concurrency/thread.cfa (modified) (1 diff)
-
libcfa/src/executor.cfa (deleted)
-
libcfa/src/expat.h (added)
-
libcfa/src/fstream.cfa (modified) (18 diffs)
-
libcfa/src/fstream.hfa (modified) (5 diffs)
-
libcfa/src/gmp.hfa (modified) (2 diffs)
-
libcfa/src/interpose.cfa (modified) (6 diffs)
-
libcfa/src/iostream.cfa (modified) (40 diffs)
-
libcfa/src/iostream.hfa (modified) (13 diffs)
-
libcfa/src/rational.cfa (modified) (3 diffs)
-
libcfa/src/stdlib.cfa (modified) (3 diffs)
-
libcfa/src/stdlib.hfa (modified) (2 diffs)
-
libcfa/src/time.cfa (modified) (10 diffs)
-
src/AST/Convert.cpp (modified) (94 diffs)
-
src/AST/Decl.hpp (modified) (2 diffs)
-
src/AST/Expr.hpp (modified) (8 diffs)
-
src/AST/Pass.hpp (modified) (1 diff)
-
src/AST/Pass.impl.hpp (modified) (1 diff)
-
src/AST/Print.cpp (modified) (85 diffs)
-
src/AST/Stmt.hpp (modified) (1 diff)
-
src/AST/SymbolTable.cpp (modified) (24 diffs)
-
src/AST/SymbolTable.hpp (modified) (7 diffs)
-
src/AST/Type.hpp (modified) (9 diffs)
-
src/AST/Visitor.hpp (modified) (1 diff)
-
src/Common/PassVisitor.h (modified) (7 diffs)
-
src/Common/PassVisitor.impl.h (modified) (106 diffs)
-
src/Common/PassVisitor.proto.h (modified) (6 diffs)
-
src/InitTweak/InitTweak.cc (modified) (15 diffs)
-
src/InitTweak/InitTweak.h (modified) (2 diffs)
-
src/Parser/LinkageSpec.h (modified) (2 diffs)
-
src/Parser/ParseNode.h (modified) (1 diff)
-
src/Parser/StatementNode.cc (modified) (1 diff)
-
src/Parser/parser.yy (modified) (2 diffs)
-
src/ResolvExpr/AdjustExprType.cc (modified) (5 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (26 diffs)
-
src/ResolvExpr/CastCost.cc (modified) (10 diffs)
-
src/ResolvExpr/CommonType.cc (modified) (71 diffs)
-
src/ResolvExpr/ConversionCost.cc (modified) (25 diffs)
-
src/ResolvExpr/ConversionCost.h (modified) (2 diffs)
-
src/ResolvExpr/PtrsAssignable.cc (modified) (4 diffs)
-
src/ResolvExpr/PtrsCastable.cc (modified) (9 diffs)
-
src/ResolvExpr/ResolveAssertions.cc (modified) (11 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (48 diffs)
-
src/ResolvExpr/Unify.cc (modified) (38 diffs)
-
src/ResolvExpr/typeops.h (modified) (7 diffs)
-
src/SymTab/Indexer.cc (modified) (32 diffs)
-
src/SymTab/Indexer.h (modified) (7 diffs)
-
src/SymTab/Mangler.cc (modified) (22 diffs)
-
src/SymTab/Mangler.h (modified) (1 diff)
-
src/SymTab/Validate.cc (modified) (68 diffs)
-
src/SymTab/Validate.h (modified) (2 diffs)
-
src/SynTree/Attribute.h (modified) (1 diff)
-
src/SynTree/BaseSyntaxNode.h (modified) (3 diffs)
-
src/SynTree/Constant.h (modified) (3 diffs)
-
src/SynTree/Declaration.h (modified) (11 diffs)
-
src/SynTree/Expression.cc (modified) (1 diff)
-
src/SynTree/Expression.h (modified) (39 diffs)
-
src/SynTree/Initializer.h (modified) (5 diffs)
-
src/SynTree/Mutator.h (modified) (1 diff)
-
src/SynTree/Statement.cc (modified) (1 diff)
-
src/SynTree/Statement.h (modified) (20 diffs)
-
src/SynTree/Type.h (modified) (22 diffs)
-
src/SynTree/Visitor.h (modified) (2 diffs)
-
src/Tuples/Explode.h (modified) (5 diffs)
-
src/Tuples/TupleAssignment.cc (modified) (27 diffs)
-
src/main.cc (modified) (1 diff)
-
tests/.expect/completeTypeError.txt (modified) (3 diffs)
-
tests/.expect/copyfile.txt (deleted)
-
tests/.in/copyfile.txt (deleted)
-
tests/copyfile.cfa (deleted)
-
tests/linking/.expect/nothreads.txt (deleted)
-
tests/linking/.expect/withthreads.txt (deleted)
-
tests/linking/nothreads.cfa (deleted)
-
tests/linking/withthreads.cfa (deleted)
-
tests/loopctrl.cfa (modified) (2 diffs)
-
tests/math1.cfa (modified) (3 diffs)
-
tests/pybin/tools.py (modified) (2 diffs)
-
tests/sum.cfa (modified) (3 diffs)
-
tests/swap.cfa (modified) (2 diffs)
-
tests/test.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Jenkinsfile_disabled
r4eb43fa rf6cc734e 2 2 3 3 import groovy.transform.Field 4 5 // For skipping stages6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils7 4 8 5 //=========================================================================================================== … … 85 82 //=========================================================================================================== 86 83 def clean() { 87 build_stage('Cleanup' , true) {84 build_stage('Cleanup') { 88 85 // clean the build by wipping the build directory 89 86 dir(BuildDir) { … … 95 92 //Compilation script is done here but environnement set-up and error handling is done in main loop 96 93 def checkout() { 97 build_stage('Checkout' , true) {94 build_stage('Checkout') { 98 95 //checkout the source code and clean the repo 99 96 final scmVars = checkout scm … … 106 103 107 104 def 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') { 131 106 // Build outside of the src tree to ease cleaning 132 107 dir (BuildDir) { … … 143 118 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet" 144 119 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' 172 122 } 173 123 } … … 175 125 176 126 def test() { 177 build_stage('Test: short', !Settings.RunAllTests) { 127 build_stage('Test') { 128 178 129 dir (BuildDir) { 179 130 //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 } 189 138 } 190 139 } … … 192 141 193 142 def benchmark() { 194 build_stage('Benchmark', Settings.RunBenchmark) { 143 build_stage('Benchmark') { 144 145 if( !Settings.RunBenchmark ) return 146 195 147 dir (BuildDir) { 196 148 //Append bench results … … 201 153 202 154 def build_doc() { 203 build_stage('Documentation', Settings.BuildDocumentation) { 155 build_stage('Documentation') { 156 157 if( !Settings.BuildDocumentation ) return 158 204 159 dir ('doc/user') { 205 160 make_doc() … … 213 168 214 169 def publish() { 215 build_stage('Publish' , true) {170 build_stage('Publish') { 216 171 217 172 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' } … … 457 412 } 458 413 459 def build_stage(String name, boolean run,Closure block ) {414 def build_stage(String name, Closure block ) { 460 415 StageName = name 461 416 echo " -------- ${StageName} -------- " 462 if(run) { 463 stage(name, block) 464 } else { 465 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) } 466 } 417 stage(name, block) 467 418 } 468 419 -
Makefile.am
r4eb43fa rf6cc734e 40 40 $(MAKE) -C tests all-tests installed=yes debug=${debug} 41 41 42 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@43 @true44 45 42 status: @LIBCFA_TARGET_MAKEFILES@ 46 43 @echo -ne "translator\n\t" -
Makefile.in
r4eb43fa rf6cc734e 940 940 $(MAKE) -C tests all-tests installed=yes debug=${debug} 941 941 942 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@943 @true944 945 942 status: @LIBCFA_TARGET_MAKEFILES@ 946 943 @echo -ne "translator\n\t" -
benchmark/Makefile.am
r4eb43fa rf6cc734e 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Jun 24 16:45:42201914 ## Update Count : 5 313 ## Last Modified On : Sun Jun 23 12:34:29 2019 14 ## Update Count : 52 15 15 ############################################################################### 16 16 … … 31 31 BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet)) 32 32 BENCH_V_UPP = $(__bench_v_UPP_$(__quiet)) 33 BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet)) 33 34 34 35 __quiet = verbose … … 45 46 __bench_v_JAVAC_verbose = $(AM_V_JAVAC) 46 47 __bench_v_UPP_verbose = $(AM_V_UPP) 48 __bench_v_QTHREAD_verbose = $(AM_V_CC) 47 49 48 50 … … 174 176 ctxswitch-upp_thread.run \ 175 177 ctxswitch-goroutine.run \ 176 ctxswitch-java_thread.run 178 ctxswitch-java_thread.run \ 179 ctxswitch-qthreads.run 177 180 178 181 … … 221 224 @echo "java JavaThread" >> a.out 222 225 @chmod a+x a.out 226 227 ctxswitch-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 223 229 224 230 ## ========================================================================================================= … … 314 320 creation-upp_thread.run \ 315 321 creation-goroutine.run \ 316 creation-java_thread.run 322 creation-java_thread.run \ 323 creation-qthreads.run 317 324 318 325 creation-cfa_coroutine$(EXEEXT): … … 342 349 @echo "java JavaThread" >> a.out 343 350 @chmod a+x a.out 351 352 creation-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 344 354 345 355 ## ========================================================================================================= -
doc/bibliography/pl.bib
r4eb43fa rf6cc734e 954 954 key = {Cforall Benchmarks}, 955 955 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}}, 957 957 } 958 958 -
doc/papers/concurrency/Paper.tex
r4eb43fa rf6cc734e 2 2 3 3 \articletype{RESEARCH ARTICLE}% 4 5 % Referees6 % Doug Lea, dl@cs.oswego.edu, SUNY Oswego7 % Herb Sutter, hsutter@microsoft.com, Microsoft Corp8 % Gor Nishanov, gorn@microsoft.com, Microsoft Corp9 % James Noble, kjx@ecs.vuw.ac.nz, Victoria University of Wellington, School of Engineering and Computer Science10 4 11 5 \received{XXXXX} … … 318 312 As 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. 319 313 From 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}.314 The 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}. 321 315 As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}. 322 316 Finally, 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. 323 317 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}.318 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}. 325 319 The 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.320 One solution is low-level qualifiers and functions (\eg, @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs. 327 321 A safer solution is high-level language constructs so the \emph{compiler} knows the optimization boundaries, and hence, provides implicit safety. 328 322 This problem is best known with respect to concurrency, but applies to other complex control-flow, like exceptions\footnote{ … … 330 324 The 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++} 331 325 } 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.326 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. 333 327 334 328 Finally, 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.329 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. 336 330 However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice. 337 331 Similarly, signals-as-hints are often a performance decision. … … 343 337 Most 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. 344 338 As 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.339 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. 346 340 Hence, rewriting and retraining costs for these languages, even \CC, are prohibitive for companies with a large C software-base. 347 341 \CFA with its orthogonal feature-set, its high-performance runtime, and direct access to all existing C libraries circumvents these problems. … … 373 367 \section{Stateful Function} 374 368 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.369 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. 376 370 Hence, 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. 377 371 This 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 variabl e 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.372 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. 373 If 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. 380 374 Hence, 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.375 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. 382 376 As well, activating a stateful function is \emph{asymmetric} or \emph{symmetric}, identified by resume/suspend (no cycles) and resume/resume (cycles). 383 377 A 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.378 Additionally, any storage management for the closure (especially in unmanaged languages, \ie, no garbage collection) must also be factored into design and performance. 385 379 Therefore, selecting between stackless and stackful semantics is a tradeoff between programming requirements and performance, where stackless is faster and stackful is more general. 386 380 Note, creation cost is amortized across usage, so activation cost is usually the dominant factor. … … 654 648 \end{center} 655 649 The 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.650 The destructor provides a newline if formatted text ends with a full line. 657 651 Figure~\ref{f:CFormatSim} shows the C implementation of the \CFA input generator with one additional field and the computed @goto@. 658 652 For contrast, Figure~\ref{f:PythonFormatter} shows the equivalent Python format generator with the same properties as the Fibonacci generator. … … 675 669 In contrast, the execution state is large, with one @resume@ and seven @suspend@s. 676 670 Hence, 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 importantin a system programming language.671 Because FSMs can be complex and frequently occur in important domains, direct support of the generator is crucial in a system programming language. 678 672 679 673 \begin{figure} … … 802 796 This semantics is basically a tail-call optimization, which compilers already perform. 803 797 The 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.798 This assembly code depends on what entry code is generated, specifically if there are local variables, and the level of optimization. 805 799 To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time. 806 800 Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing. … … 2725 2719 Each benchmark experiment is run 31 times. 2726 2720 All 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 2728 2722 2729 2723 \paragraph{Object Creation} … … 2755 2749 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 2756 2750 \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 \\ 2758 2752 \CFA Thread & 1257.8 & 1291.2 & 86.19 \\ 2759 2753 \uC Coroutine & 92.2 & 91.4 & 1.58 \\ -
doc/user/user.tex
r4eb43fa rf6cc734e 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sat Ju l 13 18:36:18201914 %% Update Count : 38 7613 %% Last Modified On : Sat Jun 15 16:29:45 2019 14 %% Update Count : 3847 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 2697 2697 \subsection{Expressions} 2698 2698 2699 % Change order of expression evaluation.2700 % http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r2.pdf2701 2702 2699 Multiple-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. 2703 2700 These notions are generalized to provide \CFA with \newterm{tuple expression}s and \newterm{tuple type}s. … … 3349 3346 3350 3347 3351 \section{ Stream I/OLibrary}3352 \label{s: StreamIOLibrary}3348 \section{I/O Stream Library} 3349 \label{s:IOStreamLibrary} 3353 3350 \index{input/output stream library} 3354 3351 \index{stream library} 3355 3352 3356 The goal of \CFA streaminput/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 I mplicit 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: 3353 The 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. 3355 I/O can be unformatted or formatted. 3356 Unformatted means \CFA selects the output or input format for values that match with the type of a variable. 3357 Formatted 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. 3362 3359 \begin{itemize} 3363 3360 \item 3364 ©printf© /Pythonformat codes are dense, making them difficult to read and remember.3361 ©printf© format codes are dense, making them difficult to read and remember. 3365 3362 \CFA/\CC format manipulators are named, making them easier to read and remember. 3366 3363 \item 3367 ©printf© /Pythonseparates 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. 3368 3365 \CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding. 3369 3366 \item 3370 Format manipulators in \C FA have local effect, whereas \CC have global effect, except ©setw©.3367 Format manipulators in \CC have global rather than local effect, except ©setw©. 3371 3368 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects. 3372 3369 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location. 3373 3370 (To guarantee no side-effects, manipulator values must be saved and restored across function calls.) 3374 \item3375 \CFA has more sophisticated implicit spacing between values than Python, plus implicit newline at the end of a print.3376 3371 \end{itemize} 3377 3372 The \CFA header file for the I/O library is \Indexc{fstream.hfa}. 3378 3373 3379 For implicit formatted output, the common case is printing a seriesof variables separated by whitespace.3374 For unformatted output, the common case is printing a sequence of variables separated by whitespace. 3380 3375 \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}} \\ 3383 3378 \begin{cfa} 3384 3379 int x = 1, y = 2, z = 3; … … 3390 3385 cout << x ®<< " "® << y ®<< " "® << z << endl; 3391 3386 \end{cfa} 3392 &3393 \begin{cfa}3394 x = 1; y = 2; z = 33395 print( x, y, z )3396 \end{cfa}3397 3387 \\ 3398 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3399 1® ®2® ®33400 \end{cfa}3401 &3402 3388 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3403 3389 1® ®2® ®3 … … 3443 3429 There 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. 3444 3430 3445 For implicit formattedinput, 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.3431 For 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. 3446 3432 \begin{cquote} 3447 3433 \begin{lrbox}{\LstBox} … … 3450 3436 \end{cfa} 3451 3437 \end{lrbox} 3452 \begin{tabular}{@{}l@{\hspace{3em}}l@{ \hspace{3em}}l@{}}3438 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 3453 3439 \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}} \\ 3455 3441 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3456 3442 sin | x | y | z; … … 3460 3446 cin >> x >> y >> z; 3461 3447 \end{cfa} 3462 &3463 \begin{cfa}[aboveskip=0pt,belowskip=0pt]3464 x = int(input()); y = float(input()); z = input();3465 \end{cfa}3466 3448 \\ 3467 3449 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3468 3450 ®1® ®2.5® ®A® 3469 3470 3471 3451 \end{cfa} 3472 3452 & 3473 3453 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3474 3454 ®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®3483 3455 \end{cfa} 3484 3456 \end{tabular} … … 3509 3481 3510 3482 \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.3483 A separator does not appear before or after a null (empty) C string. 3512 3484 \begin{cfa} 3513 3485 sout | 1 | "" | 2 | "" | 3; 3514 3486 123 3515 3487 \end{cfa} 3488 which is a local mechanism to disable insertion of the separator character. 3516 3489 3517 3490 \item 3518 3491 {\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}} 3519 A sep arator 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.3492 A seperator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@ 3520 3493 \begin{cfa}[belowskip=0pt] 3521 3494 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" … … 3525 3498 1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x 3526 3499 \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. 3500 where \lstinline[basicstyle=\tt]@»@ is a closing citation mark. 3501 3502 \item 3503 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@ 3530 3504 %$ 3531 3505 \begin{cfa}[mathescape=off] … … 3538 3512 \end{cfa} 3539 3513 %$ 3514 where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark. 3540 3515 3541 3516 \item … … 3651 3626 The tuple separator also responses to being turned on and off. 3652 3627 \begin{cfa}[belowskip=0pt] 3653 sout | t1 | sepOff | t2; §\C{// turn off implicit separator for the next item}§3628 sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator}§ 3654 3629 \end{cfa} 3655 3630 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3675 3650 \subsection{Newline Manipulators} 3676 3651 3677 The following \Index{manipulator s} control\Index{newline separation} for input and output.3652 The following \Index{manipulator} controls \Index{newline separation} for input and output. 3678 3653 3679 3654 For input: … … 3730 3705 0b0 0b11011 0b11011 0b11011 0b11011 3731 3706 sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L ); 3732 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b ®(58 1s)®1001013707 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)100101 3733 3708 \end{cfa} 3734 3709 … … 3773 3748 3774 3749 \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. 3777 3751 \begin{cfa}[belowskip=0pt] 3778 3752 sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) ); … … 3808 3782 ® ®4.000000 ® ®4.000000 4.000000 3809 3783 ® ®ab ® ®ab ab 3784 ab ab ab 3810 3785 \end{cfa} 3811 3786 If the value is larger, it is printed without truncation, ignoring the ©minimum©. -
driver/cfa.cc
r4eb43fa rf6cc734e 405 405 args[nargs] = "--undefined=__cfaabi_appready_startup"; 406 406 nargs += 1; 407 args[nargs] = "-Xlinker"; 408 nargs += 1; 409 args[nargs] = "--undefined=__cfaabi_dbg_record"; 410 nargs += 1; 407 411 408 412 // include the cfa library in case it's needed … … 410 414 nargs += 1; 411 415 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";418 416 nargs += 1; 419 417 args[nargs] = "-lcfa"; -
libcfa/prelude/builtins.c
r4eb43fa rf6cc734e 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jun 25 18:06:52201913 // Update Count : 9 712 // Last Modified On : Tue Mar 26 23:10:36 2019 13 // Update Count : 95 14 14 // 15 15 … … 49 49 void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )); 50 50 51 // i mplicit increment, decrement if += defined, and implicit not if != defined51 // increment/decrement unification 52 52 53 53 static inline { … … 63 63 forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } ) 64 64 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 ); }68 65 } // distribution 69 66 -
libcfa/src/Makefile.am
r4eb43fa rf6cc734e 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Jul 15 22:43:27 201914 ## Update Count : 24 113 ## Last Modified On : Tue Jul 24 17:25:39 2018 14 ## Update Count : 240 15 15 ############################################################################### 16 16 … … 22 22 23 23 libdir = ${CFA_LIBDIR} 24 lib_LTLIBRARIES = libcfa.la libcfathread.la24 lib_LTLIBRARIES = libcfa.la 25 25 26 26 VPATH += :../prelude … … 41 41 containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa 42 42 43 # not all platforms support concurrency, add option do disable it 44 headers_nosrc += concurrency/invoke.h 45 headers += concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa 46 43 47 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa} 44 48 45 49 # 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} 50 libsrc += concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa 49 51 else 50 52 headers = 51 thread_headers =52 53 headers_nosrc = 53 thread_headers_nosrc =54 54 libsrc = 55 55 endif … … 64 64 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa 65 65 66 thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))67 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa68 69 66 70 67 # .deps inclusion is not done automatically by automake for new languages … … 75 72 76 73 -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 85 74 86 75 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@ … … 96 85 libcfa_la_LDFLAGS = -version-info @CFA_VERSION@ 97 86 98 libcfathread_la_SOURCES = ${thread_libsrc}99 libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@100 101 87 stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ") 102 88 103 89 cfa_includedir = $(CFA_INCDIR) 104 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}90 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} 105 91 106 92 #---------------------------------------------------------------------------------------------------------------- -
libcfa/src/Makefile.in
r4eb43fa rf6cc734e 142 142 time.cfa stdlib.cfa common.cfa containers/maybe.cfa \ 143 143 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 145 149 am__dirstamp = $(am__leading_dot)dirstamp 146 150 @BUILDLIB_TRUE@am__objects_1 = fstream.lo iostream.lo iterator.lo \ … … 148 152 @BUILDLIB_TRUE@ common.lo containers/maybe.lo \ 149 153 @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 151 157 @BUILDLIB_TRUE@am__objects_2 = startup.lo interpose.lo bits/debug.lo \ 152 158 @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 154 163 am_libcfa_la_OBJECTS = prelude.lo $(am__objects_2) 155 164 libcfa_la_OBJECTS = $(am_libcfa_la_OBJECTS) … … 161 170 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 162 171 $(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.cfa170 @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.lo173 @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 $@183 172 AM_V_P = $(am__v_P_@AM_V@) 184 173 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) … … 225 214 am__v_CCLD_0 = @echo " CCLD " $@; 226 215 am__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) 216 SOURCES = $(libcfa_la_SOURCES) 217 DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST) 230 218 am__can_run_installinfo = \ 231 219 case $$AM_UPDATE_INFO_DIR in \ … … 237 225 limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \ 238 226 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 \ 242 228 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 245 232 HEADERS = $(nobase_cfa_include_HEADERS) 246 233 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 434 421 am__v_UPP_0 = @echo " UPP " $@; 435 422 am__v_UPP_1 = 436 lib_LTLIBRARIES = libcfa.la libcfathread.la423 lib_LTLIBRARIES = libcfa.la 437 424 438 425 # AM_CFLAGS for all cfa source … … 446 433 447 434 #---------------------------------------------------------------------------------------------------------------- 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 449 441 @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 453 449 @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 =456 450 457 451 # 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 462 458 463 459 #---------------------------------------------------------------------------------------------------------------- … … 467 463 # add dependency of cfa files 468 464 libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc)))) 469 thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))470 465 471 466 # .deps inclusion is not done automatically by automake for new languages … … 475 470 ) 476 471 477 thread_libdeps = $(join \478 $(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \479 $(notdir ${thread_libobjs:.lo=.Plo}) \480 )481 482 472 483 473 #---------------------------------------------------------------------------------------------------------------- 484 474 libcfa_la_SOURCES = prelude.cfa ${libsrc} 485 475 libcfa_la_LDFLAGS = -version-info @CFA_VERSION@ 486 libcfathread_la_SOURCES = ${thread_libsrc}487 libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@488 476 stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ") 489 477 cfa_includedir = $(CFA_INCDIR) 490 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}478 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} 491 479 all: all-am 492 480 … … 579 567 containers/vector.lo: containers/$(am__dirstamp) \ 580 568 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)584 569 concurrency/$(am__dirstamp): 585 570 @$(MKDIR_P) concurrency … … 588 573 @$(MKDIR_P) concurrency/$(DEPDIR) 589 574 @: > 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)598 575 concurrency/coroutine.lo: concurrency/$(am__dirstamp) \ 599 576 concurrency/$(DEPDIR)/$(am__dirstamp) … … 606 583 concurrency/mutex.lo: concurrency/$(am__dirstamp) \ 607 584 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) 585 concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \ 586 concurrency/$(DEPDIR)/$(am__dirstamp) 587 concurrency/alarm.lo: concurrency/$(am__dirstamp) \ 588 concurrency/$(DEPDIR)/$(am__dirstamp) 589 concurrency/invoke.lo: concurrency/$(am__dirstamp) \ 590 concurrency/$(DEPDIR)/$(am__dirstamp) 591 concurrency/preemption.lo: concurrency/$(am__dirstamp) \ 592 concurrency/$(DEPDIR)/$(am__dirstamp) 593 594 libcfa.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) 611 596 612 597 mostlyclean-compile: … … 937 922 $(am__mv) $$depbase.Tpo $$depbase.Plo 938 923 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa 939 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa940 924 941 925 -include $(libdeps) 942 943 -include $(thread_libdeps)944 926 945 927 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@ -
libcfa/src/bits/containers.hfa
r4eb43fa rf6cc734e 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Oct 31 16:38:50 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jun 26 08:52:20 201913 // Update Count : 411 // Last Modified By : -- 12 // Last Modified On : -- 13 // Update Count : 0 14 14 15 15 #pragma once … … 78 78 //----------------------------------------------------------------------------- 79 79 #ifdef __cforall 80 forall(dtype TYPE )80 forall(dtype TYPE | is_node(TYPE)) 81 81 #define T TYPE 82 82 #else … … 95 95 96 96 #ifdef __cforall 97 forall(dtype T )97 forall(dtype T | is_node(T)) 98 98 static inline void ?{}( __stack(T) & this ) { 99 99 (this.top){ NULL }; … … 116 116 return top; 117 117 } 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 }123 118 #endif 124 119 … … 127 122 //----------------------------------------------------------------------------- 128 123 #ifdef __cforall 129 forall(dtype TYPE )124 forall(dtype TYPE | is_node(TYPE)) 130 125 #define T TYPE 131 126 #else … … 146 141 #ifdef __cforall 147 142 148 forall(dtype T )143 forall(dtype T | is_node(T)) 149 144 static inline void ?{}( __queue(T) & this ) with( this ) { 150 145 head{ NULL }; … … 191 186 192 187 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 ) { 194 189 return this.head != 0; 195 190 } … … 273 268 274 269 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 ) { 276 271 return this.head != 0; 277 272 } -
libcfa/src/bits/debug.cfa
r4eb43fa rf6cc734e 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu Mar 30 12:30:01 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun Jul 14 22:17:35 201913 // Update Count : 411 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 1 14 14 // 15 15 … … 23 23 } 24 24 25 enum { buffer_size = 4096};25 enum { buffer_size = 512 }; 26 26 static char buffer[ buffer_size ]; 27 27 -
libcfa/src/bits/defs.hfa
r4eb43fa rf6cc734e 41 41 } 42 42 #endif 43 44 #if defined(__cforall_thread__)45 #define OPTIONAL_THREAD46 #else47 #define OPTIONAL_THREAD __attribute__((weak))48 #endif -
libcfa/src/bits/locks.hfa
r4eb43fa rf6cc734e 50 50 #ifdef __cforall 51 51 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(); 54 54 55 55 #ifdef __CFA_DEBUG__ -
libcfa/src/concurrency/alarm.cfa
r4eb43fa rf6cc734e 13 13 // Update Count : 67 14 14 // 15 16 #define __cforall_thread__17 15 18 16 extern "C" { -
libcfa/src/concurrency/coroutine.cfa
r4eb43fa rf6cc734e 13 13 // Update Count : 9 14 14 // 15 16 #define __cforall_thread__17 15 18 16 #include "coroutine.hfa" … … 100 98 101 99 void ^?{}(coroutine_desc& this) { 102 if(this.state != Halted && this.state != Start && this.state != Primed) {100 if(this.state != Halted && this.state != Start) { 103 101 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 104 102 coroutine_desc * dst = &this; -
libcfa/src/concurrency/invoke.c
r4eb43fa rf6cc734e 13 13 // Update Count : 5 14 14 // 15 16 #define __cforall_thread__17 15 18 16 #include <stdbool.h> … … 33 31 extern void __finish_creation( struct thread_desc * ); 34 32 extern void __leave_thread_monitor( struct thread_desc * this ); 35 extern void disable_interrupts() OPTIONAL_THREAD;33 extern void disable_interrupts(); 36 34 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 37 35 -
libcfa/src/concurrency/invoke.h
r4eb43fa rf6cc734e 46 46 #ifdef __cforall 47 47 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 48 51 extern thread_local struct KernelThreadData { 49 52 struct thread_desc * volatile this_thread; -
libcfa/src/concurrency/kernel.cfa
r4eb43fa rf6cc734e 13 13 // Update Count : 25 14 14 // 15 16 #define __cforall_thread__17 15 18 16 //C Includes … … 945 943 } 946 944 ) 947 948 //-----------------------------------------------------------------------------949 // Debug950 bool threading_enabled(void) {951 return true;952 }953 945 // Local Variables: // 954 946 // mode: c // -
libcfa/src/concurrency/kernel_private.hfa
r4eb43fa rf6cc734e 26 26 27 27 extern "C" { 28 void disable_interrupts() OPTIONAL_THREAD;28 void disable_interrupts(); 29 29 void enable_interrupts_noPoll(); 30 30 void enable_interrupts( __cfaabi_dbg_ctx_param ); -
libcfa/src/concurrency/monitor.cfa
r4eb43fa rf6cc734e 13 13 // Update Count : 9 14 14 // 15 16 #define __cforall_thread__17 15 18 16 #include "monitor.hfa" -
libcfa/src/concurrency/mutex.cfa
r4eb43fa rf6cc734e 15 15 // Update Count : 0 16 16 // 17 18 #define __cforall_thread__19 17 20 18 #include "mutex.hfa" -
libcfa/src/concurrency/preemption.cfa
r4eb43fa rf6cc734e 13 13 // Update Count : 37 14 14 // 15 16 #define __cforall_thread__17 15 18 16 #include "preemption.hfa" -
libcfa/src/concurrency/thread.cfa
r4eb43fa rf6cc734e 13 13 // Update Count : 8 14 14 // 15 16 #define __cforall_thread__17 15 18 16 #include "thread.hfa" -
libcfa/src/fstream.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jul 15 18:11:26201913 // Update Count : 3 4912 // Last Modified On : Thu May 16 08:33:28 2019 13 // Update Count : 328 14 14 // 15 15 … … 24 24 #include <assert.h> 25 25 #include <errno.h> // errno 26 27 28 //*********************************** ofstream ***********************************29 30 26 31 27 #define IO_MSG "I/O error: " … … 41 37 sepSetCur( os, sepGet( os ) ); 42 38 sepSetTuple( os, ", " ); 43 } // ?{}39 } 44 40 45 41 // private … … 60 56 void ?{}( ofstream & os, const char * name, const char * mode ) { 61 57 open( os, name, mode ); 62 } // ?{} 63 58 } 64 59 void ?{}( ofstream & os, const char * name ) { 65 60 open( os, name, "w" ); 66 } // ?{}61 } 67 62 68 63 void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); } … … 100 95 } // sepSet 101 96 102 void ends( ofstream & os ) {103 if ( getANL( os ) ) nl( os );104 else setPrt( os, false ); // turn off105 if ( &os == &exit ) exit( EXIT_FAILURE );106 if ( &os == &abort ) abort();107 } // ends108 109 97 int fail( ofstream & os ) { 110 98 return os.file == 0 || ferror( (FILE *)(os.file) ); … … 119 107 #ifdef __CFA_DEBUG__ 120 108 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 ) ); 122 110 } // if 123 111 #endif // __CFA_DEBUG__ … … 133 121 134 122 if ( fclose( (FILE *)(os.file) ) == EOF ) { 135 abort | IO_MSG "close output" | nl | strerror( errno);123 abort( IO_MSG "close output %s", strerror( errno ) ); 136 124 } // if 137 125 } // close … … 139 127 ofstream & write( ofstream & os, const char * data, size_t size ) { 140 128 if ( fail( os ) ) { 141 abort | IO_MSG "attempt write I/O on failed stream";129 abort( "attempt write I/O on failed stream\n" ); 142 130 } // if 143 131 144 132 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 ) ); 146 134 } // if 147 135 return os; … … 154 142 if ( len == EOF ) { 155 143 if ( ferror( (FILE *)(os.file) ) ) { 156 abort | IO_MSG "invalid write";144 abort( "invalid write\n" ); 157 145 } // if 158 146 } // if … … 165 153 166 154 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_) }; 167 ofstream & sout = soutFile , & stdout = soutFile;155 ofstream & sout = soutFile; 168 156 static 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 157 ofstream & 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 164 void nl( ofstream & os ) { 165 if ( getANL( os ) ) (ofstream &)(nl( os )); // implementation only 166 else setPrt( os, false ); // turn off 167 } 168 169 //--------------------------------------- 179 170 180 171 // private … … 182 173 is.file = file; 183 174 is.nlOnOff = false; 184 } // ?{}175 } 185 176 186 177 // public … … 189 180 void ?{}( ifstream & is, const char * name, const char * mode ) { 190 181 open( is, name, mode ); 191 } // ?{} 192 182 } 193 183 void ?{}( ifstream & is, const char * name ) { 194 184 open( is, name, "r" ); 195 } // ?{}185 } 196 186 197 187 void nlOn( ifstream & os ) { os.nlOnOff = true; } … … 211 201 #ifdef __CFA_DEBUG__ 212 202 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 ) ); 214 204 } // if 215 205 #endif // __CFA_DEBUG__ … … 225 215 226 216 if ( fclose( (FILE *)(is.file) ) == EOF ) { 227 abort | IO_MSG "close input" | nl | strerror( errno);217 abort( IO_MSG "close input %s", strerror( errno ) ); 228 218 } // if 229 219 } // close … … 231 221 ifstream & read( ifstream & is, char * data, size_t size ) { 232 222 if ( fail( is ) ) { 233 abort | IO_MSG "attempt read I/O on failed stream";223 abort( "attempt read I/O on failed stream\n" ); 234 224 } // if 235 225 236 226 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 ) ); 238 228 } // if 239 229 return is; … … 242 232 ifstream &ungetc( ifstream & is, char c ) { 243 233 if ( fail( is ) ) { 244 abort | IO_MSG "attempt ungetc I/O on failed stream";234 abort( "attempt ungetc I/O on failed stream\n" ); 245 235 } // if 246 236 247 237 if ( ungetc( c, (FILE *)(is.file) ) == EOF ) { 248 abort | IO_MSG "ungetc" | nl | strerror( errno);238 abort( IO_MSG "ungetc %s", strerror( errno ) ); 249 239 } // if 250 240 return is; … … 258 248 if ( len == EOF ) { 259 249 if ( ferror( (FILE *)(is.file) ) ) { 260 abort | IO_MSG "invalid read";250 abort( "invalid read\n" ); 261 251 } // if 262 252 } // if … … 267 257 268 258 static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) }; 269 ifstream & sin = sinFile , & stdin = sinFile;259 ifstream & sin = sinFile; 270 260 271 261 // Local Variables: // -
libcfa/src/fstream.hfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jul 15 18:10:23201913 // Update Count : 1 6712 // Last Modified On : Thu May 16 08:34:10 2019 13 // Update Count : 157 14 14 // 15 15 … … 17 17 18 18 #include "iostream.hfa" 19 20 21 //*********************************** ofstream ***********************************22 23 19 24 20 enum { sepSize = 16 }; … … 60 56 void sepSetTuple( ofstream &, const char * ); 61 57 62 void ends( ofstream & os );63 58 int fail( ofstream & ); 64 59 int flush( ofstream & ); … … 73 68 void ?{}( ofstream & os, const char * name ); 74 69 75 extern ofstream & sout, & stdout, & serr, & stderr; // aliases 76 extern ofstream & exit, & abort; 70 extern ofstream & sout, & serr; 77 71 78 79 // *********************************** ifstream ***********************************72 // extern ofstream & sout, & serr, & sexit, & sabort; 73 // void nl( ofstream & os ); 80 74 81 75 … … 102 96 void ?{}( ifstream & is, const char * name ); 103 97 104 extern ifstream & sin , & stdin; // aliases98 extern ifstream & sin; 105 99 106 100 // Local Variables: // -
libcfa/src/gmp.hfa
r4eb43fa rf6cc734e 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 13 15:25:05201913 // Update Count : 2 712 // Last Modified On : Sat Apr 20 09:01:52 2019 13 // Update Count : 24 14 14 // 15 15 … … 19 19 20 20 #include <gmp.h> // GNU multi-precise integers 21 #include <fstream.hfa> // sout21 #include <fstream.hfa> // sout 22 22 23 23 struct Int { mpz_t mpz; }; // wrap GMP implementation 24 24 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 26 static inline void ?{}( Int & this ) { mpz_init( this.mpz ); } 27 static inline void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); } 28 static inline void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); } 29 static inline void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); } 30 static inline void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); } 31 static inline void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); } 32 static inline void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); } 33 static inline void ^?{}( Int & this ) { mpz_clear( this.mpz ); } 34 35 // literal 36 static inline Int ?`mp( signed long int init ) { return (Int){ init }; } 37 static inline Int ?`mp( unsigned long int init ) { return (Int){ init }; } 38 static inline Int ?`mp( const char * init ) { return (Int){ init }; } 39 40 // assignment 41 static inline Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; } 42 static inline Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; } 43 static inline Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; } 44 static inline Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return lhs; } 45 46 static inline char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; } 47 static inline short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; } 48 static inline int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; } 49 static inline long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; } 50 static inline unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; } 51 static inline unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; } 52 static inline unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; } 53 static 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 56 static inline long int narrow( Int val ) { return mpz_get_si( val.mpz ); } 57 static inline unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); } 58 59 // comparison 60 static inline int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; } 61 static inline int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; } 62 static inline int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; } 63 static inline int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; } 64 static inline int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; } 65 66 static inline int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); } 67 static inline int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); } 68 static inline int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); } 69 static inline int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); } 70 static inline int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); } 71 72 static inline int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; } 73 static inline int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; } 74 static inline int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; } 75 static inline int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; } 76 static inline int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; } 77 78 static inline int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; } 79 static inline int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; } 80 static inline int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; } 81 static inline int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; } 82 static inline int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; } 83 84 static inline int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); } 85 static inline int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); } 86 static inline int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); } 87 static inline int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); } 88 static inline int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); } 89 90 static inline int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); } 91 static inline int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); } 92 static inline int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); } 93 static inline int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); } 94 static inline int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); } 95 96 // arithmetic 97 static inline Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; } 98 static inline Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; } 99 static inline Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; } 100 101 static inline Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; } 102 static 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; } 103 static 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; } 104 static 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; } 105 static 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; } 106 static inline Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; } 107 108 static inline Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; } 109 static 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; } 110 static 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; } 111 static 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; } 112 static 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; } 113 static inline Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; } 114 115 static inline Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; } 116 static 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; } 117 static 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; } 118 static 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; } 119 static 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; } 120 static inline Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; } 121 122 static inline Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; } 123 static 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; } 124 static 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; } 125 static inline Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; } 126 static inline Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; } 127 static inline Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; } 128 static inline Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; } 129 static inline Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; } 130 static inline Int ++?( Int & lhs ) { return lhs += 1; } 131 static inline Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; } 132 133 static inline Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; } 134 static 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; } 135 static 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; } 136 static inline Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; } 137 static inline Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; } 138 static inline Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; } 139 static inline Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; } 140 static inline Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; } 141 static inline Int --?( Int & lhs ) { return lhs -= 1; } 142 static inline Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; } 143 144 static inline Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; } 145 static inline Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; } 146 static inline Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; } 147 static inline Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; } 148 static inline Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; } 149 static inline Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; } 150 static inline Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; } 151 static inline Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; } 152 153 // some code for operators "/" and "%" taken from g++ gmpxx.h 154 static inline Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; } 155 static inline Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; } 156 static 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 ) ); 180 167 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 } // ?/? 173 static 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 } // ?/? 183 static 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 } // ?/? 194 static inline Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; } 195 static inline Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; } 196 static inline Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; } 197 198 static 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 ]; } 199 static 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 201 static inline Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; } 202 static inline Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; } 203 static 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 } // ?%? 219 static 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 } // ?%? 224 static 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 } // ?%? 235 static inline Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; } 236 static inline Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; } 237 static inline Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; } 238 239 static inline Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; } 240 static inline Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; } 241 static inline Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; } 242 static inline Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; } 243 244 // number functions 245 static inline Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; } 246 static inline Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; } 247 static inline Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; } 248 static inline Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; } 249 static inline Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; } 250 static inline void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); } 251 static inline Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; } 252 static inline Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; } 253 static inline Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; } 254 static inline int sgn( Int oper ) { return mpz_sgn( oper.mpz ); } 255 static inline Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; } 256 257 // I/O 258 static inline forall( dtype istype | istream( istype ) ) 259 istype & ?|?( istype & is, Int & mp ) { 260 gmp_scanf( "%Zd", &mp ); 261 return is; 262 } // ?|? 263 264 static 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; 263 270 } // ?|? 264 271 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 } // ?|? 277 275 } // distribution 278 276 -
libcfa/src/interpose.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed Mar 29 16:10:31 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S un Jul 14 22:57:16 201913 // Update Count : 11 612 // Last Modified On : Sat May 5 11:37:35 2018 13 // Update Count : 111 14 14 // 15 15 … … 81 81 //============================================================================================= 82 82 83 void sigHandler_segv ( __CFA_SIGPARMS__ );84 void sigHandler_ill ( __CFA_SIGPARMS__ );85 void sigHandler_fpe ( __CFA_SIGPARMS__ );86 void sigHandler_ab rt( __CFA_SIGPARMS__ );87 void sigHandler_term ( __CFA_SIGPARMS__ );83 void sigHandler_segv ( __CFA_SIGPARMS__ ); 84 void sigHandler_ill ( __CFA_SIGPARMS__ ); 85 void sigHandler_fpe ( __CFA_SIGPARMS__ ); 86 void sigHandler_abort( __CFA_SIGPARMS__ ); 87 void sigHandler_term ( __CFA_SIGPARMS__ ); 88 88 89 89 struct { … … 110 110 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO ); 111 111 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO ); 112 __cfaabi_sigaction( SIGABRT, sigHandler_ab rt, SA_SIGINFO | SA_RESETHAND);112 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND); 113 113 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO ); 114 114 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO ); … … 204 204 if ( *p == '(' ) { 205 205 name = p; 206 } else if ( *p == '+' ) { 206 } 207 else if ( *p == '+' ) { 207 208 offset_begin = p; 208 } else if ( *p == ')' ) { 209 } 210 else if ( *p == ')' ) { 209 211 offset_end = p; 210 212 break; … … 221 223 222 224 __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 { 224 228 __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] ); 225 229 } … … 254 258 } 255 259 256 void sigHandler_ab rt( __CFA_SIGPARMS__ ) {260 void sigHandler_abort( __CFA_SIGPARMS__ ) { 257 261 __cfaabi_backtrace(); 258 262 -
libcfa/src/iostream.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 13 08:07:59201913 // Update Count : 8 2112 // Last Modified On : Thu Jun 13 17:21:10 2019 13 // Update Count : 812 14 14 // 15 15 … … 30 30 31 31 32 //*********************************** ostream ***********************************32 //*********************************** Ostream *********************************** 33 33 34 34 … … 40 40 } // ?|? 41 41 void ?|?( ostype & os, zero_t z ) { 42 (ostype &)(os | z); ends( os );42 (ostype &)(os | z); nl( os ); 43 43 } // ?|? 44 44 … … 49 49 } // ?|? 50 50 void ?|?( ostype & os, one_t o ) { 51 (ostype &)(os | o); ends( os );51 (ostype &)(os | o); nl( os ); 52 52 } // ?|? 53 53 … … 58 58 } // ?|? 59 59 void ?|?( ostype & os, bool b ) { 60 (ostype &)(os | b); ends( os );60 (ostype &)(os | b); nl( os ); 61 61 } // ?|? 62 62 … … 67 67 } // ?|? 68 68 void ?|?( ostype & os, char c ) { 69 (ostype &)(os | c); ends( os );69 (ostype &)(os | c); nl( os ); 70 70 } // ?|? 71 71 … … 76 76 } // ?|? 77 77 void ?|?( ostype & os, signed char sc ) { 78 (ostype &)(os | sc); ends( os );78 (ostype &)(os | sc); nl( os ); 79 79 } // ?|? 80 80 … … 85 85 } // ?|? 86 86 void ?|?( ostype & os, unsigned char usc ) { 87 (ostype &)(os | usc); ends( os );87 (ostype &)(os | usc); nl( os ); 88 88 } // ?|? 89 89 … … 94 94 } // ?|? 95 95 void & ?|?( ostype & os, short int si ) { 96 (ostype &)(os | si); ends( os );96 (ostype &)(os | si); nl( os ); 97 97 } // ?|? 98 98 … … 103 103 } // ?|? 104 104 void & ?|?( ostype & os, unsigned short int usi ) { 105 (ostype &)(os | usi); ends( os );105 (ostype &)(os | usi); nl( os ); 106 106 } // ?|? 107 107 … … 112 112 } // ?|? 113 113 void & ?|?( ostype & os, int i ) { 114 (ostype &)(os | i); ends( os );114 (ostype &)(os | i); nl( os ); 115 115 } // ?|? 116 116 … … 121 121 } // ?|? 122 122 void & ?|?( ostype & os, unsigned int ui ) { 123 (ostype &)(os | ui); ends( os );123 (ostype &)(os | ui); nl( os ); 124 124 } // ?|? 125 125 … … 130 130 } // ?|? 131 131 void & ?|?( ostype & os, long int li ) { 132 (ostype &)(os | li); ends( os );132 (ostype &)(os | li); nl( os ); 133 133 } // ?|? 134 134 … … 139 139 } // ?|? 140 140 void & ?|?( ostype & os, unsigned long int uli ) { 141 (ostype &)(os | uli); ends( os );141 (ostype &)(os | uli); nl( os ); 142 142 } // ?|? 143 143 … … 148 148 } // ?|? 149 149 void & ?|?( ostype & os, long long int lli ) { 150 (ostype &)(os | lli); ends( os );150 (ostype &)(os | lli); nl( os ); 151 151 } // ?|? 152 152 … … 157 157 } // ?|? 158 158 void & ?|?( ostype & os, unsigned long long int ulli ) { 159 (ostype &)(os | ulli); ends( os );159 (ostype &)(os | ulli); nl( os ); 160 160 } // ?|? 161 161 … … 180 180 } // ?|? 181 181 void & ?|?( ostype & os, float f ) { 182 (ostype &)(os | f); ends( os );182 (ostype &)(os | f); nl( os ); 183 183 } // ?|? 184 184 … … 189 189 } // ?|? 190 190 void & ?|?( ostype & os, double d ) { 191 (ostype &)(os | d); ends( os );191 (ostype &)(os | d); nl( os ); 192 192 } // ?|? 193 193 … … 198 198 } // ?|? 199 199 void & ?|?( ostype & os, long double ld ) { 200 (ostype &)(os | ld); ends( os );200 (ostype &)(os | ld); nl( os ); 201 201 } // ?|? 202 202 … … 210 210 } // ?|? 211 211 void & ?|?( ostype & os, float _Complex fc ) { 212 (ostype &)(os | fc); ends( os );212 (ostype &)(os | fc); nl( os ); 213 213 } // ?|? 214 214 … … 222 222 } // ?|? 223 223 void & ?|?( ostype & os, double _Complex dc ) { 224 (ostype &)(os | dc); ends( os );224 (ostype &)(os | dc); nl( os ); 225 225 } // ?|? 226 226 … … 234 234 } // ?|? 235 235 void & ?|?( ostype & os, long double _Complex ldc ) { 236 (ostype &)(os | ldc); ends( os );236 (ostype &)(os | ldc); nl( os ); 237 237 } // ?|? 238 238 … … 276 276 } // ?|? 277 277 void ?|?( ostype & os, const char * str ) { 278 (ostype &)(os | str); ends( os );278 (ostype &)(os | str); nl( os ); 279 279 } // ?|? 280 280 … … 305 305 } // ?|? 306 306 void ?|?( ostype & os, const void * p ) { 307 (ostype &)(os | p); ends( os );307 (ostype &)(os | p); nl( os ); 308 308 } // ?|? 309 309 … … 315 315 void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) { 316 316 (ostype &)(manip( os )); 317 if ( getPrt( os ) ) ends( os ); // something printed ?317 if ( getPrt( os ) ) nl( os ); // something printed ? 318 318 setPrt( os, false ); // turn off 319 319 } // ?|? … … 335 335 } // nl 336 336 337 void nl( ostype & os ) { 338 if ( getANL( os ) ) (ostype &)(nl( os )); // implementation only 339 else setPrt( os, false ); // turn off 340 } // nl 341 337 342 ostype & nonl( ostype & os ) { 338 343 setPrt( os, false ); // turn off … … 381 386 } // ?|? 382 387 void ?|?( ostype & os, T arg, Params rest ) { 383 // (ostype &)(?|?( os, arg, rest )); ends( os );388 // (ostype &)(?|?( os, arg, rest )); nl( os ); 384 389 (ostype &)(os | arg); // print first argument 385 390 sepSetCur( os, sepGetTuple( os ) ); // switch to tuple separator 386 391 (ostype &)(os | rest); // print remaining arguments 387 392 sepSetCur( os, sepGet( os ) ); // switch to regular separator 388 ends( os );393 nl( os ); 389 394 } // ?|? 390 395 } // distribution … … 403 408 } // distribution 404 409 405 //*********************************** manipulators ***********************************406 407 //*********************************** integral ***********************************410 //*********************************** Manipulators *********************************** 411 412 //*********************************** Integral *********************************** 408 413 409 414 static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; … … 473 478 return os; \ 474 479 } /* ?|? */ \ 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 ); } \ 476 481 } // distribution 477 482 … … 487 492 IntegralFMTImpl( unsigned long long int, 'u', "% *ll ", "% *.*ll " ) 488 493 489 //*********************************** floating point ***********************************494 //*********************************** Floating Point *********************************** 490 495 491 496 #define PrintWithDP2( os, format, val, ... ) \ … … 499 504 if ( ! f.flags.left ) { \ 500 505 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 */ \ 502 507 } else { \ 503 508 for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \ … … 536 541 return os; \ 537 542 } /* ?|? */ \ 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 ); } \ 539 544 } // distribution 540 545 … … 542 547 FloatingPointFMTImpl( long double, "% *L ", "% *.*L " ) 543 548 544 //*********************************** character ***********************************549 //*********************************** Character *********************************** 545 550 546 551 forall( dtype ostype | ostream( ostype ) ) { 547 552 ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) { 548 if ( f.base != 'c' ) { // bespoke binary/octal/hex format553 if ( f.base != 'c' ) { // bespoke binary/octal/hex format 549 554 _Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} }; 550 555 fmtuc.flags.pc = f.flags.pc; … … 558 563 559 564 #define CFMTNP "% * " 560 char fmtstr[sizeof(CFMTNP)]; // sizeof includes '\0'565 char fmtstr[sizeof(CFMTNP)]; // sizeof includes '\0' 561 566 memcpy( &fmtstr, CFMTNP, sizeof(CFMTNP) ); 562 int star = 1; // position before first '*'567 int star = 1; // position before first '*' 563 568 564 569 // Insert flags into spaces before '*', from right to left. … … 566 571 fmtstr[star] = '%'; 567 572 568 fmtstr[sizeof(CFMTNP)-2] = f.base; // sizeof includes '\0'573 fmtstr[sizeof(CFMTNP)-2] = f.base; // sizeof includes '\0' 569 574 // printf( "%d %s\n", f.wd, &fmtstr[star] ); 570 575 fmt( os, &fmtstr[star], f.wd, f.val ); 571 576 return os; 572 577 } // ?|? 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 ); } 574 579 } // distribution 575 580 576 //*********************************** C string ***********************************581 //*********************************** C String *********************************** 577 582 578 583 forall( dtype ostype | ostream( ostype ) ) { … … 616 621 return os; 617 622 } // ?|? 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 ); } 619 624 } // distribution 620 625 621 626 622 //*********************************** istream ***********************************627 //*********************************** Istream *********************************** 623 628 624 629 … … 631 636 else { 632 637 fprintf( stderr, "invalid Boolean constant\n" ); 633 abort(); // cannot use abort stream638 abort(); 634 639 } // if 635 640 return is; … … 639 644 char temp; 640 645 for () { 641 fmt( is, "%c", &temp ); // must pass pointer through varg to fmt646 fmt( is, "%c", &temp ); // must pass pointer through varg to fmt 642 647 // do not overwrite parameter with newline unless appropriate 643 648 if ( temp != '\n' || getANL( is ) ) { c = temp; break; } … … 766 771 } // distribution 767 772 768 //*********************************** manipulators ***********************************773 //*********************************** Manipulators *********************************** 769 774 770 775 forall( dtype istype | istream( istype ) ) … … 773 778 if ( ! f.s ) { 774 779 // printf( "skip %s %d\n", f.scanset, f.wd ); 775 if ( f.wd == -1 ) fmt( is, f.scanset, "" ); // no input arguments780 if ( f.wd == -1 ) fmt( is, f.scanset, "" ); // no input arguments 776 781 else for ( f.wd ) fmt( is, "%*c" ); 777 782 return is; -
libcfa/src/iostream.hfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 12 12:08:38201913 // Update Count : 3 3412 // Last Modified On : Thu Jun 13 17:20:21 2019 13 // Update Count : 325 14 14 // 15 15 … … 19 19 20 20 21 //*********************************** ostream ***********************************21 //*********************************** Ostream *********************************** 22 22 23 23 … … 47 47 void sepSetTuple( ostype &, const char * ); // set tuple separator to string (15 character maximum) 48 48 49 void ends( ostype & os ); // end of output statement50 49 int fail( ostype & ); 51 50 int flush( ostype & ); … … 99 98 void ?|?( ostype &, unsigned long long int ); 100 99 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 103 102 ostype & ?|?( ostype &, double ); 104 103 void ?|?( ostype &, double ); … … 127 126 void ?|?( ostype &, ostype & (*)( ostype & ) ); 128 127 ostype & nl( ostype & ); 128 void nl( ostype & ); 129 129 ostype & nonl( ostype & ); 130 130 ostype & sep( ostype & ); … … 150 150 } // distribution 151 151 152 //*********************************** manipulators ***********************************152 //*********************************** Manipulators *********************************** 153 153 154 154 forall( otype T ) … … 169 169 }; // _Ostream_Manip 170 170 171 //*********************************** integral ***********************************171 //*********************************** Integral *********************************** 172 172 173 173 // See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular … … 207 207 IntegralFMTDecl( unsigned long long int, 'u' ) 208 208 209 //*********************************** floating point ***********************************209 //*********************************** Floating Point *********************************** 210 210 211 211 // Default suffix for values with no fraction is "." … … 236 236 FloatingPointFMTDecl( long double ) 237 237 238 //*********************************** character ***********************************238 //*********************************** Character *********************************** 239 239 240 240 static inline { … … 253 253 } // ?|? 254 254 255 //*********************************** C string ***********************************255 //*********************************** C String *********************************** 256 256 257 257 static inline { … … 272 272 273 273 274 //*********************************** istream ***********************************274 //*********************************** Istream *********************************** 275 275 276 276 … … 326 326 } // distribution 327 327 328 //*********************************** manipulators ***********************************328 //*********************************** Manipulators *********************************** 329 329 330 330 struct _Istream_Cstr { … … 403 403 404 404 405 //*********************************** time ***********************************405 //*********************************** Time *********************************** 406 406 407 407 -
libcfa/src/rational.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 12 18:12:08201913 // Update Count : 18 412 // Last Modified On : Thu Mar 28 17:33:03 2019 13 // Update Count : 181 14 14 // 15 15 … … 35 35 static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) { 36 36 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" ); 38 38 } // exit 39 39 if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator … … 167 167 168 168 void ?|?( ostype & os, Rational(RationalImpl) r ) { 169 (ostype &)(os | r); ends( os );169 (ostype &)(os | r); nl( os ); 170 170 } // ?|? 171 171 } // distribution -
libcfa/src/stdlib.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 24 17:34:44 201913 // Update Count : 4 6212 // Last Modified On : Thu Jul 12 08:03:59 2018 13 // Update Count : 458 14 14 // 15 15 … … 65 65 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) 66 66 T * anew( size_t dim, Params p ) { 67 T * arr = alloc( dim );67 T *arr = alloc( dim ); 68 68 for ( unsigned int i = 0; i < dim; i += 1 ) { 69 69 (arr[i]){ p }; // run constructor … … 252 252 long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); } 253 253 254 //---------------------------------------255 256 bool threading_enabled(void) __attribute__((weak)) {257 return false;258 }259 254 260 255 // Local Variables: // -
libcfa/src/stdlib.hfa
r4eb43fa rf6cc734e 15 15 16 16 #pragma once 17 18 #include "bits/defs.hfa"19 17 20 18 #include <stdlib.h> // *alloc, strto*, ato* … … 248 246 #include "common.hfa" 249 247 250 //---------------------------------------251 252 extern bool threading_enabled(void) OPTIONAL_THREAD;253 254 248 // Local Variables: // 255 249 // mode: c // -
libcfa/src/time.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Tue Mar 27 13:33:14 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S at Jul 13 08:41:55 201913 // Update Count : 6512 // Last Modified On : Sun Dec 23 22:57:48 2018 13 // Update Count : 57 14 14 // 15 15 16 16 #include "time.hfa" 17 #include " fstream.hfa"17 #include "iostream.hfa" 18 18 #include <stdio.h> // snprintf 19 19 #include <assert.h> … … 37 37 if ( ns != 0 ) { // some ? 38 38 char buf[16]; 39 (ostype &)(os | nanomsd( ns, buf )); // print nanoseconds39 (ostype &)(os | nanomsd( ns, buf )); // print nanoseconds 40 40 } // if 41 41 return os; … … 43 43 44 44 void ?|?( ostype & os, Duration dur ) with( dur ) { 45 (ostype &)(os | dur); ends( os );45 (ostype &)(os | dur); nl( os ); 46 46 } // ?|? 47 47 } // distribution … … 52 52 53 53 #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." 58 56 #endif // __CFA_DEBUG__ 59 57 … … 65 63 #ifdef __CFA_DEBUG__ 66 64 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 ); 68 66 } // if 69 67 #endif // __CFA_DEBUG__ … … 71 69 #ifdef __CFA_DEBUG__ 72 70 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 ); 74 72 } // if 75 73 #endif // __CFA_DEBUG__ … … 81 79 #ifdef __CFA_DEBUG__ 82 80 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 ); 84 82 } // if 85 83 #endif // __CFA_DEBUG__ … … 87 85 #ifdef __CFA_DEBUG__ 88 86 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 ); 90 88 } // if 91 89 #endif // __CFA_DEBUG__ … … 152 150 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN; // compute nanoseconds 153 151 if ( ns == 0 ) { // none ? 154 (ostype &)(os | buf); // print date/time/year152 (ostype &)(os | buf); // print date/time/year 155 153 } else { 156 154 buf[19] = '\0'; // truncate to "Wed Jun 30 21:49:08" 157 155 char buf2[16]; 158 156 nanomsd( ns, buf2 ); // compute nanoseconds 159 (ostype &)(os | buf | buf2 | ' ' | &buf[20]); // print date/time, nanoseconds and year157 (ostype &)(os | buf | buf2 | ' ' | &buf[20]); // print date/time, nanoseconds and year 160 158 } // if 161 159 return os; … … 163 161 164 162 void ?|?( ostype & os, Time time ) with( time ) { 165 (ostype &)(os | time); ends( os );163 (ostype &)(os | time); nl( os ); 166 164 } // ?|? 167 165 } // distribution -
src/AST/Convert.cpp
r4eb43fa rf6cc734e 518 518 } 519 519 520 const ast:: Decl* visit( const ast::WithStmt * node ) override final {520 const ast::Stmt * visit( const ast::WithStmt * node ) override final { 521 521 if ( inCache( node ) ) return nullptr; 522 522 auto stmt = new WithStmt( … … 524 524 get<Statement>().accept1( node->stmt ) 525 525 ); 526 declPostamble( stmt, node ); 527 return nullptr; 526 return stmtPostamble( stmt, node ); 528 527 } 529 528 … … 1051 1050 get<Expression>().accept1(node->expr), 1052 1051 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) 1055 1054 ) 1056 1055 ); … … 1367 1366 ast::Node * node = nullptr; 1368 1367 /// cache of nodes that might be referenced by readonly<> for de-duplication 1369 std::unordered_map< constBaseSyntaxNode *, ast::Node * > cache = {};1368 std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {}; 1370 1369 1371 1370 // Local Utilities: … … 1434 1433 to<std::vector>::from( make_labels( std::move( labels ) ) ) 1435 1434 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 }; } 1437 1436 1438 1437 /// returns true and sets `node` if in cache 1439 bool inCache( constBaseSyntaxNode * old ) {1438 bool inCache( BaseSyntaxNode * old ) { 1440 1439 auto it = cache.find( old ); 1441 1440 if ( it == cache.end() ) return false; … … 1446 1445 // Now all the visit functions: 1447 1446 1448 virtual void visit( constObjectDecl * old ) override final {1447 virtual void visit( ObjectDecl * old ) override final { 1449 1448 auto&& type = GET_ACCEPT_1(type, Type); 1450 1449 auto&& init = GET_ACCEPT_1(init, Init); … … 1477 1476 } 1478 1477 1479 virtual void visit( constFunctionDecl * old ) override final {1478 virtual void visit( FunctionDecl * old ) override final { 1480 1479 if ( inCache( old ) ) return; 1481 1480 auto decl = new ast::FunctionDecl{ … … 1510 1509 } 1511 1510 1512 virtual void visit( constStructDecl * old ) override final {1511 virtual void visit( StructDecl * old ) override final { 1513 1512 if ( inCache( old ) ) return; 1514 1513 auto decl = new ast::StructDecl( … … 1535 1534 } 1536 1535 1537 virtual void visit( constUnionDecl * old ) override final {1536 virtual void visit( UnionDecl * old ) override final { 1538 1537 if ( inCache( old ) ) return; 1539 1538 auto decl = new ast::UnionDecl( … … 1555 1554 } 1556 1555 1557 virtual void visit( constEnumDecl * old ) override final {1556 virtual void visit( EnumDecl * old ) override final { 1558 1557 if ( inCache( old ) ) return; 1559 1558 auto decl = new ast::EnumDecl( … … 1575 1574 } 1576 1575 1577 virtual void visit( constTraitDecl * old ) override final {1576 virtual void visit( TraitDecl * old ) override final { 1578 1577 if ( inCache( old ) ) return; 1579 1578 auto decl = new ast::TraitDecl( … … 1595 1594 } 1596 1595 1597 virtual void visit( constTypeDecl * old ) override final {1596 virtual void visit( TypeDecl * old ) override final { 1598 1597 if ( inCache( old ) ) return; 1599 1598 auto decl = new ast::TypeDecl{ … … 1615 1614 } 1616 1615 1617 virtual void visit( constTypedefDecl * old ) override final {1616 virtual void visit( TypedefDecl * old ) override final { 1618 1617 auto decl = new ast::TypedefDecl( 1619 1618 old->location, … … 1632 1631 } 1633 1632 1634 virtual void visit( constAsmDecl * old ) override final {1633 virtual void visit( AsmDecl * old ) override final { 1635 1634 auto decl = new ast::AsmDecl{ 1636 1635 old->location, … … 1644 1643 } 1645 1644 1646 virtual void visit( constStaticAssertDecl * old ) override final {1645 virtual void visit( StaticAssertDecl * old ) override final { 1647 1646 auto decl = new ast::StaticAssertDecl{ 1648 1647 old->location, … … 1657 1656 } 1658 1657 1659 virtual void visit( constCompoundStmt * old ) override final {1658 virtual void visit( CompoundStmt * old ) override final { 1660 1659 if ( inCache( old ) ) return; 1661 1660 auto stmt = new ast::CompoundStmt( … … 1669 1668 } 1670 1669 1671 virtual void visit( constExprStmt * old ) override final {1670 virtual void visit( ExprStmt * old ) override final { 1672 1671 if ( inCache( old ) ) return; 1673 1672 this->node = new ast::ExprStmt( … … 1679 1678 } 1680 1679 1681 virtual void visit( constAsmStmt * old ) override final {1680 virtual void visit( AsmStmt * old ) override final { 1682 1681 if ( inCache( old ) ) return; 1683 1682 this->node = new ast::AsmStmt( … … 1694 1693 } 1695 1694 1696 virtual void visit( constDirectiveStmt * old ) override final {1695 virtual void visit( DirectiveStmt * old ) override final { 1697 1696 if ( inCache( old ) ) return; 1698 1697 this->node = new ast::DirectiveStmt( … … 1704 1703 } 1705 1704 1706 virtual void visit( constIfStmt * old ) override final {1705 virtual void visit( IfStmt * old ) override final { 1707 1706 if ( inCache( old ) ) return; 1708 1707 this->node = new ast::IfStmt( … … 1717 1716 } 1718 1717 1719 virtual void visit( constSwitchStmt * old ) override final {1718 virtual void visit( SwitchStmt * old ) override final { 1720 1719 if ( inCache( old ) ) return; 1721 1720 this->node = new ast::SwitchStmt( … … 1728 1727 } 1729 1728 1730 virtual void visit( constCaseStmt * old ) override final {1729 virtual void visit( CaseStmt * old ) override final { 1731 1730 if ( inCache( old ) ) return; 1732 1731 this->node = new ast::CaseStmt( … … 1739 1738 } 1740 1739 1741 virtual void visit( constWhileStmt * old ) override final {1740 virtual void visit( WhileStmt * old ) override final { 1742 1741 if ( inCache( old ) ) return; 1743 1742 this->node = new ast::WhileStmt( … … 1752 1751 } 1753 1752 1754 virtual void visit( constForStmt * old ) override final {1753 virtual void visit( ForStmt * old ) override final { 1755 1754 if ( inCache( old ) ) return; 1756 1755 this->node = new ast::ForStmt( … … 1765 1764 } 1766 1765 1767 virtual void visit( constBranchStmt * old ) override final {1766 virtual void visit( BranchStmt * old ) override final { 1768 1767 if ( inCache( old ) ) return; 1769 1768 if (old->computedTarget) { … … 1802 1801 } 1803 1802 1804 virtual void visit( constReturnStmt * old ) override final {1803 virtual void visit( ReturnStmt * old ) override final { 1805 1804 if ( inCache( old ) ) return; 1806 1805 this->node = new ast::ReturnStmt( … … 1812 1811 } 1813 1812 1814 virtual void visit( constThrowStmt * old ) override final {1813 virtual void visit( ThrowStmt * old ) override final { 1815 1814 if ( inCache( old ) ) return; 1816 1815 ast::ExceptionKind kind; … … 1836 1835 } 1837 1836 1838 virtual void visit( constTryStmt * old ) override final {1837 virtual void visit( TryStmt * old ) override final { 1839 1838 if ( inCache( old ) ) return; 1840 1839 this->node = new ast::TryStmt( … … 1848 1847 } 1849 1848 1850 virtual void visit( constCatchStmt * old ) override final {1849 virtual void visit( CatchStmt * old ) override final { 1851 1850 if ( inCache( old ) ) return; 1852 1851 ast::ExceptionKind kind; … … 1873 1872 } 1874 1873 1875 virtual void visit( constFinallyStmt * old ) override final {1874 virtual void visit( FinallyStmt * old ) override final { 1876 1875 if ( inCache( old ) ) return; 1877 1876 this->node = new ast::FinallyStmt( … … 1883 1882 } 1884 1883 1885 virtual void visit( constWaitForStmt * old ) override final {1884 virtual void visit( WaitForStmt * old ) override final { 1886 1885 if ( inCache( old ) ) return; 1887 1886 ast::WaitForStmt * stmt = new ast::WaitForStmt( … … 1915 1914 } 1916 1915 1917 virtual void visit( constWithStmt * old ) override final {1916 virtual void visit( WithStmt * old ) override final { 1918 1917 if ( inCache( old ) ) return; 1919 1918 this->node = new ast::WithStmt( 1920 1919 old->location, 1921 1920 GET_ACCEPT_V(exprs, Expr), 1922 GET_ACCEPT_1(stmt, Stmt) 1921 GET_ACCEPT_1(stmt, Stmt), 1922 GET_LABELS_V(old->labels) 1923 1923 ); 1924 1924 cache.emplace( old, this->node ); 1925 1925 } 1926 1926 1927 virtual void visit( constNullStmt * old ) override final {1927 virtual void visit( NullStmt * old ) override final { 1928 1928 if ( inCache( old ) ) return; 1929 1929 this->node = new ast::NullStmt( … … 1934 1934 } 1935 1935 1936 virtual void visit( constDeclStmt * old ) override final {1936 virtual void visit( DeclStmt * old ) override final { 1937 1937 if ( inCache( old ) ) return; 1938 1938 this->node = new ast::DeclStmt( … … 1944 1944 } 1945 1945 1946 virtual void visit( constImplicitCtorDtorStmt * old ) override final {1946 virtual void visit( ImplicitCtorDtorStmt * old ) override final { 1947 1947 if ( inCache( old ) ) return; 1948 1948 auto stmt = new ast::ImplicitCtorDtorStmt( … … 2001 2001 } 2002 2002 2003 ast::Expr * visitBaseExpr_SkipResultType( constExpression * old, ast::Expr * nw) {2003 ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) { 2004 2004 2005 2005 nw->env = convertTypeSubstitution(old->env); … … 2011 2011 } 2012 2012 2013 ast::Expr * visitBaseExpr( constExpression * old, ast::Expr * nw) {2013 ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) { 2014 2014 2015 2015 nw->result = GET_ACCEPT_1(result, Type); … … 2017 2017 } 2018 2018 2019 virtual void visit( constApplicationExpr * old ) override final {2019 virtual void visit( ApplicationExpr * old ) override final { 2020 2020 this->node = visitBaseExpr( old, 2021 2021 new ast::ApplicationExpr( … … 2027 2027 } 2028 2028 2029 virtual void visit( constUntypedExpr * old ) override final {2029 virtual void visit( UntypedExpr * old ) override final { 2030 2030 this->node = visitBaseExpr( old, 2031 2031 new ast::UntypedExpr( … … 2037 2037 } 2038 2038 2039 virtual void visit( constNameExpr * old ) override final {2039 virtual void visit( NameExpr * old ) override final { 2040 2040 this->node = visitBaseExpr( old, 2041 2041 new ast::NameExpr( … … 2046 2046 } 2047 2047 2048 virtual void visit( constCastExpr * old ) override final {2048 virtual void visit( CastExpr * old ) override final { 2049 2049 this->node = visitBaseExpr( old, 2050 2050 new ast::CastExpr( … … 2056 2056 } 2057 2057 2058 virtual void visit( constKeywordCastExpr * old) override final {2058 virtual void visit( KeywordCastExpr * old) override final { 2059 2059 ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS; 2060 2060 switch (old->target) { … … 2081 2081 } 2082 2082 2083 virtual void visit( constVirtualCastExpr * old ) override final {2083 virtual void visit( VirtualCastExpr * old ) override final { 2084 2084 this->node = visitBaseExpr_SkipResultType( old, 2085 2085 new ast::VirtualCastExpr( … … 2091 2091 } 2092 2092 2093 virtual void visit( constAddressExpr * old ) override final {2093 virtual void visit( AddressExpr * old ) override final { 2094 2094 this->node = visitBaseExpr( old, 2095 2095 new ast::AddressExpr( … … 2100 2100 } 2101 2101 2102 virtual void visit( constLabelAddressExpr * old ) override final {2102 virtual void visit( LabelAddressExpr * old ) override final { 2103 2103 this->node = visitBaseExpr( old, 2104 2104 new ast::LabelAddressExpr( … … 2109 2109 } 2110 2110 2111 virtual void visit( constUntypedMemberExpr * old ) override final {2111 virtual void visit( UntypedMemberExpr * old ) override final { 2112 2112 this->node = visitBaseExpr( old, 2113 2113 new ast::UntypedMemberExpr( … … 2119 2119 } 2120 2120 2121 virtual void visit( constMemberExpr * old ) override final {2121 virtual void visit( MemberExpr * old ) override final { 2122 2122 this->node = visitBaseExpr( old, 2123 2123 new ast::MemberExpr( … … 2129 2129 } 2130 2130 2131 virtual void visit( constVariableExpr * old ) override final {2131 virtual void visit( VariableExpr * old ) override final { 2132 2132 auto expr = new ast::VariableExpr( 2133 2133 old->location … … 2140 2140 } 2141 2141 2142 virtual void visit( constConstantExpr * old ) override final {2142 virtual void visit( ConstantExpr * old ) override final { 2143 2143 ast::ConstantExpr *rslt = new ast::ConstantExpr( 2144 2144 old->location, 2145 2145 GET_ACCEPT_1(result, Type), 2146 old->constant. rep,2146 old->constant.get_value(), 2147 2147 old->constant.ival 2148 2148 ); 2149 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant. type);2149 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() ); 2150 2150 this->node = visitBaseExpr( old, rslt ); 2151 2151 } 2152 2152 2153 virtual void visit( constSizeofExpr * old ) override final {2153 virtual void visit( SizeofExpr * old ) override final { 2154 2154 assert (old->expr || old->type); 2155 2155 assert (! (old->expr && old->type)); … … 2172 2172 } 2173 2173 2174 virtual void visit( constAlignofExpr * old ) override final {2174 virtual void visit( AlignofExpr * old ) override final { 2175 2175 assert (old->expr || old->type); 2176 2176 assert (! (old->expr && old->type)); … … 2193 2193 } 2194 2194 2195 virtual void visit( constUntypedOffsetofExpr * old ) override final {2195 virtual void visit( UntypedOffsetofExpr * old ) override final { 2196 2196 this->node = visitBaseExpr( old, 2197 2197 new ast::UntypedOffsetofExpr( … … 2203 2203 } 2204 2204 2205 virtual void visit( constOffsetofExpr * old ) override final {2205 virtual void visit( OffsetofExpr * old ) override final { 2206 2206 this->node = visitBaseExpr( old, 2207 2207 new ast::OffsetofExpr( … … 2213 2213 } 2214 2214 2215 virtual void visit( constOffsetPackExpr * old ) override final {2215 virtual void visit( OffsetPackExpr * old ) override final { 2216 2216 this->node = visitBaseExpr( old, 2217 2217 new ast::OffsetPackExpr( … … 2222 2222 } 2223 2223 2224 virtual void visit( constLogicalExpr * old ) override final {2224 virtual void visit( LogicalExpr * old ) override final { 2225 2225 this->node = visitBaseExpr( old, 2226 2226 new ast::LogicalExpr( … … 2235 2235 } 2236 2236 2237 virtual void visit( constConditionalExpr * old ) override final {2237 virtual void visit( ConditionalExpr * old ) override final { 2238 2238 this->node = visitBaseExpr( old, 2239 2239 new ast::ConditionalExpr( … … 2246 2246 } 2247 2247 2248 virtual void visit( constCommaExpr * old ) override final {2248 virtual void visit( CommaExpr * old ) override final { 2249 2249 this->node = visitBaseExpr( old, 2250 2250 new ast::CommaExpr( … … 2256 2256 } 2257 2257 2258 virtual void visit( constTypeExpr * old ) override final {2258 virtual void visit( TypeExpr * old ) override final { 2259 2259 this->node = visitBaseExpr( old, 2260 2260 new ast::TypeExpr( … … 2265 2265 } 2266 2266 2267 virtual void visit( constAsmExpr * old ) override final {2267 virtual void visit( AsmExpr * old ) override final { 2268 2268 this->node = visitBaseExpr( old, 2269 2269 new ast::AsmExpr( … … 2276 2276 } 2277 2277 2278 virtual void visit( constImplicitCopyCtorExpr * old ) override final {2278 virtual void visit( ImplicitCopyCtorExpr * old ) override final { 2279 2279 auto rslt = new ast::ImplicitCopyCtorExpr( 2280 2280 old->location, … … 2285 2285 } 2286 2286 2287 virtual void visit( constConstructorExpr * old ) override final {2287 virtual void visit( ConstructorExpr * old ) override final { 2288 2288 this->node = visitBaseExpr( old, 2289 2289 new ast::ConstructorExpr( … … 2294 2294 } 2295 2295 2296 virtual void visit( constCompoundLiteralExpr * old ) override final {2296 virtual void visit( CompoundLiteralExpr * old ) override final { 2297 2297 this->node = visitBaseExpr_SkipResultType( old, 2298 2298 new ast::CompoundLiteralExpr( … … 2304 2304 } 2305 2305 2306 virtual void visit( constRangeExpr * old ) override final {2306 virtual void visit( RangeExpr * old ) override final { 2307 2307 this->node = visitBaseExpr( old, 2308 2308 new ast::RangeExpr( … … 2314 2314 } 2315 2315 2316 virtual void visit( constUntypedTupleExpr * old ) override final {2316 virtual void visit( UntypedTupleExpr * old ) override final { 2317 2317 this->node = visitBaseExpr( old, 2318 2318 new ast::UntypedTupleExpr( … … 2323 2323 } 2324 2324 2325 virtual void visit( constTupleExpr * old ) override final {2325 virtual void visit( TupleExpr * old ) override final { 2326 2326 this->node = visitBaseExpr( old, 2327 2327 new ast::TupleExpr( … … 2332 2332 } 2333 2333 2334 virtual void visit( constTupleIndexExpr * old ) override final {2334 virtual void visit( TupleIndexExpr * old ) override final { 2335 2335 this->node = visitBaseExpr( old, 2336 2336 new ast::TupleIndexExpr( … … 2342 2342 } 2343 2343 2344 virtual void visit( constTupleAssignExpr * old ) override final {2344 virtual void visit( TupleAssignExpr * old ) override final { 2345 2345 this->node = visitBaseExpr_SkipResultType( old, 2346 2346 new ast::TupleAssignExpr( … … 2352 2352 } 2353 2353 2354 virtual void visit( constStmtExpr * old ) override final {2354 virtual void visit( StmtExpr * old ) override final { 2355 2355 auto rslt = new ast::StmtExpr( 2356 2356 old->location, … … 2363 2363 } 2364 2364 2365 virtual void visit( constUniqueExpr * old ) override final {2365 virtual void visit( UniqueExpr * old ) override final { 2366 2366 auto rslt = new ast::UniqueExpr( 2367 2367 old->location, … … 2375 2375 } 2376 2376 2377 virtual void visit( constUntypedInitExpr * old ) override final {2377 virtual void visit( UntypedInitExpr * old ) override final { 2378 2378 std::deque<ast::InitAlternative> initAlts; 2379 2379 for (auto ia : old->initAlts) { … … 2392 2392 } 2393 2393 2394 virtual void visit( constInitExpr * old ) override final {2394 virtual void visit( InitExpr * old ) override final { 2395 2395 this->node = visitBaseExpr( old, 2396 2396 new ast::InitExpr( … … 2402 2402 } 2403 2403 2404 virtual void visit( constDeletedExpr * old ) override final {2404 virtual void visit( DeletedExpr * old ) override final { 2405 2405 this->node = visitBaseExpr( old, 2406 2406 new ast::DeletedExpr( … … 2408 2408 GET_ACCEPT_1(expr, Expr), 2409 2409 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( constDefaultArgExpr * old ) override final {2410 this->node : 2411 GET_ACCEPT_1(deleteStmt, Node) 2412 ) 2413 ); 2414 } 2415 2416 virtual void visit( DefaultArgExpr * old ) override final { 2417 2417 this->node = visitBaseExpr( old, 2418 2418 new ast::DefaultArgExpr( … … 2423 2423 } 2424 2424 2425 virtual void visit( constGenericExpr * old ) override final {2425 virtual void visit( GenericExpr * old ) override final { 2426 2426 std::vector<ast::GenericExpr::Association> associations; 2427 2427 for (auto association : old->associations) { … … 2440 2440 } 2441 2441 2442 void visitType( constType * old, ast::Type * type ) {2442 void visitType( Type * old, ast::Type * type ) { 2443 2443 // Some types do this in their constructor so add a check. 2444 2444 if ( !old->attributes.empty() && type->attributes.empty() ) { … … 2448 2448 } 2449 2449 2450 virtual void visit( constVoidType * old ) override final {2450 virtual void visit( VoidType * old ) override final { 2451 2451 visitType( old, new ast::VoidType{ cv( old ) } ); 2452 2452 } 2453 2453 2454 virtual void visit( constBasicType * old ) override final {2454 virtual void visit( BasicType * old ) override final { 2455 2455 auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) }; 2456 2456 // I believe this should always be a BasicType. … … 2461 2461 } 2462 2462 2463 virtual void visit( constPointerType * old ) override final {2463 virtual void visit( PointerType * old ) override final { 2464 2464 visitType( old, new ast::PointerType{ 2465 2465 GET_ACCEPT_1( base, Type ), … … 2471 2471 } 2472 2472 2473 virtual void visit( constArrayType * old ) override final {2473 virtual void visit( ArrayType * old ) override final { 2474 2474 visitType( old, new ast::ArrayType{ 2475 2475 GET_ACCEPT_1( base, Type ), … … 2481 2481 } 2482 2482 2483 virtual void visit( constReferenceType * old ) override final {2483 virtual void visit( ReferenceType * old ) override final { 2484 2484 visitType( old, new ast::ReferenceType{ 2485 2485 GET_ACCEPT_1( base, Type ), … … 2488 2488 } 2489 2489 2490 virtual void visit( constQualifiedType * old ) override final {2490 virtual void visit( QualifiedType * old ) override final { 2491 2491 visitType( old, new ast::QualifiedType{ 2492 2492 GET_ACCEPT_1( parent, Type ), … … 2496 2496 } 2497 2497 2498 virtual void visit( constFunctionType * old ) override final {2498 virtual void visit( FunctionType * old ) override final { 2499 2499 auto ty = new ast::FunctionType { 2500 2500 (ast::ArgumentFlag)old->isVarArgs, … … 2507 2507 } 2508 2508 2509 void postvisit( constReferenceToType * old, ast::ReferenceToType * ty ) {2509 void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) { 2510 2510 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 2511 2511 ty->params = GET_ACCEPT_V( parameters, Expr ); … … 2514 2514 } 2515 2515 2516 virtual void visit( constStructInstType * old ) override final {2516 virtual void visit( StructInstType * old ) override final { 2517 2517 ast::StructInstType * ty; 2518 2518 if ( old->baseStruct ) { … … 2532 2532 } 2533 2533 2534 virtual void visit( constUnionInstType * old ) override final {2534 virtual void visit( UnionInstType * old ) override final { 2535 2535 ast::UnionInstType * ty; 2536 2536 if ( old->baseUnion ) { … … 2550 2550 } 2551 2551 2552 virtual void visit( constEnumInstType * old ) override final {2552 virtual void visit( EnumInstType * old ) override final { 2553 2553 ast::EnumInstType * ty; 2554 2554 if ( old->baseEnum ) { … … 2568 2568 } 2569 2569 2570 virtual void visit( constTraitInstType * old ) override final {2570 virtual void visit( TraitInstType * old ) override final { 2571 2571 ast::TraitInstType * ty; 2572 2572 if ( old->baseTrait ) { … … 2586 2586 } 2587 2587 2588 virtual void visit( constTypeInstType * old ) override final {2588 virtual void visit( TypeInstType * old ) override final { 2589 2589 ast::TypeInstType * ty; 2590 2590 if ( old->baseType ) { … … 2606 2606 } 2607 2607 2608 virtual void visit( constTupleType * old ) override final {2608 virtual void visit( TupleType * old ) override final { 2609 2609 visitType( old, new ast::TupleType{ 2610 2610 GET_ACCEPT_V( types, Type ), … … 2614 2614 } 2615 2615 2616 virtual void visit( constTypeofType * old ) override final {2616 virtual void visit( TypeofType * old ) override final { 2617 2617 visitType( old, new ast::TypeofType{ 2618 2618 GET_ACCEPT_1( expr, Expr ), … … 2622 2622 } 2623 2623 2624 virtual void visit( constAttrType * ) override final {2624 virtual void visit( AttrType * ) override final { 2625 2625 assertf( false, "AttrType deprecated in new AST." ); 2626 2626 } 2627 2627 2628 virtual void visit( constVarArgsType * old ) override final {2628 virtual void visit( VarArgsType * old ) override final { 2629 2629 visitType( old, new ast::VarArgsType{ cv( old ) } ); 2630 2630 } 2631 2631 2632 virtual void visit( constZeroType * old ) override final {2632 virtual void visit( ZeroType * old ) override final { 2633 2633 visitType( old, new ast::ZeroType{ cv( old ) } ); 2634 2634 } 2635 2635 2636 virtual void visit( constOneType * old ) override final {2636 virtual void visit( OneType * old ) override final { 2637 2637 visitType( old, new ast::OneType{ cv( old ) } ); 2638 2638 } 2639 2639 2640 virtual void visit( constGlobalScopeType * old ) override final {2640 virtual void visit( GlobalScopeType * old ) override final { 2641 2641 visitType( old, new ast::GlobalScopeType{} ); 2642 2642 } 2643 2643 2644 virtual void visit( constDesignation * old ) override final {2644 virtual void visit( Designation * old ) override final { 2645 2645 this->node = new ast::Designation( 2646 2646 old->location, … … 2649 2649 } 2650 2650 2651 virtual void visit( constSingleInit * old ) override final {2651 virtual void visit( SingleInit * old ) override final { 2652 2652 this->node = new ast::SingleInit( 2653 2653 old->location, … … 2657 2657 } 2658 2658 2659 virtual void visit( constListInit * old ) override final {2659 virtual void visit( ListInit * old ) override final { 2660 2660 this->node = new ast::ListInit( 2661 2661 old->location, … … 2666 2666 } 2667 2667 2668 virtual void visit( constConstructorInit * old ) override final {2668 virtual void visit( ConstructorInit * old ) override final { 2669 2669 this->node = new ast::ConstructorInit( 2670 2670 old->location, … … 2675 2675 } 2676 2676 2677 virtual void visit( constConstant * ) override final {2677 virtual void visit( Constant * ) override final { 2678 2678 // Handled in visit( ConstantEpxr * ). 2679 2679 // In the new tree, Constant fields are inlined into containing ConstantExpression. … … 2681 2681 } 2682 2682 2683 virtual void visit( constAttribute * old ) override final {2683 virtual void visit( Attribute * old ) override final { 2684 2684 this->node = new ast::Attribute( 2685 2685 old->name, … … 2688 2688 } 2689 2689 2690 virtual void visit( constAttrExpr * ) override final {2690 virtual void visit( AttrExpr * ) override final { 2691 2691 assertf( false, "AttrExpr deprecated in new AST." ); 2692 2692 } -
src/AST/Decl.hpp
r4eb43fa rf6cc734e 104 104 ptr<Expr> bitfieldWidth; 105 105 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, 109 109 std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} ) 110 110 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ), … … 325 325 }; 326 326 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_FRIEND340 };341 342 327 class AsmDecl : public Decl { 343 328 public: -
src/AST/Expr.hpp
r4eb43fa rf6cc734e 50 50 51 51 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, 54 54 const Expr * e ) 55 55 : decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {} … … 115 115 case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough 116 116 case Slots: return data.resnSlots; 117 case Params: assert f(false, "Cannot return to resnSlots from Params"); abort();117 case Params: assert(!"Cannot return to resnSlots from Params"); 118 118 } 119 assertf(false, "unreachable");119 return *((ResnSlots*)nullptr); 120 120 } 121 121 … … 124 124 return data.resnSlots; 125 125 } 126 assert f(false,"Mode was not already resnSlots");127 abort();126 assert(!"Mode was not already resnSlots"); 127 return *((ResnSlots*)nullptr); 128 128 } 129 129 … … 134 134 case Params: return data.inferParams; 135 135 } 136 assertf(false, "unreachable"); 136 assert(!"unreachable"); 137 return *((InferredParams*)nullptr); 137 138 } 138 139 … … 141 142 return data.inferParams; 142 143 } 143 assert f(false,"Mode was not already Params");144 abort();144 assert(!"Mode was not already Params"); 145 return *((InferredParams*)nullptr); 145 146 } 146 147 147 148 void set_inferParams( InferredParams && ps ) { 148 149 switch(mode) { 149 case Slots: 150 case Slots: 150 151 data.resnSlots.~ResnSlots(); 151 152 // fallthrough 152 case Empty: 153 case Empty: 153 154 new(&data.inferParams) InferredParams{ std::move( ps ) }; 154 155 mode = Params; … … 174 175 data.inferParams[p.first] = std::move(p.second); 175 176 } 176 } else assert f(false,"invalid mode");177 } else assert(!"invalid mode"); 177 178 } 178 179 }; … … 386 387 387 388 ConstantExpr( 388 const CodeLocation & loc, const Type * ty, const std::string & r, 389 const CodeLocation & loc, const Type * ty, const std::string & r, 389 390 std::optional<unsigned long long> i ) 390 391 : Expr( loc, ty ), rep( r ), ival( i ) {} … … 772 773 public: 773 774 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 ) 777 778 : Expr( loc, e->result ), expr( e ), deleteStmt( del ) { assert( expr->result ); } 778 779 -
src/AST/Pass.hpp
r4eb43fa rf6cc734e 115 115 const ast::Stmt * visit( const ast::FinallyStmt * ) override final; 116 116 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; 118 118 const ast::NullStmt * visit( const ast::NullStmt * ) override final; 119 119 const ast::Stmt * visit( const ast::DeclStmt * ) override final; -
src/AST/Pass.impl.hpp
r4eb43fa rf6cc734e 909 909 // WithStmt 910 910 template< typename pass_t > 911 const ast:: Decl* ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {911 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) { 912 912 VISIT_START( node ); 913 913 -
src/AST/Print.cpp
r4eb43fa rf6cc734e 37 37 } 38 38 39 class Printer final: public Visitor {39 class Printer : public Visitor { 40 40 public: 41 41 ostream & os; … … 272 272 273 273 public: 274 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final{274 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) { 275 275 if ( ! node->name.empty() ) os << node->name << ": "; 276 276 … … 314 314 } 315 315 316 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final{316 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) { 317 317 if ( !node->name.empty() ) os << node->name << ": "; 318 318 … … 342 342 } 343 343 344 virtual const ast::Decl * visit( const ast::StructDecl * node ) override final{344 virtual const ast::Decl * visit( const ast::StructDecl * node ) { 345 345 print(node); 346 346 return node; 347 347 } 348 348 349 virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final{349 virtual const ast::Decl * visit( const ast::UnionDecl * node ) { 350 350 print(node); 351 351 return node; 352 352 } 353 353 354 virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final{354 virtual const ast::Decl * visit( const ast::EnumDecl * node ) { 355 355 print(node); 356 356 return node; 357 357 } 358 358 359 virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final{359 virtual const ast::Decl * visit( const ast::TraitDecl * node ) { 360 360 print(node); 361 361 return node; 362 362 } 363 363 364 virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final{364 virtual const ast::Decl * visit( const ast::TypeDecl * node ) { 365 365 preprint( node ); 366 366 if ( ! short_mode && node->init ) { … … 374 374 } 375 375 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 ) { 382 382 safe_print( node->stmt ); 383 383 return node; 384 384 } 385 385 386 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final{386 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) { 387 387 os << "Static Assert with condition: "; 388 388 ++indent; … … 396 396 } 397 397 398 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final{398 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) { 399 399 os << "Compound Statement:" << endl; 400 400 ++indent; … … 404 404 } 405 405 406 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final{406 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) { 407 407 ++indent; 408 408 os << "Expression Statement:" << endl << indent; … … 412 412 } 413 413 414 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final{414 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) { 415 415 os << "Assembler Statement:" << endl; 416 416 ++indent; … … 433 433 } 434 434 435 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final{435 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) { 436 436 os << "GCC Directive: " << node->directive << endl; 437 437 return node; 438 438 } 439 439 440 virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final{440 virtual const ast::Stmt * visit( const ast::IfStmt * node ) { 441 441 os << "If on condition:" << endl; 442 442 ++indent; … … 473 473 } 474 474 475 virtual const ast::Stmt * visit( const ast::WhileStmt * node ) override final{475 virtual const ast::Stmt * visit( const ast::WhileStmt * node ) { 476 476 if ( node->isDoWhile ) { os << "Do-"; } 477 477 os << "While on condition:" << endl; … … 490 490 } 491 491 492 virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final{492 virtual const ast::Stmt * visit( const ast::ForStmt * node ) { 493 493 os << "For Statement" << endl; 494 494 … … 532 532 } 533 533 534 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final{534 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) { 535 535 os << "Switch on condition: "; 536 536 safe_print( node->cond ); … … 546 546 } 547 547 548 virtual const ast::Stmt * visit( const ast::CaseStmt * node ) override final{548 virtual const ast::Stmt * visit( const ast::CaseStmt * node ) { 549 549 if ( node->isDefault() ) { 550 550 os << indent << "Default "; … … 565 565 } 566 566 567 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final{567 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) { 568 568 os << "Branch (" << node->kindName() << ")" << endl; 569 569 ++indent; … … 586 586 } 587 587 588 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final{588 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) { 589 589 os << "Return Statement, returning"; 590 590 if ( node->expr ) { … … 601 601 } 602 602 603 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final{603 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) { 604 604 if ( node->target ) os << "Non-Local "; 605 605 … … 621 621 } 622 622 623 virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final{623 virtual const ast::Stmt * visit( const ast::TryStmt * node ) { 624 624 ++indent; 625 625 os << "Try Statement" << endl << indent-1 … … 642 642 } 643 643 644 virtual const ast::Stmt * visit( const ast::CatchStmt * node ) override final{644 virtual const ast::Stmt * visit( const ast::CatchStmt * node ) { 645 645 os << "Catch "; 646 646 switch ( node->kind ) { … … 667 667 } 668 668 669 virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) override final{669 virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) { 670 670 os << "Finally Statement" << endl; 671 671 os << indent << "... with block:" << endl; … … 678 678 } 679 679 680 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final{680 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) { 681 681 os << "Waitfor Statement" << endl; 682 682 indent += 2; … … 732 732 } 733 733 734 virtual const ast:: Decl * visit( const ast::WithStmt * node ) override final{734 virtual const ast::Stmt * visit( const ast::WithStmt * node ) { 735 735 os << "With statement" << endl; 736 736 os << indent << "... with expressions:" << endl; … … 744 744 } 745 745 746 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final{746 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) { 747 747 os << "Null Statement" << endl; 748 748 print( node->labels ); … … 751 751 } 752 752 753 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final{753 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) { 754 754 os << "Declaration of "; 755 755 safe_print( node->decl ); … … 758 758 } 759 759 760 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final{760 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) { 761 761 os << "Implicit Ctor Dtor Statement" << endl; 762 762 os << indent << "... with Ctor/Dtor: "; … … 769 769 } 770 770 771 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final{771 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) { 772 772 ++indent; 773 773 os << "Application of" << endl << indent; … … 784 784 } 785 785 786 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final{786 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) { 787 787 ++indent; 788 788 os << "Applying untyped:" << endl; … … 797 797 } 798 798 799 virtual const ast::Expr * visit( const ast::NameExpr * node ) override final{799 virtual const ast::Expr * visit( const ast::NameExpr * node ) { 800 800 os << "Name: " << node->name; 801 801 postprint( node ); … … 804 804 } 805 805 806 virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final{806 virtual const ast::Expr * visit( const ast::AddressExpr * node ) { 807 807 os << "Address of:" << endl; 808 808 ++indent; … … 815 815 } 816 816 817 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final{817 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) { 818 818 os << "Address of label:" << node->arg; 819 819 … … 821 821 } 822 822 823 virtual const ast::Expr * visit( const ast::CastExpr * node ) override final{823 virtual const ast::Expr * visit( const ast::CastExpr * node ) { 824 824 ++indent; 825 825 os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent; … … 841 841 } 842 842 843 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final{843 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) { 844 844 ++indent; 845 845 os << "Keyword Cast of:" << endl << indent; … … 852 852 } 853 853 854 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final{854 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) { 855 855 ++indent; 856 856 os << "Virtual Cast of:" << endl << indent; … … 869 869 } 870 870 871 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final{871 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) { 872 872 ++indent; 873 873 os << "Untyped Member Expression, with field: " << endl << indent; … … 881 881 } 882 882 883 virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final{883 virtual const ast::Expr * visit( const ast::MemberExpr * node ) { 884 884 ++indent; 885 885 os << "Member Expression, with field:" << endl << indent; … … 893 893 } 894 894 895 virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final{895 virtual const ast::Expr * visit( const ast::VariableExpr * node ) { 896 896 os << "Variable Expression: "; 897 897 short_print( node->var ); … … 901 901 } 902 902 903 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final{903 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) { 904 904 os << "Constant Expression (" << node->rep; 905 905 if ( node->result ) { … … 913 913 } 914 914 915 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final{915 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) { 916 916 os << "Sizeof Expression on: "; 917 917 ++indent; … … 924 924 } 925 925 926 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final{926 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) { 927 927 os << "Alignof Expression on: "; 928 928 ++indent; … … 935 935 } 936 936 937 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final{937 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) { 938 938 os << "Untyped Offsetof Expression on member " << node->member << " of "; 939 939 ++indent; … … 945 945 } 946 946 947 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final{947 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) { 948 948 os << "Offsetof Expression on member " << node->member->name << " of "; 949 949 ++indent; … … 955 955 } 956 956 957 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final{957 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) { 958 958 os << "Offset Pack Expression on: "; 959 959 ++indent; … … 965 965 } 966 966 967 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final{967 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) { 968 968 os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: "; 969 969 safe_print( node->arg1 ); … … 975 975 } 976 976 977 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final{977 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) { 978 978 ++indent; 979 979 os << "Conditional expression on:" << endl << indent; … … 989 989 } 990 990 991 virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final{991 virtual const ast::Expr * visit( const ast::CommaExpr * node ) { 992 992 ++indent; 993 993 os << "Comma Expression:" << endl << indent; … … 1001 1001 } 1002 1002 1003 virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final{1003 virtual const ast::Expr * visit( const ast::TypeExpr * node ) { 1004 1004 safe_print( node->type ); 1005 1005 postprint( node ); … … 1008 1008 } 1009 1009 1010 virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final{1010 virtual const ast::Expr * visit( const ast::AsmExpr * node ) { 1011 1011 os << "Asm Expression:" << endl; 1012 1012 ++indent; … … 1019 1019 } 1020 1020 1021 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final{1021 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) { 1022 1022 ++indent; 1023 1023 os << "Implicit Copy Constructor Expression:" << endl << indent; … … 1029 1029 } 1030 1030 1031 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final{1031 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) { 1032 1032 os << "Constructor Expression:" << endl << indent+1; 1033 1033 indent += 2; … … 1039 1039 } 1040 1040 1041 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final{1041 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) { 1042 1042 ++indent; 1043 1043 os << "Compound Literal Expression: " << endl << indent; … … 1051 1051 } 1052 1052 1053 virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final{1053 virtual const ast::Expr * visit( const ast::RangeExpr * node ) { 1054 1054 os << "Range Expression: "; 1055 1055 safe_print( node->low ); … … 1061 1061 } 1062 1062 1063 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final{1063 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) { 1064 1064 os << "Untyped Tuple:" << endl; 1065 1065 ++indent; … … 1071 1071 } 1072 1072 1073 virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final{1073 virtual const ast::Expr * visit( const ast::TupleExpr * node ) { 1074 1074 os << "Tuple:" << endl; 1075 1075 ++indent; … … 1081 1081 } 1082 1082 1083 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final{1083 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) { 1084 1084 os << "Tuple Index Expression, with tuple:" << endl; 1085 1085 ++indent; … … 1093 1093 } 1094 1094 1095 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final{1095 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) { 1096 1096 os << "Tuple Assignment Expression, with stmt expr:" << endl; 1097 1097 ++indent; … … 1104 1104 } 1105 1105 1106 virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final{1106 virtual const ast::Expr * visit( const ast::StmtExpr * node ) { 1107 1107 ++indent; 1108 1108 os << "Statement Expression:" << endl << indent; … … 1122 1122 } 1123 1123 1124 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final{1124 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) { 1125 1125 ++indent; 1126 1126 os << "Unique Expression with id: " << node->id << endl << indent; … … 1136 1136 } 1137 1137 1138 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final{1138 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) { 1139 1139 ++indent; 1140 1140 os << "Untyped Init Expression" << endl << indent; … … 1152 1152 } 1153 1153 1154 virtual const ast::Expr * visit( const ast::InitExpr * node ) override final{1154 virtual const ast::Expr * visit( const ast::InitExpr * node ) { 1155 1155 ++indent; 1156 1156 os << "Init Expression" << endl << indent; … … 1163 1163 } 1164 1164 1165 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final{1165 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) { 1166 1166 ++indent; 1167 1167 os << "Deleted Expression" << endl << indent; … … 1174 1174 } 1175 1175 1176 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final{1176 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) { 1177 1177 ++indent; 1178 1178 os << "Default Argument Expression" << endl << indent; … … 1183 1183 } 1184 1184 1185 virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final{1185 virtual const ast::Expr * visit( const ast::GenericExpr * node ) { 1186 1186 ++indent; 1187 1187 os << "C11 _Generic Expression" << endl << indent; … … 1206 1206 } 1207 1207 1208 virtual const ast::Type * visit( const ast::VoidType * node ) override final{1208 virtual const ast::Type * visit( const ast::VoidType * node ) { 1209 1209 preprint( node ); 1210 1210 os << "void"; … … 1212 1212 } 1213 1213 1214 virtual const ast::Type * visit( const ast::BasicType * node ) override final{1214 virtual const ast::Type * visit( const ast::BasicType * node ) { 1215 1215 preprint( node ); 1216 1216 os << ast::BasicType::typeNames[ node->kind ]; … … 1218 1218 } 1219 1219 1220 virtual const ast::Type * visit( const ast::PointerType * node ) override final{1220 virtual const ast::Type * visit( const ast::PointerType * node ) { 1221 1221 preprint( node ); 1222 1222 if ( ! node->isArray() ) { … … 1241 1241 } 1242 1242 1243 virtual const ast::Type * visit( const ast::ArrayType * node ) override final{1243 virtual const ast::Type * visit( const ast::ArrayType * node ) { 1244 1244 preprint( node ); 1245 1245 if ( node->isStatic ) { … … 1265 1265 } 1266 1266 1267 virtual const ast::Type * visit( const ast::ReferenceType * node ) override final{1267 virtual const ast::Type * visit( const ast::ReferenceType * node ) { 1268 1268 preprint( node ); 1269 1269 os << "reference to "; … … 1273 1273 } 1274 1274 1275 virtual const ast::Type * visit( const ast::QualifiedType * node ) override final{1275 virtual const ast::Type * visit( const ast::QualifiedType * node ) { 1276 1276 preprint( node ); 1277 1277 ++indent; … … 1286 1286 } 1287 1287 1288 virtual const ast::Type * visit( const ast::FunctionType * node ) override final{1288 virtual const ast::Type * visit( const ast::FunctionType * node ) { 1289 1289 preprint( node ); 1290 1290 … … 1315 1315 } 1316 1316 1317 virtual const ast::Type * visit( const ast::StructInstType * node ) override final{1317 virtual const ast::Type * visit( const ast::StructInstType * node ) { 1318 1318 preprint( node ); 1319 1319 os << "instance of struct " << node->name; … … 1326 1326 } 1327 1327 1328 virtual const ast::Type * visit( const ast::UnionInstType * node ) override final{1328 virtual const ast::Type * visit( const ast::UnionInstType * node ) { 1329 1329 preprint( node ); 1330 1330 os << "instance of union " << node->name; … … 1337 1337 } 1338 1338 1339 virtual const ast::Type * visit( const ast::EnumInstType * node ) override final{1339 virtual const ast::Type * visit( const ast::EnumInstType * node ) { 1340 1340 preprint( node ); 1341 1341 os << "instance of enum " << node->name; … … 1348 1348 } 1349 1349 1350 virtual const ast::Type * visit( const ast::TraitInstType * node ) override final{1350 virtual const ast::Type * visit( const ast::TraitInstType * node ) { 1351 1351 preprint( node ); 1352 1352 os << "instance of trait " << node->name; … … 1356 1356 } 1357 1357 1358 virtual const ast::Type * visit( const ast::TypeInstType * node ) override final{1358 virtual const ast::Type * visit( const ast::TypeInstType * node ) { 1359 1359 preprint( node ); 1360 1360 os << "instance of type " << node->name … … 1365 1365 } 1366 1366 1367 virtual const ast::Type * visit( const ast::TupleType * node ) override final{1367 virtual const ast::Type * visit( const ast::TupleType * node ) { 1368 1368 preprint( node ); 1369 1369 os << "tuple of types" << endl; … … 1375 1375 } 1376 1376 1377 virtual const ast::Type * visit( const ast::TypeofType * node ) override final{1377 virtual const ast::Type * visit( const ast::TypeofType * node ) { 1378 1378 preprint( node ); 1379 1379 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; } … … 1384 1384 } 1385 1385 1386 virtual const ast::Type * visit( const ast::VarArgsType * node ) override final{1386 virtual const ast::Type * visit( const ast::VarArgsType * node ) { 1387 1387 preprint( node ); 1388 1388 os << "builtin var args pack"; … … 1390 1390 } 1391 1391 1392 virtual const ast::Type * visit( const ast::ZeroType * node ) override final{1392 virtual const ast::Type * visit( const ast::ZeroType * node ) { 1393 1393 preprint( node ); 1394 1394 os << "zero_t"; … … 1396 1396 } 1397 1397 1398 virtual const ast::Type * visit( const ast::OneType * node ) override final{1398 virtual const ast::Type * visit( const ast::OneType * node ) { 1399 1399 preprint( node ); 1400 1400 os << "one_t"; … … 1402 1402 } 1403 1403 1404 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final{1404 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) { 1405 1405 preprint( node ); 1406 1406 os << "Global Scope Type"; … … 1408 1408 } 1409 1409 1410 virtual const ast::Designation * visit( const ast::Designation * node ) override final{1410 virtual const ast::Designation * visit( const ast::Designation * node ) { 1411 1411 if ( node->designators.empty() ) return node; 1412 1412 os << "... designated by: " << endl; … … 1421 1421 } 1422 1422 1423 virtual const ast::Init * visit( const ast::SingleInit * node ) override final{1423 virtual const ast::Init * visit( const ast::SingleInit * node ) { 1424 1424 os << "Simple Initializer: "; 1425 1425 safe_print( node->value ); … … 1427 1427 } 1428 1428 1429 virtual const ast::Init * visit( const ast::ListInit * node ) override final{1429 virtual const ast::Init * visit( const ast::ListInit * node ) { 1430 1430 os << "Compound initializer: " << endl; 1431 1431 ++indent; … … 1445 1445 } 1446 1446 1447 virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final{1447 virtual const ast::Init * visit( const ast::ConstructorInit * node ) { 1448 1448 os << "Constructor initializer: " << endl; 1449 1449 if ( node->ctor ) { … … 1470 1470 } 1471 1471 1472 virtual const ast::Attribute * visit( const ast::Attribute * node ) override final{1472 virtual const ast::Attribute * visit( const ast::Attribute * node ) { 1473 1473 if ( node->empty() ) return node; 1474 1474 os << "Attribute with name: " << node->name; … … 1481 1481 } 1482 1482 1483 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final{1483 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) { 1484 1484 os << indent << "Types:" << endl; 1485 1485 for ( const auto& i : *node ) { -
src/AST/Stmt.hpp
r4eb43fa rf6cc734e 382 382 }; 383 383 384 /// With statement `with (...) ...` 385 class WithStmt final : public Stmt { 386 public: 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 ); } 395 private: 396 WithStmt * clone() const override { return new WithStmt{ *this }; } 397 MUTATE_FRIEND 398 }; 399 384 400 /// Any declaration in a (compound) statement. 385 401 class DeclStmt final : public Stmt { -
src/AST/SymbolTable.cpp
r4eb43fa rf6cc734e 73 73 74 74 SymbolTable::SymbolTable() 75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 76 76 prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; } 77 77 … … 171 171 } 172 172 173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl* deleter ) {173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Node * deleter ) { 174 174 // default handling of conflicts is to raise an error 175 175 addId( decl, OnConflict::error(), nullptr, deleter ); … … 189 189 } 190 190 } 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 192 192 // the same 193 193 return true; … … 209 209 const std::string &id = decl->name; 210 210 211 if ( ! typeTable ) { 211 if ( ! typeTable ) { 212 212 typeTable = TypeTable::new_ptr(); 213 213 } else { 214 214 ++*stats().map_lookups; 215 215 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 218 218 && addedTypeConflicts( existing->second.decl, decl ) ) return; 219 219 } 220 220 221 221 lazyInitScope(); 222 222 ++*stats().map_mutations; … … 237 237 ++*stats().map_lookups; 238 238 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 241 241 && addedDeclConflicts( existing->second.decl, decl ) ) return; 242 242 } … … 256 256 ++*stats().map_lookups; 257 257 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 260 260 && addedDeclConflicts( existing->second.decl, decl ) ) return; 261 261 } 262 262 263 263 lazyInitScope(); 264 264 ++*stats().map_mutations; … … 279 279 ++*stats().map_lookups; 280 280 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 283 283 && addedDeclConflicts( existing->second.decl, decl ) ) return; 284 284 } … … 298 298 ++*stats().map_lookups; 299 299 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 302 302 && addedDeclConflicts( existing->second.decl, decl ) ) return; 303 303 } … … 309 309 310 310 311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl* withStmt ) {311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt ) { 312 312 for ( const Expr * expr : withExprs ) { 313 313 if ( ! expr->result ) continue; 314 314 const Type * resTy = expr->result->stripReferences(); 315 315 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", 317 317 toString( expr->result ).c_str() ); 318 318 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", 320 320 toString( expr->result ).c_str() ); 321 321 322 322 addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) ); 323 323 } … … 373 373 } 374 374 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, 376 376 /// nullptr if none such 377 const FunctionDecl * getFunctionForOtype( 377 const FunctionDecl * getFunctionForOtype( 378 378 const DeclWithType * decl, const std::string & otypeKey ) { 379 379 auto func = dynamic_cast< const FunctionDecl * >( decl ); … … 383 383 } 384 384 385 bool SymbolTable::removeSpecialOverrides( 385 bool SymbolTable::removeSpecialOverrides( 386 386 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 394 394 // unavailable, and likewise for the assignment operator. 395 395 … … 450 450 // if this is the first user-defined function, delete non-user-defined overloads 451 451 std::vector< MangleTable::value_type > deleted; 452 452 453 453 for ( const auto& entry : *mangleTable ) { 454 454 // skip decls that aren't functions or are for the wrong type … … 489 489 if ( dataIsCopyFunc ) { 490 490 // 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 492 492 // a delete statement is the wrong approach 493 493 if ( InitTweak::isCopyFunction( decl ) ) return false; … … 499 499 } 500 500 } 501 501 502 502 // nothing (more) to fix, return true 503 503 return true; … … 525 525 526 526 bool 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 530 530 // wrong 531 531 assert( (isObject( added ) && isObject( existing.id ) ) 532 532 || ( isFunction( added ) && isFunction( existing.id ) ) ); 533 533 534 534 if ( existing.id->linkage.is_overrideable ) { 535 535 // new definition shadows the autogenerated one, even at the same scope 536 536 return false; 537 } else if ( existing.id->linkage.is_mangled 538 || ResolvExpr::typesCompatible( 537 } else if ( existing.id->linkage.is_mangled 538 || ResolvExpr::typesCompatible( 539 539 added->get_type(), existing.id->get_type(), SymbolTable{} ) ) { 540 540 541 541 // it is a conflict if one declaration is deleted and the other is not 542 542 if ( deleter && ! existing.deleter ) { … … 555 555 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 556 556 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 " : 560 560 "duplicate object definition for " ); 561 561 } … … 572 572 } 573 573 574 void SymbolTable::addId( 575 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 const Decl* deleter ) {574 void SymbolTable::addId( 575 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 const Node * deleter ) { 577 577 ++*stats().add_calls; 578 578 const std::string &name = decl->name; … … 581 581 std::string mangleName; 582 582 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 584 584 // are placed into the same "bucket" as their user defined versions. 585 585 mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } ); … … 588 588 } 589 589 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 591 591 // both have C linkage 592 592 if ( decl->linkage.is_mangled ) { … … 596 596 } 597 597 } 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 599 599 // type-compatibility, which it may not be. 600 600 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 628 628 idTable = idTable->set( 629 629 name, 630 mangleTable->set( 631 mangleName, 630 mangleTable->set( 631 mangleName, 632 632 IdData{ existing->second, handleConflicts.deleter } ) ); 633 633 } … … 647 647 } 648 648 649 void SymbolTable::addMembers( 649 void SymbolTable::addMembers( 650 650 const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) { 651 651 for ( const Decl * decl : aggr->members ) { … … 655 655 const Type * t = dwt->get_type()->stripReferences(); 656 656 if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) { 657 if ( ! dynamic_cast<const StructInstType *>(rty) 657 if ( ! dynamic_cast<const StructInstType *>(rty) 658 658 && ! dynamic_cast<const UnionInstType *>(rty) ) continue; 659 659 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; 660 660 const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost ); 661 addMembers( 661 addMembers( 662 662 rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts ); 663 663 } … … 680 680 if ( ! decl.second.id->linkage.is_mangled && decl.first == mangleName ) return true; 681 681 } 682 682 683 683 return false; 684 684 } -
src/AST/SymbolTable.hpp
r4eb43fa rf6cc734e 37 37 readonly<DeclWithType> id = nullptr; ///< Identifier of declaration 38 38 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) 40 40 unsigned long scope = 0; ///< Scope of identifier 41 41 42 42 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 ) 44 44 : id( i ), baseExpr( base ), deleter( del ), scope( s ) {} 45 45 46 46 /// Modify an existing node with a new deleter 47 IdData( const IdData & o, const Decl* del )47 IdData( const IdData & o, const Node * del ) 48 48 : id( o.id ), baseExpr( o.baseExpr ), deleter( del ), scope( o.scope ) {} 49 49 … … 58 58 struct scoped { 59 59 readonly<D> decl; ///< wrapped declaration 60 unsigned long scope; ///< scope of this declaration 60 unsigned long scope; ///< scope of this declaration 61 61 62 62 scoped(const D * d, unsigned long s) : decl(d), scope(s) {} … … 88 88 ~SymbolTable(); 89 89 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 91 91 // tell the indexer explicitly when scopes begin and end 92 92 void enterScope(); … … 118 118 void addId( const DeclWithType * decl, const Expr * baseExpr = nullptr ); 119 119 /// 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 ); 121 121 122 122 /// Adds a type to the symbol table … … 136 136 137 137 /// 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 ); 139 139 140 140 /// convenience function for adding a list of Ids to the indexer … … 154 154 const SymbolTable * atScope( unsigned long i ) const; 155 155 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 157 157 /// selected. If returns false, passed decl should not be added. 158 158 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable ); … … 164 164 Delete ///< Delete the earlier version with the delete statement 165 165 } mode; 166 const Decl* deleter; ///< Statement that deletes this expression166 const Node * deleter; ///< Statement that deletes this expression 167 167 168 168 private: 169 169 OnConflict() : mode(Error), deleter(nullptr) {} 170 OnConflict( const Decl* d ) : mode(Delete), deleter(d) {}170 OnConflict( const Node * d ) : mode(Delete), deleter(d) {} 171 171 public: 172 172 OnConflict( const OnConflict& ) = default; 173 173 174 174 static OnConflict error() { return {}; } 175 static OnConflict deleteWith( const Decl* d ) { return { d }; }175 static OnConflict deleteWith( const Node * d ) { return { d }; } 176 176 }; 177 177 178 178 /// true if the existing identifier conflicts with the added identifier 179 179 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 ); 182 182 183 183 /// 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 ); 187 187 188 188 /// adds all of the members of the Aggregate (addWith helper) -
src/AST/Type.hpp
r4eb43fa rf6cc734e 37 37 38 38 template< typename T > class Pass; 39 40 struct ForallSubstitutor; 39 class ForallSubstitutor; 41 40 42 41 class Type : public Node { … … 170 169 static const char *typeNames[]; 171 170 172 BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 171 BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 173 172 : Type(q, std::move(as)), kind(k) {} 174 173 … … 277 276 public: 278 277 using ForallList = std::vector<ptr<TypeDecl>>; 279 278 280 279 ForallList forall; 281 280 … … 341 340 bool hoistType = false; 342 341 343 ReferenceToType( 342 ReferenceToType( 344 343 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 345 344 : ParameterizedType(q, std::move(as)), params(), name(n) {} … … 362 361 readonly<StructDecl> base; 363 362 364 StructInstType( 363 StructInstType( 365 364 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 366 365 : ReferenceToType( n, q, std::move(as) ), base() {} 367 366 368 StructInstType( 367 StructInstType( 369 368 const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 370 369 … … 384 383 readonly<UnionDecl> base; 385 384 386 UnionInstType( 385 UnionInstType( 387 386 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 388 387 : ReferenceToType( n, q, std::move(as) ), base() {} 389 388 390 UnionInstType( 389 UnionInstType( 391 390 const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 392 391 … … 406 405 readonly<EnumDecl> base; 407 406 408 EnumInstType( 407 EnumInstType( 409 408 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 410 409 : ReferenceToType( n, q, std::move(as) ), base() {} 411 410 412 EnumInstType( 411 EnumInstType( 413 412 const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 414 413 … … 428 427 readonly<TraitDecl> base; 429 428 430 TraitInstType( 429 TraitInstType( 431 430 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 432 431 : ReferenceToType( n, q, std::move(as) ), base() {} 433 434 TraitInstType( 432 433 TraitInstType( 435 434 const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 436 435 … … 452 451 TypeVar::Kind kind; 453 452 454 TypeInstType( 453 TypeInstType( 455 454 const std::string& n, const TypeDecl * b, CV::Qualifiers q = {}, 456 455 std::vector<ptr<Attribute>> && as = {} ) 457 456 : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {} 458 459 TypeInstType( 457 458 TypeInstType( 460 459 const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {}, 461 460 std::vector<ptr<Attribute>> && as = {} ) -
src/AST/Visitor.hpp
r4eb43fa rf6cc734e 48 48 virtual const ast::Stmt * visit( const ast::FinallyStmt * ) = 0; 49 49 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; 51 51 virtual const ast::NullStmt * visit( const ast::NullStmt * ) = 0; 52 52 virtual const ast::Stmt * visit( const ast::DeclStmt * ) = 0; -
src/Common/PassVisitor.h
r4eb43fa rf6cc734e 60 60 61 61 virtual void visit( ObjectDecl * objectDecl ) override final; 62 virtual void visit( const ObjectDecl * objectDecl ) override final;63 62 virtual void visit( FunctionDecl * functionDecl ) override final; 64 virtual void visit( const FunctionDecl * functionDecl ) override final;65 63 virtual void visit( StructDecl * aggregateDecl ) override final; 66 virtual void visit( const StructDecl * aggregateDecl ) override final;67 64 virtual void visit( UnionDecl * aggregateDecl ) override final; 68 virtual void visit( const UnionDecl * aggregateDecl ) override final;69 65 virtual void visit( EnumDecl * aggregateDecl ) override final; 70 virtual void visit( const EnumDecl * aggregateDecl ) override final;71 66 virtual void visit( TraitDecl * aggregateDecl ) override final; 72 virtual void visit( const TraitDecl * aggregateDecl ) override final;73 67 virtual void visit( TypeDecl * typeDecl ) override final; 74 virtual void visit( const TypeDecl * typeDecl ) override final;75 68 virtual void visit( TypedefDecl * typeDecl ) override final; 76 virtual void visit( const TypedefDecl * typeDecl ) override final;77 69 virtual void visit( AsmDecl * asmDecl ) override final; 78 virtual void visit( const AsmDecl * asmDecl ) override final;79 70 virtual void visit( StaticAssertDecl * assertDecl ) override final; 80 virtual void visit( const StaticAssertDecl * assertDecl ) override final;81 71 82 72 virtual void visit( CompoundStmt * compoundStmt ) override final; 83 virtual void visit( const CompoundStmt * compoundStmt ) override final;84 73 virtual void visit( ExprStmt * exprStmt ) override final; 85 virtual void visit( const ExprStmt * exprStmt ) override final;86 74 virtual void visit( AsmStmt * asmStmt ) override final; 87 virtual void visit( const AsmStmt * asmStmt ) override final;88 75 virtual void visit( DirectiveStmt * dirStmt ) override final; 89 virtual void visit( const DirectiveStmt * dirStmt ) override final;90 76 virtual void visit( IfStmt * ifStmt ) override final; 91 virtual void visit( const IfStmt * ifStmt ) override final;92 77 virtual void visit( WhileStmt * whileStmt ) override final; 93 virtual void visit( const WhileStmt * whileStmt ) override final;94 78 virtual void visit( ForStmt * forStmt ) override final; 95 virtual void visit( const ForStmt * forStmt ) override final;96 79 virtual void visit( SwitchStmt * switchStmt ) override final; 97 virtual void visit( const SwitchStmt * switchStmt ) override final;98 80 virtual void visit( CaseStmt * caseStmt ) override final; 99 virtual void visit( const CaseStmt * caseStmt ) override final;100 81 virtual void visit( BranchStmt * branchStmt ) override final; 101 virtual void visit( const BranchStmt * branchStmt ) override final;102 82 virtual void visit( ReturnStmt * returnStmt ) override final; 103 virtual void visit( const ReturnStmt * returnStmt ) override final;104 83 virtual void visit( ThrowStmt * throwStmt ) override final; 105 virtual void visit( const ThrowStmt * throwStmt ) override final;106 84 virtual void visit( TryStmt * tryStmt ) override final; 107 virtual void visit( const TryStmt * tryStmt ) override final;108 85 virtual void visit( CatchStmt * catchStmt ) override final; 109 virtual void visit( const CatchStmt * catchStmt ) override final;110 86 virtual void visit( FinallyStmt * finallyStmt ) override final; 111 virtual void visit( const FinallyStmt * finallyStmt ) override final;112 87 virtual void visit( WaitForStmt * waitforStmt ) override final; 113 virtual void visit( const WaitForStmt * waitforStmt ) override final;114 88 virtual void visit( WithStmt * withStmt ) override final; 115 virtual void visit( const WithStmt * withStmt ) override final;116 89 virtual void visit( NullStmt * nullStmt ) override final; 117 virtual void visit( const NullStmt * nullStmt ) override final;118 90 virtual void visit( DeclStmt * declStmt ) override final; 119 virtual void visit( const DeclStmt * declStmt ) override final;120 91 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final; 121 virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;122 92 123 93 virtual void visit( ApplicationExpr * applicationExpr ) override final; 124 virtual void visit( const ApplicationExpr * applicationExpr ) override final;125 94 virtual void visit( UntypedExpr * untypedExpr ) override final; 126 virtual void visit( const UntypedExpr * untypedExpr ) override final;127 95 virtual void visit( NameExpr * nameExpr ) override final; 128 virtual void visit( const NameExpr * nameExpr ) override final;129 96 virtual void visit( CastExpr * castExpr ) override final; 130 virtual void visit( const CastExpr * castExpr ) override final;131 97 virtual void visit( KeywordCastExpr * castExpr ) override final; 132 virtual void visit( const KeywordCastExpr * castExpr ) override final;133 98 virtual void visit( VirtualCastExpr * castExpr ) override final; 134 virtual void visit( const VirtualCastExpr * castExpr ) override final;135 99 virtual void visit( AddressExpr * addressExpr ) override final; 136 virtual void visit( const AddressExpr * addressExpr ) override final;137 100 virtual void visit( LabelAddressExpr * labAddressExpr ) override final; 138 virtual void visit( const LabelAddressExpr * labAddressExpr ) override final;139 101 virtual void visit( UntypedMemberExpr * memberExpr ) override final; 140 virtual void visit( const UntypedMemberExpr * memberExpr ) override final;141 102 virtual void visit( MemberExpr * memberExpr ) override final; 142 virtual void visit( const MemberExpr * memberExpr ) override final;143 103 virtual void visit( VariableExpr * variableExpr ) override final; 144 virtual void visit( const VariableExpr * variableExpr ) override final;145 104 virtual void visit( ConstantExpr * constantExpr ) override final; 146 virtual void visit( const ConstantExpr * constantExpr ) override final;147 105 virtual void visit( SizeofExpr * sizeofExpr ) override final; 148 virtual void visit( const SizeofExpr * sizeofExpr ) override final;149 106 virtual void visit( AlignofExpr * alignofExpr ) override final; 150 virtual void visit( const AlignofExpr * alignofExpr ) override final;151 107 virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final; 152 virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final;153 108 virtual void visit( OffsetofExpr * offsetofExpr ) override final; 154 virtual void visit( const OffsetofExpr * offsetofExpr ) override final;155 109 virtual void visit( OffsetPackExpr * offsetPackExpr ) override final; 156 virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final;157 110 virtual void visit( AttrExpr * attrExpr ) override final; 158 virtual void visit( const AttrExpr * attrExpr ) override final;159 111 virtual void visit( LogicalExpr * logicalExpr ) override final; 160 virtual void visit( const LogicalExpr * logicalExpr ) override final;161 112 virtual void visit( ConditionalExpr * conditionalExpr ) override final; 162 virtual void visit( const ConditionalExpr * conditionalExpr ) override final;163 113 virtual void visit( CommaExpr * commaExpr ) override final; 164 virtual void visit( const CommaExpr * commaExpr ) override final;165 114 virtual void visit( TypeExpr * typeExpr ) override final; 166 virtual void visit( const TypeExpr * typeExpr ) override final;167 115 virtual void visit( AsmExpr * asmExpr ) override final; 168 virtual void visit( const AsmExpr * asmExpr ) override final;169 116 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final; 170 virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final;171 117 virtual void visit( ConstructorExpr * ctorExpr ) override final; 172 virtual void visit( const ConstructorExpr * ctorExpr ) override final;173 118 virtual void visit( CompoundLiteralExpr * compLitExpr ) override final; 174 virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final;175 119 virtual void visit( RangeExpr * rangeExpr ) override final; 176 virtual void visit( const RangeExpr * rangeExpr ) override final;177 120 virtual void visit( UntypedTupleExpr * tupleExpr ) override final; 178 virtual void visit( const UntypedTupleExpr * tupleExpr ) override final;179 121 virtual void visit( TupleExpr * tupleExpr ) override final; 180 virtual void visit( const TupleExpr * tupleExpr ) override final;181 122 virtual void visit( TupleIndexExpr * tupleExpr ) override final; 182 virtual void visit( const TupleIndexExpr * tupleExpr ) override final;183 123 virtual void visit( TupleAssignExpr * assignExpr ) override final; 184 virtual void visit( const TupleAssignExpr * assignExpr ) override final;185 124 virtual void visit( StmtExpr * stmtExpr ) override final; 186 virtual void visit( const StmtExpr * stmtExpr ) override final;187 125 virtual void visit( UniqueExpr * uniqueExpr ) override final; 188 virtual void visit( const UniqueExpr * uniqueExpr ) override final;189 126 virtual void visit( UntypedInitExpr * initExpr ) override final; 190 virtual void visit( const UntypedInitExpr * initExpr ) override final;191 127 virtual void visit( InitExpr * initExpr ) override final; 192 virtual void visit( const InitExpr * initExpr ) override final;193 128 virtual void visit( DeletedExpr * delExpr ) override final; 194 virtual void visit( const DeletedExpr * delExpr ) override final;195 129 virtual void visit( DefaultArgExpr * argExpr ) override final; 196 virtual void visit( const DefaultArgExpr * argExpr ) override final;197 130 virtual void visit( GenericExpr * genExpr ) override final; 198 virtual void visit( const GenericExpr * genExpr ) override final;199 131 200 132 virtual void visit( VoidType * basicType ) override final; 201 virtual void visit( const VoidType * basicType ) override final;202 133 virtual void visit( BasicType * basicType ) override final; 203 virtual void visit( const BasicType * basicType ) override final;204 134 virtual void visit( PointerType * pointerType ) override final; 205 virtual void visit( const PointerType * pointerType ) override final;206 135 virtual void visit( ArrayType * arrayType ) override final; 207 virtual void visit( const ArrayType * arrayType ) override final;208 136 virtual void visit( ReferenceType * referenceType ) override final; 209 virtual void visit( const ReferenceType * referenceType ) override final;210 137 virtual void visit( QualifiedType * qualType ) override final; 211 virtual void visit( const QualifiedType * qualType ) override final;212 138 virtual void visit( FunctionType * functionType ) override final; 213 virtual void visit( const FunctionType * functionType ) override final;214 139 virtual void visit( StructInstType * aggregateUseType ) override final; 215 virtual void visit( const StructInstType * aggregateUseType ) override final;216 140 virtual void visit( UnionInstType * aggregateUseType ) override final; 217 virtual void visit( const UnionInstType * aggregateUseType ) override final;218 141 virtual void visit( EnumInstType * aggregateUseType ) override final; 219 virtual void visit( const EnumInstType * aggregateUseType ) override final;220 142 virtual void visit( TraitInstType * aggregateUseType ) override final; 221 virtual void visit( const TraitInstType * aggregateUseType ) override final;222 143 virtual void visit( TypeInstType * aggregateUseType ) override final; 223 virtual void visit( const TypeInstType * aggregateUseType ) override final;224 144 virtual void visit( TupleType * tupleType ) override final; 225 virtual void visit( const TupleType * tupleType ) override final;226 145 virtual void visit( TypeofType * typeofType ) override final; 227 virtual void visit( const TypeofType * typeofType ) override final;228 146 virtual void visit( AttrType * attrType ) override final; 229 virtual void visit( const AttrType * attrType ) override final;230 147 virtual void visit( VarArgsType * varArgsType ) override final; 231 virtual void visit( const VarArgsType * varArgsType ) override final;232 148 virtual void visit( ZeroType * zeroType ) override final; 233 virtual void visit( const ZeroType * zeroType ) override final;234 149 virtual void visit( OneType * oneType ) override final; 235 virtual void visit( const OneType * oneType ) override final;236 150 virtual void visit( GlobalScopeType * globalType ) override final; 237 virtual void visit( const GlobalScopeType * globalType ) override final;238 151 239 152 virtual void visit( Designation * designation ) override final; 240 virtual void visit( const Designation * designation ) override final;241 153 virtual void visit( SingleInit * singleInit ) override final; 242 virtual void visit( const SingleInit * singleInit ) override final;243 154 virtual void visit( ListInit * listInit ) override final; 244 virtual void visit( const ListInit * listInit ) override final;245 155 virtual void visit( ConstructorInit * ctorInit ) override final; 246 virtual void visit( const ConstructorInit * ctorInit ) override final;247 156 248 157 virtual void visit( Constant * constant ) override final; 249 virtual void visit( const Constant * constant ) override final;250 158 251 159 virtual void visit( Attribute * attribute ) override final; 252 virtual void visit( const Attribute * attribute ) override final;253 160 254 161 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final; … … 279 186 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 280 187 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 281 virtual Declaration* mutate( WithStmt * withStmt ) override final;188 virtual Statement * mutate( WithStmt * withStmt ) override final; 282 189 virtual NullStmt * mutate( NullStmt * nullStmt ) override final; 283 190 virtual Statement * mutate( DeclStmt * declStmt ) override final; … … 358 265 359 266 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 );361 267 template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 362 268 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 );364 269 template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator ); 365 270 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 );367 271 template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator ); 368 272 369 273 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 ); }371 274 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 ); }373 275 374 276 template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); } … … 384 286 void visitStatementList ( std::list< Statement* > &statements ); 385 287 void mutateStatementList( std::list< Statement* > &statements ); 386 void visitStatementList ( const std::list< Statement * > & statements );387 288 388 289 template< typename func_t > … … 390 291 Statement * visitStatement ( Statement * stmt ); 391 292 Statement * mutateStatement( Statement * stmt ); 392 void visitStatement ( const Statement * stmt );393 293 394 294 template< typename func_t > … … 396 296 Expression * visitExpression ( Expression * expr ); 397 297 Expression * mutateExpression( Expression * expr ); 398 void visitExpression ( const Expression * expr );399 298 400 299 … … 410 309 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } 411 310 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 ); } 414 313 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 ); } 418 317 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 ); } 423 322 424 323 425 324 template< typename TreeType, typename VisitorType > 426 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );325 friend inline void indexerScopedAccept( TreeType * tree, VisitorType &visitor ); 427 326 428 327 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 ); 433 329 }; 434 330 -
src/Common/PassVisitor.impl.h
r4eb43fa rf6cc734e 80 80 81 81 template< 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 declaration91 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 >104 82 inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) { 105 83 DeclList_t* beforeDecls = mutator.get_beforeDecls(); … … 139 117 } 140 118 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 149 119 template< typename Container, typename pass_type > 150 120 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) { … … 159 129 if ( *i ) { 160 130 (*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 );184 131 } 185 132 } catch( SemanticErrorException &e ) { … … 280 227 281 228 template< 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 >301 229 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { 302 230 handleStatementList( statements, [this]( Statement *& stmt) { … … 347 275 348 276 template< 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 CompoundStmt353 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 >359 277 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { 360 278 return handleStatement( stmt, [this]( Statement * stmt ) { … … 388 306 389 307 template< 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 >403 308 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { 404 309 return handleExpression(expr, [this]( Expression * expr ) { … … 410 315 template< typename TreeType, typename VisitorType > 411 316 inline 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 ) {422 317 if ( ! visitor.get_visit_children() ) return; 423 318 auto guard = makeFuncGuard( … … 477 372 478 373 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 );491 374 492 375 VISIT_END( node ); … … 545 428 546 429 template< 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 parameters556 // 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.2562 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 nullptr566 );567 indexerAddId( &func );568 maybeAccept_impl( node->type, *this );569 // function body needs to have the same scope as parameters - CompoundStmt will not enter570 // a new scope if inFunction is true571 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 >582 430 DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) { 583 431 MUTATE_START( node ); … … 636 484 637 485 template< typename pass_type > 638 void PassVisitor< pass_type >::visit( constStructDecl * node ) {639 VISIT_START( node );486 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) { 487 MUTATE_START( node ); 640 488 641 489 // make up a forward declaration and add it before processing the members 642 490 // needs to be on the heap because addStruct saves the pointer 643 491 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 507 template< typename pass_type > 508 void 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 ); 644 513 645 514 { … … 649 518 } 650 519 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 525 template< typename pass_type > 526 Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) { 659 527 MUTATE_START( node ); 660 528 661 529 // 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 ); 664 531 665 532 { … … 669 536 } 670 537 671 // this addition replaces the forward declaration 672 indexerAddStruct( node ); 538 indexerAddUnion( node ); 673 539 674 540 MUTATE_END( Declaration, node ); … … 676 542 677 543 //-------------------------------------------------------------------------- 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 545 template< typename pass_type > 546 void 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 558 template< typename pass_type > 559 Declaration * 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 573 template< typename pass_type > 574 void PassVisitor< pass_type >::visit( TraitDecl * node ) { 575 VISIT_START( node ); 685 576 686 577 { … … 690 581 } 691 582 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 588 template< typename pass_type > 589 Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) { 590 MUTATE_START( node ); 720 591 721 592 { … … 725 596 } 726 597 727 indexerAddUnion( node );728 729 MUTATE_END( Declaration, node );730 }731 732 //--------------------------------------------------------------------------733 // EnumDecl734 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 scope741 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 scope754 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 scope767 maybeMutate_impl( node->parameters, *this );768 maybeMutate_impl( node->members , *this );769 770 MUTATE_END( Declaration, node );771 }772 773 //--------------------------------------------------------------------------774 // TraitDecl775 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 815 598 indexerAddTrait( node ); 816 599 … … 842 625 } 843 626 844 845 template< typename pass_type > 846 void PassVisitor< pass_type >::visit( const TypeDecl * node ) { 627 template< typename pass_type > 628 Declaration * 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 651 template< typename pass_type > 652 void PassVisitor< pass_type >::visit( TypedefDecl * node ) { 847 653 VISIT_START( node ); 848 654 … … 853 659 } 854 660 855 // see A NOTE ON THE ORDER OF TRAVERSAL, above856 // note that assertions come after the type is added to the symtab, since they are not part of the type proper857 // and may depend on the type itself858 661 indexerAddType( node ); 859 662 860 663 maybeAccept_impl( node->assertions, *this ); 861 664 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 668 template< typename pass_type > 669 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) { 869 670 MUTATE_START( node ); 870 671 … … 875 676 } 876 677 877 // see A NOTE ON THE ORDER OF TRAVERSAL, above878 // note that assertions come after the type is added to the symtab, since they are not part of the type proper879 // and may depend on the type itself880 678 indexerAddType( node ); 881 679 882 680 maybeMutate_impl( node->assertions, *this ); 883 681 884 indexerScopedMutate( node->init, *this );885 886 682 MUTATE_END( Declaration, node ); 887 683 } 888 684 889 685 //-------------------------------------------------------------------------- 890 // TypedefDecl891 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 //--------------------------------------------------------------------------943 686 // AsmDecl 944 687 template< typename pass_type > … … 952 695 953 696 template< 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 >963 697 AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) { 964 698 MUTATE_START( node ); … … 976 710 977 711 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 );988 712 maybeAccept_impl( node->message, *this ); 989 713 … … 1018 742 1019 743 template< 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 assignment1024 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 >1034 744 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) { 1035 745 MUTATE_START( node ); … … 1057 767 1058 768 template< 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 >1068 769 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) { 1069 770 MUTATE_START( node ); … … 1089 790 1090 791 template< 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 >1103 792 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { 1104 793 MUTATE_START( node ); … … 1122 811 1123 812 template< 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 >1131 813 Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) { 1132 814 MUTATE_START( node ); … … 1143 825 // if statements introduce a level of scope (for the initialization) 1144 826 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1145 maybeAccept_impl( node-> initialization, *this );827 maybeAccept_impl( node->get_initialization(), *this ); 1146 828 visitExpression ( node->condition ); 1147 829 node->thenPart = visitStatement( node->thenPart ); … … 1152 834 1153 835 template< typename pass_type > 1154 void PassVisitor< pass_type >::visit( constIfStmt * node ) {1155 VISIT_START( node );836 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { 837 MUTATE_START( node ); 1156 838 { 1157 839 // if statements introduce a level of scope (for the initialization) 1158 840 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 ); 1174 842 node->condition = mutateExpression( node->condition ); 1175 843 node->thenPart = mutateStatement ( node->thenPart ); … … 1191 859 visitExpression ( node->condition ); 1192 860 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 );1208 861 } 1209 862 … … 1244 897 1245 898 template< 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 >1260 899 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) { 1261 900 MUTATE_START( node ); … … 1284 923 1285 924 template< 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 >1296 925 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) { 1297 926 MUTATE_START( node ); … … 1316 945 1317 946 template< 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 >1328 947 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) { 1329 948 MUTATE_START( node ); … … 1344 963 1345 964 template< 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 >1352 965 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { 1353 966 MUTATE_START( node ); … … 1367 980 1368 981 template< 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 >1378 982 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) { 1379 983 MUTATE_START( node ); … … 1386 990 //-------------------------------------------------------------------------- 1387 991 // ThrowStmt 992 1388 993 template< typename pass_type > 1389 994 void PassVisitor< pass_type >::visit( ThrowStmt * node ) { … … 1397 1002 1398 1003 template< 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 >1409 1004 Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) { 1410 1005 MUTATE_START( node ); … … 1420 1015 template< typename pass_type > 1421 1016 void 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 ) {1433 1017 VISIT_START( node ); 1434 1018 … … 1467 1051 1468 1052 template< 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 >1482 1053 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) { 1483 1054 MUTATE_START( node ); … … 1504 1075 1505 1076 template< 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 >1515 1077 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) { 1516 1078 MUTATE_START( node ); … … 1545 1107 1546 1108 template< 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 >1568 1109 Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) { 1569 1110 MUTATE_START( node ); … … 1589 1130 1590 1131 //-------------------------------------------------------------------------- 1591 // WithStmt1132 // NullStmt 1592 1133 template< typename pass_type > 1593 1134 void PassVisitor< pass_type >::visit( WithStmt * node ) { … … 1604 1145 1605 1146 template< 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 ) { 1147 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1620 1148 MUTATE_START( node ); 1621 1149 maybeMutate_impl( node->exprs, *this ); … … 1626 1154 maybeMutate_impl( node->stmt, *this ); 1627 1155 } 1628 MUTATE_END( Declaration, node );1156 MUTATE_END( Statement, node ); 1629 1157 } 1630 1158 … … 1638 1166 1639 1167 template< 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 >1646 1168 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { 1647 1169 MUTATE_START( node ); … … 1661 1183 1662 1184 template< 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 >1672 1185 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { 1673 1186 MUTATE_START( node ); … … 1690 1203 1691 1204 template< 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 >1701 1205 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) { 1702 1206 MUTATE_START( node ); … … 1714 1218 1715 1219 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 ); 1729 1222 1730 1223 VISIT_END( node ); … … 1760 1253 1761 1254 template< 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 >1775 1255 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { 1776 1256 MUTATE_START( node ); … … 1798 1278 1799 1279 template< typename pass_type > 1800 void PassVisitor< pass_type >::visit( const NameExpr * node ) { 1280 Expression * 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 1291 template< typename pass_type > 1292 void PassVisitor< pass_type >::visit( CastExpr * node ) { 1801 1293 VISIT_START( node ); 1802 1294 1803 1295 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 1301 template< typename pass_type > 1302 Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) { 1810 1303 MUTATE_START( node ); 1811 1304 1812 1305 indexerScopedMutate( node->env , *this ); 1813 1306 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 1314 template< typename pass_type > 1315 void 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 1324 template< typename pass_type > 1325 Expression * 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 1337 template< typename pass_type > 1338 void 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 1347 template< typename pass_type > 1348 Expression * 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 1360 template< typename pass_type > 1361 void PassVisitor< pass_type >::visit( AddressExpr * node ) { 1822 1362 VISIT_START( node ); 1823 1363 … … 1829 1369 1830 1370 template< typename pass_type > 1831 void PassVisitor< pass_type >::visit( const CastExpr * node ) { 1371 Expression * 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 1383 template< typename pass_type > 1384 void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) { 1832 1385 VISIT_START( node ); 1833 1386 1834 1387 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 1392 template< typename pass_type > 1393 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) { 1842 1394 MUTATE_START( node ); 1843 1395 1844 1396 indexerScopedMutate( node->env , *this ); 1845 1397 indexerScopedMutate( node->result, *this ); 1846 maybeMutate_impl ( node->arg , *this );1847 1848 MUTATE_END( Expression, node );1849 }1850 1851 //--------------------------------------------------------------------------1852 // KeywordCastExpr1853 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 // VirtualCastExpr1886 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 // AddressExpr1919 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 // LabelAddressExpr1952 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 );1976 1398 1977 1399 MUTATE_END( Expression, node ); … … 1982 1404 template< typename pass_type > 1983 1405 void 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 ) {1995 1406 VISIT_START( node ); 1996 1407 … … 2027 1438 2028 1439 template< 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 >2039 1440 Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) { 2040 1441 MUTATE_START( node ); … … 2059 1460 2060 1461 template< 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 >2070 1462 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) { 2071 1463 MUTATE_START( node ); … … 2081 1473 template< typename pass_type > 2082 1474 void 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 ) {2093 1475 VISIT_START( node ); 2094 1476 … … 2129 1511 2130 1512 template< typename pass_type > 2131 void PassVisitor< pass_type >::visit( const SizeofExpr * node ) { 1513 Expression * 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 1529 template< typename pass_type > 1530 void PassVisitor< pass_type >::visit( AlignofExpr * node ) { 2132 1531 VISIT_START( node ); 2133 1532 … … 2143 1542 2144 1543 template< typename pass_type > 2145 Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {1544 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) { 2146 1545 MUTATE_START( node ); 2147 1546 … … 2158 1557 2159 1558 //-------------------------------------------------------------------------- 2160 // AlignofExpr 2161 template< typename pass_type > 2162 void PassVisitor< pass_type >::visit( AlignofExpr * node ) { 1559 // UntypedOffsetofExpr 1560 template< typename pass_type > 1561 void 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 1570 template< typename pass_type > 1571 Expression * 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 1583 template< typename pass_type > 1584 void 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 1593 template< typename pass_type > 1594 Expression * 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 1606 template< typename pass_type > 1607 void 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 1616 template< typename pass_type > 1617 Expression * 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 1629 template< typename pass_type > 1630 void PassVisitor< pass_type >::visit( AttrExpr * node ) { 2163 1631 VISIT_START( node ); 2164 1632 … … 2174 1642 2175 1643 template< 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 ) { 1644 Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) { 2191 1645 MUTATE_START( node ); 2192 1646 … … 2203 1657 2204 1658 //-------------------------------------------------------------------------- 2205 // UntypedOffsetofExpr2206 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 // OffsetofExpr2239 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 // OffsetPackExpr2272 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 // AttrExpr2305 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 //--------------------------------------------------------------------------2349 1659 // LogicalExpr 2350 1660 template< typename pass_type > 2351 1661 void 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 ) {2363 1662 VISIT_START( node ); 2364 1663 … … 2397 1696 2398 1697 template< typename pass_type > 2399 void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) { 1698 Expression * 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 1712 template< typename pass_type > 1713 void PassVisitor< pass_type >::visit( CommaExpr * node ) { 2400 1714 VISIT_START( node ); 2401 1715 … … 2403 1717 maybeAccept_impl ( node->arg1 , *this ); 2404 1718 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 1723 template< typename pass_type > 1724 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) { 2412 1725 MUTATE_START( node ); 2413 1726 … … 2416 1729 maybeMutate_impl ( node->arg1 , *this ); 2417 1730 maybeMutate_impl ( node->arg2 , *this ); 2418 maybeMutate_impl ( node->arg3 , *this );2419 2420 MUTATE_END( Expression, node );2421 }2422 2423 //--------------------------------------------------------------------------2424 // CommaExpr2425 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 );2455 1731 2456 1732 MUTATE_END( Expression, node ); … … 2470 1746 2471 1747 template< 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 >2482 1748 Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) { 2483 1749 MUTATE_START( node ); … … 2494 1760 template< typename pass_type > 2495 1761 void 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 ) {2508 1762 VISIT_START( node ); 2509 1763 … … 2542 1796 2543 1797 template< 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 >2554 1798 Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) { 2555 1799 MUTATE_START( node ); … … 2575 1819 2576 1820 template< 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 >2587 1821 Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) { 2588 1822 MUTATE_START( node ); … … 2608 1842 2609 1843 template< 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 >2620 1844 Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) { 2621 1845 MUTATE_START( node ); … … 2642 1866 2643 1867 template< 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 >2655 1868 Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) { 2656 1869 MUTATE_START( node ); … … 2677 1890 2678 1891 template< typename pass_type > 2679 void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) { 1892 Expression * 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 1904 template< typename pass_type > 1905 void PassVisitor< pass_type >::visit( TupleExpr * node ) { 2680 1906 VISIT_START( node ); 2681 1907 … … 2687 1913 2688 1914 template< 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 // TupleExpr2701 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 >2722 1915 Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) { 2723 1916 MUTATE_START( node ); … … 2743 1936 2744 1937 template< 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 >2755 1938 Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) { 2756 1939 MUTATE_START( node ); … … 2771 1954 indexerScopedAccept( node->result , *this ); 2772 1955 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 );2783 1956 2784 1957 VISIT_END( node ); … … 2816 1989 2817 1990 template< typename pass_type > 2818 void PassVisitor< pass_type >::visit( constStmtExpr * node ) {2819 VISIT_START( node );1991 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { 1992 MUTATE_START( node ); 2820 1993 2821 1994 // don't want statements from outer CompoundStmts to be added to this StmtExpr … … 2824 1997 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); 2825 1998 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 StmtExpr2839 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 2843 1999 indexerScopedMutate( node->result , *this ); 2844 2000 maybeMutate_impl ( node->statements , *this ); … … 2862 2018 2863 2019 template< 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 >2874 2020 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) { 2875 2021 MUTATE_START( node ); … … 2896 2042 2897 2043 template< 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 >2909 2044 Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) { 2910 2045 MUTATE_START( node ); … … 2932 2067 2933 2068 template< 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 >2945 2069 Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) { 2946 2070 MUTATE_START( node ); … … 2961 2085 2962 2086 indexerScopedAccept( node->result, *this ); 2963 maybeAccept_impl ( node->expr, *this );2087 maybeAccept_impl( node->expr, *this ); 2964 2088 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2965 2089 … … 2968 2092 2969 2093 template< typename pass_type > 2970 void PassVisitor< pass_type >::visit( const DeletedExpr * node ) { 2094 Expression * 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 2106 template< typename pass_type > 2107 void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) { 2971 2108 VISIT_START( node ); 2972 2109 2973 2110 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 ); 3009 2112 3010 2113 VISIT_END( node ); … … 3039 2142 3040 2143 template< 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 >3055 2144 Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) { 3056 2145 MUTATE_START( node ); … … 3079 2168 3080 2169 template< 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 >3090 2170 Type * PassVisitor< pass_type >::mutate( VoidType * node ) { 3091 2171 MUTATE_START( node ); … … 3100 2180 template< typename pass_type > 3101 2181 void 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 ) {3111 2182 VISIT_START( node ); 3112 2183 … … 3139 2210 3140 2211 template< 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 >3152 2212 Type * PassVisitor< pass_type >::mutate( PointerType * node ) { 3153 2213 MUTATE_START( node ); … … 3174 2234 3175 2235 template< 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 >3187 2236 Type * PassVisitor< pass_type >::mutate( ArrayType * node ) { 3188 2237 MUTATE_START( node ); … … 3208 2257 3209 2258 template< 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 >3220 2259 Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) { 3221 2260 MUTATE_START( node ); … … 3241 2280 3242 2281 template< 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 >3254 2282 Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) { 3255 2283 MUTATE_START( node ); … … 3266 2294 template< typename pass_type > 3267 2295 void 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 ) {3279 2296 VISIT_START( node ); 3280 2297 … … 3315 2332 3316 2333 template< typename pass_type > 3317 void PassVisitor< pass_type >::visit( const StructInstType * node ) { 2334 Type * 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 2350 template< typename pass_type > 2351 void PassVisitor< pass_type >::visit( UnionInstType * node ) { 3318 2352 VISIT_START( node ); 3319 2353 … … 3330 2364 3331 2365 template< typename pass_type > 3332 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {2366 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) { 3333 2367 MUTATE_START( node ); 3334 2368 … … 3345 2379 3346 2380 //-------------------------------------------------------------------------- 3347 // UnionInstType3348 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 //--------------------------------------------------------------------------3394 2381 // EnumInstType 3395 2382 template< typename pass_type > … … 3404 2391 3405 2392 template< 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 >3416 2393 Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) { 3417 2394 MUTATE_START( node ); … … 3436 2413 3437 2414 template< 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 >3448 2415 Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) { 3449 2416 MUTATE_START( node ); … … 3459 2426 template< typename pass_type > 3460 2427 void 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 ) {3471 2428 VISIT_START( node ); 3472 2429 … … 3501 2458 3502 2459 template< 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 >3514 2460 Type * PassVisitor< pass_type >::mutate( TupleType * node ) { 3515 2461 MUTATE_START( node ); … … 3526 2472 template< typename pass_type > 3527 2473 void 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 ) {3538 2474 VISIT_START( node ); 3539 2475 … … 3572 2508 3573 2509 template< 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 } // if3584 3585 VISIT_END( node );3586 }3587 3588 template< typename pass_type >3589 2510 Type * PassVisitor< pass_type >::mutate( AttrType * node ) { 3590 2511 MUTATE_START( node ); … … 3613 2534 3614 2535 template< typename pass_type > 3615 void PassVisitor< pass_type >::visit( const VarArgsType * node ) { 2536 Type * 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 2546 template< typename pass_type > 2547 void PassVisitor< pass_type >::visit( ZeroType * node ) { 3616 2548 VISIT_START( node ); 3617 2549 … … 3622 2554 3623 2555 template< typename pass_type > 3624 Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {2556 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) { 3625 2557 MUTATE_START( node ); 3626 2558 … … 3631 2563 3632 2564 //-------------------------------------------------------------------------- 3633 // ZeroType3634 template< typename pass_type > 3635 void PassVisitor< pass_type >::visit( ZeroType * node ) {2565 // OneType 2566 template< typename pass_type > 2567 void PassVisitor< pass_type >::visit( OneType * node ) { 3636 2568 VISIT_START( node ); 3637 2569 … … 3642 2574 3643 2575 template< typename pass_type > 3644 void PassVisitor< pass_type >::visit( const ZeroType * node ) { 2576 Type * 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 2586 template< typename pass_type > 2587 void PassVisitor< pass_type >::visit( GlobalScopeType * node ) { 3645 2588 VISIT_START( node ); 3646 2589 … … 3651 2594 3652 2595 template< typename pass_type > 3653 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {2596 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) { 3654 2597 MUTATE_START( node ); 3655 2598 … … 3660 2603 3661 2604 //-------------------------------------------------------------------------- 3662 // OneType3663 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 // GlobalScopeType3692 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 //--------------------------------------------------------------------------3720 2605 // Designation 3721 2606 template< typename pass_type > … … 3729 2614 3730 2615 template< 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 >3740 2616 Designation * PassVisitor< pass_type >::mutate( Designation * node ) { 3741 2617 MUTATE_START( node ); … … 3758 2634 3759 2635 template< 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 >3769 2636 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) { 3770 2637 MUTATE_START( node ); … … 3779 2646 template< typename pass_type > 3780 2647 void 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 ) {3791 2648 VISIT_START( node ); 3792 2649 … … 3821 2678 3822 2679 template< 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 >3834 2680 Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) { 3835 2681 MUTATE_START( node ); … … 3852 2698 3853 2699 template< 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 >3861 2700 Constant * PassVisitor< pass_type >::mutate( Constant * node ) { 3862 2701 MUTATE_START( node ); … … 3869 2708 template< typename pass_type > 3870 2709 void 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 ) {3880 2710 VISIT_START( node ); 3881 2711 -
src/Common/PassVisitor.proto.h
r4eb43fa rf6cc734e 118 118 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {} 119 119 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 137 120 //--------------------------------------------------------- 138 121 // Mutate … … 217 200 pass.indexer.func( arg ); \ 218 201 } \ 219 template<typename pass_type> \ 220 static inline void indexer_impl_##func ( pass_type &, long, type ) { } 202 \ 203 template<typename pass_type> \ 204 static inline void indexer_impl_##func ( pass_type &, long, type ) { } \ 221 205 222 206 #define INDEXER_FUNC2( func, type1, type2 ) \ … … 225 209 pass.indexer.func( arg1, arg2 ); \ 226 210 } \ 211 \ 227 212 template<typename pass_type> \ 228 213 static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { } 229 214 230 215 231 INDEXER_FUNC1( addId , constDeclarationWithType * );232 INDEXER_FUNC1( addType , constNamedTypeDecl * );233 INDEXER_FUNC1( addStruct , constStructDecl * );234 INDEXER_FUNC1( addEnum , constEnumDecl * );235 INDEXER_FUNC1( addUnion , constUnionDecl * );236 INDEXER_FUNC1( addTrait , constTraitDecl * );237 INDEXER_FUNC2( addWith , const std::list< Expression * > &, const Declaration* );216 INDEXER_FUNC1( addId , DeclarationWithType * ); 217 INDEXER_FUNC1( addType , NamedTypeDecl * ); 218 INDEXER_FUNC1( addStruct , StructDecl * ); 219 INDEXER_FUNC1( addEnum , EnumDecl * ); 220 INDEXER_FUNC1( addUnion , UnionDecl * ); 221 INDEXER_FUNC1( addTrait , TraitDecl * ); 222 INDEXER_FUNC2( addWith , std::list< Expression * > &, BaseSyntaxNode * ); 238 223 239 224 #undef INDEXER_FUNC1 … … 241 226 242 227 template<typename pass_type> 243 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, constStructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {228 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 244 229 StructDecl * fwd = new StructDecl( decl->name ); 245 230 cloneAll( decl->parameters, fwd->parameters ); … … 248 233 249 234 template<typename pass_type> 250 static inline auto indexer_impl_addStructFwd( pass_type &, long, constStructDecl * ) {}251 252 template<typename pass_type> 253 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, constUnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {235 static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {} 236 237 template<typename pass_type> 238 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 254 239 UnionDecl * fwd = new UnionDecl( decl->name ); 255 240 cloneAll( decl->parameters, fwd->parameters ); … … 258 243 259 244 template<typename pass_type> 260 static inline auto indexer_impl_addUnionFwd( pass_type &, long, constUnionDecl * ) {}245 static inline auto indexer_impl_addUnionFwd( pass_type &, long, UnionDecl * ) {} 261 246 262 247 template<typename pass_type> -
src/InitTweak/InitTweak.cc
r4eb43fa rf6cc734e 318 318 virtual ~ExpanderImpl() = default; 319 319 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( 321 321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 322 322 }; … … 324 324 namespace { 325 325 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, 328 328 const ast::Init * init, Out & out 329 329 ) { 330 330 const CodeLocation & loc = init->location; 331 331 332 auto cond = new ast::UntypedExpr{ 332 auto cond = new ast::UntypedExpr{ 333 333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } }; 334 334 335 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init ); 336 336 splice( callExpr->args, args ); … … 338 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } ); 339 339 340 out.emplace_back( new ast::ExprStmt{ 340 out.emplace_back( new ast::ExprStmt{ 341 341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } ); 342 342 } … … 344 344 template< typename Out > 345 345 void build( 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 347 347 const ast::Init * init, Out & out 348 348 ) { … … 371 371 372 372 static UniqueName targetLabel( "L__autogen__" ); 373 ast::Label switchLabel{ 373 ast::Label switchLabel{ 374 374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } }; 375 375 376 376 std::vector< ast::ptr< ast::Stmt > > branches; 377 377 for ( const ast::Init * init : *listInit ) { … … 381 381 std::vector< ast::ptr< ast::Stmt > > stmts; 382 382 build( callExpr, indices, init, stmts ); 383 stmts.emplace_back( 383 stmts.emplace_back( 384 384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } ); 385 385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } ); … … 398 398 return makeInitList( init ); 399 399 } 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 403 403 ) 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 408 408 // statement consuming all of expander's elements 409 409 … … 427 427 ExprImpl_new( const ast::Expr * a ) : arg( a ) {} 428 428 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 431 431 ) override { 432 432 if ( ! arg ) return {}; … … 437 437 // go through indices and layer on subscript exprs ?[?] 438 438 ++it; 439 expr = new ast::UntypedExpr{ 439 expr = new ast::UntypedExpr{ 440 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 441 } 442 442 return { expr }; 443 443 } 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 { 448 448 return {}; 449 449 } … … 464 464 } 465 465 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 467 467 /// initializers) using callExpr as the base expression to perform initialization 468 468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { … … 668 668 669 669 const ast::DeclWithType * func = getCalledFunction( appExpr->func ); 670 assertf( func, 670 assertf( func, 671 671 "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 675 675 // user-defined dtor 676 676 return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr; … … 707 707 return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){ 708 708 if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 709 const ast::FunctionType * funcType = 709 const ast::FunctionType * funcType = 710 710 GenPoly::getFunctionType( appExpr->func->result ); 711 711 assert( funcType ); … … 997 997 bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); } 998 998 999 const FunctionDecl * isCopyFunction( constDeclaration * decl, const std::string & fname ) {1000 const FunctionDecl * function = dynamic_cast< constFunctionDecl * >( decl );999 FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) { 1000 FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ); 1001 1001 if ( ! function ) return nullptr; 1002 1002 if ( function->name != fname ) return nullptr; … … 1022 1022 if ( ! t1 ) return false; 1023 1023 const ast::Type * t2 = ftype->params.back()->get_type(); 1024 1024 1025 1025 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); 1026 1026 } 1027 1027 1028 const FunctionDecl * isAssignment( constDeclaration * decl ) {1028 FunctionDecl * isAssignment( Declaration * decl ) { 1029 1029 return isCopyFunction( decl, "?=?" ); 1030 1030 } 1031 const FunctionDecl * isDestructor( constDeclaration * decl ) {1032 if ( isDestructor( decl-> name) ) {1033 return dynamic_cast< constFunctionDecl * >( decl );1031 FunctionDecl * isDestructor( Declaration * decl ) { 1032 if ( isDestructor( decl->get_name() ) ) { 1033 return dynamic_cast< FunctionDecl * >( decl ); 1034 1034 } 1035 1035 return nullptr; 1036 1036 } 1037 const FunctionDecl * isDefaultConstructor( constDeclaration * decl ) {1037 FunctionDecl * isDefaultConstructor( Declaration * decl ) { 1038 1038 if ( isConstructor( decl->name ) ) { 1039 if ( const FunctionDecl * func = dynamic_cast< constFunctionDecl * >( decl ) ) {1039 if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) { 1040 1040 if ( func->type->parameters.size() == 1 ) { 1041 1041 return func; … … 1045 1045 return nullptr; 1046 1046 } 1047 const FunctionDecl * isCopyConstructor( constDeclaration * decl ) {1047 FunctionDecl * isCopyConstructor( Declaration * decl ) { 1048 1048 return isCopyFunction( decl, "?{}" ); 1049 1049 } -
src/InitTweak/InitTweak.h
r4eb43fa rf6cc734e 26 26 // helper functions for initialization 27 27 namespace InitTweak { 28 const FunctionDecl * isAssignment( constDeclaration * decl );29 const FunctionDecl * isDestructor( constDeclaration * decl );30 const FunctionDecl * isDefaultConstructor( constDeclaration * decl );31 const FunctionDecl * isCopyConstructor( constDeclaration * decl );32 const FunctionDecl * isCopyFunction( constDeclaration * 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 ); 33 33 bool isCopyFunction( const ast::FunctionDecl * decl ); 34 34 … … 153 153 InitExpander_new & operator++ (); 154 154 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. 157 157 /// Mutates callExpr 158 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); -
src/Parser/LinkageSpec.h
r4eb43fa rf6cc734e 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:24:28 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 10 16:02:34 201913 // Update Count : 1 811 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Spt 13 15:59:00 2018 13 // Update Count : 17 14 14 // 15 15 … … 35 35 constexpr Spec( unsigned int val ) : val( val ) {} 36 36 constexpr Spec( Spec const & other ) : val( other.val ) {} 37 constexpr Spec & operator=( const Spec & ) = default;38 37 // Operators may go here. 39 38 // Supports == and != -
src/Parser/ParseNode.h
r4eb43fa rf6cc734e 437 437 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 438 438 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 439 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );439 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ); 440 440 441 441 //############################################################################## -
src/Parser/StatementNode.cc
r4eb43fa rf6cc734e 317 317 } // build_waitfor_timeout 318 318 319 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {319 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 320 320 std::list< Expression * > e; 321 321 buildMoveList( exprs, e ); 322 322 Statement * s = maybeMoveBuild<Statement>( stmt ); 323 return new DeclStmt( new WithStmt( e, s ));323 return new WithStmt( e, s ); 324 324 } // build_with 325 325 -
src/Parser/parser.yy
r4eb43fa rf6cc734e 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 14 07:54:30201913 // Update Count : 435 512 // Last Modified On : Tue May 28 17:06:37 2019 13 // Update Count : 4354 14 14 // 15 15 … … 678 678 679 679 argument_expression_list: 680 argument_expression 681 | argument_expression_list ',' argument_expression 682 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } 683 ; 684 685 argument_expression: 680 686 // empty 681 687 { $$ = 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 689 689 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 690 690 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } -
src/ResolvExpr/AdjustExprType.cc
r4eb43fa rf6cc734e 47 47 void premutate( OneType * ) { visit_children = false; } 48 48 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 ); 52 52 53 53 private: … … 61 61 62 62 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 }; 64 64 arrayType->base = nullptr; 65 65 delete arrayType; … … 72 72 73 73 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() ) ) { 75 75 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 76 76 return new PointerType{ Type::Qualifiers(), typeInst }; 77 77 } 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 ) ) { 80 80 if ( tyDecl->get_kind() == TypeDecl::Ftype ) { 81 81 return new PointerType{ Type::Qualifiers(), typeInst }; … … 89 89 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 90 90 PassVisitor<AdjustExprType_old> adjuster( env, indexer ); 91 Type * newType = type->acceptMutator( adjuster );91 Type *newType = type->acceptMutator( adjuster ); 92 92 type = newType; 93 93 } … … 149 149 } // anonymous namespace 150 150 151 const ast::Type * adjustExprType( 152 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 151 const ast::Type * adjustExprType( 152 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 153 153 ) { 154 154 ast::Pass<AdjustExprType_new> adjuster{ env, symtab }; -
src/ResolvExpr/AlternativeFinder.cc
r4eb43fa rf6cc734e 336 336 } 337 337 338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {338 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 339 339 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 ) ) { 341 341 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 342 342 } // if … … 344 344 345 345 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 ) { 347 347 std::list< Declaration* > members; 348 348 aggInst->lookup( name, members ); 349 349 350 350 for ( Declaration * decl : members ) { 351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {351 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 352 352 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 353 353 // can't construct in place and use vector::back … … 362 362 } 363 363 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 ) { 365 365 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 366 366 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 368 368 std::string tmp; 369 369 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 370 alternatives.push_back( Alternative{ 370 alternatives.push_back( Alternative{ 371 371 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 372 372 } // if … … 374 374 } 375 375 376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {376 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 377 377 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 378 378 } … … 475 475 } 476 476 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 478 478 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 479 479 // … … 1226 1226 // count one safe conversion for each value that is thrown away 1227 1227 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 ), 1230 1230 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1231 1231 inferParameters( newAlt, back_inserter( candidates ) ); … … 1328 1328 if ( sizeofExpr->get_isType() ) { 1329 1329 Type * newType = sizeofExpr->get_type()->clone(); 1330 alternatives.push_back( Alternative{ 1330 alternatives.push_back( Alternative{ 1331 1331 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1332 1332 } else { … … 1343 1343 Alternative &choice = winners.front(); 1344 1344 referenceToRvalueConversion( choice.expr, choice.cost ); 1345 alternatives.push_back( Alternative{ 1345 alternatives.push_back( Alternative{ 1346 1346 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1347 1347 } // if … … 1351 1351 if ( alignofExpr->get_isType() ) { 1352 1352 Type * newType = alignofExpr->get_type()->clone(); 1353 alternatives.push_back( Alternative{ 1353 alternatives.push_back( Alternative{ 1354 1354 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1355 1355 } else { … … 1366 1366 Alternative &choice = winners.front(); 1367 1367 referenceToRvalueConversion( choice.expr, choice.cost ); 1368 alternatives.push_back( Alternative{ 1368 alternatives.push_back( Alternative{ 1369 1369 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1370 1370 } // if … … 1377 1377 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1378 1378 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1379 alternatives.push_back( Alternative{ 1379 alternatives.push_back( Alternative{ 1380 1380 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1381 1381 renameTypes( alternatives.back().expr ); … … 1405 1405 1406 1406 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 ) { 1408 1408 // assume no polymorphism 1409 1409 // assume no implicit conversions 1410 assert( function-> parameters.size() == 1 );1410 assert( function->get_parameters().size() == 1 ); 1411 1411 PRINT( 1412 1412 std::cerr << "resolvAttr: funcDecl is "; … … 1418 1418 const SymTab::Indexer & indexer = finder.get_indexer(); 1419 1419 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 ) ) { 1421 1421 Cost cost = Cost::zero; 1422 1422 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{}, 1425 1425 AssertionList{}, Cost::zero, cost } ); 1426 1426 for ( DeclarationWithType * retVal : function->returnVals ) { … … 1431 1431 } 1432 1432 1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {1433 void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) { 1434 1434 // assume no 'pointer-to-attribute' 1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );1435 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1436 1436 assert( nameExpr ); 1437 1437 std::list< SymTab::Indexer::IdData > attrList; … … 1439 1439 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1440 1440 for ( auto & data : attrList ) { 1441 constDeclarationWithType * id = data.id;1441 DeclarationWithType * id = data.id; 1442 1442 // 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() ) ) { 1444 1444 // assume exactly one parameter 1445 if ( function-> parameters.size() == 1 ) {1445 if ( function->get_parameters().size() == 1 ) { 1446 1446 if ( attrExpr->get_isType() ) { 1447 1447 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); … … 1462 1462 Cost cost = Cost::zero; 1463 1463 Expression * newExpr = data.combine( cost ); 1464 alternatives.push_back( Alternative{ 1464 alternatives.push_back( Alternative{ 1465 1465 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1466 1466 renameTypes( alternatives.back().expr ); … … 1469 1469 } 1470 1470 1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {1471 void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) { 1472 1472 AlternativeFinder firstFinder( indexer, env ); 1473 1473 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1486 1486 cloneAll( second.need, need ); 1487 1487 1488 LogicalExpr *newExpr = new LogicalExpr{ 1488 LogicalExpr *newExpr = new LogicalExpr{ 1489 1489 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), 1492 1492 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1493 1493 } … … 1522 1522 cloneAll( third.need, need ); 1523 1523 AssertionSet have; 1524 1524 1525 1525 // unify true and false types, then infer parameters to produce new alternatives 1526 1526 Type* commonType = nullptr; 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1528 1528 need, have, openVars, indexer, commonType ) ) { 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1530 1530 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1531 1531 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1532 1532 // convert both options to the conditional result type 1533 1533 Cost cost = first.cost + second.cost + third.cost; 1534 cost += computeExpressionConversionCost( 1534 cost += computeExpressionConversionCost( 1535 1535 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1536 cost += computeExpressionConversionCost( 1536 cost += computeExpressionConversionCost( 1537 1537 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1538 1538 // output alternative 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1541 1541 AssertionList( need.begin(), need.end() ), cost }; 1542 1542 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1553 1553 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1554 1554 for ( const Alternative & alt : secondFinder.alternatives ) { 1555 alternatives.push_back( Alternative{ 1555 alternatives.push_back( Alternative{ 1556 1556 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1557 1557 } // for … … 1579 1579 1580 1580 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, 1582 1582 openVars, indexer, commonType ) ) { 1583 RangeExpr * newExpr = 1583 RangeExpr * newExpr = 1584 1584 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1585 1585 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), 1588 1588 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1589 1589 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1612 1612 cloneAll( alt.need, need ); 1613 1613 } 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), 1617 1617 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1618 1618 } // for … … 1633 1633 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1634 1634 for ( Alternative & alt : finder.alternatives ) { 1635 alternatives.push_back( Alternative{ 1635 alternatives.push_back( Alternative{ 1636 1636 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1637 1637 } … … 1685 1685 cloneAll( alt.need, need ); 1686 1686 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 1689 1689 // those are open vars? 1690 1690 PRINT( 1691 1691 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1692 1692 ) 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 1697 1697 // types to cast to. 1698 1698 int discardedValues = alt.expr->result->size() - toType->size(); 1699 1699 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 1702 1702 // atomic type (e.g. (int)([1, 2, 3])) 1703 1703 1704 1704 // unification run for side-effects 1705 1705 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); … … 1710 1710 // count one safe conversion for each value that is thrown away 1711 1711 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), 1716 1716 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1717 1717 inferParameters( newAlt, back_inserter( candidates ) ); -
src/ResolvExpr/CastCost.cc
r4eb43fa rf6cc734e 37 37 struct CastCost_old : public ConversionCost { 38 38 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 ); 40 40 41 41 using ConversionCost::previsit; 42 42 using ConversionCost::postvisit; 43 void postvisit( constBasicType * basicType );44 void postvisit( constPointerType * pointerType );43 void postvisit( BasicType * basicType ); 44 void postvisit( PointerType * pointerType ); 45 45 }; 46 46 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() ) ) { 50 50 if ( eqvClass->type ) { 51 51 return castCost( src, eqvClass->type, indexer, env ); … … 53 53 return Cost::infinity; 54 54 } 55 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name) ) {55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) { 56 56 // 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 ); 58 58 if ( type->base ) { 59 59 return castCost( src, type->base, indexer, env ) + Cost::safe; … … 74 74 PRINT( std::cerr << "compatible!" << std::endl; ) 75 75 return Cost::zero; 76 } else if ( dynamic_cast< const VoidType* >( dest ) ) {76 } else if ( dynamic_cast< VoidType* >( dest ) ) { 77 77 return Cost::safe; 78 } else if ( const ReferenceType * refType = dynamic_cast< constReferenceType * > ( dest ) ) {78 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 79 79 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 80 return convertToReferenceCost( src, refType, indexer, env, []( const Type * t1, constType * 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 ) { 81 81 return ptrsCastable( t1, t2, env, indexer ); 82 82 }); 83 83 } else { 84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( const Type *, constType *, const SymTab::Indexer &, const TypeEnvironment & ))84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & )) 87 87 castCost ); 88 88 src->accept( converter ); … … 96 96 } 97 97 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 ) 99 99 : ConversionCost( dest, indexer, env, costFunc ) { 100 100 } 101 101 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 ); 104 104 if ( destAsPointer && basicType->isInteger() ) { 105 // necessary for, e.g. unsigned long => void *105 // necessary for, e.g. unsigned long => void* 106 106 cost = Cost::unsafe; 107 107 } else { … … 110 110 } 111 111 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 ) ) { 115 115 cost = Cost::safe; 116 116 } else { … … 125 125 } // if 126 126 } // if 127 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {127 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 128 128 if ( destAsBasic->isInteger() ) { 129 // necessary for, e.g. void * => unsigned long129 // necessary for, e.g. void* => unsigned long 130 130 cost = Cost::unsafe; 131 131 } // if … … 138 138 using ConversionCost_new::postvisit; 139 139 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 142 142 const ast::TypeEnvironment & env, CostCalculation costFunc ) 143 143 : ConversionCost_new( dst, symtab, env, costFunc ) {} … … 182 182 } // anonymous namespace 183 183 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 187 187 ) { 188 188 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { … … 220 220 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 221 221 #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 &, 226 226 const ast::TypeEnvironment & ) 227 227 ) ptrsCastable ); … … 229 229 #warning cast on castCost artifact of having two functions, remove when port done 230 230 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 &, 234 234 const ast::TypeEnvironment & ) 235 235 ) castCost }; -
src/ResolvExpr/CommonType.cc
r4eb43fa rf6cc734e 38 38 namespace ResolvExpr { 39 39 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; } 42 42 43 43 void previsit( BaseSyntaxNode * ) { visit_children = false; } … … 60 60 61 61 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; // inherited62 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 67 67 bool widenFirst, widenSecond; 68 68 const SymTab::Indexer &indexer; … … 80 80 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 81 81 ) 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()) ) { 83 83 PRINT( 84 84 std::cerr << "widen okay" << std::endl; 85 85 ) 86 common-> tq |= t1->tq;87 common-> tq |= t2->tq;86 common->get_qualifiers() |= t1->get_qualifiers(); 87 common->get_qualifiers() |= t2->get_qualifiers(); 88 88 return common; 89 89 } … … 95 95 } 96 96 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 ) { 98 98 PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 99 99 … … 127 127 std::cerr << "formal is reference; result should be reference" << std::endl; 128 128 ) 129 result = new ReferenceType( ref1-> tq, result );129 result = new ReferenceType( ref1->get_qualifiers(), result ); 130 130 } 131 131 PRINT( … … 138 138 139 139 type1->accept( visitor ); 140 Type * result = visitor.pass.get_result();140 Type *result = visitor.pass.get_result(); 141 141 if ( ! result ) { 142 142 // this appears to be handling for opaque type declarations 143 143 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 ); 147 147 if ( type->get_base() ) { 148 Type::Qualifiers tq1 = type1-> tq, tq2 = type2->tq;148 Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers(); 149 149 AssertionSet have, need; 150 150 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; 153 153 if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) { 154 154 result = type1->clone(); 155 result-> tq= tq1 | tq2;155 result->get_qualifiers() = tq1 | tq2; 156 156 } // 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(); 159 159 } // if 160 160 } // if … … 190 190 */ 191 191 { 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, 193 193 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 194 194 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 198 198 }, 199 199 { 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, 201 201 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 202 202 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 206 206 }, 207 207 { 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, 209 209 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 210 210 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 214 214 }, 215 215 { 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, 217 217 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 218 218 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 222 222 }, 223 223 { 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, 225 225 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 226 226 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 230 230 }, 231 231 { 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, 233 233 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 234 234 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 238 238 }, 239 239 { 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, 241 241 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 242 242 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 246 246 }, 247 247 { 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, 249 249 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 250 250 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 254 254 }, 255 255 { 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, 257 257 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 258 258 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 262 262 }, 263 263 { 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, 265 265 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 266 266 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 270 270 }, 271 271 { 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, 273 273 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 274 274 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 278 278 }, 279 279 { 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, 281 281 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 282 282 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 286 286 }, 287 287 { 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, 289 289 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 290 290 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 294 294 }, 295 295 { 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, 297 297 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 298 298 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 302 302 }, 303 303 { 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, 305 305 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 306 306 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 310 310 }, 311 311 { 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, 313 313 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 314 314 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, … … 318 318 }, 319 319 { 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, 321 321 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 322 322 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, … … 326 326 }, 327 327 { 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, 329 329 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 330 330 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, … … 334 334 }, 335 335 { 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, 337 337 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 338 338 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, … … 342 342 }, 343 343 { 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, 345 345 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 346 346 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, … … 350 350 }, 351 351 { 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, 353 353 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 354 354 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, … … 358 358 }, 359 359 { 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, 361 361 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 362 362 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, … … 366 366 }, 367 367 { 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, 369 369 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 370 370 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, … … 374 374 }, 375 375 { 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, 377 377 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 378 378 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, … … 382 382 }, 383 383 { 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, 385 385 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 386 386 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, … … 390 390 }, 391 391 { 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, 393 393 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 394 394 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, … … 398 398 }, 399 399 { 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, 401 401 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 402 402 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, … … 406 406 }, 407 407 { 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, 409 409 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 410 410 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, … … 422 422 }, 423 423 { 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, 425 425 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 426 426 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, … … 430 430 }, 431 431 { 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, 433 433 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 434 434 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, … … 438 438 }, 439 439 { 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, 441 441 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 442 442 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, … … 446 446 }, 447 447 { 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, 449 449 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 450 450 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, … … 454 454 }, 455 455 { 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, 457 457 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 458 458 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, … … 462 462 }, 463 463 { 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, 465 465 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 466 466 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, … … 470 470 }, 471 471 { 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, 473 473 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 474 474 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, … … 481 481 // GENERATED END 482 482 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, 484 484 "Each basic type kind should have a corresponding row in the combined type matrix" 485 485 ); 486 486 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 ) 488 488 : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) { 489 489 } … … 491 491 void CommonType_old::postvisit( VoidType * ) {} 492 492 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 ) ) { 495 495 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 ); 498 498 } // 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 ) ) { 500 500 // use signed int in lieu of the enum/zero/one type 501 501 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 ); 504 504 } // if 505 505 } // if … … 507 507 508 508 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() ) ) { 511 511 OpenVarSet::const_iterator entry = openVars.find( var->get_name() ); 512 512 if ( entry != openVars.end() ) { … … 517 517 } 518 518 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 ) ) { 524 524 // 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()) ) { 526 526 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()) ) { 528 528 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 ) ) { 531 531 // 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(); 535 535 AssertionSet have, need; 536 536 OpenVarSet newOpen( openVars ); … … 542 542 result = otherPointer->clone(); 543 543 } // if 544 strict_dynamic_cast<PointerType *>(result)->base->tq= tq1 | tq2;544 strict_dynamic_cast<PointerType*>(result)->base->get_qualifiers() = tq1 | tq2; 545 545 } else { 546 546 /// std::cerr << "place for ptr-to-type" << std::endl; 547 547 } // 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; 550 550 } // if 551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {551 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) { 552 552 result = pointerType->clone(); 553 result-> tq |= type2->tq;553 result->get_qualifiers() |= type2->get_qualifiers(); 554 554 } // if 555 555 } … … 557 557 void CommonType_old::postvisit( ArrayType * ) {} 558 558 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 ) ) { 561 561 // 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()) ) { 564 564 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()) ) { 566 566 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 ) ) { 569 569 // 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(); 573 573 AssertionSet have, need; 574 574 OpenVarSet newOpen( openVars ); … … 579 579 result = otherRef->clone(); 580 580 } // if 581 strict_dynamic_cast<ReferenceType *>(result)->base->tq= tq1 | tq2;581 strict_dynamic_cast<ReferenceType*>(result)->base->get_qualifiers() = tq1 | tq2; 582 582 } else { 583 583 /// std::cerr << "place for ptr-to-type" << std::endl; 584 584 } // 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; 587 587 } // if 588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {588 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) { 589 589 result = refType->clone(); 590 result-> tq |= type2->tq;590 result->get_qualifiers() |= type2->get_qualifiers(); 591 591 } // if 592 592 } … … 596 596 void CommonType_old::postvisit( UnionInstType * ) {} 597 597 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 ) ) { 600 600 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 601 601 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); … … 606 606 } 607 607 608 void CommonType_old::postvisit( TypeInstType * inst ) {608 void CommonType_old::postvisit( TypeInstType *inst ) { 609 609 if ( widenFirst ) { 610 const NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );610 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ); 611 611 if ( nt ) { 612 const TypeDecl * type = strict_dynamic_cast< const TypeDecl* >( nt );612 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt ); 613 613 if ( type->get_base() ) { 614 Type::Qualifiers tq1 = inst-> tq, tq2 = type2->tq;614 Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers(); 615 615 AssertionSet have, need; 616 616 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; 619 619 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) { 620 620 result = type2->clone(); 621 result-> tq= tq1 | tq2;621 result->get_qualifiers() = tq1 | tq2; 622 622 } // 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(); 625 625 } // if 626 626 } // if … … 631 631 void CommonType_old::postvisit( VarArgsType * ) {} 632 632 633 void CommonType_old::postvisit( ZeroType * zeroType ) {633 void CommonType_old::postvisit( ZeroType *zeroType ) { 634 634 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() ) { 637 637 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 ) { 648 648 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() ) { 651 651 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(); 657 657 } 658 658 } … … 668 668 ast::ptr< ast::Type > result; 669 669 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, 672 672 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 673 673 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} … … 681 681 #warning remove casts when `commonTypes` moved to new AST 682 682 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 ) 688 688 ) { 689 689 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; 690 690 } 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 693 693 || dynamic_cast< const ast::ZeroType * >( type2 ) 694 694 || dynamic_cast< const ast::OneType * >( type2 ) … … 696 696 #warning remove casts when `commonTypes` moved to new AST 697 697 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 ) 703 703 ) { 704 704 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; … … 715 715 if ( entry != open.end() ) { 716 716 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 ) 719 719 ) return; 720 720 } … … 727 727 void postvisit( const ast::PointerType * pointer ) { 728 728 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 ) 733 733 ) { 734 734 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 ) 739 739 ) { 740 740 getCommonWithVoidPointer( pointer, pointer2 ); … … 746 746 ast::CV::Qualifiers q2 = pointer2->base->qualifiers; 747 747 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 749 749 // pointer{,2}->base are unchanged 750 750 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base }; 751 751 reset_qualifiers( t1 ); 752 752 reset_qualifiers( t2 ); 753 753 754 754 ast::AssertionSet have, need; 755 755 ast::OpenVarSet newOpen{ open }; … … 758 758 if ( q1.val != q2.val ) { 759 759 // 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() 762 762 )->base.get_and_mutate()->qualifiers = q1 | q2; 763 763 } … … 775 775 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 776 776 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 ) 778 778 ) { 779 779 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 ) 782 782 ) { 783 783 getCommonWithVoidPointer( ref, ref2 ); … … 788 788 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers; 789 789 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 791 791 // ref{,2}->base are unchanged 792 792 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base }; … … 800 800 if ( q1.val != q2.val ) { 801 801 // 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() 804 804 )->base.get_and_mutate()->qualifiers = q1 | q2; 805 805 } … … 819 819 820 820 void postvisit( const ast::EnumInstType * enumInst ) { 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 823 823 || dynamic_cast< const ast::ZeroType * >( type2 ) 824 824 || dynamic_cast< const ast::OneType * >( type2 ) … … 834 834 if ( ! widen.first ) return; 835 835 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 838 838 ) { 839 839 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers; … … 860 860 void postvisit( const ast::ZeroType * zero ) { 861 861 if ( ! widen.first ) return; 862 if ( 862 if ( 863 863 dynamic_cast< const ast::BasicType * >( type2 ) 864 864 || dynamic_cast< const ast::PointerType * >( type2 ) … … 870 870 } 871 871 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { 872 result = new ast::BasicType{ 872 result = new ast::BasicType{ 873 873 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers }; 874 874 } … … 877 877 void postvisit( const ast::OneType * one ) { 878 878 if ( ! widen.first ) return; 879 if ( 879 if ( 880 880 dynamic_cast< const ast::BasicType * >( type2 ) 881 881 || dynamic_cast< const ast::EnumInstType * >( type2 ) … … 886 886 } 887 887 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 888 result = new ast::BasicType{ 888 result = new ast::BasicType{ 889 889 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers }; 890 890 } … … 894 894 895 895 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 900 900 ) { 901 901 ast::ptr<ast::Type> common; … … 926 926 927 927 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 931 931 ) { 932 932 unsigned depth1 = type1->referenceDepth(); … … 940 940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); 941 941 const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >(); 942 942 943 943 if ( depth1 > depth2 ) { 944 944 assert( ref1 ); … … 978 978 ast::OpenVarSet newOpen{ open }; 979 979 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 982 982 // {type1,type->base}->strong_ref >= 1 983 983 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base }; 984 984 reset_qualifiers( t1 ); 985 985 reset_qualifiers( t2, q1 ); 986 986 987 987 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) { 988 988 result = t1; -
src/ResolvExpr/ConversionCost.cc
r4eb43fa rf6cc734e 46 46 #endif 47 47 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 ) ) { 50 50 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 ) ) { 52 52 if ( eqvClass->type ) { 53 53 return conversionCost( src, eqvClass->type, indexer, env ); … … 55 55 return Cost::infinity; 56 56 } 57 } else if ( const NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {57 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) { 58 58 PRINT( std::cerr << " found" << std::endl; ) 59 const TypeDecl * type = dynamic_cast< const TypeDecl* >( namedType );59 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 60 60 // all typedefs should be gone by this point 61 61 assert( type ); … … 77 77 PRINT( std::cerr << "compatible!" << std::endl; ) 78 78 return Cost::zero; 79 } else if ( dynamic_cast< const VoidType* >( dest ) ) {79 } else if ( dynamic_cast< VoidType* >( dest ) ) { 80 80 return Cost::safe; 81 } else if ( const ReferenceType * refType = dynamic_cast< constReferenceType * > ( dest ) ) {81 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 82 82 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 83 return convertToReferenceCost( src, refType, indexer, env, []( const Type * const t1, constType * t2, const SymTab::Indexer &, const TypeEnvironment & env ){83 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 84 84 return ptrsAssignable( t1, t2, env ); 85 85 }); 86 86 } 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&)) 90 90 conversionCost ); 91 91 src->accept( converter ); … … 98 98 } 99 99 100 Cost convertToReferenceCost( const Type * src, constType * 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 ) { 101 101 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 102 102 if ( diff > 0 ) { 103 103 // TODO: document this 104 Cost cost = convertToReferenceCost( strict_dynamic_cast< constReferenceType * >( src )->base, dest, diff-1, indexer, env, func );104 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 105 105 cost.incReference(); 106 106 return cost; 107 107 } else if ( diff < -1 ) { 108 108 // TODO: document this 109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< constReferenceType * >( dest )->base, diff+1, indexer, env, func );109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 110 110 cost.incReference(); 111 111 return cost; 112 112 } else if ( diff == 0 ) { 113 const ReferenceType * srcAsRef = dynamic_cast< constReferenceType * >( src );114 const ReferenceType * destAsRef = dynamic_cast< constReferenceType * >( dest );113 ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src ); 114 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 115 115 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 116 116 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(); 119 119 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 120 120 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 137 137 } else { 138 138 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&)) 142 142 conversionCost ); 143 143 src->accept( converter ); … … 145 145 } // if 146 146 } else { 147 const ReferenceType * destAsRef = dynamic_cast< constReferenceType * >( dest );147 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 148 148 assert( diff == -1 && destAsRef ); 149 149 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) … … 156 156 ) 157 157 // 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() ) { 159 159 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() ) { 161 161 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 162 162 } else { … … 178 178 } 179 179 180 Cost convertToReferenceCost( const Type * src, constReferenceType * 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 ) { 181 181 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 182 182 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); … … 185 185 } 186 186 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 ) 188 188 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 189 189 } … … 193 193 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves) 194 194 _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 208 208 __float80 209 _Float128 _Float128 _Complex 209 _Float128 _Float128 _Complex 210 210 __float128 211 long double long double _Complex 212 _Float128x _Float128x _Complex 211 long double long double _Complex 212 _Float128x _Float128x _Complex 213 213 */ 214 214 // GENERATED END … … 218 218 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 219 219 /* 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, }, 248 248 /* 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, }, 256 256 }; // costMatrix 257 257 static const int maxIntCost = 15; 258 258 // GENERATED END 259 259 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, 261 261 "Missing row in the cost matrix" 262 262 ); … … 266 266 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 267 267 /* 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, }, 296 296 /* 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, }, 304 304 }; // signMatrix 305 305 // GENERATED END 306 306 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, 308 308 "Missing row in the sign matrix" 309 309 ); 310 310 311 void ConversionCost::postvisit( constVoidType * ) {311 void ConversionCost::postvisit( VoidType * ) { 312 312 cost = Cost::infinity; 313 313 } 314 314 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() ]; 318 318 if ( tableResult == -1 ) { 319 319 cost = Cost::unsafe; … … 321 321 cost = Cost::zero; 322 322 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 ) ) { 326 326 // xxx - not positive this is correct, but appears to allow casting int => enum 327 327 cost = Cost::unsafe; … … 330 330 } 331 331 332 void ConversionCost::postvisit( constPointerType * 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 ) ) { 334 334 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(); 337 337 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 338 338 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 363 363 } 364 364 365 void ConversionCost::postvisit( constArrayType * ) {}366 367 void ConversionCost::postvisit( constReferenceType * refType ) {365 void ConversionCost::postvisit( ArrayType * ) {} 366 367 void ConversionCost::postvisit( ReferenceType * refType ) { 368 368 // Note: dest can never be a reference, since it would have been caught in an earlier check 369 assert( ! dynamic_cast< constReferenceType * >( dest ) );369 assert( ! dynamic_cast< ReferenceType * >( dest ) ); 370 370 // convert reference to rvalue: cv T1 & => T2 371 371 // recursively compute conversion cost from T1 to T2. 372 372 // cv can be safely dropped because of 'implicit dereference' behavior. 373 373 cost = costFunc( refType->base, dest, indexer, env ); 374 if ( refType->base-> tq == dest->tq) {374 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) { 375 375 cost.incReference(); // prefer exact qualifiers 376 } else if ( refType->base-> tq < dest->tq) {376 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) { 377 377 cost.incSafe(); // then gaining qualifiers 378 378 } else { … … 382 382 } 383 383 384 void ConversionCost::postvisit( constFunctionType * ) {}385 386 void ConversionCost::postvisit( constStructInstType * 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 ) ) { 388 388 if ( inst->name == destAsInst->name ) { 389 389 cost = Cost::zero; … … 392 392 } 393 393 394 void ConversionCost::postvisit( constUnionInstType * 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 ) ) { 396 396 if ( inst->name == destAsInst->name ) { 397 397 cost = Cost::zero; … … 400 400 } 401 401 402 void ConversionCost::postvisit( constEnumInstType * ) {402 void ConversionCost::postvisit( EnumInstType * ) { 403 403 static Type::Qualifiers q; 404 404 static BasicType integer( q, BasicType::SignedInt ); … … 409 409 } 410 410 411 void ConversionCost::postvisit( constTraitInstType * ) {}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 ) ) { 415 415 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 ) ) { 417 417 if ( inst->name == destAsInst->name ) { 418 418 cost = Cost::zero; 419 419 } 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 ); 422 422 // all typedefs should be gone by this point 423 423 assert( type ); … … 428 428 } 429 429 430 void ConversionCost::postvisit( constTupleType * tupleType ) {430 void ConversionCost::postvisit( TupleType * tupleType ) { 431 431 Cost c = Cost::zero; 432 if ( const TupleType * destAsTuple = dynamic_cast< constTupleType * >( dest ) ) {432 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) { 433 433 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 434 434 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 435 435 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 ); 437 437 if ( newCost == Cost::infinity ) { 438 438 return; … … 448 448 } 449 449 450 void ConversionCost::postvisit( constVarArgsType * ) {451 if ( dynamic_cast< const VarArgsType* >( dest ) ) {452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( constZeroType * ) {457 if ( dynamic_cast< constZeroType * >( 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 conversions461 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() ]; 462 462 if ( tableResult == -1 ) { 463 463 cost = Cost::unsafe; … … 465 465 cost = Cost::zero; 466 466 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 ) ) { 470 470 cost = Cost::zero; 471 471 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation … … 473 473 } 474 474 475 void ConversionCost::postvisit( constOneType * ) {476 if ( dynamic_cast< constOneType * >( 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 conversions480 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() ]; 481 481 if ( tableResult == -1 ) { 482 482 cost = Cost::unsafe; … … 484 484 cost = Cost::zero; 485 485 cost.incSafe( tableResult + 1 ); 486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> kind] );486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] ); 487 487 } // if 488 488 } // if … … 729 729 auto dstEnd = dstAsTuple->types.end(); 730 730 while ( srcIt != srcEnd && dstIt != dstEnd ) { 731 Cost newCost = costCalc( * srcIt++, *dstIt++, symtab, env );731 Cost newCost = costCalc( *srcIt++, *dstIt++, symtab, env ); 732 732 if ( newCost == Cost::infinity ) { 733 733 return; -
src/ResolvExpr/ConversionCost.h
r4eb43fa rf6cc734e 33 33 class TypeEnvironment; 34 34 35 typedef std::function<Cost( const Type *, constType *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;35 typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction; 36 36 struct ConversionCost : public WithShortCircuiting { 37 37 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 ); 39 39 40 40 Cost get_cost() const { return cost; } 41 41 42 void previsit( constBaseSyntaxNode * ) { visit_children = false; }42 void previsit( BaseSyntaxNode * ) { visit_children = false; } 43 43 44 void postvisit( constVoidType * voidType );45 void postvisit( constBasicType * basicType );46 void postvisit( constPointerType * pointerType );47 void postvisit( constArrayType * arrayType );48 void postvisit( constReferenceType * refType );49 void postvisit( constFunctionType * functionType );50 void postvisit( constStructInstType * aggregateUseType );51 void postvisit( constUnionInstType * aggregateUseType );52 void postvisit( constEnumInstType * aggregateUseType );53 void postvisit( constTraitInstType * aggregateUseType );54 void postvisit( constTypeInstType * aggregateUseType );55 void postvisit( constTupleType * tupleType );56 void postvisit( constVarArgsType * varArgsType );57 void postvisit( constZeroType * zeroType );58 void postvisit( constOneType * 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 ); 59 59 protected: 60 const Type *dest;60 Type *dest; 61 61 const SymTab::Indexer &indexer; 62 62 Cost cost; … … 65 65 }; 66 66 67 typedef std::function<int( const Type *, constType *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;68 Cost convertToReferenceCost( const Type * src, constReferenceType * 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 ); 69 69 70 70 // Some function pointer types, differ in return type. -
src/ResolvExpr/PtrsAssignable.cc
r4eb43fa rf6cc734e 27 27 namespace ResolvExpr { 28 28 struct PtrsAssignable : public WithShortCircuiting { 29 PtrsAssignable( const Type *dest, const TypeEnvironment &env );29 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 30 30 31 31 int get_result() const { return result; } 32 32 33 void previsit( constType * ) { visit_children = false; }34 35 void postvisit( constVoidType * voidType );36 void postvisit( constBasicType * basicType );37 void postvisit( constPointerType * pointerType );38 void postvisit( constArrayType * arrayType );39 void postvisit( constFunctionType * functionType );40 void postvisit( constStructInstType * inst );41 void postvisit( constUnionInstType * inst );42 void postvisit( constEnumInstType * inst );43 void postvisit( constTraitInstType * inst );44 void postvisit( constTypeInstType * inst );45 void postvisit( constTupleType * tupleType );46 void postvisit( constVarArgsType * varArgsType );47 void postvisit( constZeroType * zeroType );48 void postvisit( constOneType * 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 ); 49 49 private: 50 const Type *dest;50 Type *dest; 51 51 int result; 52 52 const TypeEnvironment &env; 53 53 }; 54 54 55 int ptrsAssignable( const Type *src, const Type *dest, const TypeEnvironment &env ) {55 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) { 56 56 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< constTypeInstType* >( 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() ) ) { 59 59 return ptrsAssignable( src, eqvClass->type, env ); 60 60 } // if 61 61 } // if 62 if ( dynamic_cast< constVoidType* >( dest ) ) {62 if ( dynamic_cast< VoidType* >( dest ) ) { 63 63 // void * = T * for any T is unsafe 64 64 // xxx - this should be safe, but that currently breaks the build … … 71 71 } 72 72 73 PtrsAssignable::PtrsAssignable( const Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}74 75 void PtrsAssignable::postvisit( constVoidType * ) {73 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 74 75 void PtrsAssignable::postvisit( VoidType * ) { 76 76 // T * = void * is disallowed - this is a change from C, where any 77 77 // void * can be assigned or passed to a non-void pointer without a cast. 78 78 } 79 79 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( constEnumInstType * ) {89 if ( dynamic_cast< constBasicType* >( 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 ) ) { 90 90 // int * = E *, etc. is safe. This isn't technically correct, as each 91 91 // enum has one basic type that it is compatible with, an that type can … … 97 97 } 98 98 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() ) ) { 102 102 if ( eqvClass->type ) { 103 103 // T * = S * for any S depends on the type bound to T … … 107 107 } 108 108 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 ) {} 113 113 114 114 // TODO: Get rid of the `_new` suffix when the old version is removed. -
src/ResolvExpr/PtrsCastable.cc
r4eb43fa rf6cc734e 29 29 struct PtrsCastable_old : public WithShortCircuiting { 30 30 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 ); 32 32 33 33 int get_result() const { return result; } 34 34 35 void previsit( constType * ) { visit_children = false; }36 37 void postvisit( constVoidType * voidType );38 void postvisit( constBasicType * basicType );39 void postvisit( constPointerType * pointerType );40 void postvisit( constArrayType * arrayType );41 void postvisit( constFunctionType * functionType );42 void postvisit( constStructInstType * inst );43 void postvisit( constUnionInstType * inst );44 void postvisit( constEnumInstType * inst );45 void postvisit( constTraitInstType * inst );46 void postvisit( constTypeInstType * inst );47 void postvisit( constTupleType * tupleType );48 void postvisit( constVarArgsType * varArgsType );49 void postvisit( constZeroType * zeroType );50 void postvisit( constOneType * 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 ); 51 51 private: 52 const Type *dest;52 Type *dest; 53 53 int result; 54 54 const TypeEnvironment &env; … … 57 57 58 58 namespace { 59 int objectCast( const Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {60 if ( dynamic_cast< constFunctionType* >( src ) ) {59 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 60 if ( dynamic_cast< FunctionType* >( src ) ) { 61 61 return -1; 62 } else if ( const TypeInstType * typeInst = dynamic_cast< constTypeInstType* >( src ) ) {63 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name) ) {64 if ( const TypeDecl * tyDecl = dynamic_cast< constTypeDecl* >( 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 ) { 66 66 return -1; 67 67 } // if 68 68 } //if 69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {69 } else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) { 70 70 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 71 71 return -1; … … 75 75 return 1; 76 76 } 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 ) { 78 78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast 79 79 } 80 80 } 81 81 82 int ptrsCastable( const Type * src, const Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {83 if ( const TypeInstType * destAsTypeInst = dynamic_cast< constTypeInstType* >( 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() ) ) { 85 85 // xxx - should this be ptrsCastable? 86 86 return ptrsAssignable( src, eqvClass->type, env ); 87 87 } // if 88 88 } // if 89 if ( dynamic_cast< constVoidType* >( dest ) ) {89 if ( dynamic_cast< VoidType* >( dest ) ) { 90 90 return objectCast( src, env, indexer ); 91 91 } else { … … 96 96 } 97 97 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 ) 99 99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) { 100 100 } 101 101 102 void PtrsCastable_old::postvisit( constVoidType * ) {103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( constBasicType * ) {107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( constPointerType * ) {111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( constArrayType * ) {115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( constFunctionType * ) {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 * ) { 119 119 // result = -1; 120 120 result = functionCast( dest, env, indexer ); 121 121 } 122 122 123 void PtrsCastable_old::postvisit( constStructInstType * ) {124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( constUnionInstType * ) {128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( constEnumInstType * ) {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 ) ) { 133 133 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 ) { 136 136 result = 0; 137 137 } else { … … 143 143 } 144 144 145 void PtrsCastable_old::postvisit( constTraitInstType * ) {}146 147 void PtrsCastable_old::postvisit( constTypeInstType *inst ) {145 void PtrsCastable_old::postvisit( TraitInstType * ) {} 146 147 void PtrsCastable_old::postvisit(TypeInstType *inst ) { 148 148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 149 149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 150 150 } 151 151 152 void PtrsCastable_old::postvisit( constTupleType * ) {153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( constVarArgsType * ) {157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( constZeroType * ) {161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( constOneType * ) {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 * ) { 165 165 result = objectCast( dest, env, indexer ); 166 166 } … … 168 168 namespace { 169 169 // 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 172 172 ) { 173 173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) { … … 191 191 192 192 // 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 195 195 ) { 196 196 return -1 * objectCast( src, env, symtab ); … … 204 204 int result; 205 205 206 PtrsCastable_new( 206 PtrsCastable_new( 207 207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 208 208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {} … … 278 278 } // anonymous namespace 279 279 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 283 283 ) { 284 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { -
src/ResolvExpr/ResolveAssertions.cc
r4eb43fa rf6cc734e 9 9 // Author : Aaron B. Moss 10 10 // Created On : Fri Oct 05 13:46:00 2018 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 10 16:10:37 201913 // Update Count : 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Oct 05 13:46:00 2018 13 // Update Count : 1 14 14 // 15 15 … … 197 197 } 198 198 if ( i == b.size() /* && i < a.size() */ ) return 1; 199 199 200 200 int c = a[i].compare( b[i] ); 201 201 if ( c != 0 ) return c; … … 220 220 221 221 /// Initial resolution state for an alternative 222 ResnState( Alternative & a, SymTab::Indexer& indexer )222 ResnState( Alternative& a, SymTab::Indexer& indexer ) 223 223 : alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) { 224 224 need.swap( a.need ); … … 226 226 227 227 /// Updated resolution state with new need-list 228 ResnState( ResnState && o, IterateFlag )228 ResnState( ResnState&& o, IterateFlag ) 229 229 : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(), 230 230 inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) { … … 234 234 235 235 /// 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 ); 243 243 delete varExpr->result; 244 244 varExpr->result = match.adjType->clone(); … … 247 247 // place newly-inferred assertion in proper place in cache 248 248 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(), 250 250 varExpr }; 251 251 } 252 252 253 253 /// Adds a captured assertion to the symbol table 254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer &indexer ) {254 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { 255 255 for ( auto& i : assertSet ) { 256 256 if ( i.second.isUsed ) { … … 264 264 265 265 /// Resolve a single assertion, in context 266 bool resolveAssertion( AssertionItem & assn, ResnState& resn ) {266 bool resolveAssertion( AssertionItem& assn, ResnState& resn ) { 267 267 // skip unused assertions 268 268 if ( ! assn.info.isUsed ) return true; … … 274 274 // find the candidates that unify with the desired type 275 275 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; 278 278 279 279 // build independent unification context for candidate … … 281 281 TypeEnvironment newEnv{ resn.alt.env }; 282 282 OpenVarSet newOpenVars{ resn.alt.openVars }; 283 Type * adjType = candidate->get_type()->clone();283 Type* adjType = candidate->get_type()->clone(); 284 284 adjustExprType( adjType, newEnv, resn.indexer ); 285 285 renameTyVars( adjType ); … … 368 368 std::string resKey = SymTab::Mangler::mangleType( resType ); 369 369 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 374 374 /// threshold. 375 375 void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) { … … 406 406 ResnList resns{ ResnState{ alt, root_indexer } }; 407 407 ResnList new_resns{}; 408 408 409 409 // Pruning thresholds by result type of the output alternatives. 410 410 // Alternatives *should* be generated in sorted order, so no need to retroactively prune -
src/ResolvExpr/Resolver.cc
r4eb43fa rf6cc734e 562 562 // TODO: Replace *exception type with &exception type. 563 563 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" ); 565 566 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 ) ); 567 568 findSingleExpression( throwStmt->expr, exceptType, indexer ); 568 569 } … … 971 972 /// Calls the CandidateFinder and finds the single best candidate 972 973 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, 974 975 std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {} 975 976 ) { … … 993 994 // produce invalid error if no candidates 994 995 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 != "" ? " " : ""), 997 998 "expression: ") ); 998 999 } … … 1030 1031 if ( winners.size() != 1 ) { 1031 1032 std::ostringstream stream; 1032 stream << "Cannot choose between " << winners.size() << " alternatives for " 1033 stream << "Cannot choose between " << winners.size() << " alternatives for " 1033 1034 << kind << (kind != "" ? " " : "") << "expression\n"; 1034 1035 ast::print( stream, untyped ); … … 1053 1054 struct StripCasts_new final { 1054 1055 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 ) 1058 1059 ) { 1059 1060 // generated cast is the same type as its argument, remove it after keeping env 1060 return ast::mutate_field( 1061 return ast::mutate_field( 1061 1062 castExpr->arg.get(), &ast::Expr::env, castExpr->env ); 1062 1063 } … … 1087 1088 1088 1089 /// 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, 1091 1092 const ast::TypeSubstitution * oldenv = nullptr 1092 1093 ) { 1093 1094 // set up new type substitution for expression 1094 ast::ptr< ast::TypeSubstitution > newenv = 1095 ast::ptr< ast::TypeSubstitution > newenv = 1095 1096 oldenv ? oldenv : new ast::TypeSubstitution{}; 1096 1097 env.writeToSubstitution( *newenv.get_and_mutate() ); … … 1101 1102 } // anonymous namespace 1102 1103 1103 1104 1104 1105 ast::ptr< ast::Expr > resolveInVoidContext( 1105 1106 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1106 1107 ) { 1107 1108 assertf( expr, "expected a non-null expression" ); 1108 1109 1109 1110 // set up and resolve expression cast to void 1110 1111 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr }; 1111 CandidateRef choice = findUnfinishedKindExpression( 1112 CandidateRef choice = findUnfinishedKindExpression( 1112 1113 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1113 1114 1114 1115 // a cast expression has either 0 or 1 interpretations (by language rules); 1115 1116 // if 0, an exception has already been thrown, and this code will not run … … 1121 1122 1122 1123 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` 1124 1125 /// context. 1125 ast::ptr< ast::Expr > findVoidExpression( 1126 ast::ptr< ast::Expr > findVoidExpression( 1126 1127 const ast::Expr * untyped, const ast::SymbolTable & symtab 1127 1128 ) { … … 1133 1134 } 1134 1135 1135 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1136 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1136 1137 /// lowest cost, returning the resolved version 1137 1138 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, 1140 1141 const std::string & kind = "", ResolvMode mode = {} 1141 1142 ) { 1142 1143 if ( ! untyped ) return {}; 1143 CandidateRef choice = 1144 CandidateRef choice = 1144 1145 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1145 1146 finishExpr( choice->expr, choice->env, untyped->env ); … … 1148 1149 1149 1150 /// 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 1152 1153 ) { 1153 1154 return findKindExpression( untyped, symtab ); … … 1169 1170 bool hasIntegralType( const Candidate & i ) { 1170 1171 const ast::Type * type = i.expr->result; 1171 1172 1172 1173 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) { 1173 1174 return bt->isInteger(); 1174 } else if ( 1175 dynamic_cast< const ast::EnumInstType * >( type ) 1175 } else if ( 1176 dynamic_cast< const ast::EnumInstType * >( type ) 1176 1177 || dynamic_cast< const ast::ZeroType * >( type ) 1177 1178 || dynamic_cast< const ast::OneType * >( type ) … … 1182 1183 1183 1184 /// 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 1186 1187 ) { 1187 1188 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); … … 1191 1192 bool isCharType( const ast::Type * t ) { 1192 1193 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 1195 1196 || bt->kind == ast::BasicType::UnsignedChar; 1196 1197 } … … 1252 1253 } 1253 1254 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 1256 1257 ) { 1257 1258 assert( ctorInit ); … … 1260 1261 } 1261 1262 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 1264 1265 ) { 1265 1266 assert( stmtExpr ); … … 1302 1303 1303 1304 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 1309 1310 // selecting the RHS. 1310 1311 GuardValue( currentObject ); 1311 1312 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1312 1313 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 1314 1315 // enum type is still incomplete at this point. Use `int` instead. 1315 currentObject = ast::CurrentObject{ 1316 currentObject = ast::CurrentObject{ 1316 1317 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1317 1318 } … … 1324 1325 } 1325 1326 1326 const ast::StaticAssertDecl * Resolver_new::previsit( 1327 const ast::StaticAssertDecl * assertDecl 1327 const ast::StaticAssertDecl * Resolver_new::previsit( 1328 const ast::StaticAssertDecl * assertDecl 1328 1329 ) { 1329 return ast::mutate_field( 1330 assertDecl, &ast::StaticAssertDecl::cond, 1330 return ast::mutate_field( 1331 assertDecl, &ast::StaticAssertDecl::cond, 1331 1332 findIntegralExpression( assertDecl->cond, symtab ) ); 1332 1333 } … … 1337 1338 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1338 1339 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, 1341 1342 findSingleExpression( type->dimension, sizeType, symtab ) ); 1342 1343 } … … 1355 1356 visit_children = false; 1356 1357 assertf( exprStmt->expr, "ExprStmt has null expression in resolver" ); 1357 1358 return ast::mutate_field( 1358 1359 return ast::mutate_field( 1359 1360 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) ); 1360 1361 } … … 1363 1364 visit_children = false; 1364 1365 1365 asmExpr = ast::mutate_field( 1366 asmExpr = ast::mutate_field( 1366 1367 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) ); 1367 1368 1368 1369 if ( asmExpr->inout ) { 1369 1370 asmExpr = ast::mutate_field( 1370 1371 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) ); 1371 1372 } 1372 1373 1373 1374 return asmExpr; 1374 1375 } … … 1387 1388 1388 1389 const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) { 1389 return ast::mutate_field( 1390 return ast::mutate_field( 1390 1391 whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) ); 1391 1392 } … … 1408 1409 GuardValue( currentObject ); 1409 1410 switchStmt = ast::mutate_field( 1410 switchStmt, &ast::SwitchStmt::cond, 1411 switchStmt, &ast::SwitchStmt::cond, 1411 1412 findIntegralExpression( switchStmt->cond, symtab ) ); 1412 1413 currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result }; … … 1419 1420 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1420 1421 "expression." ); 1421 1422 ast::ptr< ast::Expr > untyped = 1422 1423 ast::ptr< ast::Expr > untyped = 1423 1424 new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type }; 1424 1425 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 1427 1428 // whether it would perform a conversion. 1428 1429 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1429 1430 swap_and_save_env( newExpr, castExpr->arg ); 1430 1431 } 1431 1432 1432 1433 caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr ); 1433 1434 } … … 1442 1443 ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} }; 1443 1444 branchStmt = ast::mutate_field( 1444 branchStmt, &ast::BranchStmt::computedTarget, 1445 branchStmt, &ast::BranchStmt::computedTarget, 1445 1446 findSingleExpression( branchStmt->computedTarget, target, symtab ) ); 1446 1447 } … … 1452 1453 if ( returnStmt->expr ) { 1453 1454 returnStmt = ast::mutate_field( 1454 returnStmt, &ast::ReturnStmt::expr, 1455 returnStmt, &ast::ReturnStmt::expr, 1455 1456 findSingleExpression( returnStmt->expr, functionReturn, symtab ) ); 1456 1457 } … … 1461 1462 visit_children = false; 1462 1463 if ( throwStmt->expr ) { 1463 const ast::StructDecl * exceptionDecl = 1464 const ast::StructDecl * exceptionDecl = 1464 1465 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 1465 1466 assert( exceptionDecl ); 1466 ast::ptr< ast::Type > exceptType = 1467 ast::ptr< ast::Type > exceptType = 1467 1468 new ast::PointerType{ new ast::StructInstType{ exceptionDecl } }; 1468 1469 throwStmt = ast::mutate_field( 1469 throwStmt, &ast::ThrowStmt::expr, 1470 throwStmt, &ast::ThrowStmt::expr, 1470 1471 findSingleExpression( throwStmt->expr, exceptType, symtab ) ); 1471 1472 } … … 1476 1477 if ( catchStmt->cond ) { 1477 1478 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, 1480 1481 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1481 1482 } … … 1505 1506 1506 1507 if ( clause.target.args.empty() ) { 1507 SemanticError( stmt->location, 1508 SemanticError( stmt->location, 1508 1509 "Waitfor clause must have at least one mutex parameter"); 1509 1510 } 1510 1511 1511 1512 // Find all alternatives for all arguments in canonical form 1512 std::vector< CandidateFinder > argFinders = 1513 std::vector< CandidateFinder > argFinders = 1513 1514 funcFinder.findSubExprs( clause.target.args ); 1514 1515 1515 1516 // List all combinations of arguments 1516 1517 std::vector< CandidateList > possibilities; … … 1518 1519 1519 1520 // 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 1521 1522 // more arguments than parameters 1522 1523 CandidateList funcCandidates; … … 1525 1526 for ( CandidateRef & func : funcFinder.candidates ) { 1526 1527 try { 1527 auto pointerType = dynamic_cast< const ast::PointerType * >( 1528 auto pointerType = dynamic_cast< const ast::PointerType * >( 1528 1529 func->expr->result->stripReferences() ); 1529 1530 if ( ! pointerType ) { 1530 SemanticError( stmt->location, func->expr->result.get(), 1531 SemanticError( stmt->location, func->expr->result.get(), 1531 1532 "candidate not viable: not a pointer type\n" ); 1532 1533 } … … 1534 1535 auto funcType = pointerType->base.as< ast::FunctionType >(); 1535 1536 if ( ! funcType ) { 1536 SemanticError( stmt->location, func->expr->result.get(), 1537 SemanticError( stmt->location, func->expr->result.get(), 1537 1538 "candidate not viable: not a function type\n" ); 1538 1539 } … … 1543 1544 1544 1545 if( ! nextMutex( param, paramEnd ) ) { 1545 SemanticError( stmt->location, funcType, 1546 SemanticError( stmt->location, funcType, 1546 1547 "candidate function not viable: no mutex parameters\n"); 1547 1548 } … … 1559 1560 ast::AssertionSet need, have; 1560 1561 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 1562 1563 // parameter list are still considered open 1563 1564 resultEnv.add( funcType->forall ); … … 1579 1580 unsigned n_mutex_param = 0; 1580 1581 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 1582 1583 // parameters. The order is important 1583 1584 for ( auto & arg : argsList ) { … … 1586 1587 // We ran out of parameters but still have arguments. 1587 1588 // This function doesn't match 1588 SemanticError( stmt->location, funcType, 1589 SemanticError( stmt->location, funcType, 1589 1590 toString("candidate function not viable: too many mutex " 1590 1591 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1593 1594 ++n_mutex_param; 1594 1595 1595 // Check if the argument matches the parameter type in the current 1596 // Check if the argument matches the parameter type in the current 1596 1597 // scope 1597 1598 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 ) 1602 1603 ) { 1603 1604 // Type doesn't match … … 1626 1627 } while ( nextMutex( param, paramEnd ) ); 1627 1628 1628 // We ran out of arguments but still have parameters left; this 1629 // We ran out of arguments but still have parameters left; this 1629 1630 // function doesn't match 1630 SemanticError( stmt->location, funcType, 1631 SemanticError( stmt->location, funcType, 1631 1632 toString( "candidate function not viable: too few mutex " 1632 1633 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1656 1657 // Make sure correct number of arguments 1657 1658 if( funcCandidates.empty() ) { 1658 SemanticErrorException top( stmt->location, 1659 SemanticErrorException top( stmt->location, 1659 1660 "No alternatives for function in call to waitfor" ); 1660 1661 top.append( errors ); … … 1663 1664 1664 1665 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" ); 1667 1668 top.append( errors ); 1668 1669 throw top; … … 1670 1671 1671 1672 if( funcCandidates.size() > 1 ) { 1672 SemanticErrorException top( stmt->location, 1673 SemanticErrorException top( stmt->location, 1673 1674 "Ambiguous function in call to waitfor" ); 1674 1675 top.append( errors ); … … 1685 1686 // build new clause 1686 1687 ast::WaitForStmt::Clause clause2; 1687 1688 1688 1689 clause2.target.func = funcCandidates.front()->expr; 1689 1690 1690 1691 clause2.target.args.reserve( clause.target.args.size() ); 1691 1692 for ( auto arg : argsCandidates.front() ) { … … 1707 1708 ast::WaitForStmt::Timeout timeout2; 1708 1709 1709 ast::ptr< ast::Type > target = 1710 ast::ptr< ast::Type > target = 1710 1711 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1711 1712 timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab ); … … 1739 1740 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1740 1741 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` 1742 1743 // cursor. 1743 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1744 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1744 1745 singleInit->location, singleInit->value, currentObject.getOptions() }; 1745 1746 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab ); … … 1750 1751 1751 1752 // 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 1754 1755 // swap is not sufficient 1755 1756 ast::Expr::InferUnion inferred = initExpr->inferred; … … 1757 1758 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1758 1759 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 1760 1761 // due to conversions) 1761 1762 const ast::Type * initContext = currentObject.getCurrentType(); … … 1769 1770 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1770 1771 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* 1772 1773 // e.g. char x[] = "hello" 1773 1774 if ( auto ce = newExpr.as< ast::CastExpr >() ) { … … 1792 1793 assert( listInit->designations.size() == listInit->initializers.size() ); 1793 1794 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 1795 1796 // designated object and resolving the initializer against that object 1796 1797 listInit = ast::mutate_field_index( 1797 listInit, &ast::ListInit::designations, i, 1798 listInit, &ast::ListInit::designations, i, 1798 1799 currentObject.findNext( listInit->designations[i] ) ); 1799 1800 listInit = ast::mutate_field_index( … … 1817 1818 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr ); 1818 1819 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 1821 1822 // clean up generated code 1822 1823 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) { -
src/ResolvExpr/Unify.cc
r4eb43fa rf6cc734e 97 97 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 98 98 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, 102 102 WidenMode widen, const ast::SymbolTable & symtab ); 103 103 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 ) { 105 105 TypeEnvironment newEnv; 106 106 OpenVarSet openVars, closedVars; // added closedVars 107 107 AssertionSet needAssertions, haveAssertions; 108 Type * newFirst = first->clone(), *newSecond = second->clone();108 Type *newFirst = first->clone(), *newSecond = second->clone(); 109 109 env.apply( newFirst ); 110 110 env.apply( newSecond ); … … 121 121 } 122 122 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, 125 125 const ast::TypeEnvironment & env ) { 126 126 ast::TypeEnvironment newEnv; … … 135 135 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 136 136 137 return unifyExact( 137 return unifyExact( 138 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 139 } 140 140 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 ) { 142 142 TypeEnvironment newEnv; 143 143 OpenVarSet openVars; … … 163 163 } 164 164 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, 167 167 const ast::TypeEnvironment & env ) { 168 168 ast::TypeEnvironment newEnv; 169 169 ast::OpenVarSet open; 170 170 ast::AssertionSet need, have; 171 171 172 172 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 173 173 env.apply( newFirst ); … … 176 176 reset_qualifiers( newSecond ); 177 177 178 return unifyExact( 178 return unifyExact( 179 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 180 180 } … … 490 490 491 491 // 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() 497 497 ) { 498 498 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { … … 711 711 bool result; 712 712 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, 716 716 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), 718 718 symtab(symtab), result(false) {} 719 719 720 720 void previsit( const ast::Node * ) { visit_children = false; } 721 721 722 722 void postvisit( const ast::VoidType * ) { 723 723 result = dynamic_cast< const ast::VoidType * >( type2 ); … … 732 732 void postvisit( const ast::PointerType * pointer ) { 733 733 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, 736 736 noWiden(), symtab ); 737 737 } … … 742 742 if ( ! array2 ) return; 743 743 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 745 745 // dimension expression or not have a dimension 746 746 if ( array->isVarLen != array2->isVarLen ) return; 747 if ( ! array->isVarLen && ! array2->isVarLen 747 if ( ! array->isVarLen && ! array2->isVarLen 748 748 && array->dimension && array2->dimension ) { 749 749 auto ce1 = array->dimension.as< ast::ConstantExpr >(); … … 751 751 752 752 // 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 754 754 // compatible if both size specifiers have the same constant value 755 755 if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return; 756 756 } 757 757 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(), 760 760 symtab ); 761 761 } … … 763 763 void postvisit( const ast::ReferenceType * ref ) { 764 764 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(), 767 767 symtab ); 768 768 } … … 771 771 private: 772 772 /// 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 774 774 /// different size and structure when they should be compatible. 775 775 struct TtypeExpander_new : public ast::WithShortCircuiting { … … 800 800 auto types = flatten( d->get_type() ); 801 801 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 804 804 // 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 807 807 // requirements than a non-mutex function 808 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); … … 818 818 std::vector< ast::ptr< ast::Type > > types; 819 819 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 821 821 // that this results in a flat tuple 822 822 flatten( (*crnt)->get_type(), types ); … … 829 829 830 830 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, 834 834 const ast::SymbolTable & symtab 835 835 ) { … … 843 843 if ( isTuple1 && ! isTuple2 ) { 844 844 // 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, 847 847 noWiden(), symtab ); 848 848 } else if ( ! isTuple1 && isTuple2 ) { 849 849 // 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, 852 852 noWiden(), symtab ); 853 853 } 854 854 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 857 857 ) return false; 858 858 … … 860 860 } 861 861 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 863 863 // other is a ttype 864 864 if ( crnt1 != end1 ) { … … 866 866 const ast::Type * t1 = (*crnt1)->get_type(); 867 867 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, 870 870 noWiden(), symtab ); 871 871 } else if ( crnt2 != end2 ) { … … 873 873 const ast::Type * t2 = (*crnt2)->get_type(); 874 874 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, 877 877 noWiden(), symtab ); 878 878 } … … 881 881 } 882 882 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, 887 887 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 888 888 ) { 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, 891 891 symtab ); 892 892 } … … 900 900 901 901 /// 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 905 905 ) { 906 906 for ( const auto & tyvar : type->forall ) { … … 918 918 919 919 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 922 922 // affect unification. Does not actually mutate function parameters. 923 923 auto params = flattenList( func->params, tenv ); 924 924 auto params2 = flattenList( func2->params, tenv ); 925 925 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. 927 927 // where the ttype is to prevent errors 928 if ( 928 if ( 929 929 ( params.size() != params2.size() || func->returns.size() != func2->returns.size() ) 930 930 && ! func->isTtype() … … 933 933 934 934 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 935 if ( ! unifyDeclList( 935 if ( ! unifyDeclList( 936 936 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 937 937 938 938 markAssertions( have, need, func ); 939 939 markAssertions( have, need, func2 ); … … 941 941 result = true; 942 942 } 943 943 944 944 private: 945 945 template< typename RefType > … … 953 953 /// Creates a tuple type based on a list of TypeExpr 954 954 template< typename Iter > 955 static const ast::Type * tupleFromExprs( 955 static const ast::Type * tupleFromExprs( 956 956 const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs 957 957 ) { … … 973 973 const RefType * inst2 = handleRefType( inst, other ); 974 974 if ( ! inst2 ) return; 975 975 976 976 // check that parameters of types unify, if any 977 977 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; … … 1002 1002 } 1003 1003 1004 if ( ! unifyExact( 1004 if ( ! unifyExact( 1005 1005 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1006 1006 result = false; … … 1038 1038 private: 1039 1039 /// Creates a tuple type based on a list of Type 1040 static ast::ptr< ast::Type > tupleFromTypes( 1040 static ast::ptr< ast::Type > tupleFromTypes( 1041 1041 const std::vector< ast::ptr< ast::Type > > & tys 1042 1042 ) { 1043 1043 std::vector< ast::ptr< ast::Type > > out; 1044 1044 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 1046 1046 // that this results in a flat tuple 1047 1047 flatten( ty, out ); … … 1051 1051 } 1052 1052 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, 1057 1057 const ast::SymbolTable & symtab 1058 1058 ) { … … 1068 1068 if ( isTuple1 && ! isTuple2 ) { 1069 1069 // 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, 1072 1072 noWiden(), symtab ); 1073 1073 } else if ( ! isTuple1 && isTuple2 ) { 1074 1074 // combine entirety of list1, then unify 1075 1075 return unifyExact( 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1077 1077 noWiden(), symtab ); 1078 1078 } 1079 1079 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1082 1082 ) return false; 1083 1083 … … 1089 1089 const ast::Type * t1 = *crnt1; 1090 1090 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 1092 1092 // 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, 1095 1095 noWiden(), symtab ); 1096 1096 } else if ( crnt2 != list2.end() ) { … … 1098 1098 const ast::Type * t2 = *crnt2; 1099 1099 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 1101 1101 // from Rob's code 1102 1102 return unifyExact( 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1104 1104 noWiden(), symtab ); 1105 1105 } … … 1133 1133 void postvisit( const ast::OneType * ) { 1134 1134 result = dynamic_cast< const ast::OneType * >( type2 ); 1135 } 1135 } 1136 1136 1137 1137 private: … … 1140 1140 }; 1141 1141 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, 1145 1145 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1146 1146 ) { … … 1149 1149 } 1150 1150 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 1155 1155 ) { 1156 1156 ast::OpenVarSet closed; 1157 1157 findOpenVars( type1, open, closed, need, have, FirstClosed ); 1158 1158 findOpenVars( type2, open, closed, need, have, FirstOpen ); 1159 return unifyInexact( 1159 return unifyInexact( 1160 1160 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1161 1161 } 1162 1162 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, 1166 1166 WidenMode widen, const ast::SymbolTable & symtab 1167 1167 ) { … … 1170 1170 auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 ); 1171 1171 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(), 1174 1174 entry2 = var2 ? open.find( var2->name ) : open.end(); 1175 1175 bool isopen1 = entry1 != open.end(); … … 1178 1178 if ( isopen1 && isopen2 ) { 1179 1179 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, 1182 1182 open, widen, symtab ); 1183 1183 } else if ( isopen1 ) { … … 1192 1192 } 1193 1193 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 1199 1199 ) { 1200 1200 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 1203 1203 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1204 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 1205 reset_qualifiers( t1 ); 1206 1206 reset_qualifiers( t2 ); 1207 1207 1208 1208 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones -
src/ResolvExpr/typeops.h
r4eb43fa rf6cc734e 28 28 #include "SynTree/SynTree.h" 29 29 #include "SynTree/Type.h" 30 31 namespace SymTab { 32 class Indexer; 33 } 30 #include "SymTab/Indexer.h" 34 31 35 32 namespace ResolvExpr { … … 63 60 // in AdjustExprType.cc 64 61 /// 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 ); 66 63 67 64 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer … … 69 66 70 67 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 ) { 72 69 while ( begin != end ) { 73 70 adjustExprType( *begin++, env, indexer ); … … 76 73 77 74 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 78 const ast::Type * adjustExprType( 75 const ast::Type * adjustExprType( 79 76 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 80 77 81 78 // 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, 85 82 const ast::TypeEnvironment & env ); 86 83 87 84 // 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, 91 88 const ast::TypeEnvironment & env ); 92 89 93 90 // 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 ); 96 93 97 94 // 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 ); 99 96 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 100 97 const ast::TypeEnvironment & env ); 101 98 102 99 // 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, 106 103 const ast::TypeEnvironment & env ); 107 104 108 105 // 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 ) { 113 110 TypeEnvironment env; 114 111 return typesCompatible( t1, t2, indexer, env ); 115 112 } 116 113 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 ) { 118 115 TypeEnvironment env; 119 116 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 120 117 } 121 118 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 = {}, 124 121 const ast::TypeEnvironment & env = {} ); 125 122 126 123 bool typesCompatibleIgnoreQualifiers( 127 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 128 125 const ast::TypeEnvironment & env = {} ); 129 126 … … 134 131 135 132 // 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 ); 137 134 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, 139 136 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 140 137 141 138 // 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( 144 141 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 145 142 146 143 // in SpecCost.cc 147 int specCost( Type * type );144 int specCost( Type *type ); 148 145 int specCost( const ast::Type * type ); 149 146 150 147 // 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 ); 152 149 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 153 150 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 ) { 156 153 while ( begin != end ) { 157 154 if ( occurs( ty, *begin, env ) ) return true; … … 179 176 180 177 /// 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 183 180 ) { 184 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 185 182 for ( const ast::Type * t : tupleType->types ) { 186 183 flatten( t, out ); … … 200 197 201 198 // in TypeEnvironment.cc 202 bool isFtype( Type * type );199 bool isFtype( Type *type ); 203 200 } // namespace ResolvExpr 204 201 -
src/SymTab/Indexer.cc
r4eb43fa rf6cc734e 74 74 } 75 75 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; } 79 79 80 80 Indexer::~Indexer() { … … 84 84 void Indexer::lazyInitScope() { 85 85 if ( repScope < scope ) { 86 ++* stats().lazy_scopes;86 ++*stats().lazy_scopes; 87 87 // create rollback 88 prevScope = std::make_shared<Indexer>( * this );88 prevScope = std::make_shared<Indexer>( *this ); 89 89 // update repScope 90 90 repScope = scope; … … 95 95 ++scope; 96 96 97 ++* stats().new_scopes;97 ++*stats().new_scopes; 98 98 stats().avg_scope_depth->push( scope ); 99 99 stats().max_scope_depth->push( scope ); … … 103 103 if ( repScope == scope ) { 104 104 Ptr prev = prevScope; // make sure prevScope stays live 105 * this = std::move(*prevScope); // replace with previous scope105 *this = std::move(*prevScope); // replace with previous scope 106 106 } 107 107 … … 109 109 } 110 110 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; 113 113 if ( ! idTable ) return; 114 114 115 ++* stats().map_lookups;115 ++*stats().map_lookups; 116 116 auto decls = idTable->find( id ); 117 117 if ( decls == idTable->end() ) return; … … 122 122 } 123 123 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; 126 126 if ( ! typeTable ) return nullptr; 127 ++* stats().map_lookups;127 ++*stats().map_lookups; 128 128 auto it = typeTable->find( id ); 129 129 return it == typeTable->end() ? nullptr : it->second.decl; 130 130 } 131 131 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; 134 134 if ( ! structTable ) return nullptr; 135 ++* stats().map_lookups;135 ++*stats().map_lookups; 136 136 auto it = structTable->find( id ); 137 137 return it == structTable->end() ? nullptr : it->second.decl; 138 138 } 139 139 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; 142 142 if ( ! enumTable ) return nullptr; 143 ++* stats().map_lookups;143 ++*stats().map_lookups; 144 144 auto it = enumTable->find( id ); 145 145 return it == enumTable->end() ? nullptr : it->second.decl; 146 146 } 147 147 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; 150 150 if ( ! unionTable ) return nullptr; 151 ++* stats().map_lookups;151 ++*stats().map_lookups; 152 152 auto it = unionTable->find( id ); 153 153 return it == unionTable->end() ? nullptr : it->second.decl; 154 154 } 155 155 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; 158 158 if ( ! traitTable ) return nullptr; 159 ++* stats().map_lookups;159 ++*stats().map_lookups; 160 160 auto it = traitTable->find( id ); 161 161 return it == traitTable->end() ? nullptr : it->second.decl; 162 162 } 163 163 164 const Indexer * Indexer::atScope( unsigned long target ) const {164 const Indexer* Indexer::atScope( unsigned long target ) const { 165 165 // by lazy construction, final indexer in list has repScope 0, cannot be > target 166 166 // otherwise, will find first scope representing the target 167 const Indexer * indexer = this;167 const Indexer* indexer = this; 168 168 while ( indexer->repScope > target ) { 169 169 indexer = indexer->prevScope.get(); … … 172 172 } 173 173 174 const NamedTypeDecl * Indexer::globalLookupType( const std::string &id ) const {174 NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const { 175 175 return atScope( 0 )->lookupType( id ); 176 176 } 177 177 178 const StructDecl * Indexer::globalLookupStruct( const std::string &id ) const {178 StructDecl *Indexer::globalLookupStruct( const std::string &id ) const { 179 179 return atScope( 0 )->lookupStruct( id ); 180 180 } 181 181 182 const UnionDecl * Indexer::globalLookupUnion( const std::string &id ) const {182 UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const { 183 183 return atScope( 0 )->lookupUnion( id ); 184 184 } 185 185 186 const EnumDecl * Indexer::globalLookupEnum( const std::string &id ) const {186 EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const { 187 187 return atScope( 0 )->lookupEnum( id ); 188 188 } 189 189 190 bool isFunction( constDeclarationWithType * decl ) {190 bool isFunction( DeclarationWithType * decl ) { 191 191 return GenPoly::getFunctionType( decl->get_type() ); 192 192 } 193 193 194 bool isObject( constDeclarationWithType * decl ) {194 bool isObject( DeclarationWithType * decl ) { 195 195 return ! isFunction( decl ); 196 196 } 197 197 198 bool isDefinition( constDeclarationWithType * decl ) {199 if ( const FunctionDecl * func = dynamic_cast< constFunctionDecl * >( decl ) ) {198 bool isDefinition( DeclarationWithType * decl ) { 199 if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) { 200 200 // a function is a definition if it has a body 201 201 return func->statements; … … 207 207 } 208 208 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 214 214 // something wrong 215 215 assert( (isObject( added ) && isObject( existing.id ) ) … … 219 219 // new definition shadows the autogenerated one, even at the same scope 220 220 return false; 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 223 223 added->get_type(), existing.id->get_type(), Indexer() ) ) { 224 224 … … 238 238 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 239 239 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 " : 243 243 "duplicate object definition for " ); 244 244 } … … 255 255 } 256 256 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 { 258 258 if ( ! idTable ) return false; 259 259 260 ++* stats().map_lookups;260 ++*stats().map_lookups; 261 261 auto decls = idTable->find( id ); 262 262 if ( decls == idTable->end() ) return false; … … 270 270 } 271 271 } 272 272 273 273 return false; 274 274 } 275 275 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 { 277 278 if ( ! idTable ) return false; 278 279 279 ++* stats().map_lookups;280 ++*stats().map_lookups; 280 281 auto decls = idTable->find( id ); 281 282 if ( decls == idTable->end() ) return false; … … 294 295 295 296 /// 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 ) { 297 298 auto& params = function->type->parameters; 298 299 assert( ! params.empty() ); 299 300 // 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() ); 301 302 assert( base ); 302 303 return Mangler::mangle( base ); 303 304 } 304 305 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, 306 307 /// nullptr if none such 307 const FunctionDecl * getFunctionForOtype( constDeclarationWithType * decl, const std::string& otypeKey ) {308 const FunctionDecl * func = dynamic_cast< constFunctionDecl * >( decl );308 FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) { 309 FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ); 309 310 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr; 310 311 return func; 311 312 } 312 313 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 321 323 // unavailable, and likewise for the assignment operator. 322 324 323 325 // only relevant on function declarations 324 const FunctionDecl * function = dynamic_cast< constFunctionDecl * >( data.id );326 FunctionDecl * function = dynamic_cast< FunctionDecl * >( data.id ); 325 327 if ( ! function ) return true; 326 328 // only need to perform this check for constructors, destructors, and assignment functions … … 338 340 std::vector< MangleTable::value_type > deleted; 339 341 bool alreadyUserDefinedFunc = false; 340 341 for ( const auto& entry : * mangleTable ) {342 343 for ( const auto& entry : *mangleTable ) { 342 344 // skip decls that aren't functions or are for the wrong type 343 constFunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );345 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 344 346 if ( ! decl ) continue; 345 347 … … 366 368 // perform removals from mangle table, and deletions if necessary 367 369 for ( const auto& key : removed ) { 368 ++* stats().map_mutations;370 ++*stats().map_mutations; 369 371 mangleTable = mangleTable->erase( key ); 370 372 } 371 373 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 372 ++* stats().map_mutations;374 ++*stats().map_mutations; 373 375 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 374 376 } … … 377 379 // if this is the first user-defined function, delete non-user-defined overloads 378 380 std::vector< MangleTable::value_type > deleted; 379 380 for ( const auto& entry : * mangleTable ) {381 382 for ( const auto& entry : *mangleTable ) { 381 383 // skip decls that aren't functions or are for the wrong type 382 constFunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );384 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 383 385 if ( ! decl ) continue; 384 386 … … 400 402 // this needs to be a separate loop because of iterator invalidation 401 403 for ( const auto& entry : deleted ) { 402 ++* stats().map_mutations;404 ++*stats().map_mutations; 403 405 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 404 406 } … … 406 408 // this is an overridable generated function 407 409 // if there already exists a matching user-defined function, delete this appropriately 408 for ( const auto& entry : * mangleTable ) {410 for ( const auto& entry : *mangleTable ) { 409 411 // skip decls that aren't functions or are for the wrong type 410 constFunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );412 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 411 413 if ( ! decl ) continue; 412 414 … … 416 418 if ( dataIsCopyFunc ) { 417 419 // 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 419 421 // a delete statement is the wrong approach 420 422 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; … … 426 428 } 427 429 } 428 430 429 431 // nothing (more) to fix, return true 430 432 return true; 431 433 } 432 434 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; 436 439 const std::string &name = decl->name; 437 440 if ( name == "" ) return; 438 441 439 442 std::string mangleName; 440 443 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 442 445 // are placed into the same "bucket" as their user defined versions. 443 446 mangleName = Mangler::mangle( decl, false ); … … 446 449 } // if 447 450 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 449 452 // both have C linkage 450 453 if ( LinkageSpec::isMangled( decl->linkage ) ) { … … 454 457 } 455 458 } 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 457 460 // type-compatibility, which it may not be. 458 461 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 467 470 mangleTable = MangleTable::new_ptr(); 468 471 } else { 469 ++* stats().map_lookups;472 ++*stats().map_lookups; 470 473 auto decls = idTable->find( name ); 471 474 if ( decls == idTable->end() ) { … … 474 477 mangleTable = decls->second; 475 478 // skip in-scope repeat declarations of same identifier 476 ++* stats().map_lookups;479 ++*stats().map_lookups; 477 480 auto existing = mangleTable->find( mangleName ); 478 481 if ( existing != mangleTable->end() … … 483 486 // set delete expression for conflicting identifier 484 487 lazyInitScope(); 485 * stats().map_mutations += 2;488 *stats().map_mutations += 2; 486 489 idTable = idTable->set( 487 490 name, 488 mangleTable->set( 489 mangleName, 491 mangleTable->set( 492 mangleName, 490 493 IdData{ existing->second, handleConflicts.deleteStmt } ) ); 491 494 } … … 501 504 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 502 505 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 503 * stats().map_mutations += 2;506 *stats().map_mutations += 2; 504 507 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 505 508 } 506 509 507 void Indexer::addId( const DeclarationWithType * decl, constExpression * baseExpr ) {510 void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) { 508 511 // default handling of conflicts is to raise an error 509 512 addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr ); 510 513 } 511 514 512 void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration* deleteStmt ) {515 void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) { 513 516 // default handling of conflicts is to raise an error 514 517 addId( decl, OnConflict::error(), nullptr, deleteStmt ); 515 518 } 516 519 517 bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl *added ) {520 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 518 521 if ( existing->base == nullptr ) { 519 522 return false; … … 527 530 } 528 531 } 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 530 533 // the same 531 534 return true; 532 535 } 533 536 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 ) { 539 542 typeTable = TypeTable::new_ptr(); 540 543 } else { 541 ++* stats().map_lookups;544 ++*stats().map_lookups; 542 545 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 545 548 && addedTypeConflicts( existing->second.decl, decl ) ) return; 546 549 } 547 550 548 551 lazyInitScope(); 549 ++* stats().map_mutations;552 ++*stats().map_mutations; 550 553 typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } ); 551 554 } 552 555 553 bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl *added ) {556 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 554 557 if ( ! existing->body ) { 555 558 return false; … … 560 563 } 561 564 562 void Indexer::addStruct( const std::string & id ) {565 void Indexer::addStruct( const std::string &id ) { 563 566 addStruct( new StructDecl( id ) ); 564 567 } 565 568 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; 569 572 570 573 if ( ! structTable ) { 571 574 structTable = StructTable::new_ptr(); 572 575 } else { 573 ++* stats().map_lookups;576 ++*stats().map_lookups; 574 577 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 577 580 && addedDeclConflicts( existing->second.decl, decl ) ) return; 578 581 } 579 582 580 583 lazyInitScope(); 581 ++* stats().map_mutations;584 ++*stats().map_mutations; 582 585 structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } ); 583 586 } 584 587 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; 588 591 589 592 if ( ! enumTable ) { 590 593 enumTable = EnumTable::new_ptr(); 591 594 } else { 592 ++* stats().map_lookups;595 ++*stats().map_lookups; 593 596 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 596 599 && addedDeclConflicts( existing->second.decl, decl ) ) return; 597 600 } 598 601 599 602 lazyInitScope(); 600 ++* stats().map_mutations;603 ++*stats().map_mutations; 601 604 enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } ); 602 605 } 603 606 604 void Indexer::addUnion( const std::string & id ) {607 void Indexer::addUnion( const std::string &id ) { 605 608 addUnion( new UnionDecl( id ) ); 606 609 } 607 610 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; 611 614 612 615 if ( ! unionTable ) { 613 616 unionTable = UnionTable::new_ptr(); 614 617 } else { 615 ++* stats().map_lookups;618 ++*stats().map_lookups; 616 619 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 619 622 && addedDeclConflicts( existing->second.decl, decl ) ) return; 620 623 } 621 624 622 625 lazyInitScope(); 623 ++* stats().map_mutations;626 ++*stats().map_mutations; 624 627 unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } ); 625 628 } 626 629 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; 630 633 631 634 if ( ! traitTable ) { 632 635 traitTable = TraitTable::new_ptr(); 633 636 } else { 634 ++* stats().map_lookups;637 ++*stats().map_lookups; 635 638 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 638 641 && addedDeclConflicts( existing->second.decl, decl ) ) return; 639 642 } 640 643 641 644 lazyInitScope(); 642 ++* stats().map_mutations;645 ++*stats().map_mutations; 643 646 traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } ); 644 647 } 645 648 646 void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) { 649 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 650 OnConflict handleConflicts ) { 647 651 for ( Declaration * decl : aggr->members ) { 648 652 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 649 653 addId( dwt, handleConflicts, expr ); 650 654 if ( dwt->name == "" ) { 651 constType * 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 ) ) { 653 657 Expression * base = expr->clone(); 654 658 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost? … … 661 665 } 662 666 663 void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration* withStmt ) {664 for ( constExpression * expr : withExprs ) {667 void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) { 668 for ( Expression * expr : withExprs ) { 665 669 if ( expr->result ) { 666 670 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); … … 685 689 } 686 690 687 void Indexer::addFunctionType( constFunctionType * ftype ) {691 void Indexer::addFunctionType( FunctionType * ftype ) { 688 692 addTypes( ftype->forall ); 689 693 addIds( ftype->returnVals ); … … 696 700 Expression * base = baseExpr->clone(); 697 701 ResolvExpr::referenceToRvalueConversion( base, cost ); 698 ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base );702 ret = new MemberExpr( id, base ); 699 703 // xxx - this introduces hidden environments, for now remove them. 700 704 // std::swap( base->env, ret->env ); … … 702 706 base->env = nullptr; 703 707 } 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 ); 707 711 return ret; 708 712 } -
src/SymTab/Indexer.h
r4eb43fa rf6cc734e 34 34 virtual ~Indexer(); 35 35 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 37 37 // tell the indexer explicitly when scopes begin and end 38 38 void enterScope(); … … 40 40 41 41 struct IdData { 42 constDeclarationWithType * id = nullptr;43 constExpression * baseExpr = nullptr; // WithExpr42 DeclarationWithType * id = nullptr; 43 Expression * baseExpr = nullptr; // WithExpr 44 44 45 45 /// non-null if this declaration is deleted 46 const Declaration* deleteStmt = nullptr;46 BaseSyntaxNode * deleteStmt = nullptr; 47 47 /// scope of identifier 48 48 unsigned long scope = 0; … … 50 50 // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members. 51 51 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 ) 55 55 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {} 56 IdData( const IdData& o, const Declaration* deleteStmt )56 IdData( const IdData& o, BaseSyntaxNode * deleteStmt ) 57 57 : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {} 58 58 … … 61 61 62 62 /// 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; 64 64 /// 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; 66 66 /// 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; 68 68 /// 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; 70 70 /// 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; 72 72 /// 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; 74 74 75 75 /// 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; 77 77 /// 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; 79 79 /// 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; 81 81 /// 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; 83 83 84 void addId( const DeclarationWithType * decl, constExpression * 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 ); 86 86 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 ); 94 94 95 95 /// 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 ); 97 97 98 98 /// convenience function for adding a list of Ids to the indexer … … 103 103 104 104 /// convenience function for adding all of the declarations in a function type to the indexer 105 void addFunctionType( constFunctionType * ftype );105 void addFunctionType( FunctionType * ftype ); 106 106 107 107 private: 108 /// Wraps a Decl * with a scope108 /// Wraps a Decl* with a scope 109 109 template<typename Decl> 110 110 struct Scoped { 111 const Decl* decl; ///< declaration111 Decl* decl; ///< declaration 112 112 unsigned long scope; ///< scope of this declaration 113 113 114 Scoped( const Decl* d, unsigned long s) : decl(d), scope(s) {}114 Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {} 115 115 }; 116 116 … … 140 140 141 141 /// Gets the indexer at the given scope 142 const Indexer * atScope( unsigned long scope ) const;142 const Indexer* atScope( unsigned long scope ) const; 143 143 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 145 145 /// 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 ); 147 147 148 148 /// Options for handling identifier conflicts … … 152 152 Delete ///< Delete the earlier version with the delete statement 153 153 } mode; 154 const Declaration* deleteStmt; ///< Statement that deletes this expression154 BaseSyntaxNode * deleteStmt; ///< Statement that deletes this expression 155 155 156 156 private: 157 157 OnConflict() : mode(Error), deleteStmt(nullptr) {} 158 OnConflict( const Declaration* d ) : mode(Delete), deleteStmt(d) {}158 OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {} 159 159 public: 160 160 OnConflict( const OnConflict& ) = default; 161 161 162 162 static OnConflict error() { return {}; } 163 static OnConflict deleteWith( const Declaration* d ) { return { d }; }163 static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; } 164 164 }; 165 165 166 166 /// true if the existing identifier conflicts with the added identifier 167 167 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 ); 170 170 171 171 /// 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 ); 174 175 175 176 /// adds all of the members of the Aggregate (addWith helper) 176 void addMembers( const AggregateDecl * aggr, constExpression * expr, OnConflict handleConflicts );177 void addMembers( AggregateDecl * aggr, Expression * expr, OnConflict handleConflicts ); 177 178 178 179 /// 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; 180 181 /// 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; 182 183 }; 183 184 } // namespace SymTab -
src/SymTab/Mangler.cc
r4eb43fa rf6cc734e 42 42 Mangler_old( const Mangler_old & ) = delete; 43 43 44 void previsit( constBaseSyntaxNode * ) { visit_children = false; }45 46 void postvisit( constObjectDecl * declaration );47 void postvisit( constFunctionDecl * declaration );48 void postvisit( constTypeDecl * declaration );49 50 void postvisit( constVoidType * voidType );51 void postvisit( constBasicType * basicType );52 void postvisit( constPointerType * pointerType );53 void postvisit( constArrayType * arrayType );54 void postvisit( constReferenceType * refType );55 void postvisit( constFunctionType * functionType );56 void postvisit( constStructInstType * aggregateUseType );57 void postvisit( constUnionInstType * aggregateUseType );58 void postvisit( constEnumInstType * aggregateUseType );59 void postvisit( constTypeInstType * aggregateUseType );60 void postvisit( constTraitInstType * inst );61 void postvisit( constTupleType * tupleType );62 void postvisit( constVarArgsType * varArgsType );63 void postvisit( constZeroType * zeroType );64 void postvisit( constOneType * oneType );65 void postvisit( constQualifiedType * 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 ); 66 66 67 67 std::string get_mangleName() { return mangleName.str(); } … … 79 79 80 80 public: 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 82 82 int nextVarNum, const VarMapType& varNums ); 83 83 84 84 private: 85 void mangleDecl( const DeclarationWithType *declaration );86 void mangleRef( const ReferenceToType *refType, std::string prefix );87 88 void printQualifiers( constType *type );85 void mangleDecl( DeclarationWithType *declaration ); 86 void mangleRef( ReferenceToType *refType, std::string prefix ); 87 88 void printQualifiers( Type *type ); 89 89 }; // Mangler_old 90 90 } // namespace 91 91 92 std::string mangle( constBaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {92 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 93 93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams ); 94 94 maybeAccept( decl, mangler ); … … 96 96 } 97 97 98 std::string mangleType( constType * ty ) {98 std::string mangleType( Type * ty ) { 99 99 PassVisitor<Mangler_old> mangler( false, true, true ); 100 100 maybeAccept( ty, mangler ); … … 102 102 } 103 103 104 std::string mangleConcrete( constType * ty ) {104 std::string mangleConcrete( Type * ty ) { 105 105 PassVisitor<Mangler_old> mangler( false, false, false ); 106 106 maybeAccept( ty, mangler ); … … 110 110 namespace { 111 111 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 ), 114 114 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, 117 117 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 ), 120 120 mangleGenericParams( mangleGenericParams ) {} 121 121 122 void Mangler_old::mangleDecl( constDeclarationWithType * declaration ) {122 void Mangler_old::mangleDecl( DeclarationWithType * declaration ) { 123 123 bool wasTopLevel = isTopLevel; 124 124 if ( isTopLevel ) { … … 150 150 } 151 151 152 void Mangler_old::postvisit( constObjectDecl * declaration ) {152 void Mangler_old::postvisit( ObjectDecl * declaration ) { 153 153 mangleDecl( declaration ); 154 154 } 155 155 156 void Mangler_old::postvisit( constFunctionDecl * declaration ) {156 void Mangler_old::postvisit( FunctionDecl * declaration ) { 157 157 mangleDecl( declaration ); 158 158 } 159 159 160 void Mangler_old::postvisit( constVoidType * voidType ) {160 void Mangler_old::postvisit( VoidType * voidType ) { 161 161 printQualifiers( voidType ); 162 162 mangleName << Encoding::void_t; 163 163 } 164 164 165 void Mangler_old::postvisit( constBasicType * basicType ) {165 void Mangler_old::postvisit( BasicType * basicType ) { 166 166 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( constPointerType * 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 ) { 172 172 printQualifiers( pointerType ); 173 173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers … … 176 176 } 177 177 178 void Mangler_old::postvisit( constArrayType * arrayType ) {178 void Mangler_old::postvisit( ArrayType * arrayType ) { 179 179 // TODO: encode dimension 180 180 printQualifiers( arrayType ); … … 183 183 } 184 184 185 void Mangler_old::postvisit( constReferenceType * refType ) {185 void Mangler_old::postvisit( ReferenceType * refType ) { 186 186 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 187 187 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), … … 202 202 } 203 203 204 void Mangler_old::postvisit( constFunctionType * functionType ) {204 void Mangler_old::postvisit( FunctionType * functionType ) { 205 205 printQualifiers( functionType ); 206 206 mangleName << Encoding::function; … … 219 219 } 220 220 221 void Mangler_old::mangleRef( constReferenceToType * refType, std::string prefix ) {221 void Mangler_old::mangleRef( ReferenceToType * refType, std::string prefix ) { 222 222 printQualifiers( refType ); 223 223 … … 225 225 226 226 if ( mangleGenericParams ) { 227 const std::list< Expression* >& params = refType->parameters;227 std::list< Expression* >& params = refType->parameters; 228 228 if ( ! params.empty() ) { 229 229 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)); 233 233 maybeAccept( paramType->type, *visitor ); 234 234 } … … 238 238 } 239 239 240 void Mangler_old::postvisit( constStructInstType * aggregateUseType ) {240 void Mangler_old::postvisit( StructInstType * aggregateUseType ) { 241 241 mangleRef( aggregateUseType, Encoding::struct_t ); 242 242 } 243 243 244 void Mangler_old::postvisit( constUnionInstType * aggregateUseType ) {244 void Mangler_old::postvisit( UnionInstType * aggregateUseType ) { 245 245 mangleRef( aggregateUseType, Encoding::union_t ); 246 246 } 247 247 248 void Mangler_old::postvisit( constEnumInstType * aggregateUseType ) {248 void Mangler_old::postvisit( EnumInstType * aggregateUseType ) { 249 249 mangleRef( aggregateUseType, Encoding::enum_t ); 250 250 } 251 251 252 void Mangler_old::postvisit( constTypeInstType * typeInst ) {252 void Mangler_old::postvisit( TypeInstType * typeInst ) { 253 253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 254 254 if ( varNum == varNums.end() ) { … … 266 266 } 267 267 268 void Mangler_old::postvisit( constTraitInstType * inst ) {268 void Mangler_old::postvisit( TraitInstType * inst ) { 269 269 printQualifiers( inst ); 270 270 mangleName << inst->name.size() << inst->name; 271 271 } 272 272 273 void Mangler_old::postvisit( constTupleType * tupleType ) {273 void Mangler_old::postvisit( TupleType * tupleType ) { 274 274 printQualifiers( tupleType ); 275 275 mangleName << Encoding::tuple << tupleType->types.size(); … … 277 277 } 278 278 279 void Mangler_old::postvisit( constVarArgsType * varArgsType ) {279 void Mangler_old::postvisit( VarArgsType * varArgsType ) { 280 280 printQualifiers( varArgsType ); 281 281 static const std::string vargs = "__builtin_va_list"; … … 283 283 } 284 284 285 void Mangler_old::postvisit( constZeroType * ) {285 void Mangler_old::postvisit( ZeroType * ) { 286 286 mangleName << Encoding::zero; 287 287 } 288 288 289 void Mangler_old::postvisit( constOneType * ) {289 void Mangler_old::postvisit( OneType * ) { 290 290 mangleName << Encoding::one; 291 291 } 292 292 293 void Mangler_old::postvisit( constQualifiedType * qualType ) {293 void Mangler_old::postvisit( QualifiedType * qualType ) { 294 294 bool inqual = inQualifiedType; 295 295 if (! inqual ) { … … 307 307 } 308 308 309 void Mangler_old::postvisit( constTypeDecl * decl ) {309 void Mangler_old::postvisit( TypeDecl * decl ) { 310 310 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 311 311 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. … … 314 314 // aside from the assert false. 315 315 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; 318 318 } 319 319 … … 324 324 } 325 325 326 void Mangler_old::printQualifiers( constType * type ) {326 void Mangler_old::printQualifiers( Type * type ) { 327 327 // skip if not including qualifiers 328 328 if ( typeMode ) return; 329 if ( ! type-> forall.empty() ) {329 if ( ! type->get_forall().empty() ) { 330 330 std::list< std::string > assertionNames; 331 331 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 332 332 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() ) { 335 335 case TypeDecl::Dtype: 336 336 dcount++; … … 345 345 assert( false ); 346 346 } // 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( 350 350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 351 assert->accept( sub_mangler );351 (*assert)->accept( sub_mangler ); 352 352 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 353 353 acount++; … … 436 436 437 437 private: 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 439 439 int nextVarNum, const VarMapType& varNums ); 440 440 friend class ast::Pass<Mangler_new>; … … 457 457 namespace { 458 458 Mangler_new::Mangler_new( Mangle::Mode mode ) 459 : nextVarNum( 0 ), isTopLevel( true ), 459 : nextVarNum( 0 ), isTopLevel( true ), 460 460 mangleOverridable ( ! mode.no_overrideable ), 461 typeMode ( mode.type ), 461 typeMode ( mode.type ), 462 462 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, 465 465 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 ), 468 468 mangleGenericParams( mangleGenericParams ) {} 469 469 … … 693 693 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 694 694 for ( const ast::DeclWithType * assert : decl->assertions ) { 695 ast::Pass<Mangler_new> sub_mangler( 695 ast::Pass<Mangler_new> sub_mangler( 696 696 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 697 697 assert->accept( sub_mangler ); -
src/SymTab/Mangler.h
r4eb43fa rf6cc734e 40 40 namespace Mangler { 41 41 /// Mangle syntax tree object; primary interface to clients 42 std::string mangle( constBaseSyntaxNode * 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 ); 43 43 44 44 /// Mangle a type name; secondary interface 45 std::string mangleType( const Type* ty );45 std::string mangleType( Type* ty ); 46 46 /// Mangle ignoring generic type parameters 47 std::string mangleConcrete( const Type* ty );47 std::string mangleConcrete( Type* ty ); 48 48 49 49 namespace Encoding { -
src/SymTab/Validate.cc
r4eb43fa rf6cc734e 119 119 120 120 private: 121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );121 template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl ); 122 122 123 123 AggregateDecl * parentAggr = nullptr; … … 134 134 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 135 135 struct EnumAndPointerDecay_old { 136 void previsit( EnumDecl * aggregateDecl );137 void previsit( FunctionType * func );136 void previsit( EnumDecl *aggregateDecl ); 137 void previsit( FunctionType *func ); 138 138 }; 139 139 140 140 /// Associates forward declarations of aggregates with their definitions 141 141 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 ); 149 149 void previsit( QualifiedType * qualType ); 150 150 void postvisit( QualifiedType * qualType ); 151 151 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 ); 155 155 void postvisit( TraitDecl * traitDecl ); 156 156 157 void previsit( StructDecl * structDecl );158 void previsit( UnionDecl * unionDecl );157 void previsit( StructDecl *structDecl ); 158 void previsit( UnionDecl *unionDecl ); 159 159 160 160 void renameGenericParams( std::list< TypeDecl * > & params ); 161 161 162 162 private: 163 const Indexer * local_indexer;163 const Indexer *local_indexer; 164 164 165 165 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; … … 239 239 240 240 template<typename AggDecl> 241 void handleAggregate( AggDecl * aggregateDecl );241 void handleAggregate( AggDecl *aggregateDecl ); 242 242 243 243 void previsit( StructDecl * aggregateDecl ); … … 252 252 static void verify( std::list< Declaration * > &translationUnit ); 253 253 254 void previsit( FunctionDecl * funcDecl );254 void previsit( FunctionDecl *funcDecl ); 255 255 }; 256 256 … … 287 287 Type::StorageClasses storageClasses; 288 288 289 void premutate( ObjectDecl * objectDecl );290 Expression * postmutate( CompoundLiteralExpr * compLitExpr );289 void premutate( ObjectDecl *objectDecl ); 290 Expression * postmutate( CompoundLiteralExpr *compLitExpr ); 291 291 }; 292 292 … … 393 393 } 394 394 395 void validateType( Type * type, const Indexer *indexer ) {395 void validateType( Type *type, const Indexer *indexer ) { 396 396 PassVisitor<EnumAndPointerDecay_old> epc; 397 397 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); … … 496 496 } 497 497 498 bool shouldHoist( Declaration * decl ) {498 bool shouldHoist( Declaration *decl ) { 499 499 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 500 500 } … … 515 515 516 516 template< typename AggDecl > 517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {517 void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) { 518 518 if ( parentAggr ) { 519 519 aggregateDecl->parent = parentAggr; … … 560 560 561 561 562 bool isTypedef( Declaration * decl ) {562 bool isTypedef( Declaration *decl ) { 563 563 return dynamic_cast< TypedefDecl * >( decl ); 564 564 } … … 571 571 572 572 template< typename AggDecl > 573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {573 void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) { 574 574 filter( aggregateDecl->members, isTypedef, true ); 575 575 } … … 586 586 // remove and delete decl stmts 587 587 filter( compoundStmt->kids, [](Statement * stmt) { 588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {588 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 589 589 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) { 590 590 return true; … … 595 595 } 596 596 597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {597 void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) { 598 598 // Set the type of each member of the enumeration to be EnumConstant 599 599 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 ); 601 601 assert( obj ); 602 602 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); … … 627 627 } 628 628 629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) {629 void EnumAndPointerDecay_old::previsit( FunctionType *func ) { 630 630 // Fix up parameters and return types 631 631 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 633 633 } 634 634 635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) { 636 636 if ( other_indexer ) { 637 637 local_indexer = other_indexer; … … 641 641 } 642 642 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 ); 645 645 // it's not a semantic error if the enum is not found, just an implicit forward declaration 646 646 if ( st ) { 647 enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node647 enumInst->baseEnum = st; 648 648 } // if 649 649 if ( ! st || ! st->body ) { … … 661 661 } 662 662 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 ); 665 665 // it's not a semantic error if the struct is not found, just an implicit forward declaration 666 666 if ( st ) { 667 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node667 structInst->baseStruct = st; 668 668 } // if 669 669 if ( ! st || ! st->body ) { … … 674 674 } 675 675 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 ); 678 678 // it's not a semantic error if the union is not found, just an implicit forward declaration 679 679 if ( un ) { 680 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node680 unionInst->baseUnion = un; 681 681 } // if 682 682 if ( ! un || ! un->body ) { … … 693 693 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 694 694 // linking only makes sense for the 'oldest ancestor' of the qualified type 695 qualType->parent->accept( * visitor );695 qualType->parent->accept( *visitor ); 696 696 } 697 697 … … 762 762 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 763 763 // handle other traits 764 const TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );764 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name ); 765 765 if ( ! traitDecl ) { 766 766 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); … … 769 769 SemanticError( traitInst, "incorrect number of trait parameters: " ); 770 770 } // if 771 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node771 traitInst->baseTrait = traitDecl; 772 772 773 773 // need to carry over the 'sized' status of each decl in the instance … … 786 786 } 787 787 788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {788 void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) { 789 789 // visit enum members first so that the types of self-referencing members are updated properly 790 790 if ( enumDecl->body ) { … … 792 792 if ( fwds != forwardEnums.end() ) { 793 793 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 794 (* inst)->baseEnum = enumDecl;794 (*inst)->baseEnum = enumDecl; 795 795 } // for 796 796 forwardEnums.erase( fwds ); … … 834 834 } 835 835 836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {836 void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) { 837 837 // visit struct members first so that the types of self-referencing members are updated properly 838 838 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 841 841 if ( fwds != forwardStructs.end() ) { 842 842 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 843 (* inst)->baseStruct = structDecl;843 (*inst)->baseStruct = structDecl; 844 844 } // for 845 845 forwardStructs.erase( fwds ); … … 848 848 } 849 849 850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {850 void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) { 851 851 if ( unionDecl->body ) { 852 852 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 853 853 if ( fwds != forwardUnions.end() ) { 854 854 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 855 (* inst)->baseUnion = unionDecl;855 (*inst)->baseUnion = unionDecl; 856 856 } // for 857 857 forwardUnions.erase( fwds ); … … 860 860 } 861 861 862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {862 void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) { 863 863 // ensure generic parameter instances are renamed like the base type 864 864 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< constTypeDecl * >( 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 ); 868 868 } // if 869 869 } // if … … 877 877 // expand trait instances into their members 878 878 for ( DeclarationWithType * assertion : asserts ) { 879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {879 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 880 880 // expand trait instance into all of its members 881 881 expandAssertions( traitInst, back_inserter( type->assertions ) ); … … 897 897 } 898 898 899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) {899 void ForallPointerDecay_old::previsit( ObjectDecl *object ) { 900 900 // ensure that operator names only apply to functions or function pointers 901 901 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 905 905 } 906 906 907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) {907 void ForallPointerDecay_old::previsit( FunctionDecl *func ) { 908 908 func->fixUniqueId(); 909 909 } … … 961 961 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 962 962 // 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 ); 964 964 return qualType; 965 965 } … … 970 970 TypedefMap::const_iterator def = typedefNames.find( typeInst->name ); 971 971 if ( def != typedefNames.end() ) { 972 Type * ret = def->second.first->base->clone();972 Type *ret = def->second.first->base->clone(); 973 973 ret->location = typeInst->location; 974 974 ret->get_qualifiers() |= typeInst->get_qualifiers(); … … 982 982 // place instance parameters on the typedef'd type 983 983 if ( ! typeInst->parameters.empty() ) { 984 ReferenceToType * rtt = dynamic_cast<ReferenceToType*>(ret);984 ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret); 985 985 if ( ! rtt ) { 986 986 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); … … 988 988 rtt->parameters.clear(); 989 989 cloneAll( typeInst->parameters, rtt->parameters ); 990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters990 mutateAll( rtt->parameters, *visitor ); // recursively fix typedefs on parameters 991 991 } // if 992 992 delete typeInst; … … 1043 1043 // struct screen; 1044 1044 // 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 ) 1046 1046 // hence the type-name "screen" must be defined. 1047 1047 // Note, qualifiers on the typedef are superfluous for the forward declaration. 1048 1048 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 ) ) { 1051 1051 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 ) ) { 1053 1053 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 ) ) { 1055 1055 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 1056 1056 } // if … … 1078 1078 1079 1079 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? 1081 1081 // replace the current object declaration with a function declaration 1082 1082 FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() ); … … 1104 1104 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1105 1105 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 1106 Type * type = nullptr;1106 Type *type = nullptr; 1107 1107 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 1108 1108 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 1130 1130 GuardScope( typedefNames ); 1131 1131 GuardScope( typedeclNames ); 1132 mutateAll( aggr->parameters, * visitor );1132 mutateAll( aggr->parameters, *visitor ); 1133 1133 1134 1134 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. … … 1137 1137 1138 1138 try { 1139 * i = maybeMutate( * i, *visitor );1139 *i = maybeMutate( *i, *visitor ); 1140 1140 } catch ( SemanticErrorException &e ) { 1141 1141 errors.append( e ); … … 1217 1217 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 1218 1218 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() ); 1221 1221 } else if ( i == args.size() ) { 1222 Type * defaultType = (* paramIter)->get_init();1222 Type * defaultType = (*paramIter)->get_init(); 1223 1223 if ( defaultType ) { 1224 1224 args.push_back( new TypeExpr( defaultType->clone() ) ); 1225 sub.add( (* paramIter)->get_name(), defaultType->clone() );1225 sub.add( (*paramIter)->get_name(), defaultType->clone() ); 1226 1226 } 1227 1227 } … … 1242 1242 } 1243 1243 1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {1244 void CompoundLiteral::premutate( ObjectDecl *objectDecl ) { 1245 1245 storageClasses = objectDecl->get_storageClasses(); 1246 1246 } 1247 1247 1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {1248 Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) { 1249 1249 // transform [storage_class] ... (struct S){ 3, ... }; 1250 1250 // into [storage_class] struct S temp = { 3, ... }; 1251 1251 static UniqueName indexName( "_compLit" ); 1252 1252 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() ); 1254 1254 compLitExpr->set_result( nullptr ); 1255 1255 compLitExpr->set_initializer( nullptr ); … … 1289 1289 TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 1290 1290 // 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 ) ); 1292 1292 deleteAll( retVals ); 1293 1293 retVals.clear(); … … 1302 1302 1303 1303 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 ); 1305 1305 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1306 1306 objDecl->set_type( new_type ); … … 1308 1308 1309 1309 void FixObjectType::previsit( FunctionDecl * funcDecl ) { 1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );1310 Type *new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer ); 1311 1311 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1312 1312 funcDecl->set_type( new_type ); 1313 1313 } 1314 1314 1315 void FixObjectType::previsit( TypeDecl * typeDecl ) {1315 void FixObjectType::previsit( TypeDecl *typeDecl ) { 1316 1316 if ( typeDecl->get_base() ) { 1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );1317 Type *new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer ); 1318 1318 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1319 1319 typeDecl->set_base( new_type ); … … 1378 1378 1379 1379 namespace { 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 1381 1381 /// lists by appropriate pointers 1382 1382 struct EnumAndPointerDecay_new { … … 1385 1385 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1386 1386 // build new version of object with EnumConstant 1387 ast::ptr< ast::ObjectDecl > obj = 1387 ast::ptr< ast::ObjectDecl > obj = 1388 1388 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1389 obj.get_and_mutate()->type = 1389 obj.get_and_mutate()->type = 1390 1390 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1391 1391 1392 1392 // set into decl 1393 1393 ast::EnumDecl * mut = mutate( enumDecl ); … … 1399 1399 1400 1400 static const ast::FunctionType * fixFunctionList( 1401 const ast::FunctionType * func, 1401 const ast::FunctionType * func, 1402 1402 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1403 1403 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1404 1404 ) { 1405 const auto & dwts = func->* field;1405 const auto & dwts = func->*field; 1406 1406 unsigned nvals = dwts.size(); 1407 1407 bool hasVoid = false; … … 1409 1409 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1410 1410 } 1411 1411 1412 1412 // the only case in which "void" is valid is where it is the only one in the list 1413 1413 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1414 SemanticError( 1414 SemanticError( 1415 1415 dwts.front()->location, func, "invalid type void in function type" ); 1416 1416 } … … 1418 1418 // one void is the only thing in the list, remove it 1419 1419 if ( hasVoid ) { 1420 func = ast::mutate_field( 1420 func = ast::mutate_field( 1421 1421 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1422 1422 } … … 1432 1432 1433 1433 /// 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 1436 1436 ) { 1437 1437 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) ); 1438 1438 1439 1439 // build list of trait members, substituting trait decl parameters for instance parameters 1440 ast::TypeSubstitution sub{ 1440 ast::TypeSubstitution sub{ 1441 1441 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() }; 1442 1442 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base … … 1449 1449 1450 1450 /// 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 1453 1453 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 the1457 // 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, 1459 1459 // then can have the actual mutation applied later 1460 1460 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1461 1461 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1462 1462 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1463 1463 1464 1464 const CodeLocation & location; 1465 1465 const ast::SymbolTable * localSymtab; 1466 1466 1467 1467 ForwardEnumsType forwardEnums; 1468 1468 ForwardStructsType forwardStructs; 1469 1469 ForwardUnionsType forwardUnions; 1470 1470 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 1472 1472 /// renamed appropriately 1473 1473 bool inGeneric = false; … … 1475 1475 public: 1476 1476 /// contstruct using running symbol table 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1478 1478 : location( loc ), localSymtab( &symtab ) {} 1479 1479 1480 1480 /// 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 ) 1482 1482 : location( loc ), localSymtab( &syms ) {} 1483 1483 … … 1485 1485 // ensure generic parameter instances are renamed like the base type 1486 1486 if ( inGeneric && typeInst->base ) { 1487 typeInst = ast::mutate_field( 1487 typeInst = ast::mutate_field( 1488 1488 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1489 1489 } 1490 1490 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 ) ) 1494 1494 ) { 1495 1495 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); … … 1517 1517 for ( const ast::Expr * param : inst->params ) { 1518 1518 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1519 SemanticError( 1519 SemanticError( 1520 1520 location, inst, "Expression parameters for generic types are currently " 1521 1521 "unsupported: " ); … … 1571 1571 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1572 1572 if ( ! expr ) { 1573 SemanticError( 1573 SemanticError( 1574 1574 traitInst->params[i].get(), "Expression parameters for trait instances " 1575 1575 "are currently unsupported: " ); … … 1593 1593 return traitInst; 1594 1594 } 1595 1595 1596 1596 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1597 1597 1598 1598 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1599 1599 // 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 ) ); 1602 1602 } 1603 1603 1604 1604 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 1606 1606 // properly 1607 1607 if ( ! enumDecl->body ) return enumDecl; … … 1612 1612 auto inst = fwds.first; 1613 1613 do { 1614 // forward decl is stored * mutably* in map, can thus be updated1614 // forward decl is stored *mutably* in map, can thus be updated 1615 1615 inst->second->base = enumDecl; 1616 1616 } while ( ++inst != fwds.second ); 1617 1617 forwardEnums.erase( fwds.first, fwds.second ); 1618 1618 } 1619 1619 1620 1620 // ensure that enumerator initializers are properly set 1621 1621 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1622 1622 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1623 1623 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 1625 1625 // determine if an expression is constexpr have appropriate information 1626 1626 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, 1631 1631 ast::mutate_field( init, &ast::SingleInit::value, 1632 ResolvExpr::findSingleExpression( 1632 ResolvExpr::findSingleExpression( 1633 1633 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1634 1634 symtab ) ) ) ); … … 1639 1639 } 1640 1640 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 1642 1642 /// function forall parameters, e.g. the T in Box and the T in f, below 1643 1643 /// forall(otype T) … … 1657 1657 const ast::TypeDecl * td = aggr->params[i]; 1658 1658 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1661 1661 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1662 1662 } … … 1669 1669 1670 1670 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 1672 1672 // updated properly 1673 1673 if ( ! structDecl->body ) return; … … 1678 1678 auto inst = fwds.first; 1679 1679 do { 1680 // forward decl is stored * mutably* in map, can thus be updated1680 // forward decl is stored *mutably* in map, can thus be updated 1681 1681 inst->second->base = structDecl; 1682 1682 } while ( ++inst != fwds.second ); … … 1690 1690 1691 1691 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 1693 1693 // properly 1694 1694 if ( ! unionDecl->body ) return; … … 1699 1699 auto inst = fwds.first; 1700 1700 do { 1701 // forward decl is stored * mutably* in map, can thus be updated1701 // forward decl is stored *mutably* in map, can thus be updated 1702 1702 inst->second->base = unionDecl; 1703 1703 } while ( ++inst != fwds.second ); … … 1712 1712 "number of parameters: %zd", traitDecl->params.size() ); 1713 1713 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( 1717 1717 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1718 1718 } … … 1737 1737 traitDecl = mut; 1738 1738 } 1739 1739 1740 1740 return traitDecl; 1741 1741 } 1742 1742 }; 1743 1743 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 1745 1745 /// each object and function declaration a unique ID 1746 1746 class ForallPointerDecay_new { … … 1751 1751 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) { 1752 1752 // 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 ) 1755 1755 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() ) 1756 1756 ) { … … 1776 1776 /// Fix up assertions -- flattens assertion lists, removing all trait instances 1777 1777 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, 1780 1780 ast::ParameterizedType::ForallList parent_t::* forallField 1781 1781 ) { 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]; 1784 1784 if ( type->assertions.empty() ) continue; 1785 1785 … … 1789 1789 // expand trait instances into their members 1790 1790 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() ); 1793 1793 if ( traitInst ) { 1794 1794 // expand trait instance to all its members … … 1831 1831 } // anonymous namespace 1832 1832 1833 const ast::Type * validateType( 1833 const ast::Type * validateType( 1834 1834 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1835 1835 ast::Pass< EnumAndPointerDecay_new > epc; -
src/SymTab/Validate.h
r4eb43fa rf6cc734e 19 19 #include <list> // for list 20 20 21 structCodeLocation;22 class Declaration;23 class Type;21 class CodeLocation; 22 class Declaration; 23 class Type; 24 24 25 25 namespace ast { … … 35 35 void validateType( Type *type, const Indexer *indexer ); 36 36 37 const ast::Type * validateType( 37 const ast::Type * validateType( 38 38 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ); 39 39 } // namespace SymTab -
src/SynTree/Attribute.h
r4eb43fa rf6cc734e 50 50 Attribute * clone() const override { return new Attribute( *this ); } 51 51 virtual void accept( Visitor & v ) override { v.visit( this ); } 52 virtual void accept( Visitor & v ) const override { v.visit( this ); }53 52 virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 54 53 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/BaseSyntaxNode.h
r4eb43fa rf6cc734e 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Feb 14 07:44:20 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 10 16:13:49 201913 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 17 13:44:00 13 // Update Count : 1 14 14 // 15 15 … … 25 25 class BaseSyntaxNode { 26 26 public: 27 static Stats::Counters::SimpleCounter* new_nodes;27 static Stats::Counters::SimpleCounter* new_nodes; 28 28 29 29 CodeLocation location; 30 30 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; } 34 33 35 34 virtual ~BaseSyntaxNode() {} … … 37 36 virtual BaseSyntaxNode * clone() const = 0; 38 37 virtual void accept( Visitor & v ) = 0; 39 virtual void accept( Visitor & v ) const = 0;40 38 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. 44 42 virtual void print( std::ostream & os, Indenter indent = {} ) const = 0; 45 43 }; -
src/SynTree/Constant.h
r4eb43fa rf6cc734e 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 10 15:57:38 201913 // Update Count : 1 911 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Spt 28 14:48:00 2018 13 // Update Count : 18 14 14 // 15 15 … … 30 30 Constant( Type * type, std::string rep, std::optional<unsigned long long> i ); 31 31 Constant( const Constant & other ); 32 Constant & operator=( const Constant & ) = default;33 32 virtual ~Constant(); 34 33 35 virtual Constant * clone() const override{ return new Constant( *this ); }34 virtual Constant * clone() const { return new Constant( *this ); } 36 35 37 36 Type * get_type() { return type; } … … 51 50 static Constant null( Type * ptrtype = nullptr ); 52 51 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: 58 56 Type * type; 59 57 std::string rep; 60 58 std::optional<unsigned long long> ival; 59 60 friend class ConverterOldToNew; 61 61 }; 62 62 -
src/SynTree/Declaration.h
r4eb43fa rf6cc734e 63 63 void fixUniqueId( void ); 64 64 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; 67 66 virtual Declaration *acceptMutator( Mutator &m ) override = 0; 68 67 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; … … 140 139 141 140 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 ); } 144 142 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 145 143 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 171 169 172 170 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 ); } 175 172 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 176 173 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 241 238 242 239 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 ); } 245 241 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 246 242 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 260 256 261 257 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 ); } 264 259 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 265 260 private: … … 305 300 306 301 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 ); } 309 303 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 310 304 DeclarationNode::Aggregate kind; … … 320 314 321 315 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 ); } 324 317 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 325 318 private: … … 336 329 337 330 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 ); } 340 332 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 341 333 private: … … 353 345 354 346 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; 377 351 }; 378 352 … … 389 363 390 364 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 ); } 393 366 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 394 367 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 406 379 407 380 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 ); } 410 382 virtual StaticAssertDecl * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 411 383 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Expression.cc
r4eb43fa rf6cc734e 724 724 } 725 725 726 DeletedExpr::DeletedExpr( Expression * expr, Declaration* deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {726 DeletedExpr::DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) { 727 727 assert( expr->result ); 728 728 result = expr->result->clone(); -
src/SynTree/Expression.h
r4eb43fa rf6cc734e 82 82 virtual Expression * clone() const override = 0; 83 83 virtual void accept( Visitor & v ) override = 0; 84 virtual void accept( Visitor & v ) const override = 0;85 84 virtual Expression * acceptMutator( Mutator & m ) override = 0; 86 85 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 102 101 std::list<Expression *>& get_args() { return args; } 103 102 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; 109 107 }; 110 108 … … 131 129 static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 ); 132 130 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; 138 135 }; 139 136 … … 150 147 void set_name( std::string newValue ) { name = newValue; } 151 148 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; 157 153 }; 158 154 … … 172 168 void set_arg(Expression * newValue ) { arg = newValue; } 173 169 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; 179 174 }; 180 175 … … 189 184 virtual ~LabelAddressExpr(); 190 185 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; 196 190 }; 197 191 … … 211 205 void set_arg( Expression * newValue ) { arg = newValue; } 212 206 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; 218 211 }; 219 212 … … 232 225 const std::string & targetString() const; 233 226 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; 239 231 }; 240 232 … … 251 243 void set_arg( Expression * newValue ) { arg = newValue; } 252 244 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; 258 249 }; 259 250 … … 273 264 void set_aggregate( Expression * newValue ) { aggregate = newValue; } 274 265 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; 280 270 }; 281 271 … … 296 286 void set_aggregate( Expression * newValue ) { aggregate = newValue; } 297 287 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; 303 292 }; 304 293 … … 319 308 static VariableExpr * functionPointer( FunctionDecl * decl ); 320 309 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; 326 314 }; 327 315 … … 341 329 long long int intValue() const; 342 330 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; 348 335 }; 349 336 … … 367 354 void set_isType( bool newValue ) { isType = newValue; } 368 355 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; 374 360 }; 375 361 … … 393 379 void set_isType( bool newValue ) { isType = newValue; } 394 380 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; 400 385 }; 401 386 … … 415 400 void set_type( Type * newValue ) { type = newValue; } 416 401 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; 422 406 }; 423 407 … … 437 421 void set_member( DeclarationWithType * newValue ) { member = newValue; } 438 422 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; 444 427 }; 445 428 … … 456 439 void set_type( StructInstType * newValue ) { type = newValue; } 457 440 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; 463 445 }; 464 446 … … 485 467 void set_isType( bool newValue ) { isType = newValue; } 486 468 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; 492 473 }; 493 474 … … 508 489 void set_arg2( Expression * newValue ) { arg2 = newValue; } 509 490 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; 515 495 516 496 private: … … 536 516 void set_arg3( Expression * newValue ) { arg3 = newValue; } 537 517 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; 543 522 }; 544 523 … … 558 537 void set_arg2( Expression * newValue ) { arg2 = newValue; } 559 538 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; 565 543 }; 566 544 … … 577 555 void set_type( Type * newValue ) { type = newValue; } 578 556 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; 584 561 }; 585 562 … … 604 581 void set_operand( Expression * newValue ) { operand = newValue; } 605 582 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; 611 587 612 588 // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints … … 623 599 virtual ~ImplicitCopyCtorExpr(); 624 600 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; 630 605 }; 631 606 … … 642 617 void set_callExpr( Expression * newValue ) { callExpr = newValue; } 643 618 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; 649 623 }; 650 624 … … 661 635 void set_initializer( Initializer * i ) { initializer = i; } 662 636 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; 668 641 }; 669 642 … … 681 654 RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; } 682 655 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; 688 660 }; 689 661 … … 699 671 std::list<Expression*>& get_exprs() { return exprs; } 700 672 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; 706 677 }; 707 678 … … 717 688 std::list<Expression*>& get_exprs() { return exprs; } 718 689 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; 724 694 }; 725 695 … … 739 709 TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; } 740 710 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; 746 715 }; 747 716 … … 758 727 StmtExpr * get_stmtExpr() const { return stmtExpr; } 759 728 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; 765 733 766 734 friend class ConverterNewToOld; … … 792 760 std::list< Expression * > & get_dtors() { return dtors; } 793 761 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; 799 766 }; 800 767 … … 820 787 int get_id() const { return id; } 821 788 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; 827 793 828 794 private: … … 855 821 std::list<InitAlternative> & get_initAlts() { return initAlts; } 856 822 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; 862 827 }; 863 828 … … 877 842 InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; } 878 843 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; 884 848 }; 885 849 … … 888 852 public: 889 853 Expression * expr; 890 Declaration* deleteStmt;891 892 DeletedExpr( Expression * expr, Declaration* deleteStmt );854 BaseSyntaxNode * deleteStmt; 855 856 DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt ); 893 857 DeletedExpr( const DeletedExpr & other ); 894 858 ~DeletedExpr(); 895 859 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; 901 864 }; 902 865 … … 910 873 ~DefaultArgExpr(); 911 874 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; 917 879 }; 918 880 … … 939 901 virtual ~GenericExpr(); 940 902 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; 946 907 }; 947 908 -
src/SynTree/Initializer.h
r4eb43fa rf6cc734e 38 38 39 39 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 ); } 42 41 virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 43 42 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 53 52 virtual ~Initializer(); 54 53 55 bool get_maybeConstructed() const{ return maybeConstructed; }54 bool get_maybeConstructed() { return maybeConstructed; } 56 55 57 56 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; 60 58 virtual Initializer *acceptMutator( Mutator &m ) override = 0; 61 59 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; … … 78 76 79 77 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 ); } 82 79 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 83 80 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 107 104 108 105 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 ); } 111 107 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 112 108 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 137 133 138 134 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 ); } 141 136 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 142 137 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Mutator.h
r4eb43fa rf6cc734e 52 52 virtual Statement * mutate( FinallyStmt * catchStmt ) = 0; 53 53 virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0; 54 virtual Declaration* mutate( WithStmt * withStmt ) = 0;54 virtual Statement * mutate( WithStmt * withStmt ) = 0; 55 55 virtual NullStmt * mutate( NullStmt * nullStmt ) = 0; 56 56 virtual Statement * mutate( DeclStmt * declStmt ) = 0; -
src/SynTree/Statement.cc
r4eb43fa rf6cc734e 493 493 494 494 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 ) ) {495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {} 496 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) { 497 497 cloneAll( other.exprs, exprs ); 498 498 } -
src/SynTree/Statement.h
r4eb43fa rf6cc734e 45 45 virtual Statement * clone() const override = 0; 46 46 virtual void accept( Visitor & v ) override = 0; 47 virtual void accept( Visitor & v ) const override = 0;48 47 virtual Statement * acceptMutator( Mutator & m ) override = 0; 49 48 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 65 64 virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); } 66 65 virtual void accept( Visitor & v ) override { v.visit( this ); } 67 virtual void accept( Visitor & v ) const override { v.visit( this ); }68 66 virtual CompoundStmt * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 69 67 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 76 74 virtual NullStmt * clone() const override { return new NullStmt( *this ); } 77 75 virtual void accept( Visitor & v ) override { v.visit( this ); } 78 virtual void accept( Visitor & v ) const override { v.visit( this ); }79 76 virtual NullStmt * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 80 77 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 94 91 virtual ExprStmt * clone() const override { return new ExprStmt( *this ); } 95 92 virtual void accept( Visitor & v ) override { v.visit( this ); } 96 virtual void accept( Visitor & v ) const override { v.visit( this ); }97 93 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 98 94 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 124 120 void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; } 125 121 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; 131 126 }; 132 127 … … 138 133 virtual ~DirectiveStmt(){} 139 134 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; 145 139 }; 146 140 … … 167 161 virtual IfStmt * clone() const override { return new IfStmt( *this ); } 168 162 virtual void accept( Visitor & v ) override { v.visit( this ); } 169 virtual void accept( Visitor & v ) const override { v.visit( this ); }170 163 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 171 164 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 187 180 188 181 virtual void accept( Visitor & v ) override { v.visit( this ); } 189 virtual void accept( Visitor & v ) const override { v.visit( this ); }190 182 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 191 183 … … 216 208 217 209 virtual void accept( Visitor & v ) override { v.visit( this ); } 218 virtual void accept( Visitor & v ) const override { v.visit( this ); }219 210 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 220 211 … … 245 236 virtual WhileStmt * clone() const override { return new WhileStmt( *this ); } 246 237 virtual void accept( Visitor & v ) override { v.visit( this ); } 247 virtual void accept( Visitor & v ) const override { v.visit( this ); }248 238 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 249 239 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 271 261 virtual ForStmt * clone() const override { return new ForStmt( *this ); } 272 262 virtual void accept( Visitor & v ) override { v.visit( this ); } 273 virtual void accept( Visitor & v ) const override { v.visit( this ); }274 263 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 275 264 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 301 290 virtual BranchStmt * clone() const override { return new BranchStmt( *this ); } 302 291 virtual void accept( Visitor & v ) override { v.visit( this ); } 303 virtual void accept( Visitor & v ) const override { v.visit( this ); }304 292 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 305 293 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 321 309 virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); } 322 310 virtual void accept( Visitor & v ) override { v.visit( this ); } 323 virtual void accept( Visitor & v ) const override { v.visit( this ); }324 311 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 325 312 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 346 333 virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); } 347 334 virtual void accept( Visitor & v ) override { v.visit( this ); } 348 virtual void accept( Visitor & v ) const override { v.visit( this ); }349 335 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 350 336 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 370 356 virtual TryStmt * clone() const override { return new TryStmt( *this ); } 371 357 virtual void accept( Visitor & v ) override { v.visit( this ); } 372 virtual void accept( Visitor & v ) const override { v.visit( this ); }373 358 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 374 359 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 399 384 virtual CatchStmt * clone() const override { return new CatchStmt( *this ); } 400 385 virtual void accept( Visitor & v ) override { v.visit( this ); } 401 virtual void accept( Visitor & v ) const override { v.visit( this ); }402 386 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 403 387 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 417 401 virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); } 418 402 virtual void accept( Visitor & v ) override { v.visit( this ); } 419 virtual void accept( Visitor & v ) const override { v.visit( this ); }420 403 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 421 404 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 455 438 virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); } 456 439 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 445 class WithStmt : public Statement { 446 public: 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 }; 478 459 479 460 … … 492 473 virtual DeclStmt * clone() const override { return new DeclStmt( *this ); } 493 474 virtual void accept( Visitor & v ) override { v.visit( this ); } 494 virtual void accept( Visitor & v ) const override { v.visit( this ); }495 475 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 496 476 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 514 494 virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); } 515 495 virtual void accept( Visitor & v ) override { v.visit( this ); } 516 virtual void accept( Visitor & v ) const override { v.visit( this ); }517 496 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 518 497 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/Type.h
r4eb43fa rf6cc734e 144 144 145 145 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; } 152 152 void set_const( bool newValue ) { tq.is_const = newValue; } 153 153 void set_volatile( bool newValue ) { tq.is_volatile = newValue; } … … 184 184 virtual Type *clone() const = 0; 185 185 virtual void accept( Visitor & v ) = 0; 186 virtual void accept( Visitor & v ) const = 0;187 186 virtual Type *acceptMutator( Mutator & m ) = 0; 188 187 virtual void print( std::ostream & os, Indenter indent = {} ) const; … … 202 201 virtual VoidType *clone() const override { return new VoidType( *this ); } 203 202 virtual void accept( Visitor & v ) override { v.visit( this ); } 204 virtual void accept( Visitor & v ) const override { v.visit( this ); }205 203 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 206 204 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 261 259 virtual BasicType *clone() const override { return new BasicType( *this ); } 262 260 virtual void accept( Visitor & v ) override { v.visit( this ); } 263 virtual void accept( Visitor & v ) const override { v.visit( this ); }264 261 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 265 262 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 297 294 virtual PointerType *clone() const override { return new PointerType( *this ); } 298 295 virtual void accept( Visitor & v ) override { v.visit( this ); } 299 virtual void accept( Visitor & v ) const override { v.visit( this ); }300 296 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 301 297 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 329 325 virtual ArrayType *clone() const override { return new ArrayType( *this ); } 330 326 virtual void accept( Visitor & v ) override { v.visit( this ); } 331 virtual void accept( Visitor & v ) const override { v.visit( this ); }332 327 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 333 328 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 345 340 virtual QualifiedType *clone() const override { return new QualifiedType( *this ); } 346 341 virtual void accept( Visitor & v ) override { v.visit( this ); } 347 virtual void accept( Visitor & v ) const override { v.visit( this ); }348 342 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 349 343 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 372 366 virtual ReferenceType *clone() const override { return new ReferenceType( *this ); } 373 367 virtual void accept( Visitor & v ) override { v.visit( this ); } 374 virtual void accept( Visitor & v ) const override { v.visit( this ); }375 368 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 376 369 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 402 395 virtual FunctionType *clone() const override { return new FunctionType( *this ); } 403 396 virtual void accept( Visitor & v ) override { v.visit( this ); } 404 virtual void accept( Visitor & v ) const override { v.visit( this ); }405 397 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 406 398 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 463 455 virtual StructInstType *clone() const override { return new StructInstType( *this ); } 464 456 virtual void accept( Visitor & v ) override { v.visit( this ); } 465 virtual void accept( Visitor & v ) const override { v.visit( this ); }466 457 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 467 458 … … 501 492 virtual UnionInstType *clone() const override { return new UnionInstType( *this ); } 502 493 virtual void accept( Visitor & v ) override { v.visit( this ); } 503 virtual void accept( Visitor & v ) const override { v.visit( this ); }504 494 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 505 495 … … 529 519 virtual EnumInstType *clone() const override { return new EnumInstType( *this ); } 530 520 virtual void accept( Visitor & v ) override { v.visit( this ); } 531 virtual void accept( Visitor & v ) const override { v.visit( this ); }532 521 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 533 522 … … 553 542 virtual TraitInstType *clone() const override { return new TraitInstType( *this ); } 554 543 virtual void accept( Visitor & v ) override { v.visit( this ); } 555 virtual void accept( Visitor & v ) const override { v.visit( this ); }556 544 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 557 545 private: … … 581 569 virtual TypeInstType *clone() const override { return new TypeInstType( *this ); } 582 570 virtual void accept( Visitor & v ) override { v.visit( this ); } 583 virtual void accept( Visitor & v ) const override { v.visit( this ); }584 571 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 585 572 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 619 606 virtual TupleType *clone() const override { return new TupleType( *this ); } 620 607 virtual void accept( Visitor & v ) override { v.visit( this ); } 621 virtual void accept( Visitor & v ) const override { v.visit( this ); }622 608 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 623 609 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 630 616 631 617 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, 633 619 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 634 620 TypeofType( const TypeofType& ); … … 642 628 virtual TypeofType *clone() const override { return new TypeofType( *this ); } 643 629 virtual void accept( Visitor & v ) override { v.visit( this ); } 644 virtual void accept( Visitor & v ) const override { v.visit( this ); }645 630 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 646 631 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 672 657 virtual AttrType *clone() const override { return new AttrType( *this ); } 673 658 virtual void accept( Visitor & v ) override { v.visit( this ); } 674 virtual void accept( Visitor & v ) const override { v.visit( this ); }675 659 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 676 660 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 687 671 virtual VarArgsType *clone() const override { return new VarArgsType( *this ); } 688 672 virtual void accept( Visitor & v ) override { v.visit( this ); } 689 virtual void accept( Visitor & v ) const override { v.visit( this ); }690 673 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 691 674 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 700 683 virtual ZeroType *clone() const override { return new ZeroType( *this ); } 701 684 virtual void accept( Visitor & v ) override { v.visit( this ); } 702 virtual void accept( Visitor & v ) const override { v.visit( this ); }703 685 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 704 686 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 713 695 virtual OneType *clone() const override { return new OneType( *this ); } 714 696 virtual void accept( Visitor & v ) override { v.visit( this ); } 715 virtual void accept( Visitor & v ) const override { v.visit( this ); }716 697 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 717 698 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 724 705 virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); } 725 706 virtual void accept( Visitor & v ) override { v.visit( this ); } 726 virtual void accept( Visitor & v ) const override { v.visit( this ); }727 707 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 728 708 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/Visitor.h
r4eb43fa rf6cc734e 27 27 // of the given syntax node, but performs no other action. 28 28 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; 49 39 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; 90 60 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; 167 99 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; 206 119 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; 215 124 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; 218 126 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; 221 128 }; 222 129 223 130 template< 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 ) { 131 inline void maybeAccept( TreeType *tree, VisitorType &visitor ) { 232 132 if ( tree ) { 233 133 tree->accept( visitor ); … … 236 136 237 137 template< typename Container, typename VisitorType > 238 inline void acceptAll( Container & container, VisitorType &visitor ) {138 inline void acceptAll( Container &container, VisitorType &visitor ) { 239 139 SemanticErrorException errors; 240 for ( auto * i : container) {140 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 241 141 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 ); 261 144 } 262 145 } catch( SemanticErrorException &e ) { -
src/Tuples/Explode.h
r4eb43fa rf6cc734e 51 51 template<typename OutputIterator> 52 52 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, 54 54 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 55 55 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost }; … … 58 58 /// Append alternative to an ExplodedActual 59 59 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 61 61 const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 62 62 ea.exprs.emplace_back( expr ); … … 111 111 } else { 112 112 // 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, 114 114 alt.cost, alt.cvtCost ); 115 115 } … … 174 174 template< typename Output > 175 175 void 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 178 178 ) { 179 179 } … … 239 239 /// explode list of candidates into flattened list of candidates 240 240 template< typename Output > 241 void explode( 242 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 241 void explode( 242 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 243 243 bool isTupleAssign = false 244 244 ) { -
src/Tuples/TupleAssignment.cc
r4eb43fa rf6cc734e 67 67 struct Matcher { 68 68 public: 69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 70 70 const ResolvExpr::AltList& rhs ); 71 71 virtual ~Matcher() {} 72 72 73 73 virtual void match( std::list< Expression * > &out ) = 0; 74 74 ObjectDecl * newObject( UniqueName & namer, Expression * expr ); … … 83 83 for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); } 84 84 } 85 85 86 86 ResolvExpr::AltList lhs, rhs; 87 87 TupleAssignSpotter_old &spotter; … … 264 264 } 265 265 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 267 267 // that together form a single alternative 268 268 std::list< Expression *> solved_assigns; … … 271 271 matcher->combineState( alt ); 272 272 } 273 273 274 274 // xxx -- was push_front 275 275 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() ), 279 279 ResolvExpr::sumCost( current ) + matcher->baseCost } ); 280 280 } … … 284 284 : lhs(lhs), rhs(rhs), spotter(spotter), 285 285 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 286 combineState( lhs ); 286 combineState( lhs ); 287 287 combineState( rhs ); 288 288 } … … 390 390 return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() ); 391 391 } 392 392 393 393 /// true if `expr` is of tuple type or a reference to one 394 394 bool refToTuple( const ast::Expr * expr ) { … … 421 421 } 422 422 423 Matcher( 423 Matcher( 424 424 TupleAssignSpotter_new & s, const CodeLocation & loc, 425 425 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(), 428 428 env(), open(), need() { 429 429 for ( auto & cand : lhs ) combineState( *cand ); 430 430 for ( auto & cand : rhs ) combineState( *cand ); 431 431 } 432 virtual ~Matcher() = default;433 432 434 433 virtual std::vector< ast::ptr< ast::Expr > > match() = 0; 435 434 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 438 437 /// bindings to the env 439 438 struct EnvRemover { … … 456 455 ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) { 457 456 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 }, 461 460 ast::Storage::Classes{}, ast::Linkage::Cforall }; 462 461 463 462 // if expression type is a reference, just need an initializer, otherwise construct 464 463 if ( ! expr->result.as< ast::ReferenceType >() ) { 465 464 // resolve ctor/dtor for the new object 466 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 465 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 467 466 InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms ); 468 467 // remove environments from subexpressions of stmtExpr … … 475 474 } 476 475 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 480 479 ) { 481 480 assert( left ); … … 487 486 args.front() = new ast::AddressExpr{ location, args.front() }; 488 487 if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; } 489 return new ast::UntypedExpr{ 488 return new ast::UntypedExpr{ 490 489 location, new ast::NameExpr{ location, "?=?" }, std::move(args) }; 491 490 } else { 492 return new ast::UntypedExpr{ 491 return new ast::UntypedExpr{ 493 492 location, new ast::NameExpr{ location, fname }, std::move(args) }; 494 493 } … … 499 498 struct MassAssignMatcher final : public Matcher { 500 499 MassAssignMatcher( 501 TupleAssignSpotter_new & s, const CodeLocation & loc, 500 TupleAssignSpotter_new & s, const CodeLocation & loc, 502 501 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 503 502 : Matcher( s, loc, l, r ) {} … … 509 508 assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 ); 510 509 511 ast::ptr< ast::ObjectDecl > rtmp = 510 ast::ptr< ast::ObjectDecl > rtmp = 512 511 rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr; 513 512 514 513 std::vector< ast::ptr< ast::Expr > > out; 515 514 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 517 516 // involving the RHS 518 517 ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr ); … … 529 528 struct MultipleAssignMatcher final : public Matcher { 530 529 MultipleAssignMatcher( 531 TupleAssignSpotter_new & s, const CodeLocation & loc, 530 TupleAssignSpotter_new & s, const CodeLocation & loc, 532 531 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 533 532 : Matcher( s, loc, l, r ) {} … … 539 538 if ( lhs.size() != rhs.size() ) return {}; 540 539 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 542 541 // create the calls 543 542 std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp; … … 548 547 ResolvExpr::CandidateRef & rhsCand = rhs[i]; 549 548 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 551 550 // is && and RHS is lvalue 552 551 auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >(); … … 558 557 rtmp.emplace_back( std::move( robj ) ); 559 558 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 561 560 // type as needed, and transfer the resulting environment 562 561 ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env }; … … 565 564 env = std::move( finder.candidates.front()->env ); 566 565 } 567 566 568 567 splice( tmpDecls, ltmp ); 569 568 splice( tmpDecls, rtmp ); 570 569 571 570 return out; 572 571 } … … 576 575 std::string fname; 577 576 std::unique_ptr< Matcher > matcher; 578 577 579 578 public: 580 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 579 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 581 580 : crntFinder( f ), fname(), matcher() {} 582 581 583 582 // 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 586 585 ) { 587 586 if ( auto op = expr->func.as< ast::NameExpr >() ) { … … 600 599 if ( ! refToTuple( lhsCand->expr ) ) continue; 601 600 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 603 602 // reference cast 604 603 if ( ! lhsCand->expr.as< ast::CastExpr >() ) { 605 lhsCand->expr = new ast::CastExpr{ 604 lhsCand->expr = new ast::CastExpr{ 606 605 lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } }; 607 606 } … … 611 610 explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true ); 612 611 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 614 613 // just cast to reference here 615 614 if ( ! cand->expr->result.as< ast::ReferenceType >() ) { … … 630 629 // multiple assignment 631 630 explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true ); 632 matcher.reset( 631 matcher.reset( 633 632 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 634 633 } else { 635 634 // mass assignment 636 635 rhs.emplace_back( rhsCand ); 637 matcher.reset( 636 matcher.reset( 638 637 new MassAssignMatcher{ *this, expr->location, lhs, rhs } ); 639 638 } … … 643 642 // expand all possible RHS possibilities 644 643 std::vector< ResolvExpr::CandidateList > rhsCands; 645 combos( 644 combos( 646 645 std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) ); 647 646 for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) { … … 649 648 ResolvExpr::CandidateList rhs; 650 649 explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true ); 651 matcher.reset( 650 matcher.reset( 652 651 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 653 652 match(); … … 664 663 665 664 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 668 667 // candidates are generated 669 668 if ( newAssigns.empty() ) return; … … 693 692 } 694 693 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 696 695 // that together form a sigle candidate 697 696 std::vector< ast::ptr< ast::Expr > > solved; … … 702 701 703 702 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 ), 707 706 ResolvExpr::sumCost( crnt ) + matcher->baseCost ) ); 708 707 } … … 710 709 } // anonymous namespace 711 710 712 void handleTupleAssignment( 713 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 711 void handleTupleAssignment( 712 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 714 713 std::vector< ResolvExpr::CandidateFinder > & args 715 714 ) { -
src/main.cc
r4eb43fa rf6cc734e 460 460 const char * descript; 461 461 } 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" }, 464 472 { "declstats", declstatsp, true, "code property statistics" }, 465 473 { "parse", yydebug, true, "yacc (parsing) debug information" }, 466 474 { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" }, 475 { "resolver", bresolvep, true, "before resolver step" }, 467 476 { "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" }, 482 481 }; 483 482 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) }; -
tests/.expect/completeTypeError.txt
r4eb43fa rf6cc734e 27 27 void 28 28 ) 29 Environment:( _8 3_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) 30 30 31 31 … … 50 50 void 51 51 ) 52 Environment:( _8 3_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) 53 53 54 54 … … 127 127 void 128 128 ) 129 Environment:( _10 2_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) 130 130 131 131 Could not satisfy assertion: 132 132 ?=?: pointer to function 133 133 ... with parameters 134 reference to instance of type _10 2_0_T (not function type)135 instance of type _10 2_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) 136 136 ... returning 137 _retval__operator_assign: instance of type _10 2_0_T (not function type)137 _retval__operator_assign: instance of type _101_0_T (not function type) 138 138 ... with attributes: 139 139 Attribute with name: unused -
tests/loopctrl.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed Aug 8 18:32:59 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 12 12:05:05201913 // Update Count : 10 612 // Last Modified On : Sat Apr 13 11:03:09 2019 13 // Update Count : 104 14 14 // 15 15 … … 32 32 S ?-=?( S & t, one_t ) { t.i -= 1; t.j -= 1; return t; } 33 33 ofstream & ?|?( ofstream & os, S v ) { return os | '(' | v.i | v.j | ')'; } 34 void & ?|?( ofstream & os, S v ) { (ofstream &)(os | v); ends( os ); }34 void & ?|?( ofstream & os, S v ) { (ofstream &)(os | v); nl( os ); } 35 35 36 36 int main() { -
tests/math1.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Fri Apr 22 14:59:21 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 14 10:16:45201913 // Update Count : 1 1212 // Last Modified On : Mon Mar 25 22:56:47 2019 13 // Update Count : 109 14 14 // 15 15 … … 33 33 sout | quot | l; 34 34 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 ); 36 36 sout | "fdim:" | fdim( 1.0F, -1.0F ) | fdim( 1.0D, -1.0D ) | fdim( 1.0L, -1.0L ); 37 37 sout | "nan:" | (float)nan( "" ) | (double)nan( "" ) | (long double)nan( "" ); … … 59 59 S ?\?( S s, unsigned long y ) { return (S){ s.i \ y }; } 60 60 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 ); } 62 62 S s = { 4 }; 63 63 S x = s \ 2; -
tests/pybin/tools.py
r4eb43fa rf6cc734e 179 179 os.chdir(cwd) 180 180 181 def killgroup():182 try:183 os.killpg(os.getpgrp(), signal.SIGINT)184 except KeyboardInterrupt:185 pass # expected186 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 192 181 ################################################################################ 193 182 # file handling … … 312 301 self.end = time.time() 313 302 self.duration = self.end - self.start 314 315 def timed(src, timeout):316 expire = time.time() + timeout317 i = iter(src)318 while True:319 yield i.next(max(expire - time.time(), 0)) -
tests/sum.cfa
r4eb43fa rf6cc734e 11 11 // Created On : Wed May 27 17:56:53 2015 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : T ue Jul 16 09:51:37201914 // Update Count : 33 613 // Last Modified On : Thu Jun 6 16:18:22 2019 14 // Update Count : 333 15 15 // 16 16 … … 97 97 S ?++( S & t ) { S temp = t; t += (S){1}; return temp; } 98 98 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 ); } 100 100 101 101 S s = (S){0}, a[size], v = { low, low }; … … 184 184 S ?++( S & t ) { S temp = t; t += (S){1}; return temp; } 185 185 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 }; 189 189 for ( int i = 0; i < size; i += 1, v += (S){1} ) { 190 190 s += (S)v; -
tests/swap.cfa
r4eb43fa rf6cc734e 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 12 12:05:26 201913 // Update Count : 7 912 // Last Modified On : Sun Dec 23 23:00:49 2018 13 // Update Count : 77 14 14 // 15 15 … … 85 85 struct S { int i, j; } s1 = { 1, 2 }, s2 = { 2, 1 }; 86 86 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 ); } 88 88 sout | "struct S\t\t" | s1 | "," | s2 | "\t\tswap " | nonl; 89 89 swap( s1, s2 ); -
tests/test.py
r4eb43fa rf6cc734e 202 202 if error : 203 203 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 206 211 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 213 213 214 214 # run the given list of tests with the given parameters … … 220 220 pool = multiprocessing.Pool(jobs) 221 221 222 failed = False223 224 222 # for each test to run 225 223 try : 226 num = len(tests) 227 fancy = sys.stdout.isatty() 228 results = pool.imap_unordered( 224 results = pool.map_async( 229 225 run_test_worker, 230 226 tests, 231 227 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) 244 229 except KeyboardInterrupt: 245 print("Tests interrupted by user", file=sys.stderr)246 230 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) 256 233 257 234 # clean the workspace 258 235 make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL) 259 236 260 return 1 if failed else 0 237 for failed in results: 238 if failed : 239 return 1 240 241 return 0 261 242 262 243
Note:
See TracChangeset
for help on using the changeset viewer.