Changes in / [24d6572:34b4268]
- Files:
-
- 156 added
- 744 deleted
- 239 edited
-
Jenkins/FullBuild (modified) (5 diffs)
-
Jenkins/Promote (modified) (2 diffs)
-
Jenkinsfile (modified) (4 diffs)
-
Makefile.am (modified) (3 diffs)
-
benchmark/Makefile.am (modified) (5 diffs)
-
benchmark/convoy/data/nasus_12_12_2022_0NCS (deleted)
-
benchmark/convoy/data/nasus_12_12_2022_1NCS (deleted)
-
benchmark/convoy/data/single_16_thd (deleted)
-
benchmark/convoy/genConvoyStats.py (deleted)
-
benchmark/mutexStmt/JavaThread.java (added)
-
configure.ac (modified) (3 diffs)
-
doc/LaTeXmacros/common.sty (modified) (7 diffs)
-
doc/LaTeXmacros/common.tex (modified) (5 diffs)
-
doc/LaTeXmacros/lstlang.sty (modified) (2 diffs)
-
doc/bibliography/pl.bib (modified) (71 diffs)
-
doc/papers/llheap/.gitignore (deleted)
-
doc/papers/llheap/AMA-stix_New.zip (deleted)
-
doc/papers/llheap/AMA-stix_New/Documents/.log (deleted)
-
doc/papers/llheap/AMA-stix_New/Documents/README.txt (deleted)
-
doc/papers/llheap/AMA-stix_New/Documents/wileyNJD-Doc.tex (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/STIXGeneral-Bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/STIXGeneral-BoldItalic.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/STIXGeneral-Italic.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/STIXGeneral-Regular.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/Windows-Stix-fontinstaller.exe (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/a_axxd65.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls1stix.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls1stixbb.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls1stixfrak.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls1stixscr.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls1stixsf.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls2stix.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls2stixcal.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls2stixex.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ls2stixtt.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ly1sti.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneral-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneral-bolditalic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneral-italic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneral.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneralsc-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneralsc-bold.vf (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneralsc.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1-stixgeneralsc.vf (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot1stix.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneral-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneral-bolditalic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneral-italic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneral.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneralsc-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneralsc-bold.vf (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneralsc.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2-stixgeneralsc.vf (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ot2stix.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-extra1.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-extra1.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-extra2.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-extra2.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-extra3.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-extra3.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbb-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbb-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbb.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbb.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbbit-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbbit-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbbit.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathbbit.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathcal-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathcal-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathcal.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathcal.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathex-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathex-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathex.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathex.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathfrak-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathfrak-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathfrak.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathfrak.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathit-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathit-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathit.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathit.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathrm-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathrm-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathrm.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathrm.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathscr-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathscr-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathscr.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathscr.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsf-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsf-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsf.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsf.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsfit-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsfit-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsfit.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathsfit.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathtt-bold.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathtt-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathtt.pfb (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-mathtt.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-ot1.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-ot2.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-t1.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix-ts1.enc (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix.dtx (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix.fdd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix.map (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/stix.sty (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneral-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneral-bolditalic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneral-italic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneral.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneralsc-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneralsc-bold.vf (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneralsc.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1-stixgeneralsc.vf (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/t1stix.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ts1-stixgeneral-bold.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ts1-stixgeneral-bolditalic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ts1-stixgeneral-italic.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ts1-stixgeneral.tfm (deleted)
-
doc/papers/llheap/AMA-stix_New/Stix-fonts/ts1stix.fd (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/NJDnatbib.sty (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/WileyNJD-v2.cls (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/empty.eps (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.aux (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.bbl (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.bib (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.blg (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.log (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.pag (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.synctex (deleted)
-
doc/papers/llheap/AMA-stix_New/ama/wileyNJD-AMA.tex (deleted)
-
doc/papers/llheap/Makefile (deleted)
-
doc/papers/llheap/Paper.tex (deleted)
-
doc/papers/llheap/WileyNJD-v2.cls (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/cache_scratch_0-scratch.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/cache_thrash_0-thrash.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/churn.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-dl.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-glc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-hrd.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-je.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-llh.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-pt3.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-rp.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-1-prod-1-cons-100-tbb.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-dl.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-glc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-hrd.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-je.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-llh.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-pt3.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-rp.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/mem-4-prod-4-cons-100-tbb.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-1-malloc-null.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-10-malloc-realloc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-11-calloc-realloc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-12-malloc-realloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-13-calloc-realloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-14-m-c-re-alloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-2-free-null.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-3-malloc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-4-realloc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-5-free.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-6-calloc.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-7-malloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-8-realloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/algol-perf-eps/speed-9-calloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/cache_scratch_0-scratch.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/cache_thrash_0-thrash.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/churn.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-dl.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-glc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-hrd.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-je.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-llh.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-pt3.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-rp.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-1-prod-1-cons-100-tbb.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-dl.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-glc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-hrd.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-je.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-llh.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-pt3.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-rp.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/mem-4-prod-4-cons-100-tbb.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-1-malloc-null.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-10-malloc-realloc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-11-calloc-realloc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-12-malloc-realloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-13-calloc-realloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-14-m-c-re-alloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-2-free-null.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-3-malloc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-4-realloc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-5-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-6-calloc.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-7-malloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-8-realloc-free.eps (deleted)
-
doc/papers/llheap/evaluations/nasus-perf-eps/speed-9-calloc-free.eps (deleted)
-
doc/papers/llheap/examples/C++Cor-ts.cpp (deleted)
-
doc/papers/llheap/examples/DatingServiceThread.cfa (deleted)
-
doc/papers/llheap/examples/Fib.c (deleted)
-
doc/papers/llheap/examples/Fib.cfa (deleted)
-
doc/papers/llheap/examples/Fib.cpp (deleted)
-
doc/papers/llheap/examples/Fib.js (deleted)
-
doc/papers/llheap/examples/Fib.py (deleted)
-
doc/papers/llheap/examples/Fib.sim (deleted)
-
doc/papers/llheap/examples/Fib1.c (deleted)
-
doc/papers/llheap/examples/Fib2.c (deleted)
-
doc/papers/llheap/examples/Fib2.cfa (deleted)
-
doc/papers/llheap/examples/Fib2.cpp (deleted)
-
doc/papers/llheap/examples/Fib2.py (deleted)
-
doc/papers/llheap/examples/Fib3.c (deleted)
-
doc/papers/llheap/examples/Fib3.cc (deleted)
-
doc/papers/llheap/examples/FibRefactor.py (deleted)
-
doc/papers/llheap/examples/Fmt.sim (deleted)
-
doc/papers/llheap/examples/Format.c (deleted)
-
doc/papers/llheap/examples/Format.cc (deleted)
-
doc/papers/llheap/examples/Format.cfa (deleted)
-
doc/papers/llheap/examples/Format.cpp (deleted)
-
doc/papers/llheap/examples/Format.data (deleted)
-
doc/papers/llheap/examples/Format.js (deleted)
-
doc/papers/llheap/examples/Format.py (deleted)
-
doc/papers/llheap/examples/Format.sim (deleted)
-
doc/papers/llheap/examples/Format1.c (deleted)
-
doc/papers/llheap/examples/PingPong.c (deleted)
-
doc/papers/llheap/examples/PingPong.cc (deleted)
-
doc/papers/llheap/examples/Pingpong.cc (deleted)
-
doc/papers/llheap/examples/Pingpong.cfa (deleted)
-
doc/papers/llheap/examples/Pingpong.py (deleted)
-
doc/papers/llheap/examples/Pingpong2.cfa (deleted)
-
doc/papers/llheap/examples/ProdCons.cfa (deleted)
-
doc/papers/llheap/examples/ProdCons.cpp (deleted)
-
doc/papers/llheap/examples/ProdCons.py (deleted)
-
doc/papers/llheap/examples/ProdCons.sim (deleted)
-
doc/papers/llheap/examples/RWMonitorEXT.cfa (deleted)
-
doc/papers/llheap/examples/RWMonitorINT.cfa (deleted)
-
doc/papers/llheap/examples/Refactor.py (deleted)
-
doc/papers/llheap/examples/channels.go (deleted)
-
doc/papers/llheap/examples/channels.rs (deleted)
-
doc/papers/llheap/examples/counter.cpp (deleted)
-
doc/papers/llheap/examples/future.rs (deleted)
-
doc/papers/llheap/figures/AddressSpace.fig (deleted)
-
doc/papers/llheap/figures/Alignment1.fig (deleted)
-
doc/papers/llheap/figures/Alignment2.fig (deleted)
-
doc/papers/llheap/figures/Alignment2Impl.fig (deleted)
-
doc/papers/llheap/figures/AllocDS1.fig (deleted)
-
doc/papers/llheap/figures/AllocDS2.fig (deleted)
-
doc/papers/llheap/figures/AllocInducedActiveFalseSharing.fig (deleted)
-
doc/papers/llheap/figures/AllocInducedPassiveFalseSharing.fig (deleted)
-
doc/papers/llheap/figures/AllocatedObject.fig (deleted)
-
doc/papers/llheap/figures/AllocatorComponents.fig (deleted)
-
doc/papers/llheap/figures/AllocatorComponents.fig.bak (deleted)
-
doc/papers/llheap/figures/CoalesceAllocated.fig (deleted)
-
doc/papers/llheap/figures/CoalesceFree.fig (deleted)
-
doc/papers/llheap/figures/CondSigWait.fig (deleted)
-
doc/papers/llheap/figures/Container.fig (deleted)
-
doc/papers/llheap/figures/ContainerFalseSharing1.fig (deleted)
-
doc/papers/llheap/figures/ContainerFalseSharing2.fig (deleted)
-
doc/papers/llheap/figures/ContainerNoOwnership.fig (deleted)
-
doc/papers/llheap/figures/ContainerNoOwnershipFreelist.fig (deleted)
-
doc/papers/llheap/figures/ContainerOwnership.fig (deleted)
-
doc/papers/llheap/figures/ContainerOwnershipFreelist.fig (deleted)
-
doc/papers/llheap/figures/ContigFragmentation.fig (deleted)
-
doc/papers/llheap/figures/FakeHeader.fig (deleted)
-
doc/papers/llheap/figures/FreeListAmongContainers.fig (deleted)
-
doc/papers/llheap/figures/FreeListWithinContainers.fig (deleted)
-
doc/papers/llheap/figures/FullCoroutinePhases.fig (deleted)
-
doc/papers/llheap/figures/FullProdConsStack.fig (deleted)
-
doc/papers/llheap/figures/Header.fig (deleted)
-
doc/papers/llheap/figures/HeapStructure.fig (deleted)
-
doc/papers/llheap/figures/IntExtFragmentation.fig (deleted)
-
doc/papers/llheap/figures/MemoryFragmentation.fig (deleted)
-
doc/papers/llheap/figures/MultipleHeapsNoOwnership.fig (deleted)
-
doc/papers/llheap/figures/MultipleHeapsOwnership.fig (deleted)
-
doc/papers/llheap/figures/MultipleHeapsOwnershipStorage.fig (deleted)
-
doc/papers/llheap/figures/MultipleHeapsStorage.fig (deleted)
-
doc/papers/llheap/figures/NewHeapStructure.eps (deleted)
-
doc/papers/llheap/figures/NonContigFragmentation.fig (deleted)
-
doc/papers/llheap/figures/ObjectHeaders.fig (deleted)
-
doc/papers/llheap/figures/PerThreadHeap.fig (deleted)
-
doc/papers/llheap/figures/PrivatePublicHeaps.fig (deleted)
-
doc/papers/llheap/figures/ProgramFalseSharing.fig (deleted)
-
doc/papers/llheap/figures/RemoteFreeList.fig (deleted)
-
doc/papers/llheap/figures/RunTimeStructure.fig (deleted)
-
doc/papers/llheap/figures/SharedHeaps.fig (deleted)
-
doc/papers/llheap/figures/SingleHeap.fig (deleted)
-
doc/papers/llheap/figures/SuperContainers.fig (deleted)
-
doc/papers/llheap/figures/UserKernelHeaps.fig (deleted)
-
doc/papers/llheap/figures/llheap.fig (deleted)
-
doc/papers/llheap/local.bib (deleted)
-
doc/proposals/alt-enums.md (deleted)
-
doc/theses/colby_parsons_MMAth/.gitignore (deleted)
-
doc/theses/colby_parsons_MMAth/Makefile (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Executor/AkkaExecutor.scala (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Executor/application.conf (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Executor/build.sbt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Matrix/AkkaMatrix.scala (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Matrix/application.conf (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Matrix/build.sbt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Repeat/AkkaRepeat.scala (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Repeat/application.conf (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/Repeat/build.sbt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/SendDynamic/AkkaSendDynamic.scala (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/SendDynamic/application.conf (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/SendDynamic/build.sbt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/SendStatic/AkkaSendStatic.scala (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/SendStatic/application.conf (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/akka/SendStatic/build.sbt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/caf/CAFExecutor.cpp (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/caf/CAFMatrix.cpp (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/caf/CAFRepeat.cpp (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/caf/CAFSendDynamic.cpp (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/caf/CAFSendStatic.cpp (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/caf/caf-application.conf (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/balance.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/bench.hfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/dynamic.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/executor.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/matrix.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/repeat.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/cfa/static.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/nasusSendDynamic (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/nasusSendStatic (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/nasus_ALL.txt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/nasus_CFA.txt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/nasus_SEND.txt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/pykeSendDynamic (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/pykeSendStatic (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/pyke_ALL.txt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/pyke_CFA.txt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/data/pyke_SEND.txt (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/genPlots (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/plotData.py (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Executor/GoExecutor.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Executor/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Executor/go.sum (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/INSTALL (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Matrix/GoMatrix.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Matrix/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Matrix/go.sum (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Repeat/GoRepeat.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Repeat/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/Repeat/go.sum (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/SendDynamic/GoSendDynamic.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/SendDynamic/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/SendDynamic/go.sum (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/SendStatic/GoSendStatic.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/SendStatic/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/proto/SendStatic/go.sum (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/run (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/ucpp/uC++Executor.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/ucpp/uC++Matrix.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/ucpp/uC++Repeat.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/ucpp/uC++SendDynamic.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/actors/ucpp/uC++SendStatic.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/barrier.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/churn.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/contend.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/daisy_chain.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/hot_potato.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/ping_pong.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/cfa/pub_sub.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/barrier.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/churn.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/contend.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/daisy_chain.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/hot_potato.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/ping_pong.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/pub_sub.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/plotData.py (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/channels/run (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/bench.h (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cfa/baseline.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cfa/order.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cfa/rand.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cpp/baseline.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cpp/cppLock.hpp (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cpp/order.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cpp/rand.cc (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/plotData.py (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/run (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/contend.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/future.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/sidechan.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/spin.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend/contend.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend2/contend.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend2/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend4/contend.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend4/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend8/contend.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/contend8/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/sidechan/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/sidechan/sidechan.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin/spin.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin2/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin2/spin.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin4/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin4/spin.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin8/go.mod (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/go/spin8/spin.go (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/run (deleted)
-
doc/theses/colby_parsons_MMAth/benchmarks/waituntil/ucpp/future.cc (deleted)
-
doc/theses/colby_parsons_MMAth/code/basic_actor_example.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/code/swap_queues.cfa (deleted)
-
doc/theses/colby_parsons_MMAth/data/nasusExecutorMem (deleted)
-
doc/theses/colby_parsons_MMAth/data/nasusSendDynamic (deleted)
-
doc/theses/colby_parsons_MMAth/data/nasusSendStatic (deleted)
-
doc/theses/colby_parsons_MMAth/data/pykeExecutorMem (deleted)
-
doc/theses/colby_parsons_MMAth/data/pykeSendDynamic (deleted)
-
doc/theses/colby_parsons_MMAth/data/pykeSendStatic (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/M_to_one_swap.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/acyclic_swap.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/chain_swap.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/cyclic_swap.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/gulp.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/inverted_actor.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/diagrams/standard_actor.tikz (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusCFABalance-Multi.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusCFABalance-One.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusCFAExecutor.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusCFAMatrix.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusCFARepeat.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusExecutor.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusMatrix.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasusRepeat.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasus_Aggregate_Lock_2.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasus_Aggregate_Lock_4.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasus_Aggregate_Lock_8.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/nasus_Channel_Contention.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeCFABalance-Multi.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeCFABalance-One.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeCFAExecutor.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeCFAMatrix.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeCFARepeat.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeExecutor.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeMatrix.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pykeRepeat.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pyke_Aggregate_Lock_2.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pyke_Aggregate_Lock_4.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pyke_Aggregate_Lock_8.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/figures/pyke_Channel_Contention.pgf (deleted)
-
doc/theses/colby_parsons_MMAth/glossary.tex (deleted)
-
doc/theses/colby_parsons_MMAth/local.bib (deleted)
-
doc/theses/colby_parsons_MMAth/style/style.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/CFA_concurrency.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/CFA_intro.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/actors.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/channels.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/frontpgs.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/intro.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/mutex_stmt.tex (deleted)
-
doc/theses/colby_parsons_MMAth/text/waituntil.tex (deleted)
-
doc/theses/colby_parsons_MMAth/thesis.tex (deleted)
-
doc/theses/mike_brooks_MMath/Makefile (modified) (5 diffs)
-
doc/theses/mike_brooks_MMath/benchmarks/list/.gitignore (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/Makefile (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/_classic.c (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/driver.c (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/expect.queue-insfirst.txt (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/expect.queue-inslast.txt (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/expect.stack-insfirst.txt (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/expect.stack-inslast.txt (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/fx-cfa-cfa.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/fx-cpp-stlref.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/fx-lq-list.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/fx-lq-tailq.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/fx-upp-upp.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/observation.c (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/observation.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-queue-insfirst-allhead.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-queue-insfirst-inselem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-queue-insfirst-remelem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-queue-inslast-allhead.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-queue-inslast-inselem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-queue-inslast-remelem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-stack-insfirst-allhead.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-stack-insfirst-inselem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-stack-insfirst-remelem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-stack-inslast-allhead.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-stack-inslast-inselem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/op-stack-inslast-remelem.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/proglang.h (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/results-baseline.csv (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/results-sizing.csv (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/tailq-bug.c (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/test-correctness-regenerate-expected.sh (deleted)
-
doc/theses/mike_brooks_MMath/benchmarks/list/test-correctness.sh (deleted)
-
doc/theses/mike_brooks_MMath/list.tex (deleted)
-
doc/theses/mike_brooks_MMath/pictures/lst-issues-attach.pdf (deleted)
-
doc/theses/mike_brooks_MMath/pictures/lst-issues-attach.vsdx (deleted)
-
doc/theses/mike_brooks_MMath/pictures/lst-issues-direct.pdf (deleted)
-
doc/theses/mike_brooks_MMath/pictures/lst-issues-direct.vsdx (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-features-intro.run.cfa (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-features-multidir.run.cfa (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-attach-reduction-byref.run.cpp (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-attach-reduction-emplaced.run.cpp (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-attach-reduction.hpp (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-intrusive.run.c (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-multi-static.run.c (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-wrapped-byref.run.cpp (deleted)
-
doc/theses/mike_brooks_MMath/programs/lst-issues-wrapped-emplaced.run.cpp (deleted)
-
doc/theses/mike_brooks_MMath/uw-ethesis.bib (modified) (1 diff)
-
doc/theses/mike_brooks_MMath/uw-ethesis.tex (modified) (6 diffs)
-
driver/cfa.cc (modified) (6 diffs)
-
libcfa/configure.ac (modified) (2 diffs)
-
libcfa/prelude/builtins.c (modified) (4 diffs)
-
libcfa/prelude/prelude-gen.cc (modified) (2 diffs)
-
libcfa/src/Makefile.am (modified) (5 diffs)
-
libcfa/src/algorithms/range_iterator.hfa (modified) (1 diff)
-
libcfa/src/bitmanip.hfa (modified) (1 diff)
-
libcfa/src/bits/containers.hfa (modified) (2 diffs)
-
libcfa/src/bits/random.hfa (modified) (17 diffs)
-
libcfa/src/bits/weakso_locks.cfa (modified) (2 diffs)
-
libcfa/src/bits/weakso_locks.hfa (modified) (4 diffs)
-
libcfa/src/common.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/actor.hfa (deleted)
-
libcfa/src/concurrency/atomic.hfa (deleted)
-
libcfa/src/concurrency/channel.hfa (deleted)
-
libcfa/src/concurrency/clib/cfathread.cfa (modified) (8 diffs)
-
libcfa/src/concurrency/clib/cfathread.h (modified) (3 diffs)
-
libcfa/src/concurrency/coroutine.cfa (modified) (1 diff)
-
libcfa/src/concurrency/coroutine.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/future.hfa (modified) (5 diffs)
-
libcfa/src/concurrency/invoke.h (modified) (2 diffs)
-
libcfa/src/concurrency/io.cfa (modified) (28 diffs)
-
libcfa/src/concurrency/io/call.cfa.in (modified) (11 diffs)
-
libcfa/src/concurrency/io/setup.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/io/types.hfa (modified) (5 diffs)
-
libcfa/src/concurrency/iofwd.hfa (modified) (5 diffs)
-
libcfa/src/concurrency/kernel.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel/cluster.cfa (modified) (5 diffs)
-
libcfa/src/concurrency/kernel/cluster.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel/private.hfa (modified) (3 diffs)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/locks.cfa (modified) (16 diffs)
-
libcfa/src/concurrency/locks.hfa (modified) (31 diffs)
-
libcfa/src/concurrency/monitor.cfa (modified) (1 diff)
-
libcfa/src/concurrency/monitor.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/mutex.cfa (modified) (1 diff)
-
libcfa/src/concurrency/mutex.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/mutex_stmt.hfa (modified) (4 diffs)
-
libcfa/src/concurrency/preemption.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/pthread.cfa (modified) (37 diffs)
-
libcfa/src/concurrency/ready_queue.cfa (modified) (1 diff)
-
libcfa/src/concurrency/select.cfa (deleted)
-
libcfa/src/concurrency/select.hfa (deleted)
-
libcfa/src/concurrency/thread.cfa (modified) (4 diffs)
-
libcfa/src/concurrency/thread.hfa (modified) (2 diffs)
-
libcfa/src/containers/array.hfa (modified) (1 diff)
-
libcfa/src/containers/list.hfa (modified) (3 diffs)
-
libcfa/src/containers/vector.hfa (modified) (2 diffs)
-
libcfa/src/containers/vector2.hfa (modified) (1 diff)
-
libcfa/src/exception.h (modified) (3 diffs)
-
libcfa/src/heap.cfa (modified) (21 diffs)
-
libcfa/src/interpose.cfa (modified) (5 diffs)
-
libcfa/src/interpose_thread.cfa (modified) (3 diffs)
-
libcfa/src/iostream.cfa (modified) (2 diffs)
-
libcfa/src/iostream.hfa (modified) (7 diffs)
-
libcfa/src/iterator.hfa (modified) (3 diffs)
-
libcfa/src/limits.cfa (modified) (1 diff)
-
libcfa/src/math.trait.hfa (modified) (6 diffs)
-
libcfa/src/stdlib.cfa (modified) (2 diffs)
-
libcfa/src/stdlib.hfa (modified) (3 diffs)
-
libcfa/src/vec/vec.hfa (modified) (1 diff)
-
libcfa/src/virtual_dtor.hfa (deleted)
-
src/AST/Attribute.hpp (modified) (1 diff)
-
src/AST/Convert.cpp (modified) (8 diffs)
-
src/AST/Create.cpp (modified) (1 diff)
-
src/AST/Decl.cpp (modified) (3 diffs)
-
src/AST/Decl.hpp (modified) (6 diffs)
-
src/AST/Expr.cpp (modified) (1 diff)
-
src/AST/Expr.hpp (modified) (4 diffs)
-
src/AST/Fwd.hpp (modified) (3 diffs)
-
src/AST/Init.hpp (modified) (1 diff)
-
src/AST/Inspect.cpp (modified) (2 diffs)
-
src/AST/Inspect.hpp (modified) (2 diffs)
-
src/AST/Node.cpp (modified) (1 diff)
-
src/AST/Node.hpp (modified) (2 diffs)
-
src/AST/ParseNode.hpp (modified) (1 diff)
-
src/AST/Pass.hpp (modified) (4 diffs)
-
src/AST/Pass.impl.hpp (modified) (10 diffs)
-
src/AST/Pass.proto.hpp (modified) (1 diff)
-
src/AST/Print.cpp (modified) (16 diffs)
-
src/AST/Print.hpp (modified) (2 diffs)
-
src/AST/Stmt.hpp (modified) (7 diffs)
-
src/AST/SymbolTable.cpp (modified) (10 diffs)
-
src/AST/SymbolTable.hpp (modified) (1 diff)
-
src/AST/TranslationUnit.hpp (modified) (3 diffs)
-
src/AST/Type.cpp (modified) (2 diffs)
-
src/AST/Type.hpp (modified) (3 diffs)
-
src/AST/TypeEnvironment.cpp (modified) (10 diffs)
-
src/AST/TypeEnvironment.hpp (modified) (5 diffs)
-
src/AST/TypeSubstitution.cpp (modified) (3 diffs)
-
src/AST/TypeSubstitution.hpp (modified) (4 diffs)
-
src/AST/Visitor.hpp (modified) (1 diff)
-
src/AST/porting.md (modified) (3 diffs)
-
src/CodeGen/CodeGenerator.cc (modified) (2 diffs)
-
src/CodeGen/GenType.cc (modified) (1 diff)
-
src/Common/CodeLocationTools.cpp (modified) (3 diffs)
-
src/Common/CompilerError.h (added)
-
src/Common/Debug.h (added)
-
src/Common/DeclStats.cpp (modified) (1 diff)
-
src/Common/Eval.cc (modified) (2 diffs)
-
src/Common/Eval.h (deleted)
-
src/Common/Iterate.hpp (deleted)
-
src/Common/ResolvProtoDump.cpp (modified) (2 diffs)
-
src/Common/ScopedMap.h (modified) (6 diffs)
-
src/Common/SemanticError.h (modified) (3 diffs)
-
src/Common/ToString.hpp (deleted)
-
src/Common/UnimplementedError.h (added)
-
src/Common/module.mk (modified) (3 diffs)
-
src/Common/utility.h (modified) (7 diffs)
-
src/CompilationState.cc (modified) (3 diffs)
-
src/CompilationState.h (modified) (3 diffs)
-
src/Concurrency/Actors.cpp (deleted)
-
src/Concurrency/Actors.hpp (deleted)
-
src/Concurrency/KeywordsNew.cpp (modified) (1 diff)
-
src/Concurrency/WaitforNew.cpp (modified) (2 diffs)
-
src/Concurrency/Waituntil.cpp (deleted)
-
src/Concurrency/Waituntil.hpp (deleted)
-
src/Concurrency/module.mk (modified) (2 diffs)
-
src/ControlStruct/ExceptDeclNew.cpp (modified) (1 diff)
-
src/ControlStruct/ExceptTranslateNew.cpp (modified) (1 diff)
-
src/ControlStruct/MLEMutator.cc (modified) (1 diff)
-
src/GenPoly/Box.cc (modified) (44 diffs)
-
src/GenPoly/ErasableScopedMap.h (modified) (4 diffs)
-
src/GenPoly/FindFunction.cc (modified) (3 diffs)
-
src/GenPoly/FindFunction.h (modified) (2 diffs)
-
src/GenPoly/GenPoly.cc (modified) (10 diffs)
-
src/GenPoly/GenPoly.h (modified) (1 diff)
-
src/GenPoly/InstantiateGeneric.cc (modified) (1 diff)
-
src/GenPoly/InstantiateGenericNew.cpp (modified) (2 diffs)
-
src/GenPoly/Lvalue.cc (modified) (1 diff)
-
src/GenPoly/LvalueNew.cpp (modified) (5 diffs)
-
src/GenPoly/ScopedSet.h (modified) (1 diff)
-
src/GenPoly/ScrubTyVars.cc (modified) (5 diffs)
-
src/GenPoly/ScrubTyVars.h (modified) (5 diffs)
-
src/GenPoly/SpecializeNew.cpp (modified) (1 diff)
-
src/InitTweak/FixInit.cc (modified) (3 diffs)
-
src/InitTweak/FixInitNew.cpp (modified) (12 diffs)
-
src/InitTweak/GenInit.cc (modified) (2 diffs)
-
src/InitTweak/InitTweak.cc (modified) (2 diffs)
-
src/MakeLibCfaNew.cpp (modified) (1 diff)
-
src/Parser/DeclarationNode.cc (modified) (45 diffs)
-
src/Parser/DeclarationNode.h (deleted)
-
src/Parser/ExpressionNode.cc (modified) (19 diffs)
-
src/Parser/ExpressionNode.h (deleted)
-
src/Parser/InitializerNode.cc (modified) (4 diffs)
-
src/Parser/InitializerNode.h (deleted)
-
src/Parser/ParseNode.h (modified) (5 diffs)
-
src/Parser/ParserTypes.h (modified) (1 diff)
-
src/Parser/RunParser.cpp (deleted)
-
src/Parser/RunParser.hpp (deleted)
-
src/Parser/StatementNode.cc (modified) (8 diffs)
-
src/Parser/StatementNode.h (deleted)
-
src/Parser/TypeData.cc (modified) (47 diffs)
-
src/Parser/TypeData.h (modified) (5 diffs)
-
src/Parser/TypedefTable.cc (modified) (2 diffs)
-
src/Parser/TypedefTable.h (modified) (2 diffs)
-
src/Parser/lex.ll (modified) (7 diffs)
-
src/Parser/module.mk (modified) (2 diffs)
-
src/Parser/parser.yy (modified) (150 diffs)
-
src/Parser/parserutility.cc (modified) (3 diffs)
-
src/Parser/parserutility.h (modified) (1 diff)
-
src/ResolvExpr/AdjustExprType.hpp (deleted)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (3 diffs)
-
src/ResolvExpr/AlternativeFinder.h (modified) (1 diff)
-
src/ResolvExpr/Candidate.cpp (modified) (2 diffs)
-
src/ResolvExpr/CandidateFinder.cpp (modified) (11 diffs)
-
src/ResolvExpr/CandidateFinder.hpp (modified) (1 diff)
-
src/ResolvExpr/CastCost.cc (modified) (4 diffs)
-
src/ResolvExpr/CastCost.hpp (deleted)
-
src/ResolvExpr/CommonType.cc (modified) (22 diffs)
-
src/ResolvExpr/CommonType.hpp (deleted)
-
src/ResolvExpr/ConversionCost.cc (modified) (5 diffs)
-
src/ResolvExpr/ConversionCost.h (modified) (3 diffs)
-
src/ResolvExpr/CurrentObject.cc (modified) (9 diffs)
-
src/ResolvExpr/CurrentObject.h (modified) (2 diffs)
-
src/ResolvExpr/ExplodedArg.hpp (modified) (1 diff)
-
src/ResolvExpr/PolyCost.cc (modified) (1 diff)
-
src/ResolvExpr/PolyCost.hpp (deleted)
-
src/ResolvExpr/PtrsAssignable.cc (modified) (1 diff)
-
src/ResolvExpr/PtrsAssignable.hpp (deleted)
-
src/ResolvExpr/PtrsCastable.cc (modified) (4 diffs)
-
src/ResolvExpr/PtrsCastable.hpp (deleted)
-
src/ResolvExpr/RenameVars.cc (modified) (2 diffs)
-
src/ResolvExpr/ResolveAssertions.cc (modified) (1 diff)
-
src/ResolvExpr/Resolver.cc (modified) (6 diffs)
-
src/ResolvExpr/Resolver.h (modified) (1 diff)
-
src/ResolvExpr/SatisfyAssertions.cpp (modified) (5 diffs)
-
src/ResolvExpr/SpecCost.hpp (deleted)
-
src/ResolvExpr/Unify.cc (modified) (37 diffs)
-
src/ResolvExpr/Unify.h (modified) (2 diffs)
-
src/ResolvExpr/WidenMode.h (modified) (2 diffs)
-
src/ResolvExpr/module.mk (modified) (4 diffs)
-
src/ResolvExpr/typeops.h (modified) (7 diffs)
-
src/SymTab/Autogen.cc (modified) (4 diffs)
-
src/SymTab/Autogen.h (modified) (8 diffs)
-
src/SymTab/FixFunction.cc (modified) (1 diff)
-
src/SymTab/GenImplicitCall.cpp (deleted)
-
src/SymTab/GenImplicitCall.hpp (deleted)
-
src/SymTab/Indexer.cc (modified) (1 diff)
-
src/SymTab/Mangler.cc (modified) (6 diffs)
-
src/SymTab/Validate.cc (modified) (3 diffs)
-
src/SymTab/ValidateType.cc (modified) (1 diff)
-
src/SymTab/module.mk (modified) (1 diff)
-
src/SynTree/AggregateDecl.cc (modified) (1 diff)
-
src/SynTree/ApplicationExpr.cc (modified) (2 diffs)
-
src/SynTree/BasicType.cc (modified) (1 diff)
-
src/SynTree/FunctionDecl.cc (modified) (1 diff)
-
src/SynTree/Type.cc (modified) (2 diffs)
-
src/SynTree/Type.h (modified) (39 diffs)
-
src/Tuples/Explode.cc (modified) (1 diff)
-
src/Validate/Autogen.cpp (modified) (10 diffs)
-
src/Validate/FixQualifiedTypes.cpp (modified) (1 diff)
-
src/Validate/FixReturnTypes.cpp (modified) (1 diff)
-
src/Validate/ForallPointerDecay.cpp (modified) (1 diff)
-
src/Validate/GenericParameter.cpp (modified) (1 diff)
-
src/Validate/HandleAttributes.cc (modified) (1 diff)
-
src/Validate/HoistStruct.cpp (modified) (1 diff)
-
src/Validate/ReplaceTypedef.cpp (modified) (3 diffs)
-
src/Virtual/ExpandCasts.cc (modified) (1 diff)
-
src/Virtual/VirtualDtor.cpp (deleted)
-
src/Virtual/VirtualDtor.hpp (deleted)
-
src/Virtual/module.mk (modified) (1 diff)
-
src/include/cassert (modified) (1 diff)
-
src/main.cc (modified) (22 diffs)
-
tests/.expect/PRNG.x64.txt (modified) (1 diff)
-
tests/.expect/PRNG.x86.txt (modified) (1 diff)
-
tests/.expect/alloc.txt.old (added)
-
tests/.expect/array-ERR1.txt (deleted)
-
tests/.expect/array-ERR2.txt (deleted)
-
tests/.expect/array-ERR3.txt (deleted)
-
tests/.expect/array.txt (modified) (1 diff)
-
tests/.expect/attributes.arm64.txt (modified) (2 diffs)
-
tests/.expect/attributes.x64.txt (modified) (2 diffs)
-
tests/.expect/attributes.x86.txt (modified) (2 diffs)
-
tests/.expect/declarationSpecifier.arm64.txt (modified) (18 diffs)
-
tests/.expect/declarationSpecifier.x64.txt (modified) (18 diffs)
-
tests/.expect/declarationSpecifier.x86.txt (modified) (18 diffs)
-
tests/.expect/forall.txt (modified) (1 diff)
-
tests/.expect/nested_function.x64.txt (modified) (1 diff)
-
tests/.expect/nested_function.x86.txt (modified) (1 diff)
-
tests/Makefile.am (modified) (14 diffs)
-
tests/PRNG.cfa (modified) (19 diffs)
-
tests/array.cfa (modified) (1 diff)
-
tests/attributes.cfa (modified) (2 diffs)
-
tests/avltree/avl.h (modified) (1 diff)
-
tests/collections/vector-demo.cfa (modified) (1 diff)
-
tests/concurrency/.expect/clib.txt (deleted)
-
tests/concurrency/.expect/clib_tls.txt (deleted)
-
tests/concurrency/.expect/cluster.txt (deleted)
-
tests/concurrency/.expect/coroutineYield.txt (deleted)
-
tests/concurrency/.expect/ctor-check.txt (deleted)
-
tests/concurrency/.expect/join.txt (deleted)
-
tests/concurrency/.expect/joinerror.sed (deleted)
-
tests/concurrency/.expect/keywordErrors.txt (deleted)
-
tests/concurrency/.expect/lockfree_stack.txt (deleted)
-
tests/concurrency/.expect/mainError.txt (deleted)
-
tests/concurrency/.expect/migrate.txt (deleted)
-
tests/concurrency/.expect/monitor.txt (deleted)
-
tests/concurrency/.expect/multi-monitor.txt (deleted)
-
tests/concurrency/.expect/once.txt (deleted)
-
tests/concurrency/.expect/preempt.txt (deleted)
-
tests/concurrency/.expect/preempt2.txt (deleted)
-
tests/concurrency/.expect/sleep.txt (deleted)
-
tests/concurrency/.expect/suspend_then.txt (deleted)
-
tests/concurrency/.expect/thread.txt (deleted)
-
tests/concurrency/actors/.expect/dynamic.txt (deleted)
-
tests/concurrency/actors/.expect/executor.txt (deleted)
-
tests/concurrency/actors/.expect/inherit.txt (deleted)
-
tests/concurrency/actors/.expect/matrix.txt (deleted)
-
tests/concurrency/actors/.expect/pingpong.txt (deleted)
-
tests/concurrency/actors/.expect/poison.txt (deleted)
-
tests/concurrency/actors/.expect/static.txt (deleted)
-
tests/concurrency/actors/.expect/types.txt (deleted)
-
tests/concurrency/actors/dynamic.cfa (deleted)
-
tests/concurrency/actors/executor.cfa (deleted)
-
tests/concurrency/actors/inherit.cfa (deleted)
-
tests/concurrency/actors/matrix.cfa (deleted)
-
tests/concurrency/actors/pingpong.cfa (deleted)
-
tests/concurrency/actors/poison.cfa (deleted)
-
tests/concurrency/actors/static.cfa (deleted)
-
tests/concurrency/actors/types.cfa (deleted)
-
tests/concurrency/barrier/.expect/generation.txt (deleted)
-
tests/concurrency/barrier/.expect/last.txt (deleted)
-
tests/concurrency/barrier/.expect/order.txt (deleted)
-
tests/concurrency/barrier/gen_generation_expect.cfa (deleted)
-
tests/concurrency/barrier/generation.cfa (deleted)
-
tests/concurrency/barrier/last.cfa (deleted)
-
tests/concurrency/barrier/order.cfa (deleted)
-
tests/concurrency/channels/.expect/big_elems.txt (deleted)
-
tests/concurrency/channels/.expect/churn.txt (deleted)
-
tests/concurrency/channels/.expect/contend.txt (deleted)
-
tests/concurrency/channels/.expect/daisy_chain.txt (deleted)
-
tests/concurrency/channels/.expect/hot_potato.txt (deleted)
-
tests/concurrency/channels/.expect/ping_pong.txt (deleted)
-
tests/concurrency/channels/.expect/pub_sub.txt (deleted)
-
tests/concurrency/channels/.expect/zero_size.txt (deleted)
-
tests/concurrency/channels/barrier.cfa (deleted)
-
tests/concurrency/channels/big_elems.cfa (deleted)
-
tests/concurrency/channels/churn.cfa (deleted)
-
tests/concurrency/channels/contend.cfa (deleted)
-
tests/concurrency/channels/daisy_chain.cfa (deleted)
-
tests/concurrency/channels/hot_potato.cfa (deleted)
-
tests/concurrency/channels/parallel_harness.hfa (deleted)
-
tests/concurrency/channels/ping_pong.cfa (deleted)
-
tests/concurrency/channels/pub_sub.cfa (deleted)
-
tests/concurrency/channels/zero_size.cfa (deleted)
-
tests/concurrency/clib.c (deleted)
-
tests/concurrency/clib_tls.c (deleted)
-
tests/concurrency/cluster.cfa (deleted)
-
tests/concurrency/coroutineYield.cfa (deleted)
-
tests/concurrency/ctor-check.cfa (deleted)
-
tests/concurrency/examples/.expect/boundedBufferEXT.txt (deleted)
-
tests/concurrency/examples/.expect/boundedBufferINT.txt (deleted)
-
tests/concurrency/examples/.expect/datingService.txt (deleted)
-
tests/concurrency/examples/.expect/gortn.txt (deleted)
-
tests/concurrency/examples/.expect/matrixSum.txt (deleted)
-
tests/concurrency/examples/.expect/quickSort.txt (deleted)
-
tests/concurrency/examples/.in/quickSort.txt (deleted)
-
tests/concurrency/examples/boundedBufferEXT.cfa (deleted)
-
tests/concurrency/examples/boundedBufferINT.cfa (deleted)
-
tests/concurrency/examples/boundedBufferTHREAD.cfa (deleted)
-
tests/concurrency/examples/datingService.cfa (deleted)
-
tests/concurrency/examples/gortn.cfa (deleted)
-
tests/concurrency/examples/matrixSum.cfa (deleted)
-
tests/concurrency/examples/multiSort.cfa (deleted)
-
tests/concurrency/examples/quickSort.cfa (deleted)
-
tests/concurrency/examples/quickSort.generic.cfa (deleted)
-
tests/concurrency/futures/.expect/abandon.txt (deleted)
-
tests/concurrency/futures/.expect/basic.txt (deleted)
-
tests/concurrency/futures/.expect/multi.txt (deleted)
-
tests/concurrency/futures/.expect/select_future.txt (deleted)
-
tests/concurrency/futures/.expect/typed.txt (deleted)
-
tests/concurrency/futures/.expect/wait_any.txt (deleted)
-
tests/concurrency/futures/abandon.cfa (deleted)
-
tests/concurrency/futures/basic.cfa (deleted)
-
tests/concurrency/futures/multi.cfa (deleted)
-
tests/concurrency/futures/select_future.cfa (deleted)
-
tests/concurrency/futures/typed.cfa (deleted)
-
tests/concurrency/futures/wait_any.cfa (deleted)
-
tests/concurrency/join.cfa (deleted)
-
tests/concurrency/joinerror.cfa (deleted)
-
tests/concurrency/keywordErrors.cfa (deleted)
-
tests/concurrency/lockfree_stack.cfa (deleted)
-
tests/concurrency/mainError.cfa (deleted)
-
tests/concurrency/migrate.cfa (deleted)
-
tests/concurrency/monitor.cfa (deleted)
-
tests/concurrency/multi-monitor.cfa (deleted)
-
tests/concurrency/mutexstmt/.expect/locks.txt (deleted)
-
tests/concurrency/mutexstmt/.expect/monitors.txt (deleted)
-
tests/concurrency/mutexstmt/locks.cfa (deleted)
-
tests/concurrency/mutexstmt/monitors.cfa (deleted)
-
tests/concurrency/once.cfa (deleted)
-
tests/concurrency/park/.expect/contention.txt (deleted)
-
tests/concurrency/park/.expect/force_preempt.txt (deleted)
-
tests/concurrency/park/.expect/start_parked.txt (deleted)
-
tests/concurrency/park/contention.cfa (deleted)
-
tests/concurrency/park/force_preempt.cfa (deleted)
-
tests/concurrency/park/start_parked.cfa (deleted)
-
tests/concurrency/preempt.cfa (deleted)
-
tests/concurrency/preempt2.cfa (deleted)
-
tests/concurrency/pthread/.expect/bounded_buffer.x64.txt (deleted)
-
tests/concurrency/pthread/.expect/bounded_buffer.x86.txt (deleted)
-
tests/concurrency/pthread/.expect/pthread_attr_test.txt (deleted)
-
tests/concurrency/pthread/.expect/pthread_cond_test.txt (deleted)
-
tests/concurrency/pthread/.expect/pthread_demo_create_join.txt (deleted)
-
tests/concurrency/pthread/.expect/pthread_demo_lock.txt (deleted)
-
tests/concurrency/pthread/.expect/pthread_key_test.txt (deleted)
-
tests/concurrency/pthread/.expect/pthread_once_test.txt (deleted)
-
tests/concurrency/pthread/bounded_buffer.cfa (deleted)
-
tests/concurrency/pthread/pthread_attr_test.cfa (deleted)
-
tests/concurrency/pthread/pthread_cond_test.cfa (deleted)
-
tests/concurrency/pthread/pthread_demo_create_join.cfa (deleted)
-
tests/concurrency/pthread/pthread_demo_lock.cfa (deleted)
-
tests/concurrency/pthread/pthread_key_test.cfa (deleted)
-
tests/concurrency/pthread/pthread_once_test.cfa (deleted)
-
tests/concurrency/readyQ/.expect/barrier_sleeper.txt (deleted)
-
tests/concurrency/readyQ/.expect/leader_spin.txt (deleted)
-
tests/concurrency/readyQ/barrier_sleeper.cfa (deleted)
-
tests/concurrency/readyQ/leader_spin.cfa (deleted)
-
tests/concurrency/signal/.expect/block.txt (deleted)
-
tests/concurrency/signal/.expect/disjoint.txt (deleted)
-
tests/concurrency/signal/.expect/wait.txt (deleted)
-
tests/concurrency/signal/block.cfa (deleted)
-
tests/concurrency/signal/disjoint.cfa (deleted)
-
tests/concurrency/signal/wait.cfa (deleted)
-
tests/concurrency/sleep.cfa (deleted)
-
tests/concurrency/suspend_then.cfa (deleted)
-
tests/concurrency/thread.cfa (deleted)
-
tests/concurrency/unified_locking/.expect/block_spin_lock.txt (deleted)
-
tests/concurrency/unified_locking/.expect/exp_backoff.txt (deleted)
-
tests/concurrency/unified_locking/.expect/fast_block_lock.txt (deleted)
-
tests/concurrency/unified_locking/.expect/futex_mutex.txt (deleted)
-
tests/concurrency/unified_locking/.expect/locks.txt (deleted)
-
tests/concurrency/unified_locking/.expect/mcs.txt (deleted)
-
tests/concurrency/unified_locking/.expect/mcs_block_spin_lock.txt (deleted)
-
tests/concurrency/unified_locking/.expect/mcs_spin.txt (deleted)
-
tests/concurrency/unified_locking/.expect/pthread_locks.txt (deleted)
-
tests/concurrency/unified_locking/.expect/simple_owner_lock.txt (deleted)
-
tests/concurrency/unified_locking/.expect/spin_queue_lock.txt (deleted)
-
tests/concurrency/unified_locking/.expect/timeout_lock.txt (deleted)
-
tests/concurrency/unified_locking/block_spin_lock.cfa (deleted)
-
tests/concurrency/unified_locking/exp_backoff.cfa (deleted)
-
tests/concurrency/unified_locking/fast_block_lock.cfa (deleted)
-
tests/concurrency/unified_locking/futex_mutex.cfa (deleted)
-
tests/concurrency/unified_locking/locks.cfa (deleted)
-
tests/concurrency/unified_locking/mcs.cfa (deleted)
-
tests/concurrency/unified_locking/mcs_block_spin_lock.cfa (deleted)
-
tests/concurrency/unified_locking/mcs_spin.cfa (deleted)
-
tests/concurrency/unified_locking/mutex_test.hfa (deleted)
-
tests/concurrency/unified_locking/pthread_locks.cfa (deleted)
-
tests/concurrency/unified_locking/simple_owner_lock.cfa (deleted)
-
tests/concurrency/unified_locking/spin_queue_lock.cfa (deleted)
-
tests/concurrency/unified_locking/spintest.cfa (deleted)
-
tests/concurrency/unified_locking/test_debug.cfa (deleted)
-
tests/concurrency/unified_locking/thread_test.cfa (deleted)
-
tests/concurrency/unified_locking/timeout_lock.cfa (deleted)
-
tests/concurrency/waitfor/.expect/barge.txt (deleted)
-
tests/concurrency/waitfor/.expect/dtor.txt (deleted)
-
tests/concurrency/waitfor/.expect/else.txt (deleted)
-
tests/concurrency/waitfor/.expect/parse.txt (deleted)
-
tests/concurrency/waitfor/.expect/recurse.txt (deleted)
-
tests/concurrency/waitfor/.expect/statment.txt (deleted)
-
tests/concurrency/waitfor/.expect/when.txt (deleted)
-
tests/concurrency/waitfor/barge.cfa (deleted)
-
tests/concurrency/waitfor/dtor.cfa (deleted)
-
tests/concurrency/waitfor/else.cfa (deleted)
-
tests/concurrency/waitfor/parse.cfa (deleted)
-
tests/concurrency/waitfor/recurse.cfa (deleted)
-
tests/concurrency/waitfor/simple.cfa (deleted)
-
tests/concurrency/waitfor/statment.cfa (deleted)
-
tests/concurrency/waitfor/when.cfa (deleted)
-
tests/concurrency/waituntil/.expect/all_types.txt (deleted)
-
tests/concurrency/waituntil/.expect/basic_else.txt (deleted)
-
tests/concurrency/waituntil/.expect/channel_close.txt (deleted)
-
tests/concurrency/waituntil/.expect/channel_zero_size.txt (deleted)
-
tests/concurrency/waituntil/.expect/channels.txt (deleted)
-
tests/concurrency/waituntil/.expect/futures.txt (deleted)
-
tests/concurrency/waituntil/.expect/locks.txt (deleted)
-
tests/concurrency/waituntil/.expect/one_chan.txt (deleted)
-
tests/concurrency/waituntil/.expect/timeout.txt (deleted)
-
tests/concurrency/waituntil/all_types.cfa (deleted)
-
tests/concurrency/waituntil/basic_else.cfa (deleted)
-
tests/concurrency/waituntil/channel_close.cfa (deleted)
-
tests/concurrency/waituntil/channel_zero_size.cfa (deleted)
-
tests/concurrency/waituntil/channels.cfa (deleted)
-
tests/concurrency/waituntil/futures.cfa (deleted)
-
tests/concurrency/waituntil/locks.cfa (deleted)
-
tests/concurrency/waituntil/one_chan.cfa (deleted)
-
tests/concurrency/waituntil/timeout.cfa (deleted)
-
tests/concurrent/.expect/clib.txt (added)
-
tests/concurrent/.expect/clib_tls.txt (added)
-
tests/concurrent/.expect/cluster.txt (added)
-
tests/concurrent/.expect/coroutineYield.txt (added)
-
tests/concurrent/.expect/ctor-check.txt (added)
-
tests/concurrent/.expect/join.txt (added)
-
tests/concurrent/.expect/joinerror.sed (added)
-
tests/concurrent/.expect/keywordErrors.txt (added)
-
tests/concurrent/.expect/mainError.txt (added)
-
tests/concurrent/.expect/migrate.txt (added)
-
tests/concurrent/.expect/monitor.txt (added)
-
tests/concurrent/.expect/multi-monitor.txt (added)
-
tests/concurrent/.expect/once.txt (added)
-
tests/concurrent/.expect/preempt.txt (added)
-
tests/concurrent/.expect/preempt2.txt (added)
-
tests/concurrent/.expect/sleep.txt (added)
-
tests/concurrent/.expect/suspend_then.txt (added)
-
tests/concurrent/.expect/thread.txt (added)
-
tests/concurrent/barrier/.expect/generation.txt (added)
-
tests/concurrent/barrier/.expect/last.txt (added)
-
tests/concurrent/barrier/.expect/order.txt (added)
-
tests/concurrent/barrier/gen_generation_expect.cfa (added)
-
tests/concurrent/barrier/generation.cfa (added)
-
tests/concurrent/barrier/last.cfa (added)
-
tests/concurrent/barrier/order.cfa (added)
-
tests/concurrent/clib.c (added)
-
tests/concurrent/clib_tls.c (added)
-
tests/concurrent/cluster.cfa (added)
-
tests/concurrent/coroutineYield.cfa (added)
-
tests/concurrent/ctor-check.cfa (added)
-
tests/concurrent/examples/.expect/boundedBufferEXT.txt (added)
-
tests/concurrent/examples/.expect/boundedBufferINT.txt (added)
-
tests/concurrent/examples/.expect/datingService.txt (added)
-
tests/concurrent/examples/.expect/gortn.txt (added)
-
tests/concurrent/examples/.expect/matrixSum.txt (added)
-
tests/concurrent/examples/.expect/quickSort.txt (added)
-
tests/concurrent/examples/.in/quickSort.txt (added)
-
tests/concurrent/examples/boundedBufferEXT.cfa (added)
-
tests/concurrent/examples/boundedBufferINT.cfa (added)
-
tests/concurrent/examples/boundedBufferTHREAD.cfa (added)
-
tests/concurrent/examples/datingService.cfa (added)
-
tests/concurrent/examples/gortn.cfa (added)
-
tests/concurrent/examples/matrixSum.cfa (added)
-
tests/concurrent/examples/multiSort.cfa (added)
-
tests/concurrent/examples/quickSort.cfa (added)
-
tests/concurrent/examples/quickSort.generic.cfa (added)
-
tests/concurrent/futures/.expect/abandon.txt (added)
-
tests/concurrent/futures/.expect/basic.txt (added)
-
tests/concurrent/futures/.expect/multi.txt (added)
-
tests/concurrent/futures/.expect/typed.txt (added)
-
tests/concurrent/futures/.expect/wait_any.txt (added)
-
tests/concurrent/futures/abandon.cfa (added)
-
tests/concurrent/futures/basic.cfa (added)
-
tests/concurrent/futures/multi.cfa (added)
-
tests/concurrent/futures/typed.cfa (added)
-
tests/concurrent/futures/wait_any.cfa (added)
-
tests/concurrent/join.cfa (added)
-
tests/concurrent/joinerror.cfa (added)
-
tests/concurrent/keywordErrors.cfa (added)
-
tests/concurrent/mainError.cfa (added)
-
tests/concurrent/migrate.cfa (added)
-
tests/concurrent/monitor.cfa (added)
-
tests/concurrent/multi-monitor.cfa (added)
-
tests/concurrent/mutexstmt/.expect/locks.txt (added)
-
tests/concurrent/mutexstmt/.expect/monitors.txt (added)
-
tests/concurrent/mutexstmt/.expect/scoped_lock.txt (added)
-
tests/concurrent/mutexstmt/locks.cfa (added)
-
tests/concurrent/mutexstmt/monitors.cfa (added)
-
tests/concurrent/mutexstmt/scoped_lock.cfa (added)
-
tests/concurrent/once.cfa (added)
-
tests/concurrent/park/.expect/contention.txt (added)
-
tests/concurrent/park/.expect/force_preempt.txt (added)
-
tests/concurrent/park/.expect/start_parked.txt (added)
-
tests/concurrent/park/contention.cfa (added)
-
tests/concurrent/park/force_preempt.cfa (added)
-
tests/concurrent/park/start_parked.cfa (added)
-
tests/concurrent/preempt.cfa (added)
-
tests/concurrent/preempt2.cfa (added)
-
tests/concurrent/pthread/.expect/bounded_buffer.txt (added)
-
tests/concurrent/pthread/.expect/pthread_attr_test.txt (added)
-
tests/concurrent/pthread/.expect/pthread_cond_test.txt (added)
-
tests/concurrent/pthread/.expect/pthread_demo_create_join.txt (added)
-
tests/concurrent/pthread/.expect/pthread_demo_lock.txt (added)
-
tests/concurrent/pthread/.expect/pthread_key_test.txt (added)
-
tests/concurrent/pthread/.expect/pthread_once_test.txt (added)
-
tests/concurrent/pthread/bounded_buffer.cfa (added)
-
tests/concurrent/pthread/pthread_attr_test.cfa (added)
-
tests/concurrent/pthread/pthread_cond_test.cfa (added)
-
tests/concurrent/pthread/pthread_demo_create_join.cfa (added)
-
tests/concurrent/pthread/pthread_demo_lock.cfa (added)
-
tests/concurrent/pthread/pthread_key_test.cfa (added)
-
tests/concurrent/pthread/pthread_once_test.cfa (added)
-
tests/concurrent/readyQ/.expect/barrier_sleeper.txt (added)
-
tests/concurrent/readyQ/.expect/leader_spin.txt (added)
-
tests/concurrent/readyQ/barrier_sleeper.cfa (added)
-
tests/concurrent/readyQ/leader_spin.cfa (added)
-
tests/concurrent/signal/.expect/block.txt (added)
-
tests/concurrent/signal/.expect/disjoint.txt (added)
-
tests/concurrent/signal/.expect/wait.txt (added)
-
tests/concurrent/signal/block.cfa (added)
-
tests/concurrent/signal/disjoint.cfa (added)
-
tests/concurrent/signal/wait.cfa (added)
-
tests/concurrent/sleep.cfa (added)
-
tests/concurrent/suspend_then.cfa (added)
-
tests/concurrent/thread.cfa (added)
-
tests/concurrent/waitfor/.expect/barge.txt (added)
-
tests/concurrent/waitfor/.expect/dtor.txt (added)
-
tests/concurrent/waitfor/.expect/else.txt (added)
-
tests/concurrent/waitfor/.expect/recurse.txt (added)
-
tests/concurrent/waitfor/.expect/statment.txt (added)
-
tests/concurrent/waitfor/.expect/when.txt (added)
-
tests/concurrent/waitfor/barge.cfa (added)
-
tests/concurrent/waitfor/dtor.cfa (added)
-
tests/concurrent/waitfor/else.cfa (added)
-
tests/concurrent/waitfor/parse.cfa (added)
-
tests/concurrent/waitfor/parse2.cfa (added)
-
tests/concurrent/waitfor/recurse.cfa (added)
-
tests/concurrent/waitfor/simple.cfa (added)
-
tests/concurrent/waitfor/statment.cfa (added)
-
tests/concurrent/waitfor/when.cfa (added)
-
tests/declarationSpecifier.cfa (modified) (3 diffs)
-
tests/enum_tests/.expect/pointerEnum.cfa (added)
-
tests/enum_tests/.expect/qualifiedEnum.cfa (added)
-
tests/enum_tests/.expect/typedIntEnum.txt (modified) (1 diff)
-
tests/enum_tests/pointerEnum.cfa (modified) (1 diff)
-
tests/enum_tests/typedIntEnum.cfa (modified) (1 diff)
-
tests/errors/.expect/declaration.txt (modified) (3 diffs)
-
tests/forall.cfa (modified) (11 diffs)
-
tests/function-operator.cfa (modified) (2 diffs)
-
tests/include/includes.cfa (modified) (5 diffs)
-
tests/io/comp_basic.cfa (modified) (1 diff)
-
tests/io/comp_fair.cfa (modified) (1 diff)
-
tests/linking/mangling/.expect/anon.txt (deleted)
-
tests/linking/mangling/header.hfa (modified) (1 diff)
-
tests/linking/mangling/lib.cfa (modified) (1 diff)
-
tests/linking/mangling/main.cfa (modified) (2 diffs)
-
tests/pybin/settings.py (modified) (2 diffs)
-
tests/quotedKeyword.cfa (modified) (1 diff)
-
tests/sum.cfa (modified) (2 diffs)
-
tests/test.py (modified) (3 diffs)
-
tests/unified_locking/.expect/block_spin_lock.txt (added)
-
tests/unified_locking/.expect/clh.txt (added)
-
tests/unified_locking/.expect/fast_block_lock.txt (added)
-
tests/unified_locking/.expect/futex_mutex.txt (added)
-
tests/unified_locking/.expect/lin_backoff.txt (added)
-
tests/unified_locking/.expect/locks.txt (added)
-
tests/unified_locking/.expect/mcs.txt (added)
-
tests/unified_locking/.expect/mcs_block_spin_lock.txt (added)
-
tests/unified_locking/.expect/mcs_spin.txt (added)
-
tests/unified_locking/.expect/pthread_locks.txt (added)
-
tests/unified_locking/.expect/simple_owner_lock.txt (added)
-
tests/unified_locking/.expect/spin_queue_lock.txt (added)
-
tests/unified_locking/.expect/timeout_lock.txt (added)
-
tests/unified_locking/block_spin_lock.cfa (added)
-
tests/unified_locking/clh.cfa (added)
-
tests/unified_locking/fast_block_lock.cfa (added)
-
tests/unified_locking/futex_mutex.cfa (added)
-
tests/unified_locking/lin_backoff.cfa (added)
-
tests/unified_locking/locks.cfa (added)
-
tests/unified_locking/mcs.cfa (added)
-
tests/unified_locking/mcs_block_spin_lock.cfa (added)
-
tests/unified_locking/mcs_spin.cfa (added)
-
tests/unified_locking/mutex_test.hfa (added)
-
tests/unified_locking/pthread_locks.cfa (added)
-
tests/unified_locking/simple_owner_lock.cfa (added)
-
tests/unified_locking/spin_queue_lock.cfa (added)
-
tests/unified_locking/thread_test.cfa (added)
-
tests/unified_locking/timeout_lock.cfa (added)
-
tests/zombies/prolog.c (added)
Legend:
- Unmodified
- Added
- Removed
-
Jenkins/FullBuild
r24d6572 r34b4268 20 20 gcc_08_x86_new: { trigger_build( 'gcc-10', 'x86', false ) }, 21 21 gcc_07_x86_new: { trigger_build( 'gcc-9', 'x86', false ) }, 22 gcc_11_x64_new: { trigger_build( 'gcc-11', 'x64', false ) },23 22 gcc_10_x64_new: { trigger_build( 'gcc-10', 'x64', false ) }, 24 23 gcc_09_x64_new: { trigger_build( 'gcc-9', 'x64', false ) }, 25 24 gcc_08_x64_new: { trigger_build( 'gcc-8', 'x64', false ) }, 26 25 gcc_07_x64_new: { trigger_build( 'gcc-7', 'x64', false ) }, 27 //gcc_06_x64_new: { trigger_build( 'gcc-6', 'x64', false ) },26 gcc_06_x64_new: { trigger_build( 'gcc-6', 'x64', false ) }, 28 27 clang_x64_new: { trigger_build( 'clang', 'x64', true ) }, 29 28 ) … … 42 41 } 43 42 44 // If an exception is caught we need to change the status and remember to45 // attach the build log to the email43 //If an exception is caught we need to change the status and remember to 44 //attach the build log to the email 46 45 catch (Exception caughtError) { 47 46 echo('error caught') … … 74 73 // Run the build 75 74 // Don't propagate, it doesn't play nice with our email setup 76 def result = build job: 'Cforall/master', \75 def result = build job: 'Cforall/master', \ 77 76 parameters: [ \ 78 77 [$class: 'StringParameterValue', \ … … 84 83 [$class: 'BooleanParameterValue', \ 85 84 name: 'NewAST', \ 86 value: true], \85 value: true], \ 87 86 [$class: 'BooleanParameterValue', \ 88 87 name: 'RunAllTests', \ 89 value: true], \88 value: true], \ 90 89 [$class: 'BooleanParameterValue', \ 91 90 name: 'RunBenchmark', \ 92 value: true], \91 value: true], \ 93 92 [$class: 'BooleanParameterValue', \ 94 name: 'BuildDocumentation', \93 name: 'BuildDocumentation', \ 95 94 value: doc], \ 96 95 [$class: 'BooleanParameterValue', \ 97 96 name: 'Publish', \ 98 value: true], \97 value: true], \ 99 98 [$class: 'BooleanParameterValue', \ 100 99 name: 'Silent', \ 101 value: true], \102 ], \100 value: true], \ 101 ], \ 103 102 propagate: false 104 103 … … 112 111 113 112 def trigger_dist(String commitId, String buildNum) { 114 def result = build job: 'Cforall_Distribute_Ref', \113 def result = build job: 'Cforall_Distribute_Ref', \ 115 114 parameters: [ \ 116 115 string(name: 'GitRef', value: commitId), \ 117 string(name: 'Build' , value: buildNum) \118 ], \116 string(name: 'Build' , value: buildNum) \ 117 ], \ 119 118 propagate: false 120 119 -
Jenkins/Promote
r24d6572 r34b4268 36 36 dir (BuildDir) { 37 37 sh 'rm -rf *' 38 sshagent (credentials: ['git _key_mar27']) {38 sshagent (credentials: ['github_key_jun1']) { 39 39 sh "git clone --bare ${RemoteRepo} repo" 40 40 } … … 69 69 sh "git status" 70 70 sh "git diff-index --quiet HEAD || git commit -m 'Push from build machine: ${name}'" 71 sshagent (credentials: ['git _key_mar27']) {71 sshagent (credentials: ['github_key_jun1']) { 72 72 sh "git push origin master" 73 73 } -
Jenkinsfile
r24d6572 r34b4268 155 155 dir (BuildDir) { 156 156 //Run the tests from the tests directory 157 sh """make ${jopt} --no-print-directory -C tests timeout =600 global-timeout=14400 tests debug=yes archive-errors=${BuildDir}/tests/crashes/full-debug"""157 sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug""" 158 158 } 159 159 } … … 162 162 dir (BuildDir) { 163 163 //Run the tests from the tests directory 164 sh """make ${jopt} --no-print-directory -C tests timeout =600 global-timeout=14400 tests debug=no archive-errors=${BuildDir}/tests/crashes/full-nodebug"""164 sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no archiveerrors=${BuildDir}/tests/crashes/full-nodebug""" 165 165 } 166 166 } … … 305 305 this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto') 306 306 break 307 //case 'gcc-6':308 //this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')309 //break310 //case 'gcc-5':311 //this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')312 //break313 //case 'gcc-4.9':314 //this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')315 //break307 case 'gcc-6': 308 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto') 309 break 310 case 'gcc-5': 311 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto') 312 break 313 case 'gcc-4.9': 314 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto') 315 break 316 316 case 'clang': 317 317 this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-10', '-flto=thin -flto-jobs=0') … … 359 359 def prepare_build() { 360 360 // prepare the properties 361 properties ([ \362 buildDiscarder(logRotator( \363 artifactDaysToKeepStr: '', \364 artifactNumToKeepStr: '', \365 daysToKeepStr: '730', \366 numToKeepStr: '1000' \367 )), \368 [$class: 'ParametersDefinitionProperty', \369 parameterDefinitions: [ \370 [$class: 'ChoiceParameterDefinition', \371 description: 'Which compiler to use', \372 name: 'Compiler', \373 choices: 'gcc-11\ngcc-10\ngcc-9\ngcc-8\ngcc-7\n clang', \374 defaultValue: 'gcc- 9',\375 ], \376 [$class: 'ChoiceParameterDefinition', \377 description: 'The target architecture', \378 name: 'Architecture', \379 choices: 'x64\nx86', \380 defaultValue: 'x64', \381 ], \382 [$class: 'BooleanParameterDefinition', \361 properties ([ \ 362 buildDiscarder(logRotator( \ 363 artifactDaysToKeepStr: '', \ 364 artifactNumToKeepStr: '', \ 365 daysToKeepStr: '730', \ 366 numToKeepStr: '1000' \ 367 )), \ 368 [$class: 'ParametersDefinitionProperty', \ 369 parameterDefinitions: [ \ 370 [$class: 'ChoiceParameterDefinition', \ 371 description: 'Which compiler to use', \ 372 name: 'Compiler', \ 373 choices: 'gcc-11\ngcc-10\ngcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang', \ 374 defaultValue: 'gcc-8', \ 375 ], \ 376 [$class: 'ChoiceParameterDefinition', \ 377 description: 'The target architecture', \ 378 name: 'Architecture', \ 379 choices: 'x64\nx86', \ 380 defaultValue: 'x64', \ 381 ], \ 382 [$class: 'BooleanParameterDefinition', \ 383 383 description: 'If false, the test suite is only ran in debug', \ 384 name: 'RunAllTests', \385 defaultValue: false, \386 ], \387 [$class: 'BooleanParameterDefinition', \388 description: 'If true, jenkins also runs benchmarks', \389 name: 'RunBenchmark', \390 defaultValue: false, \391 ], \392 [$class: 'BooleanParameterDefinition', \393 description: 'If true, jenkins also builds documentation', \394 name: 'BuildDocumentation', \395 defaultValue: true, \396 ], \397 [$class: 'BooleanParameterDefinition', \398 description: 'If true, jenkins also publishes results', \399 name: 'Publish', \400 defaultValue: false, \401 ], \402 [$class: 'BooleanParameterDefinition', \403 description: 'If true, jenkins will not send emails', \404 name: 'Silent', \405 defaultValue: false, \406 ], \384 name: 'RunAllTests', \ 385 defaultValue: false, \ 386 ], \ 387 [$class: 'BooleanParameterDefinition', \ 388 description: 'If true, jenkins also runs benchmarks', \ 389 name: 'RunBenchmark', \ 390 defaultValue: false, \ 391 ], \ 392 [$class: 'BooleanParameterDefinition', \ 393 description: 'If true, jenkins also builds documentation', \ 394 name: 'BuildDocumentation', \ 395 defaultValue: true, \ 396 ], \ 397 [$class: 'BooleanParameterDefinition', \ 398 description: 'If true, jenkins also publishes results', \ 399 name: 'Publish', \ 400 defaultValue: false, \ 401 ], \ 402 [$class: 'BooleanParameterDefinition', \ 403 description: 'If true, jenkins will not send emails', \ 404 name: 'Silent', \ 405 defaultValue: false, \ 406 ], \ 407 407 ], 408 408 ]]) 409 // choices: 'gcc-11\ngcc-10\ngcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang',410 // defaultValue: 'gcc-8',411 409 412 410 // It's unfortunate but it looks like we need to checkout the entire repo just to get -
Makefile.am
r24d6572 r34b4268 11 11 ## Created On : Sun May 31 22:14:18 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Wed May 17 11:02:34 202314 ## Update Count : 5613 ## Last Modified On : Sat Feb 2 16:54:42 2019 14 ## Update Count : 21 15 15 ############################################################################### 16 16 … … 24 24 DIST_SUBDIRS = driver src . libcfa tests 25 25 26 @LIBCFA_TARGET_MAKEFILES@ : Makefile $ {srcdir}/libcfa/configure27 @$ {eval config_file = ${dir ${@}}config.data}28 @ls $ {config_file}|| (echo "Missing config.data, re-run configure script again" && false)29 @$ {eval config_data = ${shell cat ${config_file}}}30 @echo "Configuring libcfa ($ {abs_top_srcdir}/libcfa/configure) with '${config_data}' from ${shell pwd} / ${dir ${@}}"31 @cd $ {dir ${@}} && ${abs_top_srcdir}/libcfa/configure ${config_data}26 @LIBCFA_TARGET_MAKEFILES@ : Makefile $(srcdir)/libcfa/configure 27 @$(eval config_file = $(dir $@)config.data) 28 @ls $(config_file) || (echo "Missing config.data, re-run configure script again" && false) 29 @$(eval config_data = $(shell cat $(config_file))) 30 @echo "Configuring libcfa ($(abs_top_srcdir)/libcfa/configure) with '$(config_data)' from $(shell pwd) / $(dir $@)" 31 @cd $(dir $@) && $(abs_top_srcdir)/libcfa/configure $(config_data) 32 32 33 33 noinst_DATA = @LIBCFA_TARGET_MAKEFILES@ … … 37 37 EXTRA_DIST = LICENSE doc/man/cfa.1 libcfa/configure libcfa/Makefile.dist.am libcfa/Makefile.dist.in tools/build/distcc_hash tools/build/push2dist.sh 38 38 39 debug ?= yes 40 installed ?= no 41 ARCH = ${if ${arch},"arch=${arch}"} 42 arch_support = "x86/x64/arm" 39 debug=yes 40 check: 41 $(MAKE) -C tests all-tests installed=no debug=${debug} 43 42 44 # target "all" created by automake 43 installcheck: 44 $(MAKE) -C tests all-tests installed=yes debug=${debug} 45 45 46 c heck :47 ${MAKE} -C tests tests installed=${installed} debug=${debug} ${ARCH}46 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@ 47 @true 48 48 49 tests : check # synonym 50 51 installcheck : 52 ${MAKE} -C tests tests installed=yes debug=${debug} ${ARCH} 53 54 installtest : installcheck # synonym 55 56 status : @LIBCFA_TARGET_MAKEFILES@ 49 status: @LIBCFA_TARGET_MAKEFILES@ 57 50 @echo -ne "translator\n\t" 58 51 @./config.status --config | sed "s/ /\n\t/g; s/\t'/\t/g; s/'\n/\n/g; s/^'//g; s/'$$//g" 59 52 @find libcfa -name config.status -printf "\n%h\n\t" -exec {} --config \; | sed "s/ /\n\t/g; s/\t'/\t/g; s/'\n/\n/g; s/^'//g; s/'$$//g" 60 53 61 help : 62 @echo "user targets:" 63 @echo " Compile compiler/runtime." 64 @echo " $$ make (null) / all" 65 @echo "" 66 @echo " Compile compiler/runtime and run test suite." 67 @echo " $$ make check / tests [debug=yes/no] [installed=yes/no] [arch=${arch_support}]" 68 @echo "" 69 @echo " Compile compiler/runtime, install, and run test suite on installed system." 70 @echo " $$ make installcheck / installtests [debug=yes/no] installed=yes [arch=${arch_support}]" 71 @echo "" 72 @echo " Print configuration parameters and system build information." 73 @echo " $$ make status" 54 @LIBCFA_TARGET_DIRS@:: 55 $(MAKE) -C $@ $(MAKECMDGOALS) 74 56 75 configure-libcfa : @LIBCFA_TARGET_MAKEFILES@ 76 @true 77 78 @LIBCFA_TARGET_DIRS@ :: 79 ${MAKE} -C ${@} ${MAKECMDGOALS} 80 81 mostlyclean clean distclean maintainer-clean : @LIBCFA_TARGET_DIRS@ 57 mostlyclean clean distclean maintainer-clean: @LIBCFA_TARGET_DIRS@ -
benchmark/Makefile.am
r24d6572 r34b4268 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Fri May 26 12:13:48 202314 ## Update Count : 2 6013 ## Last Modified On : Tue Mar 10 11:41:18 2020 14 ## Update Count : 258 15 15 ############################################################################### 16 16 … … 374 374 ## ========================================================================================================= 375 375 376 mutexStmt$(EXEEXT) : \377 mutexStmt-cpp1.run \378 mutexStmt-cpp2.run \379 mutexStmt-cpp4.run \380 mutexStmt-cpp8.run \381 mutexStmt-java.run \382 mutexStmt-lock1.run \383 mutexStmt-lock2.run \384 mutexStmt-lock4.run \385 mutexStmt-lock8.run \386 mutexStmt-no-stmt-lock1.run \387 mutexStmt-no-stmt-lock2.run \388 mutexStmt-no-stmt-lock4.run \389 mutexStmt-no-stmt-lock8.run \390 mutexStmt-monitor1.run \391 mutexStmt-monitor2.run \376 mutexStmt$(EXEEXT) : \ 377 mutexStmt-cpp1.run \ 378 mutexStmt-cpp2.run \ 379 mutexStmt-cpp4.run \ 380 mutexStmt-cpp8.run \ 381 mutexStmt-java.run \ 382 mutexStmt-lock1.run \ 383 mutexStmt-lock2.run \ 384 mutexStmt-lock4.run \ 385 mutexStmt-lock8.run \ 386 mutexStmt-no-stmt-lock1.run \ 387 mutexStmt-no-stmt-lock2.run \ 388 mutexStmt-no-stmt-lock4.run \ 389 mutexStmt-no-stmt-lock8.run \ 390 mutexStmt-monitor1.run \ 391 mutexStmt-monitor2.run \ 392 392 mutexStmt-monitor4.run 393 393 … … 567 567 compile-array.make \ 568 568 compile-attributes.make \ 569 compile-empty.make \569 compile-empty.make \ 570 570 compile-expression.make \ 571 571 compile-io.make \ … … 592 592 593 593 compile-monitor$(EXEEXT): 594 $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurren cy/monitor.cfa594 $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurrent/monitor.cfa 595 595 596 596 compile-operators$(EXEEXT): … … 598 598 599 599 compile-thread$(EXEEXT): 600 $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurren cy/thread.cfa600 $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurrent/thread.cfa 601 601 602 602 compile-typeof$(EXEEXT): -
configure.ac
r24d6572 r34b4268 47 47 48 48 #============================================================================== 49 # HACK to be able to use condition als inside makefiles49 # HACK to be able to use conditionnals inside makefiles 50 50 DOifskipcompile='ifeq ($(skipcompile),yes) 51 51 else' … … 226 226 AC_PROG_YACC 227 227 if test "${YACC}" = "yacc" ; then echo "Error: bison required." ; exit 1 ; fi 228 AC_PROG_LEX (yywrap)228 AC_PROG_LEX 229 229 if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi 230 LT_INIT 230 AC_PROG_LIBTOOL 231 231 AC_PROG_INSTALL 232 232 … … 284 284 tools/Makefile 285 285 tools/prettyprinter/Makefile 286 benchmark/Cargo.toml287 286 ]) 287 288 AC_OUTPUT(benchmark/Cargo.toml) 288 289 ]) 289 290 290 291 AC_CONFIG_LINKS([tests/test.py:tests/test.py]) 291 AC_CONFIG_FILES([tests/config.py]) 292 293 AC_OUTPUT 292 293 AC_OUTPUT(tests/config.py) 294 294 295 295 # Final text -
doc/LaTeXmacros/common.sty
r24d6572 r34b4268 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Apr 4 12:03:19 202314 %% Update Count : 5 8513 %% Last Modified On : Sat Apr 2 17:35:23 2022 14 %% Update Count : 570 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 30 30 \setlist[itemize,1]{label=\textbullet}% local 31 31 %\renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 32 \setlist[enumerate]{ topsep=0.5ex,parsep=0.25ex,itemsep=0.25ex,listparindent=\parindent}% global32 \setlist[enumerate]{listparindent=\parindent}% global 33 33 \setlist[enumerate,2]{leftmargin=\parindent,labelsep=*,align=parleft,label=\alph*.}% local 34 34 \setlist[description]{topsep=0.5ex,itemsep=0pt,listparindent=\parindent,leftmargin=\parindent,labelsep=1.5ex} … … 49 49 \newcommand{\CCseventeen}{\protect\CCIcon{17}\xspace} % C++17 symbolic name 50 50 \newcommand{\CCtwenty}{\protect\CCIcon{20}\xspace} % C++20 symbolic name 51 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\ relsize{2}$^\sharp$}\xspace} % C# symbolic name51 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name 52 52 53 53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 54 55 \usepackage[scaled=0.85]{helvet} % descent Helvetica font and scale to times size 56 \usepackage[T1]{fontenc} 55 \usepackage{pslatex} % reduce size of san serif font 57 56 \usepackage{relsize} % must be after change to small or selects old size 58 57 \usepackage{rotating} … … 196 195 \newcommand{\viz}{\VIZ\CheckPeriod} 197 196 198 \newcommand{\VS}{\abbrevFont{vs}}199 \newcommand{\vs}{\VS\CheckPeriod}200 201 197 \newenvironment{cquote}{% 202 198 \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}% … … 248 244 \renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}} 249 245 \newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}} 250 \newcommand{\VRefrange}[3][Sections]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vrefrange{#2}{#3}}251 246 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 252 \newcommand{\VPagerefrange}[3][pages]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}{#3}}253 247 254 248 \let\Oldthebibliography\thebibliography … … 266 260 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 267 261 \newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}} 268 \newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}}269 262 270 263 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly … … 287 280 columns=fullflexible, 288 281 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 289 stringstyle=\ small\tt,% use typewriter font282 stringstyle=\tt, % use typewriter font 290 283 tabsize=5, % N space tabbing 291 284 xleftmargin=\parindentlnth, % indent code to paragraph indentation -
doc/LaTeXmacros/common.tex
r24d6572 r34b4268 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Apr 4 12:03:18 202314 %% Update Count : 5 6713 %% Last Modified On : Tue Apr 26 16:02:48 2022 14 %% Update Count : 558 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 49 49 \newcommand{\CCseventeen}{\protect\CCIcon{17}\xspace} % C++17 symbolic name 50 50 \newcommand{\CCtwenty}{\protect\CCIcon{20}\xspace} % C++20 symbolic name 51 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\ relsize{2}$^\sharp$}\xspace} % C# symbolic name51 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name 52 52 53 53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 54 55 \usepackage[scaled=0.85]{helvet} % descent Helvetica font and scale to times size 56 \usepackage[T1]{fontenc} 55 \usepackage{pslatex} % reduce size of san serif font 57 56 \usepackage{relsize} % must be after change to small or selects old size 58 57 \usepackage{rotating} … … 197 196 \newcommand{\viz}{\VIZ\CheckPeriod} 198 197 199 \newcommand{\VS}{\abbrevFont{vs}}200 \newcommand{\vs}{\VS\CheckPeriod}201 198 \makeatother 202 199 … … 269 266 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 270 267 \newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}} 271 \newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}}272 268 273 269 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly … … 291 287 columns=fullflexible, 292 288 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 293 stringstyle=\ small\tt,% use typewriter font289 stringstyle=\tt, % use typewriter font 294 290 tabsize=5, % N space tabbing 295 291 xleftmargin=\parindentlnth, % indent code to paragraph indentation -
doc/LaTeXmacros/lstlang.sty
r24d6572 r34b4268 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Tue May 2 08:52:35 202311 %% Update Count : 3010 %% Last Modified On : Mon May 31 08:20:41 2021 11 %% Update Count : 28 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 112 112 \lstdefinelanguage{CFA}[ANSI]{C}{ 113 113 morekeywords={ 114 _Alignas, _Alignof, __alignof, __alignof__, and, asm, __asm, __asm__, _Atomic, __attribute, __attribute__, 115 __auto_type, basetypeof, _Bool, catch, catchResume, choose, coerce, _Complex, __complex, __complex__, __const, __const__, 116 coroutine, _Decimal32, _Decimal64, _Decimal128, disable, enable, exception, __extension__, fallthrough, fallthru, finally, fixup, 117 __float80, float80, __float128, float128, _Float16, _Float32, _Float32x, _Float64, _Float64x, _Float128, _Float128x, 118 forall, fortran, generator, _Generic, _Imaginary, __imag, __imag__, inline, __inline, __inline__, int128, __int128, __int128_t, 119 __label__, monitor, mutex, _Noreturn, __builtin_offsetof, one_t, or, recover, report, restrict, __restrict, __restrict__, 120 __signed, __signed__, _Static_assert, suspend, thread, __thread, _Thread_local, throw, throwResume, timeout, trait, try, 121 typeof, __typeof, __typeof__, typeid, __uint128_t, __builtin_va_arg, __builtin_va_list, virtual, __volatile, __volatile__, 122 vtable, waitfor, waituntil, when, with, zero_t, 114 _Alignas, _Alignof, __alignof, __alignof__, asm, __asm, __asm__, __attribute, __attribute__, 115 auto, basetypeof, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__, 116 coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally, fixup, 117 __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__, 118 inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or, 119 otype, restrict, __restrict, __restrict__, recover, report, __signed, __signed__, _Static_assert, suspend, 120 thread, __thread, _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__, 121 virtual, __volatile, __volatile__, waitfor, when, with, zero_t, 123 122 }, 124 123 moredirectives={defined,include_next}% -
doc/bibliography/pl.bib
r24d6572 r34b4268 147 147 author = {Zhang, Yizhou and Salvaneschi, Guido and Beightol, Quinn and Liskov, Barbara and Myers, Andrew C.}, 148 148 title = {Accepting Blame for Safe Tunneled Exceptions}, 149 organization= {Proceedings of the 37th ACM SIGPLAN Conference on Programming Language Design and Implementation},149 booktitle = {Proceedings of the 37th ACM SIGPLAN Conference on Programming Language Design and Implementation}, 150 150 series = {PLDI'16}, 151 151 year = {2016}, … … 198 198 } 199 199 200 @inproceedings{Koster16,201 keywords = {Actor Model, Concurrency},202 contributer = {pabuhr@plg},203 author = {De Koster, Joeri and Van Cutsem, Tom and De Meuter, Wolfgang},204 title = {43 Years of Actors: A Taxonomy of Actor Models and Their Key Properties},205 publisher = {ACM},206 address = {New York, NY, USA},207 organization= {Proceedings of the 6th International Workshop on Programming Based on Actors, Agents, and Decentralized Control},208 pages = {31-40},209 numpages = {10},210 year = {2016},211 location = {Amsterdam, Netherlands},212 series = {AGERE 2016}213 }214 215 @misc{ActorBenchmarks,216 keywords = {Actors, microbenchmarks, uC++. CAF, ProtoActor, AkkaC, AkkaT},217 contributer = {pabuhr@plg},218 key = {ActorBenchmarks},219 title = {Actor Benchmarks},220 author = {Peter A. Buhr and Colby A. Parsons},221 howpublished= {\href{https://github.com/pabuhr/ActorExperiments}{https://\-github.com/\-pabuhr/\-ActorExperiments}},222 year = 2022,223 }224 225 200 @book{Actors, 226 201 keywords = {actors, concurrency}, … … 230 205 publisher = {MIT Press, Cambridge}, 231 206 year = 1986 232 }233 234 @inproceedings{Srinivasan08,235 author = {Srinivasan, Sriram and Mycroft, Alan},236 editor = {Vitek, Jan},237 title = {Kilim: Isolation-Typed Actors for Java},238 organization= {ECOOP 2008 -- Object-Oriented Programming},239 year = {2008},240 publisher = {Springer Berlin Heidelberg},241 address = {Berlin, Heidelberg},242 pages = {104--128},243 }244 245 @inproceedings{Haller07,246 author = {Haller, Philipp and Odersky, Martin},247 editor = {Murphy, Amy L. and Vitek, Jan},248 title = {Actors That Unify Threads and Events},249 organization= {Coordination Models and Languages},250 year = 2007,251 publisher = {Springer Berlin Heidelberg},252 address = {Berlin, Heidelberg},253 pages = {171-190},254 207 } 255 208 … … 292 245 } 293 246 294 @manual{Ada95,295 keywords = {Ada},296 contributer = {pabuhr@plg},297 title = {{A}da Reference Manual},298 edition = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}},299 organization= {Intermetrics, Inc.},300 month = dec,301 year = 1995,302 note = {Language and Standards Libraries}303 }304 305 @manual{Ada12,306 keywords = {ISO/IEC Ada},307 contributer = {pabuhr@plg},308 author = {Ada12},309 title = {Programming languages -- {Ada} ISO/IEC 8652:2012},310 edition = {3rd},311 organization= {International Standard Organization},312 address = {Geneva, Switzerland},313 year = 2012,314 note = {\href{https://www.iso.org/standard/61507.html}{https://\-www.iso.org/\-standard/\-61507.html}},315 }316 317 @manual{Ada95:annotated,318 keywords = {Ada},319 contributer = {pabuhr@plg},320 title = {Annotated {A}da Reference Manual},321 edition = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}},322 organization= {Intermetrics, Inc.},323 month = dec,324 year = 1995,325 note = {Language and Standards Libraries}326 }327 328 247 @article{dim:ada, 329 248 keywords = {Dimensional Analysis, Ada}, … … 337 256 number = 2, 338 257 pages = {189-203}, 339 }340 341 @article{Agrawal08,342 keywords = {Adaptive scheduling, multiprocessing, processor allocation, randomized algorithm, space sharing, thread scheduling, two-level scheduling, work-stealing},343 author = {Agrawal, Kunal and Leiserson, Charles E. and He, Yuxiong and Hsu, Wen Jing},344 title = {Adaptive Work-stealing with Parallelism Feedback},345 journal = {ACM Trans. Comput. Syst.},346 issue_date = {September 2008},347 volume = {26},348 number = {3},349 month = sep,350 year = {2008},351 pages = {7:1-7:32},352 publisher = {ACM},353 address = {New York, NY, USA},354 258 } 355 259 … … 472 376 month = sep, 473 377 year = 2016, 474 note = {\url{http://doc.akka.io/docs/akka/2.4/AkkaScala.pdf}}, 475 } 476 477 @misc{AkkaClassic, 478 contributer = {pabuhr@plg}, 479 key = {AkkaClassic}, 480 title = {Akka Classic Actors}, 481 author = {{Lightbend}}, 482 howpublished= {\url{https://doc.akka.io/docs/akka/current/index-classic.html}}, 483 year = 2023, 484 } 485 486 @misc{AkkaFuture, 487 contributer = {pabuhr@plg}, 488 key = {AkkaFuture}, 489 title = {Akka Futures}, 490 author = {{Lightbend}}, 491 howpublished= {\url{https://doc.akka.io/docs/akka/2.5/futures.html}}, 492 year = 2022, 493 } 494 495 @misc{AkkaTyped, 496 contributer = {pabuhr@plg}, 497 key = {AkkaTyped}, 498 title = {Akka Typed Actors}, 499 author = {{Lightbend}}, 500 howpublished= {\url{https://doc.akka.io/docs/akka/2.5/typed-actors.html}}, 501 year = 2022, 378 note = {\href{http://doc.akka.io/docs/akka/2.4/AkkaScala.pdf}{http://\-doc.akka.io/\-docs/\-akka/\-2.4/\-AkkaScala.pdf}}, 502 379 } 503 380 … … 671 548 } 672 549 673 @inproceedings{Mitzenmacher98,674 author = {Mitzenmacher, Michael},675 title = {Analyses of Load Stealing Models Based on Differential Equations},676 organization= {Proceedings of the Tenth Annual ACM Symposium on Parallel Algorithms and Architectures},677 series = {SPAA '98},678 year = {1998},679 isbn = {0-89791-989-0},680 location = {Puerto Vallarta, Mexico},681 pages = {212-221},682 publisher = {ACM},683 address = {New York, NY, USA},684 }685 686 @inproceedings{Squillante91,687 author = {Squillante, Mark S. and Nelson, Randolph D.},688 title = {Analysis of Task Migration in Shared-memory Multiprocessor Scheduling},689 organization= {Proceedings of the 1991 ACM SIGMETRICS Conference on Measurement and Modeling of Computer Systems},690 series = {SIGMETRICS '91},691 year = {1991},692 isbn = {0-89791-392-2},693 location = {San Diego, California, USA},694 pages = {143-155},695 publisher = {ACM},696 address = {New York, NY, USA},697 }698 699 550 @article{Sinha00, 700 551 author = {Saurabh Sinha and Mary Jean Harrold}, … … 711 562 author = {Martin P. Robillard and Gail C. Murphy}, 712 563 title = {Analyzing Exception Flow in {J}ava Programs}, 713 organization= {ESEC/FSE-7: Proceedings of the 7th European Software Engineering Conference held jointly564 booktitle = {ESEC/FSE-7: Proceedings of the 7th European Software Engineering Conference held jointly 714 565 with the 7th ACM SIGSOFT International Symposium on Foundations of Software Engineering}, 715 566 year = 1999, … … 753 604 author = {Henry Qin and Qian Li and Jacqueline Speiser and Peter Kraft and John Ousterhout}, 754 605 title = {Arachne: Core-Aware Thread Management}, 755 organization= {13th {USENIX} Symp. on Oper. Sys. Design and Impl. ({OSDI} 18)},606 booktitle = {13th {USENIX} Symp. on Oper. Sys. Design and Impl. ({OSDI} 18)}, 756 607 year = {2018}, 757 608 address = {Carlsbad, CA}, … … 810 661 author = {Jaewoong Chung and Luke Yen and Stephan Diestelhorst and Martin Pohlack and Michael Hohmuth and David Christie and Dan Grossman}, 811 662 title = {ASF: AMD64 Extension for Lock-Free Data Structures and Transactional Memory}, 812 organization= {Proceedings of the 2010 43rd Annual IEEE/ACM International Symposium on Microarchitecture},663 booktitle = {Proceedings of the 2010 43rd Annual IEEE/ACM International Symposium on Microarchitecture}, 813 664 series = {MICRO '43}, 814 665 year = 2010, … … 831 682 } 832 683 833 @misc{AsyncAwait,834 contributer = {pabuhr@plg},835 key = {AsyncAwait},836 title = {Async Await},837 author = {{WikipediA}},838 howpublished= {\href{https://en.wikipedia.org/wiki/Async/await}{https://\-en.wikipedia.org/\-wiki/\-Async/\-await}},839 year = 2022,840 }841 842 684 @inproceedings{Krischer08, 843 685 keywords = {exception handling, asynchronous, blocked tasks}, … … 845 687 author = {Roy Krischer and Peter A. Buhr}, 846 688 title = {Asynchronous Exception Propagation in Blocked Tasks}, 847 organization= {4th International Workshop on Exception Handling (WEH.08)},689 booktitle = {4th International Workshop on Exception Handling (WEH.08)}, 848 690 optorganization= {16th International Symposium on the Foundations of Software Engineering (FSE 16)}, 849 691 address = {Atlanta, U.S.A}, … … 854 696 855 697 @article{Joung00, 856 keywords = {group mutual exclusion, congenial talking philosophers, resource allocation, shared-memory algorithms},857 698 author = {Joung, Yuh-Jzer}, 858 699 title = {Asynchronous group mutual exclusion}, … … 918 759 publisher = {ACM}, 919 760 address = {New York, NY, USA}, 920 }921 922 @techreport{Neill09,923 author = {Daniel Neill and Adam Wierman},924 title = {On the Benefits of Work Stealing in Shared-Memory Multiprocessors},925 institution = {Carnegie Mellon University},926 address = {California Institute of Technology, Pasadena, CA, USA},927 note = {\href{http://www.cs.cmu.edu/~acw/15740/paper.pdf}{http://\-www.cs.cmu.edu/\-$\sim$acw/\-15740/\-paper.pdf}, Accessed May 2014},928 year = 2009,929 761 } 930 762 … … 1084 916 } 1085 917 1086 @inproceedings{Ding12,1087 keywords = {fairness, multicore, time sharing, work stealing},1088 author = {Ding, Xiaoning and Wang, Kaibo and Gibbons, Phillip B. and Zhang, Xiaodong},1089 title = {BWS: Balanced Work Stealing for Time-sharing Multicores},1090 organization= {Proceedings of the 7th ACM European Conference on Computer Systems},1091 series = {EuroSys '12},1092 year = {2012},1093 location = {Bern, Switzerland},1094 pages = {365-378},1095 publisher = {ACM},1096 address = {New York, NY, USA},1097 }1098 1099 918 % C 1100 919 … … 1171 990 } 1172 991 1173 @inproceedings{CAF,1174 keywords = {performance measurement, actor model, c++, message-oriented middleware, distributed debugging},1175 contributer = {pabuhr@plg},1176 author = {Charousset, Dominik and Hiesgen, Raphael and Schmidt, Thomas C.},1177 title = {{CAF} -- the {C}++ Actor Framework for Scalable and Resource-Efficient Applications},1178 publisher = {ACM},1179 address = {New York, NY, USA},1180 organization= {Proceedings of the 4th International Workshop on Programming Based on Actors Agents \& Decentralized Control},1181 pages = {15-28},1182 numpages = 14,1183 location = {Portland, Oregon, USA},1184 series = {AGERE'14},1185 year = 2014,1186 }1187 1188 992 @techreport{cfa-cc, 1189 993 keywords = {Cforall, cfa-cc, transpiler}, … … 1209 1013 year = 2018, 1210 1014 pages = {2111-2146}, 1211 optnote = {\href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}},1015 note = {\href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}}, 1212 1016 } 1213 1017 … … 1368 1172 @techreport{Prokopec11, 1369 1173 keywords = {ctrie, concurrent map}, 1370 contributer = {a3moss@uwaterloo.ca},1174 contributer = {a3moss@uwaterloo.ca}, 1371 1175 title = {Cache-aware lock-free concurrent hash tries}, 1372 1176 author = {Prokopec, Aleksandar and Bagwell, Phil and Odersky, Martin}, … … 1692 1496 author = {Emery D. Berger and Benjamin G. Zorn and Kathryn S. McKinley}, 1693 1497 title = {Composing High-Performance Memory Allocators}, 1694 organization= {{SIGPLAN} Conference on Programming Language Design and Implementation},1498 booktitle = {{SIGPLAN} Conference on Programming Language Design and Implementation}, 1695 1499 pages = {114-124}, 1696 1500 year = 2001, … … 1870 1674 month = sep, 1871 1675 year = 2020, 1872 note = {\ url{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uC++.pdf}},1676 note = {\href{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uC++.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-pub/\-uSystem/uC++.pdf}}, 1873 1677 } 1874 1678 … … 2004 1808 number = 5, 2005 1809 pages = {1005-1042}, 2006 optnote = {\href{https://onlinelibrary.wiley.com/doi/10.1002/spe.2925}{https://\-onlinelibrary.wiley.com/\-doi/\-10.1002/\-spe.2925}},1810 note = {\href{https://onlinelibrary.wiley.com/doi/10.1002/spe.2925}{https://\-onlinelibrary.wiley.com/\-doi/\-10.1002/\-spe.2925}}, 2007 1811 } 2008 1812 … … 2192 1996 address = {Eindhoven, Neth.}, 2193 1997 year = 1965, 2194 optnote = {Reprinted in \cite{Genuys68} pp. 43--112.}, 2195 note = {\url{https://pure.tue.nl/ws/files/4279816/344354178746665.pdf}}, 1998 note = {Reprinted in \cite{Genuys68} pp. 43--112.} 2196 1999 } 2197 2000 … … 2200 2003 author = {Adya, Atul and Howell, Jon and Theimer, Marvin and Bolosky, William J. and Douceur, John R.}, 2201 2004 title = {Cooperative Task Management Without Manual Stack Management}, 2202 organization= {Proc. of the General Track USENIX Tech. Conf.},2005 booktitle = {Proc. of the General Track USENIX Tech. Conf.}, 2203 2006 series = {ATEC '02}, 2204 2007 year = {2002}, … … 2308 2111 year = 2016, 2309 2112 note = {\href{http://dlang.org/spec/spec.html}{http://\-dlang.org/\-spec/\-spec.html}}, 2310 }2311 2312 @article{Acar02,2313 author = {Acar, Umut A. and Blelloch, Guy E. and Blumofe, Robert D.},2314 title = {The Data Locality of Work Stealing},2315 journal = {Theory of Computing Systems},2316 volume = {35},2317 number = {3},2318 year = {2002},2319 publisher = {Springer-Verlag},2320 pages = {321-347},2321 2113 } 2322 2114 … … 2578 2370 editor = {R. E. A. Mason}, 2579 2371 organization= {IFIP}, 2580 publisher = {North-Holland},2581 summary = {2372 publisher = {North-Holland}, 2373 summary = { 2582 2374 Packages group related declarations or subprograms, and encapsulate 2583 2375 data types. Separate interfaces and bodies promotes information … … 2806 2598 address = {Waterview Corporate Center, 20 Waterview Boulevard, Parsippany, NJ 07054}, 2807 2599 year = {1993} 2808 }2809 2810 @inproceedings{Chen14,2811 keywords = {Core allocation, Multi-programmed, Work-stealing},2812 author = {Chen, Quan and Zheng, Long and Guo, Minyi},2813 title = {DWS: Demand-aware Work-Stealing in Multi-programmed Multi-core Architectures},2814 organization= {Proceedings of Programming Models and Applications on Multicores and Manycores},2815 series = {PMAM'14},2816 year = {2007},2817 location = {Orlando, FL, USA},2818 pages = {131:131-131:139},2819 articleno = {131},2820 numpages = {9},2821 publisher = {ACM},2822 address = {New York, NY, USA},2823 2600 } 2824 2601 … … 2854 2631 year = 2003, 2855 2632 pages = {29-35}, 2856 }2857 2858 @inproceedings{Hamidzadeh96,2859 keywords = {processor scheduling, resource allocation, shared memory systems, average memory referencing delay},2860 author = {Hamidzadeh, B. and Lilja, D.J.},2861 booktitle = {Distributed Computing Systems, 1996., Proceedings of the 16th International Conference on},2862 title = {Dynamic scheduling strategies for shared-memory multiprocessors},2863 year = {1996},2864 month = {May},2865 pages = {208-215},2866 }2867 2868 @article{Hendler06,2869 keywords = {Concurrent programming; Load balancing; Work stealing; Lock-free; Data structures},2870 author = {Hendler, Danny and Lev, Yossi and Moir, Mark and Shavit, Nir},2871 title = {A dynamic-sized nonblocking work stealing deque},2872 journal = {Distributed Computing},2873 volume = {18},2874 number = {3},2875 year = {2006},2876 publisher = {Springer-Verlag},2877 pages = {189-207},2878 2633 } 2879 2634 … … 2979 2734 } 2980 2735 2981 @inproceedings{Blelloch04,2982 keywords = {chip multiprocessors, multithreaded architectures, scheduling algorithms, shared cache},2983 author = {Blelloch, Guy E. and Gibbons, Phillip B.},2984 title = {Effectively Sharing a Cache Among Threads},2985 organization= {Proceedings of the Sixteenth Annual ACM Symposium on Parallelism in Algorithms and Architectures},2986 series = {SPAA '04},2987 year = {2004},2988 location = {Barcelona, Spain},2989 pages = {235-244},2990 publisher = {ACM},2991 address = {New York, NY, USA},2992 }2993 2994 2736 @techreport{Habermann80, 2995 2737 keywords = {Ada, threads}, … … 3066 2808 title = {Encapsulation and Inheritance in Object-Oriented Programming Languages}, 3067 2809 journal = sigplan, 3068 volume = {21}, 3069 number = {11}, 2810 volume = {21}, number = {11}, 3070 2811 pages = {38-45}, 3071 month = nov, 3072 year = 1986, 2812 month = nov, year = 1986, 3073 2813 comment = { 3074 2814 Client, child interfaces should be distinct. Child interface … … 3126 2866 } 3127 2867 3128 @inproceedings{Ribic14,3129 keywords = {dvfs, energy efficiency, language runtimes, thread management, work stealing},3130 author = {Ribic, Haris and Liu, Yu David},3131 title = {Energy-efficient Work-stealing Language Runtimes},3132 organization= {Proceedings of the 19th International Conference on Architectural Support for Programming Languages and Operating Systems},3133 series = {ASPLOS '14},3134 year = {2014},3135 location = {Salt Lake City, Utah, USA},3136 pages = {513-528},3137 publisher = {ACM},3138 address = {New York, NY, USA},3139 }3140 3141 2868 @manual{EPT, 3142 2869 keywords = {concurrency, light-weight threads}, … … 3160 2887 } 3161 2888 3162 @misc{Soleimani16,3163 keywords = {Erlang, scheduler, history},3164 contributer = {pabuhr@plg},3165 author = {Hamidreza Soleimani},3166 title = {Erlang Scheduler Details and Why It Matters},3167 month = feb,3168 year = 2016,3169 howpublished= {\url{https://hamidreza-s.github.io/erlang/scheduling/real-time/preemptive/migration/2016/02/09/erlang-scheduler-details.html}},3170 }3171 3172 2889 @inproceedings{MH88, 3173 2890 keywords = {modules, general sums, general products}, … … 3186 2903 publisher = {North Oxford Academic}, 3187 2904 year = 1985 3188 }3189 3190 @article{Torrellas95,3191 author = {J. Torrellas and A. Tucker and A. Gupta},3192 title = {Evaluating the Performance of Cache-Affinity Scheduling in Shared-Memory Multiprocessors},3193 journal = {Journal of Parallel and Distributed Computing},3194 volume = {24},3195 number = {2},3196 pages = {139-151},3197 year = {1995},3198 2905 } 3199 2906 … … 3907 3614 author = {Robert Griesemer and Rob Pike and Ken Thompson}, 3908 3615 title = {{Go} Programming Language}, 3909 address = {Mountain View, CA, USA},3910 3616 organization= {Google}, 3911 3617 year = 2009, … … 4019 3725 @article{Michael04a, 4020 3726 keywords = {Lock-free, synchronization, concurrent programming, memory management, multiprogramming, dynamic data structures}, 4021 contributer = {pabuhr@plg},4022 3727 author = {Maged M. Michael}, 4023 3728 title = {Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects}, … … 4030 3735 publisher = {IEEE Press}, 4031 3736 address = {Piscataway, NJ, USA}, 4032 }4033 4034 @inproceedings{Johansson02,4035 keywords = {concurrent languages, erlang, garbage collection, message passing, runtime systems},4036 contributer = {pabuhr@plg},4037 author = {Erik Johansson and Konstantinos Sagonas and Jesper Wilhelmsson},4038 title = {Heap Architectures for Concurrent Languages Using Message Passing},4039 year = {2002},4040 isbn = {1581135394},4041 publisher = {ACM},4042 address = {New York, NY, USA},4043 organization= {Proceedings of the 3rd International Symposium on Memory Management},4044 pages = {88-99},4045 location = {Berlin, Germany},4046 3737 } 4047 3738 … … 4223 3914 title = {Implementing Lock-Free Queues}, 4224 3915 booktitle = {Seventh International Conference on Parallel and Distributed Computing Systems}, 4225 organization= {International Society for Computers and Their Applications},4226 3916 address = {Las Vegas, Nevada, U.S.A.}, 4227 3917 year = {1994}, 4228 3918 pages = {64-69}, 4229 }4230 4231 @inproceedings{Halstead84,4232 author = {Halstead,Jr., Robert H.},4233 title = {Implementation of Multilisp: Lisp on a Multiprocessor},4234 organization= {Proceedings of the 1984 ACM Symposium on LISP and Functional Programming},4235 series = {LFP '84},4236 year = {1984},4237 location = {Austin, Texas, USA},4238 pages = {9-17},4239 publisher = {ACM},4240 address = {New York, NY, USA},4241 3919 } 4242 3920 … … 5017 4695 contributer = {pabuhr@plg}, 5018 4696 author = {Lua}, 5019 title = {Lua 5.4 Reference Manual}, 5020 organization= {Pontifical Catholic University}, 5021 address = {\href{https://www.lua.org/manual/5.4}{https://\-www.lua.org/\-manual/\-5.4}}, 5022 year = 2020, 4697 title = {Lua 5.3 Reference Manual}, 4698 address = {\href{https://www.lua.org/manual/5.3}{https://\-www.lua.org/\-manual/\-5.3}}, 4699 year = 2018, 5023 4700 } 5024 4701 … … 5087 4764 } 5088 4765 5089 @m isc{MMTk,4766 @manual{MMTk, 5090 4767 keywords = {Java memory management}, 5091 4768 contributer = {pabuhr@plg}, … … 5094 4771 month = sep, 5095 4772 year = 2006, 5096 howpublished= {\url{http://cs.anu.edu.au/~Robin.Garner/mmtk-guide.pdf}}, 4773 note = {\href{http://cs.anu.edu.au/~Robin.Garner/mmtk-guide.pdf} 4774 {http://cs.anu.edu.au/\-$\sim$Robin.Garner/\-mmtk-guide.pdf}}, 5097 4775 } 5098 4776 … … 5400 5078 year = 2015, 5401 5079 note = {\href{http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf}{http://www.mpi-forum.org/\-docs/\-mpi-3.1/\-mpi31-report.pdf}}, 5402 }5403 5404 @article{Lombardo19,5405 contributer = {pabuhr@plg},5406 author = {Lombardo, Gianfranco and Fornacciari, Paolo and Mordonini, Monica and Tomaiuolo, Michele and Poggi, Agostino},5407 title = {A Multi-Agent Architecture for Data Analysis},5408 journal = {Future Internet},5409 volume = 11,5410 year = 2019,5411 number = 2,5412 5080 } 5413 5081 … … 5609 5277 Programming Language}, 5610 5278 year = 1980, 5611 month = dec, 5612 pages = {139-145}, 5279 month = dec, pages = {139-145}, 5613 5280 note = {SIGPLAN Notices, v. 15, n. 11}, 5614 5281 abstract = { … … 5731 5398 year = 2005, 5732 5399 pages = {146-196}, 5733 publisher = {ACM},5734 address = {New York, NY, USA},5735 }5736 5737 @inproceedings{Hendler02,5738 author = {Hendler, Danny and Shavit, Nir},5739 title = {Non-blocking Steal-half Work Queues},5740 organization= {Proceedings of the Twenty-first Annual Symposium on Principles of Distributed Computing},5741 series = {PODC '02},5742 year = {2002},5743 location = {Monterey, California},5744 pages = {280-289},5745 5400 publisher = {ACM}, 5746 5401 address = {New York, NY, USA}, … … 5991 5646 } 5992 5647 5993 @misc{OpenTelemetry,5994 contributer = {pabuhr@plg},5995 key = {OpenTelemetry},5996 title = {OpenTelemetry},5997 author = {{Asynkron AB}},5998 howpublished= {\href{https://proto.actor/docs/tracing}{https://\-proto.actor/\-docs/\-tracing}},5999 year = 2022,6000 }6001 6002 5648 @inproceedings{Krebbers14, 6003 5649 keywords = {c formalization}, … … 6237 5883 } 6238 5884 6239 @article{Nigro21,6240 keywords = {Actors, Asynchronous messages, Reflective control on message passing, Lock-free parallel computing, Java, Scalable multi-agent systems, Parallel matrix multiplication, Iterated Prisoner's Dilemma},6241 contributer = {pabuhr@plg},6242 author = {Libero Nigro},6243 title = {Parallel Theatre: An actor framework in {Java} for high performance computing},6244 journal = {Simulation Modelling Practice and Theory},6245 volume = {106},6246 number = {102189},6247 year = {2021},6248 }6249 6250 5885 @incollection{Stroustrup96, 6251 5886 keywords = {concurrency, C++}, … … 6282 5917 journal = ieeese, 6283 5918 year = 1984, 6284 month = sep, 6285 volume = "SE-10", 6286 number = 5, 6287 pages = {528-543}, 5919 month = sep, volume = "SE-10", number = 5, pages = {528-543}, 6288 5920 abstract = { 6289 5921 Parameterized programming is a powerful technique for the reliable … … 6317 5949 booktitle = {USENIX {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Conference}, 6318 5950 organization= {USENIX Association}, 6319 year = 1988, 6320 pages = {1-18}, 5951 year = 1988, pages = {1-18} 6321 5952 } 6322 5953 … … 6406 6037 } 6407 6038 6408 @incollection{Kazempour08,6409 keywords = {multicore processors; cache affinity; performance evaluation; scheduling},6410 author = {Kazempour, Vahid and Fedorova, Alexandra and Alagheband, Pouya},6411 title = {Performance Implications of Cache Affinity on Multicore Processors},6412 organization= {Euro-Par 2008 -- Parallel Processing},6413 series = {Lecture Notes in Computer Science},6414 editor = {Luque, Emilio and Margalef, Tomas and Benitez, Domingo},6415 year = {2008},6416 volume = {5168},6417 pages = {151-161},6418 publisher = {Springer Berlin Heidelberg},6419 }6420 6421 @article{Anderson89,6422 keywords = {data structures, multiprocessing systems, operating systems (computers), performance evaluation, critical resource waiting},6423 author = {Anderson, T.E. and Lazowska, E.D. and Levy, H.M.},6424 journal = {Computers, IEEE Transactions on},6425 title = {The Performance Implications of Thread Management Alternatives for Shared-Memory Multiprocessors},6426 year = {1989},6427 month = {Dec},6428 volume = {38},6429 number = {12},6430 pages = {1631-1644},6431 }6432 6433 6039 @article{Anderson90, 6434 6040 keywords = {spin locks, back off, performance}, … … 6442 6048 number = 1, 6443 6049 pages = {6-16}, 6444 }6445 6446 @article{Blumofe98,6447 author = {Blumofe, Robert D. and Papadopoulos, Dionisios},6448 title = {The Performance of Work Stealing in Multiprogrammed Environments (Extended Abstract)},6449 journal = {SIGMETRICS Perform. Eval. Rev.},6450 volume = {26},6451 number = {1},6452 month = jun,6453 year = {1998},6454 issn = {0163-5999},6455 pages = {266-267},6456 publisher = {ACM},6457 address = {New York, NY, USA},6458 6050 } 6459 6051 … … 6694 6286 } 6695 6287 6696 @article{Varela01,6697 keywords = {programming languages, SALSA, continuations, actors, java, internet, network computing, open systems, mobile computing},6698 contributer = {pabuhr@plg},6699 author = {Varela, Carlos and Agha, Gul},6700 title = {Programming Dynamically Reconfigurable Open Systems with SALSA},6701 issue_date = {December 2001},6702 publisher = {Association for Computing Machinery},6703 address = {New York, NY, USA},6704 volume = 36,6705 number = 12,6706 journal = {SIGPLAN Not.},6707 year = 2001,6708 month = dec,6709 pages = {20-34},6710 }6711 6712 6288 @book{PowerPC, 6713 6289 key = {PowerPC processor}, … … 6771 6347 title = {Programming Languages -- {C}}, 6772 6348 organization= {International Standard ISO/IEC 9899:1999 (E)}, 6773 publisher = {American National Standards Institute},6349 publisher = {American National Standards Institute}, 6774 6350 address = {www.ansi.org}, 6775 6351 year = 1999, … … 6782 6358 title = {{C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Programming Language ISO/IEC 14882:1998}, 6783 6359 edition = {1st}, 6784 organization = {International Standard Organization},6360 organization = {International Standard Organization}, 6785 6361 address = {Geneva, Switzerland}, 6786 6362 year = 1998, … … 7073 6649 } 7074 6650 7075 @misc{protoactor,7076 contributer = {pabuhr@plg},7077 key = {Protoactor},7078 author = {{proto.actor}},7079 title = {Asynkron AB},7080 year = 2023,7081 howpublished= {\url{https://proto.actor}},7082 }7083 7084 6651 @misc{Pthreads, 7085 6652 keywords = {pthreads, C concurrency}, … … 7193 6760 } 7194 6761 7195 @inproceedings{Bacon03, 7196 keywords = {utilization, real-time scheduling, read barrier, defragmentation}, 7197 contributer = {pabuhr@plg}, 7198 author = {David F. Bacon and Perry Cheng and V. T. Rajan}, 7199 title = {A Real-Time Garbage Collector with Low Overhead and Consistent Utilization}, 7200 year = {2003}, 7201 organization= {Proceedings of the 30th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages}, 7202 publisher = {ACM}, 7203 address = {New York, NY, USA}, 7204 pages = {285-298}, 7205 location = {New Orleans, Louisiana, USA}, 6762 @manual{Ada95, 6763 keywords = {Ada}, 6764 contributer = {pabuhr@plg}, 6765 title = {{A}da Reference Manual}, 6766 edition = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}}, 6767 organization= {Intermetrics, Inc.}, 6768 month = dec, 6769 year = 1995, 6770 note = {Language and Standards Libraries} 6771 } 6772 6773 @manual{Ada12, 6774 keywords = {ISO/IEC Ada}, 6775 contributer = {pabuhr@plg}, 6776 author = {Ada12}, 6777 title = {Programming languages -- {Ada} ISO/IEC 8652:2012}, 6778 edition = {3rd}, 6779 organization= {International Standard Organization}, 6780 address = {Geneva, Switzerland}, 6781 year = 2012, 6782 note = {\href{https://www.iso.org/standard/61507.html}{https://\-www.iso.org/\-standard/\-61507.html}}, 6783 } 6784 6785 @manual{Ada95:annotated, 6786 keywords = {Ada}, 6787 contributer = {pabuhr@plg}, 6788 title = {Annotated {A}da Reference Manual}, 6789 edition = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}}, 6790 organization = {Intermetrics, Inc.}, 6791 month = dec, 6792 year = 1995, 6793 note = {Language and Standards Libraries} 7206 6794 } 7207 6795 … … 7339 6927 journal = sigplan, 7340 6928 year = 1991, 7341 month = oct, 7342 volume = 26, 7343 number = 10, 7344 pages = {29-43}, 6929 month = oct, volume = 26, number = 10, pages = {29-43}, 7345 6930 abstract = { 7346 6931 {\tt lcc} is a new retargetable compiler for ANSI C. Versions for … … 7402 6987 } 7403 6988 7404 @misc{rpmalloc,7405 author = {Mattias Jansson},7406 title = {rpmalloc version 1.4.1},7407 month = apr,7408 year = 2022,7409 howpublished= {\href{https://github.com/mjansson/rpmalloc}{https://\-github.com/\-mjansson/\-rpmalloc}},7410 }7411 7412 6989 @manual{Rust, 7413 6990 keywords = {Rust programming language}, … … 7440 7017 publisher = {ACM}, 7441 7018 address = {New York, NY, USA}, 7442 organization= {Proceedings of the 4th International Workshop on Programming Based on Actors Agents \& Decentralized Control},7019 booktitle = {Proceedings of the 4th International Workshop on Programming Based on Actors Agents \& Decentralized Control}, 7443 7020 pages = {67-80}, 7444 7021 numpages = {14}, … … 7464 7041 booktitle = {PLDI '04: Proceedings of the ACM SIGPLAN 2004 Conference on Programming Language Design and Implementation}, 7465 7042 location = {Washington DC, USA}, 7466 organization= {ACM},7043 publisher = {ACM}, 7467 7044 address = {New York, NY, USA}, 7468 7045 volume = 39, … … 7470 7047 month = jun, 7471 7048 pages = {35-46}, 7472 }7473 7474 @article{Nickolls08,7475 author = {Nickolls, John and Buck, Ian and Garland, Michael and Skadron, Kevin},7476 title = {Scalable Parallel Programming with CUDA},7477 journal = {Queue},7478 volume = {6},7479 number = {2},7480 month = mar,7481 year = 2008,7482 pages = {40-53},7483 publisher = {ACM},7484 address = {New York, NY, USA},7485 7049 } 7486 7050 … … 7498 7062 } 7499 7063 7500 @article{Blumofe99,7501 keywords = {critical-path length, multiprocessor, multithreading, randomized algorithm, thread scheduling, work stealing},7502 author = {Blumofe, Robert D. and Leiserson, Charles E.},7503 title = {Scheduling Multithreaded Computations by Work Stealing},7504 journal = {Journal of the ACM},7505 volume = {46},7506 number = {5},7507 month = sep,7508 year = {1999},7509 pages = {720-748},7510 publisher = {ACM},7511 address = {New York, NY, USA},7512 }7513 7514 @inproceedings{Acar13,7515 keywords = {dynamic load balancing, nested parallelism, work stealing},7516 author = {Acar, Umut A. and Chargueraud, Arthur and Rainey, Mike},7517 title = {Scheduling Parallel Programs by Work Stealing with Private Deques},7518 organization= {Proceedings of the 18th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming},7519 series = {PPoPP '13},7520 year = {2013},7521 location = {Shenzhen, China},7522 pages = {219-228},7523 publisher = {ACM},7524 address = {New York, NY, USA},7525 }7526 7527 @inproceedings{Chen07,7528 keywords = {chip multiprocessors, constructive cache sharing, parallel depth first, scheduling algorithms, thread granularity, work stealing, working set profiling},7529 author = {Chen, Shimin and Gibbons, Phillip B. and Kozuch, Michael and Liaskovitis, Vasileios and Ailamaki, Anastassia and Blelloch, Guy E. and Falsafi, Babak and Fix, Limor and Hardavellas, Nikos and Mowry, Todd C. and Wilkerson, Chris},7530 title = {Scheduling Threads for Constructive Cache Sharing on CMPs},7531 organization= {Proceedings of the Nineteenth Annual ACM Symposium on Parallel Algorithms and Architectures},7532 series = {SPAA '07},7533 year = {2007},7534 location = {San Diego, California, USA},7535 pages = {105-115},7536 numpages = {11},7537 publisher = {ACM},7538 address = {New York, NY, USA},7539 }7540 7541 7064 @manual{SELF, 7542 7065 keywords = {programming language, obect-oriented, polymorphism}, … … 7560 7083 publisher = {Springer}, 7561 7084 note = {Lecture Notes in Computer Science v. 173}, 7562 }7563 7564 @inproceedings{Kahn74,7565 keywords = {programming language, obect-oriented, polymorphism},7566 contributer = {pabuhr@plg},7567 title = {The Semantics of a Simple Language for Parallel Programming},7568 author = {Gilles Kahn},7569 organization= {IFIP Congress},7570 year = 1974,7571 7085 } 7572 7086 … … 7629 7143 number = 12, 7630 7144 pages = {66-76}, 7631 }7632 7633 @book{Scott13,7634 author = {Michael L. Scott},7635 title = {Shared-Memory Synchronization},7636 publisher = {Morgan \& Claypool},7637 year = 2013,7638 }7639 7640 @inproceedings{Leissa14,7641 title = {{S}ierra: a {SIMD} extension for {C}++},7642 author = {Lei{\ss}a, Roland and Haffner, Immanuel and Hack, Sebastian},7643 booktitle = {Proceedings of the 2014 Workshop on Workshop on programming models for SIMD/Vector processing},7644 pages = {17-24},7645 year = {2014},7646 organization= {ACM}7647 7145 } 7648 7146 … … 8282 7780 8283 7781 @article{SysVABI, 8284 keywords = {System V ABI},8285 contributer = {a3moss@uwaterloo.ca},7782 keywords = {System V ABI}, 7783 contributer = {a3moss@uwaterloo.ca}, 8286 7784 title = {System {V} application binary interface}, 8287 7785 author = {Matz, Michael and Hubicka, Jan and Jaeger, Andreas and Mitchell, Mark}, … … 8289 7787 volume = {99}, 8290 7788 year = {2013} 8291 }8292 8293 @article{Albert18,8294 keywords = {actor-based concurrency, partial order reduction, systematic testing, synchronization, task independence},8295 contributer = {pabuhr@plg},8296 author = {Albert, Elvira and Arenas, Puri and G\'{o}mez-Zamalloa, Miguel},8297 title = {Systematic testing of actor systems},8298 journal = {Software Testing, Verification and Reliability},8299 volume = {28},8300 number = {3},8301 pages = {e1661},8302 year = {2018}8303 7789 } 8304 7790 … … 8327 7813 journal = jcss, 8328 7814 year = 1978, 8329 volume = 17, 8330 pages = {348-375}, 7815 volume = 17, pages = {348-375} 8331 7816 } 8332 7817 … … 8339 7824 address = {New York, New York, U.S.A.}, 8340 7825 year = 1982 8341 }8342 8343 @article{Arora01,8344 author = {Arora, N. S. and Blumofe, R. D. and Plaxton, C. G.},8345 title = {Thread Scheduling for Multiprogrammed Multiprocessors},8346 journal = {Theory of Computing Systems},8347 year = {2001},8348 volume = {34},8349 number = {2},8350 pages = {115-144},8351 publisher = {Springer-Verlag},8352 7826 } 8353 7827 … … 8579 8053 } 8580 8054 8581 @misc{AkkaBecome,8582 contributer = {pabuhr@plg},8583 key = {AkkaBecome},8584 title = {Typed Actors},8585 author = {{Lightbend}},8586 howpublished= {\href{https://doc.akka.io/docs/akka/2.5/typed-actors.html}{https://\-doc.akka.io/\-docs/\-akka/\-2.5/\-typed-actors.html}},8587 year = 2022,8588 }8589 8590 8055 @article{concatenation, 8591 8056 keywords = {record concatenation, isa}, … … 8652 8117 author = {Paul R. Wilson}, 8653 8118 title = {Uniprocessor Garbage Collection Techniques}, 8654 organization= {Proceedings of the International Workshop on Memory Management},8119 booktitle = {Proceedings of the International Workshop on Memory Management}, 8655 8120 location = {St. Malo, France}, 8656 8121 publisher = {Springer}, … … 8665 8130 author = {Carl Hewitt and Peter Bishop and Richard Steiger}, 8666 8131 title = {A Universal Modular {ACTOR} Formalism for Artificial Intelligence}, 8667 organization= {Proceedings of the 3rd International Joint Conference on Artificial Intelligence},8132 booktitle = {Proceedings of the 3rd International Joint Conference on Artificial Intelligence}, 8668 8133 address = {Standford, California, U.S.A.}, 8669 8134 pages = {235-245}, 8670 location = {Stanford, USA},8671 series = {IJCAI'73},8672 8135 month = aug, 8673 8136 year = 1973, … … 8701 8164 @article{Karsten20, 8702 8165 author = {Karsten, Martin and Barghi, Saman}, 8703 title = { User-level Threading: Have Your Cake and Eat It Too},8166 title = {{User-level Threading: Have Your Cake and Eat It Too}}, 8704 8167 year = {2020}, 8705 8168 issue_date = {March 2020}, … … 8726 8189 } 8727 8190 8728 @article{Squillante93,8729 keywords = {buffer storage, performance evaluation, queueing theory, scheduling, shared memory systems, processor-cache affinity},8730 author = {Squillante, M.S. and Lazowska, E.D.},8731 title = {Using Processor-Cache Affinity Information in Shared-Memory Multiprocessor Scheduling},8732 journal = {Parallel and Distributed Systems, IEEE Transactions on},8733 year = {1993},8734 month = {Feb},8735 volume = {4},8736 number = {2},8737 pages = {131-143},8738 }8739 8740 8191 @article{delegation, 8741 8192 keywords = {delegation, inheritance, actors}, … … 8887 8338 year = 2003, 8888 8339 pages = {19-24}, 8889 }8890 8891 @inproceedings{Saman18,8892 keywords = {actors, scheduling, NUMA, locality},8893 contributer = {pabuhr@plg},8894 author = {Saman Barghi and Martin Karsten},8895 organization= {2018 IEEE International Parallel and Distributed Processing Symposium (IPDPS)},8896 title = {Work-Stealing, Locality-Aware Actor Scheduling},8897 year = {2018},8898 address = {Vancouver, BC, Canada},8899 pages = {484-494},8900 }8901 8902 @article{Wimmer13,8903 keywords = {priorities, scheduler hints, strategies, work-stealing},8904 author = {Wimmer, Martin and Cederman, Daniel and Tr\"{a}ff, Jesper Larsson and Tsigas, Philippas},8905 title = {Work-stealing with Configurable Scheduling Strategies},8906 journal = {SIGPLAN Not.},8907 issue_date = {August 2013},8908 volume = {48},8909 number = {8},8910 month = feb,8911 year = {2013},8912 issn = {0362-1340},8913 pages = {315-316},8914 publisher = {ACM},8915 address = {New York, NY, USA},8916 8340 } 8917 8341 -
doc/theses/mike_brooks_MMath/Makefile
r24d6572 r34b4268 8 8 PicSRC = ${notdir ${wildcard ${Pictures}/*.png}} 9 9 DemoSRC = ${notdir ${wildcard ${Programs}/*-demo.cfa}} 10 PgmSRC = ${notdir ${wildcard ${Programs}/*}} 11 RunPgmSRC = ${notdir ${wildcard ${Programs}/*.run.*}} 10 PgmSRC = ${notdir ${wildcard ${Programs}/*.cfa}} 12 11 BibSRC = ${wildcard *.bib} 13 12 … … 15 14 BibLIB = .:../../bibliography # common citation repository 16 15 17 #MAKEFLAGS = --no-print-directory # --silent16 MAKEFLAGS = --no-print-directory # --silent 18 17 VPATH = ${Build} ${Pictures} ${Programs} # extra search path for file names used in document 19 18 … … 21 20 BASE = ${basename ${DOCUMENT}} # remove suffix 22 21 23 DemoTex = ${DemoSRC:%.cfa=${Build}/%.tex}24 RunPgmExe = ${addprefix ${Build}/,${basename ${basename ${RunPgmSRC}}}}25 RunPgmOut = ${RunPgmExe:%=%.out}26 27 22 # Commands 28 23 29 24 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && pdflatex -halt-on-error -output-directory=${Build} 30 25 BibTeX = BIBINPUTS=${BibLIB} && export BIBINPUTS && bibtex 31 CFA = cfa -O0 -g 32 CC = gcc -O0 -g 33 CXX = g++-11 --std=c++20 -O0 -g 26 CFA = cfa 34 27 35 28 # Rules and Recipes 36 29 37 .PHONY : all fragments_ran clean # not file names 38 .PRECIOUS : ${Build}/% ${Build}/%-demo # don't delete intermediates 30 .PHONY : all clean # not file names 39 31 .ONESHELL : 40 32 41 all : fragments_ran ${DOCUMENT} 42 43 fragments_ran : $(RunPgmOut) 33 all : ${DOCUMENT} 44 34 45 35 clean : … … 48 38 # File Dependencies 49 39 50 %.pdf : ${TeXSRC} ${Demo Tex} ${PicSRC} ${PgmSRC} ${BibSRC} Makefile | ${Build}40 %.pdf : ${TeXSRC} ${DemoSRC:%.cfa=%.tex} ${PicSRC} ${PgmSRC} ${BibSRC} Makefile | ${Build} 51 41 ${LaTeX} ${BASE} 52 42 ${BibTeX} ${Build}/${BASE} … … 62 52 63 53 %-demo.tex: %-demo | ${Build} 64 $ < >$@54 ${Build}/$< > ${Build}/$@ 65 55 66 ${Build}/%-demo: ${Programs}/%-demo.cfa | ${Build} 67 ${CFA} $< -o $ @56 %-demo: %-demo.cfa 57 ${CFA} $< -o ${Build}/$@ 68 58 69 ${Build}/%: ${Programs}/%.run.cfa | ${Build}70 ${CFA} $< -o $@71 72 ${Build}/%: ${Programs}/%.run.c | ${Build}73 ${CC} $< -o $@74 75 ${Build}/%: ${Programs}/%.run.cpp | ${Build}76 ${CXX} -MMD $< -o $@77 78 ${Build}/%.out: ${Build}/% | ${Build}79 $< > $@80 81 -include ${Build}/*.d -
doc/theses/mike_brooks_MMath/uw-ethesis.bib
r24d6572 r34b4268 65 65 bibsource = {dblp computer science bibliography, https://dblp.org} 66 66 } 67 68 % --------------------------------------------------69 % Linked-list prior work70 71 @misc{CFAStackEvaluation,72 contributer = {a3moss@plg},73 author = {Aaron Moss},74 title = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs},75 year = 2018,76 howpublished= {\href{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}{https://cforall.uwaterloo.ca/\-CFAStackEvaluation.zip}},77 }78 79 @misc{lst:linuxq,80 title = {queue(7) — Linux manual page},81 howpublished= {\href{https://man7.org/linux/man-pages/man3/queue.3.html}{https://man7.org/linux/man-pages/man3/queue.3.html}},82 }83 % see also https://man7.org/linux/man-pages/man7/queue.7.license.html84 % https://man7.org/tlpi/85 % https://www.kernel.org/doc/man-pages/86 87 @misc{lst:stl,88 title = {std::list},89 howpublished= {\href{https://en.cppreference.com/w/cpp/container/list}{https://en.cppreference.com/w/cpp/container/list}},90 }91 -
doc/theses/mike_brooks_MMath/uw-ethesis.tex
r24d6572 r34b4268 60 60 % For hyperlinked PDF, suitable for viewing on a computer, use this: 61 61 \documentclass[letterpaper,12pt,titlepage,oneside,final]{book} 62 \usepackage{times}63 62 \usepackage[T1]{fontenc} % Latin-1 => 256-bit characters, => | not dash, <> not Spanish question marks 64 63 … … 88 87 \usepackage{comment} % Removes large sections of the document. 89 88 \usepackage{tabularx} 90 \usepackage[labelformat=simple,aboveskip=0pt,farskip=0pt,font=normalsize]{subfig} 91 \renewcommand\thesubfigure{(\alph{subfigure})} 89 \usepackage{subfigure} 92 90 93 91 \usepackage{algorithm} … … 117 115 citecolor=blue, % color of links to bibliography 118 116 filecolor=magenta, % color of file links 119 urlcolor=blue, % color of external links 120 breaklinks=true 117 urlcolor=blue % color of external links 121 118 } 122 119 \ifthenelse{\boolean{PrintVersion}}{ % for improved print quality, change some hyperref options … … 132 129 % although it's supposed to be in both the TeX Live and MikTeX distributions. There are also documentation and 133 130 % installation instructions there. 134 135 % Customizing tabularx136 \newcolumntype{Y}{>{\centering\arraybackslash}X}137 131 138 132 % Setting up the page margins... … … 181 175 \CFAStyle % CFA code-style 182 176 \lstset{language=CFA} % default language 183 \lstset{basicstyle=\linespread{0.9}\ sf} % CFA typewriter font177 \lstset{basicstyle=\linespread{0.9}\tt} % CFA typewriter font 184 178 \lstset{inputpath={programs}} 185 179 \newcommand{\PAB}[1]{{\color{red}PAB: #1}} 186 187 \newcommand{\uCpp}{$\mu$\CC}188 180 189 181 %====================================================================== … … 209 201 %---------------------------------------------------------------------- 210 202 \begin{sloppypar} 203 211 204 \input{intro} 212 205 \input{background} 213 \input{list}214 206 \input{array} 215 207 \input{string} -
driver/cfa.cc
r24d6572 r34b4268 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 30 10:47:52 202313 // Update Count : 4 7812 // Last Modified On : Wed Jul 14 21:55:12 2021 13 // Update Count : 467 14 14 // 15 15 … … 44 44 static int flags = 0; 45 45 46 // This allocation 'leaks' memory from the program to the execution47 // environment, as putenv does not manage the storage of the string used48 // as an environment variable. This leak is necessary to ensure the49 // underlying C string is allocated long enough.50 46 if ( putenv( (char *)( *new string( string( __CFA_FLAGPREFIX__ + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) ) { 51 47 cerr << argv[0] << " error, cannot set environment variable." << endl; … … 202 198 } // if 203 199 } else if ( arg == "-CFA" ) { 204 CFA_flag = true; // strip -CFA flag200 CFA_flag = true; // strip the -CFA flag 205 201 link = false; 206 202 args[nargs++] = "-fsyntax-only"; // stop after stage 2 207 203 } else if ( arg == "-debug" ) { 208 debug = true; // strip debug flag204 debug = true; // strip the debug flag 209 205 } else if ( arg == "-nodebug" ) { 210 debug = false; // strip nodebug flag206 debug = false; // strip the nodebug flag 211 207 } else if ( arg == "-quiet" ) { 212 quiet = true; // strip quiet flag208 quiet = true; // strip the quiet flag 213 209 } else if ( arg == "-noquiet" ) { 214 quiet = false; // strip noquiet flag 215 } else if ( arg == "-invariant" ) { 216 Putenv( argv, "-" + arg ); 217 } else if ( arg == "--invariant" ) { 218 Putenv( argv, arg ); 210 quiet = false; // strip the noquiet flag 219 211 } else if ( arg == "-no-include-stdhdr" ) { 220 noincstd_flag = true; // strip no-include-stdhdr flag212 noincstd_flag = true; // strip the no-include-stdhdr flag 221 213 } else if ( arg == "-nolib" ) { 222 nolib = true; // strip nolib flag214 nolib = true; // strip the nolib flag 223 215 } else if ( arg == "-help" ) { 224 help = true; // strip help flag216 help = true; // strip the help flag 225 217 } else if ( arg == "-nohelp" ) { 226 help = false; // strip nohelp flag218 help = false; // strip the nohelp flag 227 219 } else if ( arg == "-cfalib") { 228 220 compiling_libs = true; … … 282 274 } // if 283 275 } else if ( prefix( arg, "-B" ) ) { 284 bprefix = arg.substr(2); // strip -B flag276 bprefix = arg.substr(2); // strip the -B flag 285 277 } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) { 286 278 args[nargs++] = argv[i]; // pass flag along … … 329 321 #endif // __x86_64__ 330 322 331 // ARM -mno-outline-atomics => use LL/SC instead of calls to atomic routines: __aarch64_swp_acq_rel, __aarch64_cas8_acq_rel332 // ARM -march=armv8.2-a+lse => generate Arm LSE extension instructions SWAP and CAS333 // https://community.arm.com/developer/tools-software/tools/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10334 #ifdef __ARM_ARCH335 args[nargs++] = "-mno-outline-atomics"; // use ARM LL/SC instructions for atomics336 #endif // __ARM_ARCH337 338 323 #ifdef __DEBUG_H__ 339 324 cerr << "args:"; … … 459 444 460 445 args[nargs++] = "-fexceptions"; // add exception flags (unconditionally) 461 args[nargs++] = "-D_GNU_SOURCE"; // force gnu libraries462 446 463 447 // add flags based on the type of compile -
libcfa/configure.ac
r24d6572 r34b4268 122 122 AC_PROG_CC 123 123 AM_PROG_AS 124 LT_INIT 124 AC_PROG_LIBTOOL 125 125 AC_PROG_INSTALL 126 126 AC_PROG_MAKE_SET … … 246 246 AC_CONFIG_HEADERS(prelude/defines.hfa) 247 247 248 AC_OUTPUT 248 AC_OUTPUT() 249 249 250 250 # Final text -
libcfa/prelude/builtins.c
r24d6572 r34b4268 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:33:56 202313 // Update Count : 13 512 // Last Modified On : Sat Aug 14 08:45:54 2021 13 // Update Count : 133 14 14 // 15 15 … … 64 64 static inline void ^?{}(generator$ &) {} 65 65 66 forall( T & ) 67 trait is_generator { 66 trait is_generator(T &) { 68 67 void main(T & this); 69 68 generator$ * get_generator(T & this); … … 149 148 150 149 static inline { 151 int ?\?( int x, unsigned int y ) { __CFA_EXP__(); }150 long int ?\?( int x, unsigned int y ) { __CFA_EXP__(); } 152 151 long int ?\?( long int x, unsigned long int y ) { __CFA_EXP__(); } 153 152 long long int ?\?( long long int x, unsigned long long int y ) { __CFA_EXP__(); } 154 153 // unsigned computation may be faster and larger 155 unsigned int ?\?( unsigned int x, unsigned int y ) { __CFA_EXP__(); }154 unsigned long int ?\?( unsigned int x, unsigned int y ) { __CFA_EXP__(); } 156 155 unsigned long int ?\?( unsigned long int x, unsigned long int y ) { __CFA_EXP__(); } 157 156 unsigned long long int ?\?( unsigned long long int x, unsigned long long int y ) { __CFA_EXP__(); } … … 176 175 177 176 static inline { 178 int ?\=?( int & x, unsigned int y ) { x = x \ y; return x; }177 long int ?\=?( int & x, unsigned int y ) { x = x \ y; return x; } 179 178 long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; } 180 179 long long int ?\=?( long long int & x, unsigned long long int y ) { x = x \ y; return x; } 181 unsigned int ?\=?( unsigned int & x, unsigned int y ) { x = x \ y; return x; }180 unsigned long int ?\=?( unsigned int & x, unsigned int y ) { x = x \ y; return x; } 182 181 unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; } 183 182 unsigned long long int ?\=?( unsigned long long int & x, unsigned long long int y ) { x = x \ y; return x; } -
libcfa/prelude/prelude-gen.cc
r24d6572 r34b4268 10 10 // Created On : Sat Feb 16 08:44:58 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 2 11:40:01 202313 // Update Count : 3 812 // Last Modified On : Tue Apr 2 17:18:24 2019 13 // Update Count : 37 14 14 // 15 15 … … 159 159 int main() { 160 160 cout << "# 2 \"prelude.cfa\" // needed for error messages from this file" << endl; 161 cout << " forall( T & ) trait sized{};" << endl;161 cout << "trait sized(T &) {};" << endl; 162 162 163 163 cout << "//////////////////////////" << endl; -
libcfa/src/Makefile.am
r24d6572 r34b4268 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Thu May 25 15:20:04 202314 ## Update Count : 25 913 ## Last Modified On : Fri Jul 16 16:00:40 2021 14 ## Update Count : 255 15 15 ############################################################################### 16 16 … … 48 48 math.hfa \ 49 49 time_t.hfa \ 50 virtual_dtor.hfa \51 50 bits/algorithm.hfa \ 52 51 bits/align.hfa \ … … 59 58 bits/queue.hfa \ 60 59 bits/sequence.hfa \ 61 concurrency/atomic.hfa \62 60 concurrency/iofwd.hfa \ 63 61 concurrency/barrier.hfa \ … … 115 113 concurrency/once.hfa \ 116 114 concurrency/kernel/fwd.hfa \ 117 concurrency/mutex_stmt.hfa \ 118 concurrency/channel.hfa \ 119 concurrency/actor.hfa 115 concurrency/mutex_stmt.hfa 120 116 121 117 inst_thread_headers_src = \ … … 128 124 concurrency/monitor.hfa \ 129 125 concurrency/mutex.hfa \ 130 concurrency/select.hfa \131 126 concurrency/thread.hfa 132 127 -
libcfa/src/algorithms/range_iterator.hfa
r24d6572 r34b4268 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Nov 30 13:06:22 2021 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Mar 13 23:10:35 202313 // Update Count : 111 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 14 14 // 15 16 #pragma once17 15 18 16 generator RangeIter { -
libcfa/src/bitmanip.hfa
r24d6572 r34b4268 11 11 // Created On : Sat Mar 14 18:12:27 2020 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Mon Jan 9 09:02:43 202314 // Update Count : 14 413 // Last Modified On : Sat Oct 8 08:28:15 2022 14 // Update Count : 142 15 15 // 16 16 17 17 #pragma once 18 19 #include "bits/debug.hfa" // verify20 18 21 19 // Reference: Bit Twiddling Hacks: http://graphics.stanford.edu/%7Eseander/bithacks.html#CountBitsSetNaive -
libcfa/src/bits/containers.hfa
r24d6572 r34b4268 10 10 // Created On : Tue Oct 31 16:38:50 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:33:08 202313 // Update Count : 2 912 // Last Modified On : Wed Jan 15 07:42:35 2020 13 // Update Count : 28 14 14 15 15 #pragma once … … 69 69 70 70 #ifdef __cforall 71 forall( T & ) 72 trait is_node { 71 trait is_node(T &) { 73 72 T *& get_next( T & ); 74 73 }; -
libcfa/src/bits/random.hfa
r24d6572 r34b4268 10 10 // Created On : Fri Jan 14 07:18:11 2022 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 20 21:45:24 202313 // Update Count : 1 8612 // Last Modified On : Sun Dec 11 18:43:58 2022 13 // Update Count : 171 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <stdint.h> // uintXX_t18 #include <stdint.h> 19 19 20 20 #define GLUE2( x, y ) x##y … … 24 24 #ifdef __x86_64__ // 64-bit architecture 25 25 // 64-bit generators 26 //#define LEHMER6426 #define LEHMER64 27 27 //#define XORSHIFT_12_25_27 28 #define XOSHIRO256PP28 //#define XOSHIRO256PP 29 29 //#define KISS_64 30 // #define SPLITMIX_6431 30 32 31 // 32-bit generators 33 //#define XORSHIFT_6_21_7 34 #define XOSHIRO128PP 35 // #define SPLITMIX_32 32 #define XORSHIFT_6_21_7 33 //#define XOSHIRO128PP 36 34 #else // 32-bit architecture 37 35 // 64-bit generators 38 //#define XORSHIFT_13_7_17 39 #define XOSHIRO256PP 40 // #define SPLITMIX_64 36 #define XORSHIFT_13_7_17 41 37 42 38 // 32-bit generators 43 //#define XORSHIFT_6_21_7 44 #define XOSHIRO128PP 45 // #define SPLITMIX_32 39 #define XORSHIFT_6_21_7 46 40 #endif // __x86_64__ 47 41 48 42 // Define C/CFA PRNG name and random-state. 43 44 // SKULLDUGGERY: typedefs name struct and typedef with the same name to deal with CFA typedef numbering problem. 49 45 50 46 #ifdef XOSHIRO256PP 51 47 #define PRNG_NAME_64 xoshiro256pp 52 48 #define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t) 53 typedef struct { uint64_t s0, s1, s2, s3; } PRNG_STATE_64_T;49 typedef struct PRNG_STATE_64_T { uint64_t s[4]; } PRNG_STATE_64_T; 54 50 #endif // XOSHIRO256PP 55 51 … … 57 53 #define PRNG_NAME_32 xoshiro128pp 58 54 #define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t) 59 typedef struct { uint32_t s0, s1, s2, s3; } PRNG_STATE_32_T;55 typedef struct PRNG_STATE_32_T { uint32_t s[4]; } PRNG_STATE_32_T; 60 56 #endif // XOSHIRO128PP 61 57 … … 85 81 #endif // XORSHIFT_12_25_27 86 82 87 #ifdef SPLITMIX_6488 #define PRNG_NAME_64 splitmix6489 #define PRNG_STATE_64_T uint64_t90 #endif // SPLITMIX3291 92 #ifdef SPLITMIX_3293 #define PRNG_NAME_32 splitmix3294 #define PRNG_STATE_32_T uint32_t95 #endif // SPLITMIX3296 97 83 #ifdef KISS_64 98 84 #define PRNG_NAME_64 kiss_64 99 85 #define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t) 100 typedef struct { uint64_t z, w, jsr, jcong; } PRNG_STATE_64_T;86 typedef struct PRNG_STATE_64_T { uint64_t z, w, jsr, jcong; } PRNG_STATE_64_T; 101 87 #endif // KISS_^64 102 88 … … 104 90 #define PRNG_NAME_32 xorwow 105 91 #define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t) 106 typedef struct { uint32_t a, b, c, d, counter; } PRNG_STATE_32_T;92 typedef struct PRNG_STATE_32_T { uint32_t a, b, c, d, counter; } PRNG_STATE_32_T; 107 93 #endif // XOSHIRO128PP 108 94 … … 124 110 125 111 // ALL PRNG ALGORITHMS ARE OPTIMIZED SO THAT THE PRNG LOGIC CAN HAPPEN IN PARALLEL WITH THE USE OF THE RESULT. 126 // Specifically, the current random state is copied for returning, before computing the next value. As a consequence, 127 // the set_seed routine primes the PRNG by calling it with the state so the seed is not return as the first random 128 // value. 129 112 // Therefore, the set_seed routine primes the PRNG by calling it with the state so the seed is not return as the 113 // first random value. 130 114 131 115 #ifdef __cforall // don't include in C code (invoke.h) 132 133 // https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64134 //135 // Splitmix64 is not recommended for demanding random number requirements, but is often used to calculate initial states136 // for other more complex pseudo-random number generators (see https://prng.di.unimi.it).137 // Also https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64.138 static inline uint64_t splitmix64( uint64_t & state ) {139 state += 0x9e3779b97f4a7c15;140 uint64_t z = state;141 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;142 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;143 return z ^ (z >> 31);144 } // splitmix64145 146 static inline void splitmix64_set_seed( uint64_t & state , uint64_t seed ) {147 state = seed;148 splitmix64( state ); // prime149 } // splitmix64_set_seed150 151 // https://github.com/bryc/code/blob/master/jshash/PRNGs.md#splitmix32152 //153 // Splitmix32 is not recommended for demanding random number requirements, but is often used to calculate initial states154 // for other more complex pseudo-random number generators (see https://prng.di.unimi.it).155 156 static inline uint32_t splitmix32( uint32_t & state ) {157 state += 0x9e3779b9;158 uint64_t z = state;159 z = (z ^ (z >> 15)) * 0x85ebca6b;160 z = (z ^ (z >> 13)) * 0xc2b2ae35;161 return z ^ (z >> 16);162 } // splitmix32163 164 static inline void splitmix32_set_seed( uint32_t & state, uint64_t seed ) {165 state = seed;166 splitmix32( state ); // prime167 } // splitmix32_set_seed168 169 #ifdef __SIZEOF_INT128__170 //--------------------------------------------------171 static inline uint64_t lehmer64( __uint128_t & state ) {172 __uint128_t ret = state;173 state *= 0x_da94_2042_e4dd_58b5;174 return ret >> 64;175 } // lehmer64176 177 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) {178 // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed.179 state = splitmix64( seed ); // prime180 } // lehmer64_set_seed181 182 //--------------------------------------------------183 static inline uint64_t wyhash64( uint64_t & state ) {184 uint64_t ret = state;185 state += 0x_60be_e2be_e120_fc15;186 __uint128_t tmp;187 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d;188 uint64_t m1 = (tmp >> 64) ^ tmp;189 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9;190 uint64_t m2 = (tmp >> 64) ^ tmp;191 return m2;192 } // wyhash64193 194 static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) {195 state = splitmix64( seed ); // prime196 } // wyhash64_set_seed197 #endif // __SIZEOF_INT128__198 116 199 117 // https://prng.di.unimi.it/xoshiro256starstar.c … … 208 126 209 127 #ifndef XOSHIRO256PP 210 typedef struct { uint64_t s0, s1, s2, s3; } xoshiro256pp_t;128 typedef struct xoshiro256pp_t { uint64_t s[4]; } xoshiro256pp_t; 211 129 #endif // ! XOSHIRO256PP 212 130 213 131 static inline uint64_t xoshiro256pp( xoshiro256pp_t & rs ) with(rs) { 214 inline uint64_t rotl( const uint64_t x, int k) {132 inline uint64_t rotl(const uint64_t x, int k) { 215 133 return (x << k) | (x >> (64 - k)); 216 134 } // rotl 217 135 218 const uint64_t result = rotl( s 0 + s3, 23 ) + s0;219 const uint64_t t = s 1<< 17;220 221 s 2 ^= s0;222 s 3 ^= s1;223 s 1 ^= s2;224 s 0 ^= s3;225 s 2^= t;226 s 3 = rotl( s3, 45 );136 const uint64_t result = rotl( s[0] + s[3], 23 ) + s[0]; 137 const uint64_t t = s[1] << 17; 138 139 s[2] ^= s[0]; 140 s[3] ^= s[1]; 141 s[1] ^= s[2]; 142 s[0] ^= s[3]; 143 s[2] ^= t; 144 s[3] = rotl( s[3], 45 ); 227 145 return result; 228 146 } // xoshiro256pp 229 147 230 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) { 231 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 232 uint64_t seed1 = splitmix64( seed ); // prime 233 uint64_t seed2 = splitmix64( seed ); 234 uint64_t seed3 = splitmix64( seed ); 235 uint64_t seed4 = splitmix64( seed ); 236 state = (xoshiro256pp_t){ seed1, seed2, seed3, seed4 }; 148 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) { 149 state = (xoshiro256pp_t){ {seed, seed, seed, seed} }; 150 xoshiro256pp( state ); 237 151 } // xoshiro256pp_set_seed 238 152 … … 247 161 248 162 #ifndef XOSHIRO128PP 249 typedef struct { uint32_t s0, s1, s2, s3; } xoshiro128pp_t;163 typedef struct xoshiro128pp_t { uint32_t s[4]; } xoshiro128pp_t; 250 164 #endif // ! XOSHIRO128PP 251 165 … … 255 169 } // rotl 256 170 257 const uint32_t result = rotl( s 0 + s3, 7 ) + s0;258 const uint32_t t = s 1<< 9;259 260 s 2 ^= s0;261 s 3 ^= s1;262 s 1 ^= s2;263 s 0 ^= s3;264 s 2^= t;265 s 3 = rotl( s3, 11 );171 const uint32_t result = rotl( s[0] + s[3], 7 ) + s[0]; 172 const uint32_t t = s[1] << 9; 173 174 s[2] ^= s[0]; 175 s[3] ^= s[1]; 176 s[1] ^= s[2]; 177 s[0] ^= s[3]; 178 s[2] ^= t; 179 s[3] = rotl( s[3], 11 ); 266 180 return result; 267 181 } // xoshiro128pp 268 182 269 183 static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) { 270 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 271 uint32_t seed1 = splitmix32( seed ); // prime 272 uint32_t seed2 = splitmix32( seed ); 273 uint32_t seed3 = splitmix32( seed ); 274 uint32_t seed4 = splitmix32( seed ); 275 state = (xoshiro128pp_t){ seed1, seed2, seed3, seed4 }; 184 state = (xoshiro128pp_t){ {seed, seed, seed, seed} }; 185 xoshiro128pp( state ); // prime 276 186 } // xoshiro128pp_set_seed 187 188 #ifdef __SIZEOF_INT128__ 189 // Pipelined to allow out-of-order overlap with reduced dependencies. Critically, the current random state is 190 // returned (copied), and then compute and store the next random value. 191 //-------------------------------------------------- 192 static inline uint64_t lehmer64( __uint128_t & state ) { 193 __uint128_t ret = state; 194 state *= 0xda942042e4dd58b5; 195 return ret >> 64; 196 } // lehmer64 197 198 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 199 state = seed; 200 lehmer64( state ); 201 } // lehmer64_set_seed 202 203 //-------------------------------------------------- 204 static inline uint64_t wyhash64( uint64_t & state ) { 205 uint64_t ret = state; 206 state += 0x_60be_e2be_e120_fc15; 207 __uint128_t tmp; 208 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d; 209 uint64_t m1 = (tmp >> 64) ^ tmp; 210 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9; 211 uint64_t m2 = (tmp >> 64) ^ tmp; 212 return m2; 213 } // wyhash64 214 215 static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) { 216 state = seed; 217 wyhash64( state ); // prime 218 } // wyhash64_set_seed 219 #endif // __SIZEOF_INT128__ 277 220 278 221 //-------------------------------------------------- … … 286 229 287 230 static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint64_t seed ) { 288 state = splitmix64( seed ); // prime 231 state = seed; 232 xorshift_13_7_17( state ); // prime 289 233 } // xorshift_13_7_17_set_seed 290 234 … … 303 247 304 248 static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) { 305 state = splitmix32( seed ); // prime 249 state = seed; 250 xorshift_6_21_7( state ); // prime 306 251 } // xorshift_6_21_7_set_seed 307 252 … … 317 262 318 263 static inline void xorshift_12_25_27_set_seed( uint64_t & state, uint64_t seed ) { 319 state = splitmix64( seed ); // prime 264 state = seed; 265 xorshift_12_25_27( state ); // prime 320 266 } // xorshift_12_25_27_set_seed 321 267 … … 323 269 // The state must be seeded with a nonzero value. 324 270 #ifndef KISS_64 325 typedef struct { uint64_t z, w, jsr, jcong; } kiss_64_t;271 typedef struct kiss_64_t { uint64_t z, w, jsr, jcong; } kiss_64_t; 326 272 #endif // ! KISS_64 327 273 328 static inline uint64_t kiss_64( kiss_64_t & rs ) with(rs) {329 kiss_64_t ret = rs;274 static inline uint64_t kiss_64( kiss_64_t & state ) with(state) { 275 kiss_64_t ret = state; 330 276 z = 36969 * (z & 65535) + (z >> 16); 331 277 w = 18000 * (w & 65535) + (w >> 16); 278 jsr ^= (jsr << 17); 332 279 jsr ^= (jsr << 13); 333 jsr ^= (jsr >> 17);334 280 jsr ^= (jsr << 5); 335 281 jcong = 69069 * jcong + 1234567; … … 337 283 } // kiss_64 338 284 339 static inline void kiss_64_set_seed( kiss_64_t & rs, uint64_t seed ) with(rs) { 340 z = 1; w = 1; jsr = 4; jcong = splitmix64( seed ); // prime 285 static inline void kiss_64_set_seed( kiss_64_t & state, uint64_t seed ) with(state) { 286 z = 1; w = 1; jsr = 4; jcong = seed; 287 kiss_64( state ); // prime 341 288 } // kiss_64_set_seed 342 289 … … 344 291 // The state array must be initialized to non-zero in the first four words. 345 292 #ifndef XORWOW 346 typedef struct { uint32_t a, b, c, d, counter; } xorwow_t;293 typedef struct xorwow_t { uint32_t a, b, c, d, counter; } xorwow_t; 347 294 #endif // ! XORWOW 348 295 349 static inline uint32_t xorwow( xorwow_t & rs ) with(rs) {296 static inline uint32_t xorwow( xorwow_t & state ) with(state) { 350 297 // Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs". 351 298 uint32_t ret = a + counter; … … 365 312 } // xorwow 366 313 367 static inline void xorwow_set_seed( xorwow_t & rs, uint32_t seed ) { 368 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 369 uint32_t seed1 = splitmix32( seed ); // prime 370 uint32_t seed2 = splitmix32( seed ); 371 uint32_t seed3 = splitmix32( seed ); 372 uint32_t seed4 = splitmix32( seed ); 373 rs = (xorwow_t){ seed1, seed2, seed3, seed4, 0 }; 314 static inline void xorwow_set_seed( xorwow_t & state, uint32_t seed ) { 315 state = (xorwow_t){ seed, seed, seed, seed, 0 }; 316 xorwow( state ); // prime 374 317 } // xorwow_set_seed 375 318 … … 377 320 // Used in __tls_rand_fwd 378 321 #define M (1_l64u << 48_l64u) 379 #define A (25 _214_903_917_l64u)380 #define AI (18 _446_708_753_438_544_741_l64u)322 #define A (25214903917_l64u) 323 #define AI (18446708753438544741_l64u) 381 324 #define C (11_l64u) 382 325 #define D (16_l64u) 383 326 384 327 // Bi-directional LCG random-number generator 385 static inline uint32_t LCGBI_fwd( uint64_t & rs) {386 rs = (A * rs+ C) & (M - 1);387 return rs>> D;328 static inline uint32_t LCGBI_fwd( uint64_t & state ) { 329 state = (A * state + C) & (M - 1); 330 return state >> D; 388 331 } // LCGBI_fwd 389 332 390 static inline uint32_t LCGBI_bck( uint64_t & rs) {391 unsigned int r = rs>> D;392 rs = AI * (rs- C) & (M - 1);333 static inline uint32_t LCGBI_bck( uint64_t & state ) { 334 unsigned int r = state >> D; 335 state = AI * (state - C) & (M - 1); 393 336 return r; 394 337 } // LCGBI_bck -
libcfa/src/bits/weakso_locks.cfa
r24d6572 r34b4268 15 15 // Update Count : 16 16 // 17 17 18 #include "bits/weakso_locks.hfa" 19 18 20 #pragma GCC visibility push(default) 19 21 … … 25 27 void unlock( blocking_lock & ) {} 26 28 void on_notify( blocking_lock &, struct thread$ * ) {} 27 size_t on_wait( blocking_lock & , void (*pp_fn)( void * ), void * pp_datum) { return 0; }29 size_t on_wait( blocking_lock & ) { return 0; } 28 30 void on_wakeup( blocking_lock &, size_t ) {} 29 31 size_t wait_count( blocking_lock & ) { return 0; } 30 bool register_select( blocking_lock & this, select_node & node ) { return false; }31 bool unregister_select( blocking_lock & this, select_node & node ) { return false; }32 void on_selected( blocking_lock & this, select_node & node ) {}33 -
libcfa/src/bits/weakso_locks.hfa
r24d6572 r34b4268 23 23 #include "containers/list.hfa" 24 24 25 struct select_node;25 struct thread$; 26 26 27 27 //----------------------------------------------------------------------------- … … 32 32 33 33 // List of blocked threads 34 dlist( select_node) blocked_threads;34 dlist( thread$ ) blocked_threads; 35 35 36 36 // Count of current blocked threads … … 57 57 void unlock( blocking_lock & this ) OPTIONAL_THREAD; 58 58 void on_notify( blocking_lock & this, struct thread$ * t ) OPTIONAL_THREAD; 59 size_t on_wait( blocking_lock & this , void (*pp_fn)( void * ), void * pp_datum) OPTIONAL_THREAD;59 size_t on_wait( blocking_lock & this ) OPTIONAL_THREAD; 60 60 void on_wakeup( blocking_lock & this, size_t ) OPTIONAL_THREAD; 61 61 size_t wait_count( blocking_lock & this ) OPTIONAL_THREAD; 62 bool register_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;63 bool unregister_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;64 void on_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;65 62 66 63 //---------- … … 75 72 static inline bool try_lock ( multiple_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); } 76 73 static inline void unlock ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 77 static inline size_t on_wait ( multiple_acquisition_lock & this , void (*pp_fn)( void * ), void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum); }74 static inline size_t on_wait ( multiple_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); } 78 75 static inline void on_wakeup( multiple_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 79 76 static inline void on_notify( multiple_acquisition_lock & this, struct thread$ * t ){ on_notify( (blocking_lock &)this, t ); } 80 static inline bool register_select( multiple_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }81 static inline bool unregister_select( multiple_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }82 static inline void on_selected( multiple_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } -
libcfa/src/common.hfa
r24d6572 r34b4268 32 32 } // extern "C" 33 33 static inline __attribute__((always_inline)) { 34 unsigned char abs( signed char v ) { return (int)abs( (int)v ); }34 unsigned char abs( signed char v ) { return abs( (int)v ); } 35 35 // use default C routine for int 36 36 unsigned long int abs( long int v ) { return labs( v ); } … … 70 70 unsigned int min( unsigned int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 71 71 long int min( long int v1, long int v2 ) { return v1 < v2 ? v1 : v2; } 72 unsigned long int min( unsigned long int v1, unsigned longint v2 ) { return v1 < v2 ? v1 : v2; }72 unsigned long int min( unsigned long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 73 73 long long int min( long long int v1, long long int v2 ) { return v1 < v2 ? v1 : v2; } 74 unsigned long long int min( unsigned long long int v1, unsigned long longint v2 ) { return v1 < v2 ? v1 : v2; }74 unsigned long long int min( unsigned long long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 75 75 forall( T | { int ?<?( T, T ); } ) // generic 76 76 T min( T v1, T v2 ) { return v1 < v2 ? v1 : v2; } -
libcfa/src/concurrency/clib/cfathread.cfa
r24d6572 r34b4268 16 16 // #define EPOLL_FOR_SOCKETS 17 17 18 #include <string.h>19 20 18 #include "fstream.hfa" 21 19 #include "locks.hfa" … … 25 23 #include "time.hfa" 26 24 #include "stdlib.hfa" 27 #include "iofwd.hfa" 25 28 26 #include "cfathread.h" 27 28 extern "C" { 29 #include <string.h> 30 #include <errno.h> 31 } 29 32 30 33 extern void ?{}(processor &, const char[], cluster &, thread$ *); 31 34 extern "C" { 32 extern void __cfactx_invoke_thread(void (*main)(void *), void * this); 35 extern void __cfactx_invoke_thread(void (*main)(void *), void * this); 36 extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags); 33 37 } 34 38 … … 435 439 // Mutex 436 440 struct cfathread_mutex { 437 exp_backoff_then_block_lock impl;441 linear_backoff_then_block_lock impl; 438 442 }; 439 443 int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; } … … 450 454 // Condition 451 455 struct cfathread_condition { 452 condition_variable( exp_backoff_then_block_lock) impl;456 condition_variable(linear_backoff_then_block_lock) impl; 453 457 }; 454 458 int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; } … … 468 472 } 469 473 474 #include <iofwd.hfa> 475 470 476 extern "C" { 477 #include <unistd.h> 478 #include <sys/types.h> 479 #include <sys/socket.h> 480 471 481 //-------------------- 472 482 // IO operations … … 478 488 , protocol); 479 489 } 480 int cfathread_bind(int socket, __CONST_SOCKADDR_ARGaddress, socklen_t address_len) {490 int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len) { 481 491 return bind(socket, address, address_len); 482 492 } … … 486 496 } 487 497 488 int cfathread_accept(int socket, __SOCKADDR_ARGaddress, socklen_t *restrict address_len) {498 int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) { 489 499 #if defined(EPOLL_FOR_SOCKETS) 490 500 int ret; … … 503 513 } 504 514 505 int cfathread_connect(int socket, __CONST_SOCKADDR_ARGaddress, socklen_t address_len) {515 int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len) { 506 516 #if defined(EPOLL_FOR_SOCKETS) 507 517 int ret; -
libcfa/src/concurrency/clib/cfathread.h
r24d6572 r34b4268 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Sep 22 15:31:20 2020 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Mar 13 23:48:40 202313 // Update Count : 711 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 14 14 // 15 15 16 #pragma once17 18 16 #if defined(__cforall) || defined(__cplusplus) 19 #include <unistd.h>20 #include <errno.h>21 #include <sys/socket.h>22 23 17 extern "C" { 24 18 #endif 19 #include <asm/types.h> 20 #include <errno.h> 21 #include <unistd.h> 22 23 25 24 //-------------------- 26 25 // Basic types … … 74 73 } cfathread_mutexattr_t; 75 74 typedef struct cfathread_mutex * cfathread_mutex_t; 76 int cfathread_mutex_init(cfathread_mutex_t * restrict mut, const cfathread_mutexattr_t *restrict attr) __attribute__((nonnull (1)));75 int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict attr) __attribute__((nonnull (1))); 77 76 int cfathread_mutex_destroy(cfathread_mutex_t *mut) __attribute__((nonnull (1))); 78 77 int cfathread_mutex_lock(cfathread_mutex_t *mut) __attribute__((nonnull (1))); … … 92 91 //-------------------- 93 92 // IO operations 93 struct sockaddr; 94 struct msghdr; 94 95 int cfathread_socket(int domain, int type, int protocol); 95 int cfathread_bind(int socket, __CONST_SOCKADDR_ARGaddress, socklen_t address_len);96 int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len); 96 97 int cfathread_listen(int socket, int backlog); 97 int cfathread_accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);98 int cfathread_connect(int socket, __CONST_SOCKADDR_ARGaddress, socklen_t address_len);98 int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len); 99 int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len); 99 100 int cfathread_dup(int fildes); 100 101 int cfathread_close(int fildes); -
libcfa/src/concurrency/coroutine.cfa
r24d6572 r34b4268 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 16 15:34:46 202313 // Update Count : 2 412 // Last Modified On : Tue Dec 15 12:06:04 2020 13 // Update Count : 23 14 14 // 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #include "coroutine.hfa" -
libcfa/src/concurrency/coroutine.hfa
r24d6572 r34b4268 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:31:42 202313 // Update Count : 1 312 // Last Modified On : Thu Jan 6 16:33:16 2022 13 // Update Count : 12 14 14 // 15 15 … … 38 38 // Anything that implements this trait can be resumed. 39 39 // Anything that is resumed is a coroutine. 40 forall( T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T)) ) 41 trait is_coroutine { 40 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T))) { 42 41 void main(T & this); 43 42 coroutine$ * get_coroutine(T & this); -
libcfa/src/concurrency/future.hfa
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // concurrency/future.hfa --7 // io/types.hfa -- 8 8 // 9 // Author : Thierry Delisle & Peiran Hong & Colby Parsons9 // Author : Thierry Delisle & Peiran Hong 10 10 // Created On : Wed Jan 06 17:33:18 2021 11 11 // Last Modified By : … … 18 18 #include "bits/locks.hfa" 19 19 #include "monitor.hfa" 20 #include "select.hfa"21 #include "locks.hfa"22 23 //----------------------------------------------------------------------------24 // future25 // I don't use future_t here since I need to use a lock for this future26 // since it supports multiple consumers27 // future_t is lockfree and uses atomics which aren't needed given we use locks here28 forall( T ) {29 // enum { FUTURE_EMPTY = 0, FUTURE_FULFILLED = 1 }; // Enums seem to be broken so feel free to add this back afterwards30 31 // temporary enum replacement32 const int FUTURE_EMPTY = 0;33 const int FUTURE_FULFILLED = 1;34 35 struct future {36 int state;37 T result;38 dlist( select_node ) waiters;39 futex_mutex lock;40 };41 42 struct future_node {43 inline select_node;44 T * my_result;45 };46 47 static inline {48 49 void ?{}( future_node(T) & this, thread$ * blocked_thread, T * my_result ) {50 ((select_node &)this){ blocked_thread };51 this.my_result = my_result;52 }53 54 void ?{}( future(T) & this ) {55 this.waiters{};56 this.state = FUTURE_EMPTY;57 this.lock{};58 }59 60 // Reset future back to original state61 void reset( future(T) & this ) with(this)62 {63 lock( lock );64 if( ! waiters`isEmpty )65 abort("Attempting to reset a future with blocked waiters");66 state = FUTURE_EMPTY;67 unlock( lock );68 }69 70 // check if the future is available71 // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected72 bool available( future(T) & this ) { return __atomic_load_n( &this.state, __ATOMIC_RELAXED ); }73 74 75 // memcpy wrapper to help copy values76 void copy_T( T & from, T & to ) {77 memcpy((void *)&to, (void *)&from, sizeof(T));78 }79 80 // internal helper to signal waiters off of the future81 void _internal_flush( future(T) & this ) with(this) {82 while( ! waiters`isEmpty ) {83 if ( !__handle_waituntil_OR( waiters ) ) // handle special waituntil OR case84 break; // if handle_OR returns false then waiters is empty so break85 select_node &s = try_pop_front( waiters );86 87 if ( s.clause_status == 0p ) // poke in result so that woken threads do not need to reacquire any locks88 copy_T( result, *(((future_node(T) &)s).my_result) );89 90 wake_one( waiters, s );91 }92 }93 94 // Fulfil the future, returns whether or not someone was unblocked95 bool fulfil( future(T) & this, T val ) with(this) {96 lock( lock );97 if( state != FUTURE_EMPTY )98 abort("Attempting to fulfil a future that has already been fulfilled");99 100 copy_T( val, result );101 102 bool ret_val = ! waiters`isEmpty;103 state = FUTURE_FULFILLED;104 _internal_flush( this );105 unlock( lock );106 return ret_val;107 }108 109 // Wait for the future to be fulfilled110 // Also return whether the thread had to block or not111 [T, bool] get( future(T) & this ) with( this ) {112 lock( lock );113 T ret_val;114 if( state == FUTURE_FULFILLED ) {115 copy_T( result, ret_val );116 unlock( lock );117 return [ret_val, false];118 }119 120 future_node(T) node = { active_thread(), &ret_val };121 insert_last( waiters, ((select_node &)node) );122 unlock( lock );123 park( );124 125 return [ret_val, true];126 }127 128 // Wait for the future to be fulfilled129 T get( future(T) & this ) {130 [T, bool] tt;131 tt = get(this);132 return tt.0;133 }134 135 // Gets value if it is available and returns [ val, true ]136 // otherwise returns [ default_val, false]137 // will not block138 [T, bool] try_get( future(T) & this ) with(this) {139 lock( lock );140 T ret_val;141 if( state == FUTURE_FULFILLED ) {142 copy_T( result, ret_val );143 unlock( lock );144 return [ret_val, true];145 }146 unlock( lock );147 148 return [ret_val, false];149 }150 151 bool register_select( future(T) & this, select_node & s ) with(this) {152 lock( lock );153 154 // check if we can complete operation. If so race to establish winner in special OR case155 if ( !s.park_counter && state != FUTURE_EMPTY ) {156 if ( !__make_select_node_available( s ) ) { // we didn't win the race so give up on registering157 unlock( lock );158 return false;159 }160 }161 162 // future not ready -> insert select node and return163 if( state == FUTURE_EMPTY ) {164 insert_last( waiters, s );165 unlock( lock );166 return false;167 }168 169 __make_select_node_available( s );170 unlock( lock );171 return true;172 }173 174 bool unregister_select( future(T) & this, select_node & s ) with(this) {175 if ( ! s`isListed ) return false;176 lock( lock );177 if ( s`isListed ) remove( s );178 unlock( lock );179 return false;180 }181 182 void on_selected( future(T) & this, select_node & node ) {}183 }184 }185 186 //--------------------------------------------------------------------------------------------------------187 // These futures below do not support select statements so they may not have as many features as 'future'188 // however the 'single_future' is cheap and cheerful and is most likely more performant than 'future'189 // since it uses raw atomics and no locks190 //191 // As far as 'multi_future' goes I can't see many use cases as it will be less performant than 'future'192 // since it is monitor based and also is not compatible with select statements193 //--------------------------------------------------------------------------------------------------------194 20 195 21 forall( T ) { 196 struct single_future {22 struct future { 197 23 inline future_t; 198 24 T result; … … 201 27 static inline { 202 28 // Reset future back to original state 203 void reset( single_future(T) & this) { reset( (future_t&)this ); }29 void reset(future(T) & this) { reset( (future_t&)this ); } 204 30 205 31 // check if the future is available 206 bool available( single_future(T) & this ) { return available( (future_t&)this ); }32 bool available( future(T) & this ) { return available( (future_t&)this ); } 207 33 208 34 // Mark the future as abandoned, meaning it will be deleted by the server 209 35 // This doesn't work beause of the potential need for a destructor 210 void abandon( single_future(T) & this );36 void abandon( future(T) & this ); 211 37 212 38 // Fulfil the future, returns whether or not someone was unblocked 213 thread$ * fulfil( single_future(T) & this, T result ) {39 thread$ * fulfil( future(T) & this, T result ) { 214 40 this.result = result; 215 41 return fulfil( (future_t&)this ); … … 218 44 // Wait for the future to be fulfilled 219 45 // Also return whether the thread had to block or not 220 [T, bool] wait( single_future(T) & this ) {46 [T, bool] wait( future(T) & this ) { 221 47 bool r = wait( (future_t&)this ); 222 48 return [this.result, r]; … … 224 50 225 51 // Wait for the future to be fulfilled 226 T wait( single_future(T) & this ) {52 T wait( future(T) & this ) { 227 53 [T, bool] tt; 228 54 tt = wait(this); -
libcfa/src/concurrency/invoke.h
r24d6572 r34b4268 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 14 13:39:31 2023 13 // Update Count : 59 14 // 15 16 // No not use #pragma once was this file is included twice in some places. It has its own guard system. 12 // Last Modified On : Tue Nov 29 20:42:21 2022 13 // Update Count : 56 14 // 17 15 18 16 #include "bits/containers.hfa" … … 217 215 struct __thread_user_link cltr_link; 218 216 217 // used to store state between clh lock/unlock 218 volatile bool * clh_prev; 219 220 // used to point to this thd's current clh node 221 volatile bool * clh_node; 222 219 223 struct processor * last_proc; 220 221 // ptr used during handover between blocking lists to allow for stack allocation of intrusive nodes222 // main use case is wait-morphing to allow a different node to be used to block on condvar vs lock223 void * link_node;224 224 225 225 PRNG_STATE_T random_state; // fast random numbers -
libcfa/src/concurrency/io.cfa
r24d6572 r34b4268 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #if defined(__CFA_DEBUG__) … … 84 85 static io_context$ * __ioarbiter_allocate( io_arbiter$ & this, __u32 idxs[], __u32 want ); 85 86 static void __ioarbiter_submit( io_context$ * , __u32 idxs[], __u32 have, bool lazy ); 86 static void __ioarbiter_flush ( io_context$ & , bool kernel);87 static void __ioarbiter_flush ( io_context$ & ); 87 88 static inline void __ioarbiter_notify( io_context$ & ctx ); 88 89 //============================================================================================= … … 93 94 extern void __kernel_unpark( thread$ * thrd, unpark_hint ); 94 95 95 static inline void __post(oneshot & this, bool kernel, unpark_hint hint) {96 thread$ * t = post( this, false );97 if(kernel) __kernel_unpark( t, hint );98 else unpark( t, hint );99 }100 101 // actual system call of io uring102 // wrap so everything that needs to happen around it is always done103 // i.e., stats, book keeping, sqe reclamation, etc.104 96 static void ioring_syscsll( struct io_context$ & ctx, unsigned int min_comp, unsigned int flags ) { 105 97 __STATS__( true, io.calls.flush++; ) 106 98 int ret; 107 99 for() { 108 // do the system call in a loop, repeat on interrupts109 100 ret = syscall( __NR_io_uring_enter, ctx.fd, ctx.sq.to_submit, min_comp, flags, (sigset_t *)0p, _NSIG / 8); 110 101 if( ret < 0 ) { … … 129 120 /* paranoid */ verify( ctx.sq.to_submit >= ret ); 130 121 131 // keep track of how many still need submitting 132 __atomic_fetch_sub(&ctx.sq.to_submit, ret, __ATOMIC_SEQ_CST); 122 ctx.sq.to_submit -= ret; 133 123 134 124 /* paranoid */ verify( ctx.sq.to_submit <= *ctx.sq.num ); … … 139 129 /* paranoid */ verify( ! __preemption_enabled() ); 140 130 141 // mark that there is no pending io left142 131 __atomic_store_n(&ctx.proc->io.pending, false, __ATOMIC_RELAXED); 143 132 } 144 133 145 // try to acquire an io context for draining, helping means we never *need* to drain, we can always do it later146 134 static bool try_acquire( io_context$ * ctx ) __attribute__((nonnull(1))) { 147 135 /* paranoid */ verify( ! __preemption_enabled() ); … … 150 138 151 139 { 152 // if there is nothing to drain there is no point in acquiring anything153 140 const __u32 head = *ctx->cq.head; 154 141 const __u32 tail = *ctx->cq.tail; … … 157 144 } 158 145 159 // try a simple spinlock acquire, it's likely there are completions to drain 160 if(!__atomic_try_acquire(&ctx->cq.try_lock)) { 161 // some other processor already has it 146 // Drain the queue 147 if(!__atomic_try_acquire(&ctx->cq.lock)) { 162 148 __STATS__( false, io.calls.locked++; ) 163 149 return false; 164 150 } 165 151 166 // acquired!!167 152 return true; 168 153 } 169 154 170 // actually drain the completion171 155 static bool __cfa_do_drain( io_context$ * ctx, cluster * cltr ) __attribute__((nonnull(1, 2))) { 172 156 /* paranoid */ verify( ! __preemption_enabled() ); 173 157 /* paranoid */ verify( ready_schedule_islocked() ); 174 /* paranoid */ verify( ctx->cq.try_lock == true ); 175 176 // get all the invariants and initial state 158 /* paranoid */ verify( ctx->cq.lock == true ); 159 177 160 const __u32 mask = *ctx->cq.mask; 178 161 const __u32 num = *ctx->cq.num; … … 183 166 for() { 184 167 // re-read the head and tail in case it already changed. 185 // count the difference between the two186 168 const __u32 head = *ctx->cq.head; 187 169 const __u32 tail = *ctx->cq.tail; … … 189 171 __STATS__( false, io.calls.drain++; io.calls.completed += count; ) 190 172 191 // for everything between head and tail, drain it192 173 for(i; count) { 193 174 unsigned idx = (head + i) & mask; … … 196 177 /* paranoid */ verify(&cqe); 197 178 198 // find the future in the completion199 179 struct io_future_t * future = (struct io_future_t *)(uintptr_t)cqe.user_data; 200 180 // __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", &cqe, cqe.res, future ); 201 181 202 // don't directly fulfill the future, preemption is disabled so we need to use kernel_unpark203 182 __kernel_unpark( fulfil( *future, cqe.res, false ), UNPARK_LOCAL ); 204 183 } 205 184 206 // update the timestamps accordingly207 // keep a local copy so we can update the relaxed copy208 185 ts_next = ctx->cq.ts = rdtscl(); 209 186 … … 213 190 ctx->proc->idle_wctx.drain_time = ts_next; 214 191 215 // we finished draining the completions... unless the ring buffer was full and there are more secret completions in the kernel.216 192 if(likely(count < num)) break; 217 193 218 // the ring buffer was full, there could be more stuff in the kernel.219 194 ioring_syscsll( *ctx, 0, IORING_ENTER_GETEVENTS); 220 195 } … … 224 199 /* paranoid */ verify( ! __preemption_enabled() ); 225 200 226 // everything is drained, we can release the lock 227 __atomic_unlock(&ctx->cq.try_lock); 228 229 // update the relaxed timestamp 201 __atomic_unlock(&ctx->cq.lock); 202 230 203 touch_tsc( cltr->sched.io.tscs, ctx->cq.id, ts_prev, ts_next, false ); 231 204 … … 233 206 } 234 207 235 // call from a processor to flush236 // contains all the bookkeeping a proc must do, not just the barebones flushing logic237 void __cfa_do_flush( io_context$ & ctx, bool kernel ) {238 /* paranoid */ verify( ! __preemption_enabled() );239 240 // flush any external requests241 ctx.sq.last_external = false; // clear the external bit, the arbiter will reset it if needed242 __ioarbiter_flush( ctx, kernel );243 244 // if submitting must be submitted, do the system call245 if(ctx.sq.to_submit != 0) {246 ioring_syscsll(ctx, 0, 0);247 }248 }249 250 // call from a processor to drain251 // contains all the bookkeeping a proc must do, not just the barebones draining logic252 208 bool __cfa_io_drain( struct processor * proc ) { 253 209 bool local = false; 254 210 bool remote = false; 255 211 256 // make sure no ones creates/destroys io contexts257 212 ready_schedule_lock(); 258 213 … … 262 217 /* paranoid */ verify( ctx ); 263 218 264 // Help if needed265 219 with(cltr->sched) { 266 220 const size_t ctxs_count = io.count; … … 276 230 const unsigned long long ctsc = rdtscl(); 277 231 278 // only help once every other time279 // pick a target when not helping280 232 if(proc->io.target == UINT_MAX) { 281 233 uint64_t chaos = __tls_rand(); 282 // choose who to help and whether to accept helping far processors283 234 unsigned ext = chaos & 0xff; 284 235 unsigned other = (chaos >> 8) % (ctxs_count); 285 236 286 // if the processor is on the same cache line or is lucky ( 3 out of 256 odds ) help it287 237 if(ext < 3 || __atomic_load_n(&caches[other / __shard_factor.io].id, __ATOMIC_RELAXED) == this_cache) { 288 238 proc->io.target = other; … … 290 240 } 291 241 else { 292 // a target was picked last time, help it293 242 const unsigned target = proc->io.target; 294 243 /* paranoid */ verify( io.tscs[target].t.tv != ULLONG_MAX ); 295 // make sure the target hasn't stopped existing since last time296 244 HELP: if(target < ctxs_count) { 297 // calculate it's age and how young it could be before we give up on helping298 245 const __readyQ_avg_t cutoff = calc_cutoff(ctsc, ctx->cq.id, ctxs_count, io.data, io.tscs, __shard_factor.io, false); 299 246 const __readyQ_avg_t age = moving_average(ctsc, io.tscs[target].t.tv, io.tscs[target].t.ma, false); 300 247 __cfadbg_print_safe(io, "Kernel I/O: Help attempt on %u from %u, age %'llu vs cutoff %'llu, %s\n", target, ctx->cq.id, age, cutoff, age > cutoff ? "yes" : "no"); 301 // is the target older than the cutoff, recall 0 is oldest and bigger ints are younger302 248 if(age <= cutoff) break HELP; 303 249 304 // attempt to help the submission side 305 __cfa_do_flush( *io.data[target], true ); 306 307 // attempt to help the completion side 308 if(!try_acquire(io.data[target])) break HELP; // already acquire no help needed 309 310 // actually help 250 if(!try_acquire(io.data[target])) break HELP; 251 311 252 if(!__cfa_do_drain( io.data[target], cltr )) break HELP; 312 253 313 // track we did help someone314 254 remote = true; 315 255 __STATS__( true, io.calls.helped++; ) 316 256 } 317 318 // reset the target319 257 proc->io.target = UINT_MAX; 320 258 } 321 259 } 260 322 261 323 262 // Drain the local queue … … 331 270 332 271 ready_schedule_unlock(); 333 334 // return true if some completion entry, local or remote, was drained335 272 return local || remote; 336 273 } 337 274 338 339 340 // call from a processor to flush341 // contains all the bookkeeping a proc must do, not just the barebones flushing logic342 275 bool __cfa_io_flush( struct processor * proc ) { 343 276 /* paranoid */ verify( ! __preemption_enabled() ); … … 345 278 /* paranoid */ verify( proc->io.ctx ); 346 279 347 __cfa_do_flush( *proc->io.ctx, false ); 348 349 // also drain since some stuff will immediately complete 280 io_context$ & ctx = *proc->io.ctx; 281 282 __ioarbiter_flush( ctx ); 283 284 if(ctx.sq.to_submit != 0) { 285 ioring_syscsll(ctx, 0, 0); 286 287 } 288 350 289 return __cfa_io_drain( proc ); 351 290 } … … 454 393 //============================================================================================= 455 394 // submission 456 // barebones logic to submit a group of sqes 457 static inline void __submit_only( struct io_context$ * ctx, __u32 idxs[], __u32 have, bool lock) { 458 if(!lock) 459 lock( ctx->ext_sq.lock __cfaabi_dbg_ctx2 ); 395 static inline void __submit_only( struct io_context$ * ctx, __u32 idxs[], __u32 have) { 460 396 // We can proceed to the fast path 461 397 // Get the right objects … … 472 408 // Make the sqes visible to the submitter 473 409 __atomic_store_n(sq.kring.tail, tail + have, __ATOMIC_RELEASE); 474 __atomic_fetch_add(&sq.to_submit, have, __ATOMIC_SEQ_CST); 475 476 // set the bit to mark things need to be flushed 410 sq.to_submit += have; 411 477 412 __atomic_store_n(&ctx->proc->io.pending, true, __ATOMIC_RELAXED); 478 413 __atomic_store_n(&ctx->proc->io.dirty , true, __ATOMIC_RELAXED); 479 480 if(!lock) 481 unlock( ctx->ext_sq.lock ); 482 } 483 484 // submission logic + maybe flushing 414 } 415 485 416 static inline void __submit( struct io_context$ * ctx, __u32 idxs[], __u32 have, bool lazy) { 486 417 __sub_ring_t & sq = ctx->sq; 487 __submit_only(ctx, idxs, have , false);418 __submit_only(ctx, idxs, have); 488 419 489 420 if(sq.to_submit > 30) { … … 497 428 } 498 429 499 // call from a processor to flush500 // might require arbitration if the thread was migrated after the allocation501 430 void cfa_io_submit( struct io_context$ * inctx, __u32 idxs[], __u32 have, bool lazy ) __attribute__((nonnull (1))) libcfa_public { 502 431 // __cfadbg_print_safe(io, "Kernel I/O : attempting to submit %u (%s)\n", have, lazy ? "lazy" : "eager"); … … 512 441 if( ctx == inctx ) // We have the right instance? 513 442 { 514 // yes! fast submit515 443 __submit(ctx, idxs, have, lazy); 516 444 … … 579 507 __atomic_store_n(&ctx.sq.free_ring.tail, ftail + count, __ATOMIC_SEQ_CST); 580 508 581 // notify the allocator that new allocations can be made582 509 __ioarbiter_notify(ctx); 583 510 … … 630 557 } 631 558 632 // notify the arbiter that new allocations are available633 559 static void __ioarbiter_notify( io_arbiter$ & this, io_context$ * ctx ) { 634 560 /* paranoid */ verify( !empty(this.pending.queue) ); 635 /* paranoid */ verify( __preemption_enabled() ); 636 637 // mutual exclusion is needed 561 638 562 lock( this.pending.lock __cfaabi_dbg_ctx2 ); 639 563 { 640 __cfadbg_print_safe(io, "Kernel I/O : notifying\n");641 642 // as long as there are pending allocations try to satisfy them643 // for simplicity do it in FIFO order644 564 while( !empty(this.pending.queue) ) { 645 // get first pending allocs565 __cfadbg_print_safe(io, "Kernel I/O : notifying\n"); 646 566 __u32 have = ctx->sq.free_ring.tail - ctx->sq.free_ring.head; 647 567 __pending_alloc & pa = (__pending_alloc&)head( this.pending.queue ); 648 568 649 // check if we have enough to satisfy the request650 569 if( have > pa.want ) goto DONE; 651 652 // if there are enough allocations it means we can drop the request653 570 drop( this.pending.queue ); 654 571 655 572 /* paranoid */__attribute__((unused)) bool ret = 656 573 657 // actually do the alloc658 574 __alloc(ctx, pa.idxs, pa.want); 659 575 660 576 /* paranoid */ verify( ret ); 661 577 662 // write out which context statisfied the request and post663 // this664 578 pa.ctx = ctx; 579 665 580 post( pa.waitctx ); 666 581 } … … 670 585 } 671 586 unlock( this.pending.lock ); 672 673 /* paranoid */ verify( __preemption_enabled() ); 674 } 675 676 // short hand to avoid the mutual exclusion of the pending is empty regardless 587 } 588 677 589 static void __ioarbiter_notify( io_context$ & ctx ) { 678 if(empty( ctx.arbiter->pending )) return; 679 __ioarbiter_notify( *ctx.arbiter, &ctx ); 680 } 681 682 // Submit from outside the local processor: append to the outstanding list 590 if(!empty( ctx.arbiter->pending )) { 591 __ioarbiter_notify( *ctx.arbiter, &ctx ); 592 } 593 } 594 595 // Simply append to the pending 683 596 static void __ioarbiter_submit( io_context$ * ctx, __u32 idxs[], __u32 have, bool lazy ) { 684 597 __cfadbg_print_safe(io, "Kernel I/O : submitting %u from the arbiter to context %u\n", have, ctx->fd); … … 686 599 __cfadbg_print_safe(io, "Kernel I/O : waiting to submit %u\n", have); 687 600 688 // create the intrusive object to append689 601 __external_io ei; 690 602 ei.idxs = idxs; … … 692 604 ei.lazy = lazy; 693 605 694 // enqueue the io695 606 bool we = enqueue(ctx->ext_sq, (__outstanding_io&)ei); 696 607 697 // mark pending698 608 __atomic_store_n(&ctx->proc->io.pending, true, __ATOMIC_SEQ_CST); 699 609 700 // if this is the first to be enqueued, signal the processor in an attempt to speed up flushing701 // if it's not the first enqueue, a signal is already in transit702 610 if( we ) { 703 611 sigval_t value = { PREEMPT_IO }; 704 612 __cfaabi_pthread_sigqueue(ctx->proc->kernel_thread, SIGUSR1, value); 705 __STATS__( false, io.flush.signal += 1; ) 706 } 707 __STATS__( false, io.submit.extr += 1; ) 708 709 // to avoid dynamic allocation/memory reclamation headaches, wait for it to have been submitted 613 } 614 710 615 wait( ei.waitctx ); 711 616 … … 713 618 } 714 619 715 // flush the io arbiter: move all external io operations to the submission ring 716 static void __ioarbiter_flush( io_context$ & ctx, bool kernel ) { 717 // if there are no external operations just return 718 if(empty( ctx.ext_sq )) return; 719 720 // stats and logs 721 __STATS__( false, io.flush.external += 1; ) 722 __cfadbg_print_safe(io, "Kernel I/O : arbiter flushing\n"); 723 724 // this can happen from multiple processors, mutual exclusion is needed 725 lock( ctx.ext_sq.lock __cfaabi_dbg_ctx2 ); 726 { 727 // pop each operation one at a time. 728 // There is no wait morphing because of the io sq ring 729 while( !empty(ctx.ext_sq.queue) ) { 730 // drop the element from the queue 731 __external_io & ei = (__external_io&)drop( ctx.ext_sq.queue ); 732 733 // submit it 734 __submit_only(&ctx, ei.idxs, ei.have, true); 735 736 // wake the thread that was waiting on it 737 // since this can both be called from kernel and user, check the flag before posting 738 __post( ei.waitctx, kernel, UNPARK_LOCAL ); 620 static void __ioarbiter_flush( io_context$ & ctx ) { 621 if(!empty( ctx.ext_sq )) { 622 __STATS__( false, io.flush.external += 1; ) 623 624 __cfadbg_print_safe(io, "Kernel I/O : arbiter flushing\n"); 625 626 lock( ctx.ext_sq.lock __cfaabi_dbg_ctx2 ); 627 { 628 while( !empty(ctx.ext_sq.queue) ) { 629 __external_io & ei = (__external_io&)drop( ctx.ext_sq.queue ); 630 631 __submit_only(&ctx, ei.idxs, ei.have); 632 633 post( ei.waitctx ); 634 } 635 636 ctx.ext_sq.empty = true; 739 637 } 740 741 // mark the queue as empty 742 ctx.ext_sq.empty = true; 743 ctx.sq.last_external = true; 744 } 745 unlock(ctx.ext_sq.lock ); 746 } 747 748 extern "C" { 749 // debug functions used for gdb 750 // io_uring doesn't yet support gdb soe the kernel-shared data structures aren't viewable in gdb 751 // these functions read the data that gdb can't and should be removed once the support is added 752 static __u32 __cfagdb_cq_head( io_context$ * ctx ) __attribute__((nonnull(1),used,noinline)) { return *ctx->cq.head; } 753 static __u32 __cfagdb_cq_tail( io_context$ * ctx ) __attribute__((nonnull(1),used,noinline)) { return *ctx->cq.tail; } 754 static __u32 __cfagdb_cq_mask( io_context$ * ctx ) __attribute__((nonnull(1),used,noinline)) { return *ctx->cq.mask; } 755 static __u32 __cfagdb_sq_head( io_context$ * ctx ) __attribute__((nonnull(1),used,noinline)) { return *ctx->sq.kring.head; } 756 static __u32 __cfagdb_sq_tail( io_context$ * ctx ) __attribute__((nonnull(1),used,noinline)) { return *ctx->sq.kring.tail; } 757 static __u32 __cfagdb_sq_mask( io_context$ * ctx ) __attribute__((nonnull(1),used,noinline)) { return *ctx->sq.mask; } 758 759 // fancier version that reads an sqe and copies it out. 760 static struct io_uring_sqe __cfagdb_sq_at( io_context$ * ctx, __u32 at ) __attribute__((nonnull(1),used,noinline)) { 761 __u32 ax = at & *ctx->sq.mask; 762 __u32 ix = ctx->sq.kring.array[ax]; 763 return ctx->sq.sqes[ix]; 638 unlock(ctx.ext_sq.lock ); 764 639 } 765 640 } -
libcfa/src/concurrency/io/call.cfa.in
r24d6572 r34b4268 31 31 Prelude = """#define __cforall_thread__ 32 32 33 #include <unistd.h>34 #include <errno.h>35 #include <sys/socket.h>36 #include <time.hfa>37 38 33 #include "bits/defs.hfa" 39 34 #include "kernel.hfa" … … 48 43 #include <assert.h> 49 44 #include <stdint.h> 45 #include <errno.h> 50 46 #include <linux/io_uring.h> 47 51 48 #include "kernel/fwd.hfa" 52 49 … … 85 82 // I/O Forwards 86 83 //============================================================================================= 84 #include <time.hfa> 85 86 // Some forward declarations 87 #include <errno.h> 88 #include <unistd.h> 87 89 88 90 extern "C" { 91 #include <asm/types.h> 92 #include <sys/socket.h> 93 #include <sys/syscall.h> 94 89 95 #if defined(CFA_HAVE_PREADV2) 90 96 struct iovec; 91 extern ssize_t preadv2 (int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags);97 extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags); 92 98 #endif 93 99 #if defined(CFA_HAVE_PWRITEV2) 94 100 struct iovec; 95 extern ssize_t pwritev2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags);101 extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags); 96 102 #endif 97 103 … … 108 114 struct msghdr; 109 115 struct sockaddr; 110 extern ssize_t sendmsg(int sockfd, const struct msghdr * msg, int flags); 111 extern ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags); 112 extern ssize_t send(int sockfd, const void * buf, size_t len, int flags); 113 extern ssize_t recv(int sockfd, void * buf, size_t len, int flags); 116 extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); 117 extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); 118 extern ssize_t send(int sockfd, const void *buf, size_t len, int flags); 119 extern ssize_t recv(int sockfd, void *buf, size_t len, int flags); 120 extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags); 121 extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 114 122 115 123 extern int fallocate(int fd, int mode, off_t offset, off_t len); 116 124 extern int posix_fadvise(int fd, off_t offset, off_t len, int advice); 117 extern int madvise(void * addr, size_t length, int advice);118 119 extern int openat(int dirfd, const char * pathname, int flags, mode_t mode);125 extern int madvise(void *addr, size_t length, int advice); 126 127 extern int openat(int dirfd, const char *pathname, int flags, mode_t mode); 120 128 extern int close(int fd); 121 129 122 extern ssize_t read (int fd, void * buf, size_t count);130 extern ssize_t read (int fd, void *buf, size_t count); 123 131 124 132 struct epoll_event; 125 extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event * event);126 127 extern ssize_t splice(int fd_in, __off64_t * off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags);133 extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 134 135 extern ssize_t splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags); 128 136 extern ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags); 129 137 } … … 224 232 calls = [ 225 233 # CFA_HAVE_IORING_OP_READV 226 Call('READV', 'ssize_t preadv2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags)', {234 Call('READV', 'ssize_t preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)', { 227 235 'fd' : 'fd', 228 'addr': '(typeof(sqe->addr))iov', 236 'off' : 'offset', 237 'addr': '(uintptr_t)iov', 229 238 'len' : 'iovcnt', 230 'off' : 'offset',231 'rw_flags' : 'flags'232 239 }, define = 'CFA_HAVE_PREADV2'), 233 240 # CFA_HAVE_IORING_OP_WRITEV 234 Call('WRITEV', 'ssize_t pwritev2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags)', {241 Call('WRITEV', 'ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)', { 235 242 'fd' : 'fd', 236 'addr': '(typeof(sqe->addr))iov',237 'len' : 'iovcnt',238 243 'off' : 'offset', 239 'rw_flags' : 'flags' 244 'addr': '(uintptr_t)iov', 245 'len' : 'iovcnt' 240 246 }, define = 'CFA_HAVE_PWRITEV2'), 241 247 # CFA_HAVE_IORING_OP_FSYNC … … 244 250 }), 245 251 # CFA_HAVE_IORING_OP_EPOLL_CTL 246 Call('EPOLL_CTL', 'int epoll_ctl(int epfd, int op, int fd, struct epoll_event * event)', {252 Call('EPOLL_CTL', 'int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)', { 247 253 'fd': 'epfd', 254 'addr': 'fd', 248 255 'len': 'op', 249 'addr': 'fd', 250 'off': '(typeof(sqe->off))event' 256 'off': '(uintptr_t)event' 251 257 }), 252 258 # CFA_HAVE_IORING_OP_SYNC_FILE_RANGE … … 258 264 }), 259 265 # CFA_HAVE_IORING_OP_SENDMSG 260 Call('SENDMSG', 'ssize_t sendmsg(int sockfd, const struct msghdr * msg, int flags)', {261 'fd': 'sockfd', 262 'addr': '( typeof(sqe->addr))(struct msghdr *)msg',266 Call('SENDMSG', 'ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)', { 267 'fd': 'sockfd', 268 'addr': '(uintptr_t)(struct msghdr *)msg', 263 269 'len': '1', 264 270 'msg_flags': 'flags' 265 271 }), 266 272 # CFA_HAVE_IORING_OP_RECVMSG 267 Call('RECVMSG', 'ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags)', {268 'fd': 'sockfd', 269 'addr': '( typeof(sqe->addr))(struct msghdr *)msg',273 Call('RECVMSG', 'ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)', { 274 'fd': 'sockfd', 275 'addr': '(uintptr_t)(struct msghdr *)msg', 270 276 'len': '1', 271 277 'msg_flags': 'flags' 272 278 }), 273 279 # CFA_HAVE_IORING_OP_SEND 274 Call('SEND', 'ssize_t send(int sockfd, const void * buf, size_t len, int flags)', {275 'fd': 'sockfd', 276 'addr': '( typeof(sqe->addr))buf',280 Call('SEND', 'ssize_t send(int sockfd, const void *buf, size_t len, int flags)', { 281 'fd': 'sockfd', 282 'addr': '(uintptr_t)buf', 277 283 'len': 'len', 278 284 'msg_flags': 'flags' 279 285 }), 280 286 # CFA_HAVE_IORING_OP_RECV 281 Call('RECV', 'ssize_t recv(int sockfd, void * buf, size_t len, int flags)', {282 'fd': 'sockfd', 283 'addr': '( typeof(sqe->addr))buf',287 Call('RECV', 'ssize_t recv(int sockfd, void *buf, size_t len, int flags)', { 288 'fd': 'sockfd', 289 'addr': '(uintptr_t)buf', 284 290 'len': 'len', 285 291 'msg_flags': 'flags' 286 292 }), 287 293 # CFA_HAVE_IORING_OP_ACCEPT 288 Call('ACCEPT', 'int accept4(int sockfd, __SOCKADDR_ARG addr, socklen_t * restrictaddrlen, int flags)', {289 'fd': 'sockfd', 290 'addr': '( typeof(sqe->addr))&addr',291 'addr2': '( typeof(sqe->addr2))addrlen',294 Call('ACCEPT', 'int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)', { 295 'fd': 'sockfd', 296 'addr': '(uintptr_t)addr', 297 'addr2': '(uintptr_t)addrlen', 292 298 'accept_flags': 'flags' 293 299 }), 294 300 # CFA_HAVE_IORING_OP_CONNECT 295 Call('CONNECT', 'int connect(int sockfd, __CONST_SOCKADDR_ARGaddr, socklen_t addrlen)', {296 'fd': 'sockfd', 297 'addr': '( typeof(sqe->addr))&addr',301 Call('CONNECT', 'int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)', { 302 'fd': 'sockfd', 303 'addr': '(uintptr_t)addr', 298 304 'off': 'addrlen' 299 305 }), … … 301 307 Call('FALLOCATE', 'int fallocate(int fd, int mode, off_t offset, off_t len)', { 302 308 'fd': 'fd', 309 'addr': '(uintptr_t)len', 303 310 'len': 'mode', 304 'off': 'offset', 305 'addr': 'len' 311 'off': 'offset' 306 312 }), 307 313 # CFA_HAVE_IORING_OP_FADVISE … … 313 319 }), 314 320 # CFA_HAVE_IORING_OP_MADVISE 315 Call('MADVISE', 'int madvise(void * addr, size_t length, int advice)', {316 'addr': '( typeof(sqe->addr))addr',321 Call('MADVISE', 'int madvise(void *addr, size_t length, int advice)', { 322 'addr': '(uintptr_t)addr', 317 323 'len': 'length', 318 324 'fadvise_advice': 'advice' 319 325 }), 320 326 # CFA_HAVE_IORING_OP_OPENAT 321 Call('OPENAT', 'int openat(int dirfd, const char * pathname, int flags, mode_t mode)', {327 Call('OPENAT', 'int openat(int dirfd, const char *pathname, int flags, mode_t mode)', { 322 328 'fd': 'dirfd', 323 'addr': '( typeof(sqe->addr))pathname',324 ' open_flags': 'flags;',325 ' len': 'mode'329 'addr': '(uintptr_t)pathname', 330 'len': 'mode', 331 'open_flags': 'flags;' 326 332 }), 327 333 # CFA_HAVE_IORING_OP_OPENAT2 328 Call('OPENAT2', 'int openat2(int dirfd, const char * pathname, struct open_how * how, size_t size)', {334 Call('OPENAT2', 'int openat2(int dirfd, const char *pathname, struct open_how * how, size_t size)', { 329 335 'fd': 'dirfd', 330 'addr': ' (typeof(sqe->addr))pathname',331 ' off': '(typeof(sqe->off))how',332 ' len': 'sizeof(*how)'336 'addr': 'pathname', 337 'len': 'sizeof(*how)', 338 'off': '(uintptr_t)how', 333 339 }, define = 'CFA_HAVE_OPENAT2'), 334 340 # CFA_HAVE_IORING_OP_CLOSE … … 337 343 }), 338 344 # CFA_HAVE_IORING_OP_STATX 339 Call('STATX', 'int statx(int dirfd, const char * pathname, int flags, unsigned int mask, struct statx *statxbuf)', {345 Call('STATX', 'int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf)', { 340 346 'fd': 'dirfd', 341 ' addr': '(typeof(sqe->addr))pathname',342 ' statx_flags': 'flags',347 'off': '(uintptr_t)statxbuf', 348 'addr': 'pathname', 343 349 'len': 'mask', 344 ' off': '(typeof(sqe->off))statxbuf'350 'statx_flags': 'flags' 345 351 }, define = 'CFA_HAVE_STATX'), 346 352 # CFA_HAVE_IORING_OP_READ 347 353 Call('READ', 'ssize_t read(int fd, void * buf, size_t count)', { 348 354 'fd': 'fd', 349 'addr': '( typeof(sqe->addr))buf',355 'addr': '(uintptr_t)buf', 350 356 'len': 'count' 351 357 }), … … 353 359 Call('WRITE', 'ssize_t write(int fd, void * buf, size_t count)', { 354 360 'fd': 'fd', 355 'addr': '( typeof(sqe->addr))buf',361 'addr': '(uintptr_t)buf', 356 362 'len': 'count' 357 363 }), 358 364 # CFA_HAVE_IORING_OP_SPLICE 359 Call('SPLICE', 'ssize_t splice(int fd_in, __off64_t * off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags)', {365 Call('SPLICE', 'ssize_t splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags)', { 360 366 'splice_fd_in': 'fd_in', 361 'splice_off_in': 'off_in ? ( typeof(sqe->splice_off_in))*off_in : (typeof(sqe->splice_off_in))-1',367 'splice_off_in': 'off_in ? (__u64)*off_in : (__u64)-1', 362 368 'fd': 'fd_out', 363 'off': 'off_out ? ( typeof(sqe->off))*off_out : (typeof(sqe->off))-1',369 'off': 'off_out ? (__u64)*off_out : (__u64)-1', 364 370 'len': 'len', 365 371 'splice_flags': 'flags' -
libcfa/src/concurrency/io/setup.cfa
r24d6572 r34b4268 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #if defined(__CFA_DEBUG__) … … 215 216 216 217 // completion queue 217 cq. try_lock= false;218 cq.lock = false; 218 219 cq.id = MAX; 219 220 cq.ts = rdtscl(); -
libcfa/src/concurrency/io/types.hfa
r24d6572 r34b4268 37 37 //----------------------------------------------------------------------- 38 38 // Ring Data structure 39 // represent the io_uring submission ring which contains operations that will be sent to io_uring for processing 40 struct __sub_ring_t { 41 // lock needed because remote processors might need to flush the instance 42 __spinlock_t lock; 43 39 struct __sub_ring_t { 44 40 struct { 45 41 // Head and tail of the ring (associated with array) … … 62 58 63 59 // number of sqes to submit on next system call. 64 volatile__u32 to_submit;60 __u32 to_submit; 65 61 66 62 // number of entries and mask to go with it … … 81 77 void * ring_ptr; 82 78 size_t ring_sz; 83 84 // for debug purposes, whether or not the last flush was due to a arbiter flush85 bool last_external;86 79 }; 87 80 88 // represent the io_uring completion ring which contains operations that have completed89 81 struct __cmp_ring_t { 90 // needed because remote processors can help drain the buffer 91 volatile bool try_lock; 82 volatile bool lock; 92 83 93 // id of the ring, used for the helping/topology algorithms94 84 unsigned id; 95 85 96 // timestamp from last time it was drained97 86 unsigned long long ts; 98 87 … … 116 105 }; 117 106 118 // struct representing an io operation that still needs processing119 // actual operations are expected to inherit from this120 107 struct __outstanding_io { 121 // intrusive link fields122 108 inline Colable; 123 124 // primitive on which to block until the io is processed125 109 oneshot waitctx; 126 110 }; 127 111 static inline __outstanding_io *& Next( __outstanding_io * n ) { return (__outstanding_io *)Next( (Colable *)n ); } 128 112 129 // queue of operations that are outstanding130 113 struct __outstanding_io_queue { 131 // spinlock for protection132 // TODO: changing to a lock that blocks, I haven't examined whether it should be a kernel or user lock133 114 __spinlock_t lock; 134 135 // the actual queue136 115 Queue(__outstanding_io) queue; 137 138 // volatile used to avoid the need for taking the lock if it's empty139 116 volatile bool empty; 140 117 }; 141 118 142 // struct representing an operation that was submitted143 119 struct __external_io { 144 // inherits from outstanding io145 120 inline __outstanding_io; 146 147 // pointer and count to an array of ids to be submitted148 121 __u32 * idxs; 149 122 __u32 have; 150 151 // whether or not these can be accumulated before flushing the buffer152 123 bool lazy; 153 124 }; 154 125 155 // complete io_context, contains all the data for io submission and completion 126 156 127 struct __attribute__((aligned(64))) io_context$ { 157 // arbiter, used in cases where threads for migrated at unfortunate moments158 128 io_arbiter$ * arbiter; 159 160 // which prcessor the context is tied to161 129 struct processor * proc; 162 130 163 // queue of io submissions that haven't beeen processed.164 131 __outstanding_io_queue ext_sq; 165 132 166 // io_uring ring data structures167 133 struct __sub_ring_t sq; 168 134 struct __cmp_ring_t cq; 169 170 // flag the io_uring rings where created with171 135 __u32 ring_flags; 172 173 // file descriptor that identifies the io_uring instance174 136 int fd; 175 137 }; 176 138 177 // short hand to check when the io_context was last processed (io drained)178 139 static inline unsigned long long ts(io_context$ *& this) { 179 140 const __u32 head = *this->cq.head; 180 141 const __u32 tail = *this->cq.tail; 181 142 182 // if there is no pending completions, just pretend it's infinetely recent183 143 if(head == tail) return ULLONG_MAX; 184 144 … … 186 146 } 187 147 188 // structure represeting allocations that couldn't succeed locally189 148 struct __pending_alloc { 190 // inherit from outstanding io191 149 inline __outstanding_io; 192 193 // array and size of the desired allocation194 150 __u32 * idxs; 195 151 __u32 want; 196 197 // output param, the context the io was allocated from198 152 io_context$ * ctx; 199 153 }; 200 154 201 // arbiter that handles cases where the context tied to the local processor is unable to satisfy the io202 155 monitor __attribute__((aligned(64))) io_arbiter$ { 203 // contains a queue of io for pending allocations204 156 __outstanding_io_queue pending; 205 157 }; -
libcfa/src/concurrency/iofwd.hfa
r24d6572 r34b4268 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu Apr 23 17:31:00 2020 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Mar 13 23:54:57 202313 // Update Count : 111 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 14 14 // 15 15 … … 17 17 18 18 #include <unistd.h> 19 #include <sys/socket.h>20 21 19 extern "C" { 22 20 #include <asm/types.h> … … 50 48 typedef __off64_t off64_t; 51 49 50 struct cluster; 51 struct io_context$; 52 53 struct iovec; 54 struct msghdr; 55 struct sockaddr; 56 struct statx; 52 57 struct epoll_event; 58 59 struct io_uring_sqe; 53 60 54 61 //----------------------------------------------------------------------- … … 81 88 // synchronous calls 82 89 #if defined(CFA_HAVE_PREADV2) 83 extern ssize_t cfa_preadv2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags, __u64 submit_flags);90 extern ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, __u64 submit_flags); 84 91 #endif 85 92 #if defined(CFA_HAVE_PWRITEV2) 86 extern ssize_t cfa_pwritev2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags, __u64 submit_flags);93 extern ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, __u64 submit_flags); 87 94 #endif 88 95 extern int cfa_fsync(int fd, __u64 submit_flags); 89 extern int cfa_epoll_ctl(int epfd, int op, int fd, struct epoll_event * event, __u64 submit_flags);96 extern int cfa_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event, __u64 submit_flags); 90 97 extern int cfa_sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags, __u64 submit_flags); 91 extern ssize_t cfa_sendmsg(int sockfd, const struct msghdr * msg, int flags, __u64 submit_flags);92 extern ssize_t cfa_recvmsg(int sockfd, struct msghdr * msg, int flags, __u64 submit_flags);93 extern ssize_t cfa_send(int sockfd, const void * buf, size_t len, int flags, __u64 submit_flags);94 extern ssize_t cfa_recv(int sockfd, void * buf, size_t len, int flags, __u64 submit_flags);95 extern int cfa_accept4(int sockfd, __SOCKADDR_ARG addr, socklen_t * restrictaddrlen, int flags, __u64 submit_flags);96 extern int cfa_connect(int sockfd, __CONST_SOCKADDR_ARGaddr, socklen_t addrlen, __u64 submit_flags);98 extern ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags, __u64 submit_flags); 99 extern ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags, __u64 submit_flags); 100 extern ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags, __u64 submit_flags); 101 extern ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags, __u64 submit_flags); 102 extern int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, __u64 submit_flags); 103 extern int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen, __u64 submit_flags); 97 104 extern int cfa_fallocate(int fd, int mode, off_t offset, off_t len, __u64 submit_flags); 98 105 extern int cfa_posix_fadvise(int fd, off_t offset, off_t len, int advice, __u64 submit_flags); 99 extern int cfa_madvise(void * addr, size_t length, int advice, __u64 submit_flags);100 extern int cfa_openat(int dirfd, const char * pathname, int flags, mode_t mode, __u64 submit_flags);106 extern int cfa_madvise(void *addr, size_t length, int advice, __u64 submit_flags); 107 extern int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode, __u64 submit_flags); 101 108 #if defined(CFA_HAVE_OPENAT2) 102 extern int cfa_openat2(int dirfd, const char * pathname, struct open_how * how, size_t size, __u64 submit_flags);109 extern int cfa_openat2(int dirfd, const char *pathname, struct open_how * how, size_t size, __u64 submit_flags); 103 110 #endif 104 111 extern int cfa_close(int fd, __u64 submit_flags); 105 112 #if defined(CFA_HAVE_STATX) 106 extern int cfa_statx(int dirfd, const char * pathname, int flags, unsigned int mask, struct statx *statxbuf, __u64 submit_flags);113 extern int cfa_statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf, __u64 submit_flags); 107 114 #endif 108 115 extern ssize_t cfa_read(int fd, void * buf, size_t count, __u64 submit_flags); 109 116 extern ssize_t cfa_write(int fd, void * buf, size_t count, __u64 submit_flags); 110 extern ssize_t cfa_splice(int fd_in, __off64_t * off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags, __u64 submit_flags);117 extern ssize_t cfa_splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags, __u64 submit_flags); 111 118 extern ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags, __u64 submit_flags); 112 119 … … 114 121 // asynchronous calls 115 122 #if defined(CFA_HAVE_PREADV2) 116 extern void async_preadv2(io_future_t & future, int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags, __u64 submit_flags);123 extern void async_preadv2(io_future_t & future, int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, __u64 submit_flags); 117 124 #endif 118 125 #if defined(CFA_HAVE_PWRITEV2) 119 extern void async_pwritev2(io_future_t & future, int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags, __u64 submit_flags);126 extern void async_pwritev2(io_future_t & future, int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, __u64 submit_flags); 120 127 #endif 121 128 extern void async_fsync(io_future_t & future, int fd, __u64 submit_flags); 122 extern void async_epoll_ctl(io_future_t & future, int epfd, int op, int fd, struct epoll_event * event, __u64 submit_flags);129 extern void async_epoll_ctl(io_future_t & future, int epfd, int op, int fd, struct epoll_event *event, __u64 submit_flags); 123 130 extern void async_sync_file_range(io_future_t & future, int fd, off64_t offset, off64_t nbytes, unsigned int flags, __u64 submit_flags); 124 extern void async_sendmsg(io_future_t & future, int sockfd, const struct msghdr * msg, int flags, __u64 submit_flags);125 extern void async_recvmsg(io_future_t & future, int sockfd, struct msghdr * msg, int flags, __u64 submit_flags);126 extern void async_send(io_future_t & future, int sockfd, const void * buf, size_t len, int flags, __u64 submit_flags);127 extern void async_recv(io_future_t & future, int sockfd, void * buf, size_t len, int flags, __u64 submit_flags);128 extern void async_accept4(io_future_t & future, int sockfd, __SOCKADDR_ARG addr, socklen_t * restrictaddrlen, int flags, __u64 submit_flags);129 extern void async_connect(io_future_t & future, int sockfd, __CONST_SOCKADDR_ARGaddr, socklen_t addrlen, __u64 submit_flags);131 extern void async_sendmsg(io_future_t & future, int sockfd, const struct msghdr *msg, int flags, __u64 submit_flags); 132 extern void async_recvmsg(io_future_t & future, int sockfd, struct msghdr *msg, int flags, __u64 submit_flags); 133 extern void async_send(io_future_t & future, int sockfd, const void *buf, size_t len, int flags, __u64 submit_flags); 134 extern void async_recv(io_future_t & future, int sockfd, void *buf, size_t len, int flags, __u64 submit_flags); 135 extern void async_accept4(io_future_t & future, int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, __u64 submit_flags); 136 extern void async_connect(io_future_t & future, int sockfd, const struct sockaddr *addr, socklen_t addrlen, __u64 submit_flags); 130 137 extern void async_fallocate(io_future_t & future, int fd, int mode, off_t offset, off_t len, __u64 submit_flags); 131 138 extern void async_posix_fadvise(io_future_t & future, int fd, off_t offset, off_t len, int advice, __u64 submit_flags); 132 extern void async_madvise(io_future_t & future, void * addr, size_t length, int advice, __u64 submit_flags);133 extern void async_openat(io_future_t & future, int dirfd, const char * pathname, int flags, mode_t mode, __u64 submit_flags);139 extern void async_madvise(io_future_t & future, void *addr, size_t length, int advice, __u64 submit_flags); 140 extern void async_openat(io_future_t & future, int dirfd, const char *pathname, int flags, mode_t mode, __u64 submit_flags); 134 141 #if defined(CFA_HAVE_OPENAT2) 135 extern void async_openat2(io_future_t & future, int dirfd, const char * pathname, struct open_how * how, size_t size, __u64 submit_flags);142 extern void async_openat2(io_future_t & future, int dirfd, const char *pathname, struct open_how * how, size_t size, __u64 submit_flags); 136 143 #endif 137 144 extern void async_close(io_future_t & future, int fd, __u64 submit_flags); 138 145 #if defined(CFA_HAVE_STATX) 139 extern void async_statx(io_future_t & future, int dirfd, const char * pathname, int flags, unsigned int mask, struct statx *statxbuf, __u64 submit_flags);146 extern void async_statx(io_future_t & future, int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf, __u64 submit_flags); 140 147 #endif 141 148 void async_read(io_future_t & future, int fd, void * buf, size_t count, __u64 submit_flags); 142 149 extern void async_write(io_future_t & future, int fd, void * buf, size_t count, __u64 submit_flags); 143 extern void async_splice(io_future_t & future, int fd_in, __off64_t * off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags, __u64 submit_flags);150 extern void async_splice(io_future_t & future, int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags, __u64 submit_flags); 144 151 extern void async_tee(io_future_t & future, int fd_in, int fd_out, size_t len, unsigned int flags, __u64 submit_flags); 145 152 -
libcfa/src/concurrency/kernel.cfa
r24d6572 r34b4268 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 9 08:42:05 202313 // Update Count : 7 712 // Last Modified On : Wed Nov 30 18:14:08 2022 13 // Update Count : 76 14 14 // 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 // #define __CFA_DEBUG_PRINT_RUNTIME_CORE__ … … 257 258 __cfadbg_print_safe(runtime_core, "Kernel : core %p stopping\n", this); 258 259 } 259 260 __cfa_io_flush( this );261 __cfa_io_drain( this );262 260 263 261 post( this->terminated ); -
libcfa/src/concurrency/kernel/cluster.cfa
r24d6572 r34b4268 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #include "bits/defs.hfa" … … 68 69 return max_cores_l; 69 70 } 71 72 #if defined(CFA_HAVE_LINUX_LIBRSEQ) 73 // No forward declaration needed 74 #define __kernel_rseq_register rseq_register_current_thread 75 #define __kernel_rseq_unregister rseq_unregister_current_thread 76 #elif defined(CFA_HAVE_LINUX_RSEQ_H) 77 static void __kernel_raw_rseq_register (void); 78 static void __kernel_raw_rseq_unregister(void); 79 80 #define __kernel_rseq_register __kernel_raw_rseq_register 81 #define __kernel_rseq_unregister __kernel_raw_rseq_unregister 82 #else 83 // No forward declaration needed 84 // No initialization needed 85 static inline void noop(void) {} 86 87 #define __kernel_rseq_register noop 88 #define __kernel_rseq_unregister noop 89 #endif 70 90 71 91 //======================================================================= … … 91 111 // Lock-Free registering/unregistering of threads 92 112 unsigned register_proc_id( void ) with(__scheduler_lock.lock) { 113 __kernel_rseq_register(); 114 93 115 bool * handle = (bool *)&kernelTLS().sched_lock; 94 116 … … 140 162 141 163 __atomic_store_n(cell, 0p, __ATOMIC_RELEASE); 164 165 __kernel_rseq_unregister(); 142 166 } 143 167 … … 481 505 /* paranoid */ verify( mock_head(this) == this.l.prev ); 482 506 } 507 508 #if defined(CFA_HAVE_LINUX_LIBRSEQ) 509 // No definition needed 510 #elif defined(CFA_HAVE_LINUX_RSEQ_H) 511 512 #if defined( __x86_64 ) || defined( __i386 ) 513 #define RSEQ_SIG 0x53053053 514 #elif defined( __ARM_ARCH ) 515 #ifdef __ARMEB__ 516 #define RSEQ_SIG 0xf3def5e7 /* udf #24035 ; 0x5de3 (ARMv6+) */ 517 #else 518 #define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */ 519 #endif 520 #endif 521 522 extern void __disable_interrupts_hard(); 523 extern void __enable_interrupts_hard(); 524 525 static void __kernel_raw_rseq_register (void) { 526 /* paranoid */ verify( __cfaabi_rseq.cpu_id == RSEQ_CPU_ID_UNINITIALIZED ); 527 528 // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, (sigset_t *)0p, _NSIG / 8); 529 int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, RSEQ_SIG); 530 if(ret != 0) { 531 int e = errno; 532 switch(e) { 533 case EINVAL: abort("KERNEL ERROR: rseq register invalid argument"); 534 case ENOSYS: abort("KERNEL ERROR: rseq register no supported"); 535 case EFAULT: abort("KERNEL ERROR: rseq register with invalid argument"); 536 case EBUSY : abort("KERNEL ERROR: rseq register already registered"); 537 case EPERM : abort("KERNEL ERROR: rseq register sig argument on unregistration does not match the signature received on registration"); 538 default: abort("KERNEL ERROR: rseq register unexpected return %d", e); 539 } 540 } 541 } 542 543 static void __kernel_raw_rseq_unregister(void) { 544 /* paranoid */ verify( __cfaabi_rseq.cpu_id >= 0 ); 545 546 // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, (sigset_t *)0p, _NSIG / 8); 547 int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG); 548 if(ret != 0) { 549 int e = errno; 550 switch(e) { 551 case EINVAL: abort("KERNEL ERROR: rseq unregister invalid argument"); 552 case ENOSYS: abort("KERNEL ERROR: rseq unregister no supported"); 553 case EFAULT: abort("KERNEL ERROR: rseq unregister with invalid argument"); 554 case EBUSY : abort("KERNEL ERROR: rseq unregister already registered"); 555 case EPERM : abort("KERNEL ERROR: rseq unregister sig argument on unregistration does not match the signature received on registration"); 556 default: abort("KERNEL ERROR: rseq unregisteunexpected return %d", e); 557 } 558 } 559 } 560 #else 561 // No definition needed 562 #endif -
libcfa/src/concurrency/kernel/cluster.hfa
r24d6572 r34b4268 40 40 41 41 // convert to log2 scale but using double 42 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2( (__readyQ_avg_t)intsc); }42 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2(intsc); } 43 43 44 44 #define warn_large_before warnf( !strict || old_avg < 35.0, "Suspiciously large previous average: %'lf, %'" PRId64 "ms \n", old_avg, program()`ms ) … … 146 146 } 147 147 148 conststatic struct {149 unsigned readyq;150 unsigned io;148 static struct { 149 const unsigned readyq; 150 const unsigned io; 151 151 } __shard_factor = { 2, 1 }; 152 152 -
libcfa/src/concurrency/kernel/private.hfa
r24d6572 r34b4268 10 10 // Created On : Mon Feb 13 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 2 16:04:46 202313 // Update Count : 1112 // Last Modified On : Wed Aug 12 08:21:33 2020 13 // Update Count : 9 14 14 // 15 15 … … 29 29 30 30 extern "C" { 31 #if defined(CFA_HAVE_LINUX_LIBRSEQ) 32 #include <rseq/rseq.h> 33 #elif defined(CFA_HAVE_LINUX_RSEQ_H) 34 #include <linux/rseq.h> 35 #else 36 #ifndef _GNU_SOURCE 37 #error kernel/private requires gnu_source 38 #endif 31 39 #include <sched.h> 40 #endif 32 41 } 33 42 … … 101 110 // Hardware 102 111 112 #if defined(CFA_HAVE_LINUX_LIBRSEQ) 113 // No data needed 114 #elif defined(CFA_HAVE_LINUX_RSEQ_H) 115 extern "Cforall" { 116 extern __attribute__((aligned(64))) __thread volatile struct rseq __cfaabi_rseq; 117 } 118 #else 119 // No data needed 120 #endif 121 103 122 static inline int __kernel_getcpu() { 104 123 /* paranoid */ verify( ! __preemption_enabled() ); 124 #if defined(CFA_HAVE_LINUX_LIBRSEQ) 125 return rseq_current_cpu(); 126 #elif defined(CFA_HAVE_LINUX_RSEQ_H) 127 int r = __cfaabi_rseq.cpu_id; 128 /* paranoid */ verify( r >= 0 ); 129 return r; 130 #else 105 131 return sched_getcpu(); 132 #endif 106 133 } 107 134 -
libcfa/src/concurrency/kernel/startup.cfa
r24d6572 r34b4268 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 // #define __CFA_DEBUG_PRINT_RUNTIME_CORE__ 19 20 20 21 // C Includes 21 #include <errno.h> // errno22 #include <errno.h> // errno 22 23 #include <signal.h> 23 #include <string.h> // strerror24 #include <unistd.h> 25 #include <limits.h> // PTHREAD_STACK_MIN 24 #include <string.h> // strerror 25 #include <unistd.h> // sysconf 26 26 27 extern "C" { 27 #include <sys/eventfd.h> // eventfd 28 #include <sys/mman.h> // mprotect 29 #include <sys/resource.h> // getrlimit 28 #include <limits.h> // PTHREAD_STACK_MIN 29 #include <unistd.h> // syscall 30 #include <sys/eventfd.h> // eventfd 31 #include <sys/mman.h> // mprotect 32 #include <sys/resource.h> // getrlimit 30 33 } 31 34 … … 33 36 #include "kernel/private.hfa" 34 37 #include "iofwd.hfa" 35 #include "startup.hfa" // STARTUP_PRIORITY_XXX38 #include "startup.hfa" // STARTUP_PRIORITY_XXX 36 39 #include "limits.hfa" 37 40 #include "math.hfa" … … 147 150 __scheduler_RWLock_t __scheduler_lock @= { 0 }; 148 151 152 #if defined(CFA_HAVE_LINUX_LIBRSEQ) 153 // No data needed 154 #elif defined(CFA_HAVE_LINUX_RSEQ_H) 155 extern "Cforall" { 156 __attribute__((aligned(64))) __thread volatile struct rseq __cfaabi_rseq @= { 157 .cpu_id : RSEQ_CPU_ID_UNINITIALIZED, 158 }; 159 } 160 #else 161 // No data needed 162 #endif 163 149 164 //----------------------------------------------------------------------------- 150 165 // Struct to steal stack -
libcfa/src/concurrency/locks.cfa
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // locks. cfa -- LIBCFATHREAD7 // locks.hfa -- LIBCFATHREAD 8 8 // Runtime locks that used with the runtime thread system. 9 9 // … … 16 16 17 17 #define __cforall_thread__ 18 #define _GNU_SOURCE 18 19 19 20 #include "locks.hfa" … … 79 80 // lock is held by some other thread 80 81 if ( owner != 0p && owner != thrd ) { 81 select_node node; 82 insert_last( blocked_threads, node ); 82 insert_last( blocked_threads, *thrd ); 83 83 wait_count++; 84 84 unlock( lock ); 85 85 park( ); 86 return; 87 } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread 86 } 87 // multi acquisition lock is held by current thread 88 else if ( owner == thrd && multi_acquisition ) { 88 89 recursion_count++; 89 } else { // lock isn't held 90 unlock( lock ); 91 } 92 // lock isn't held 93 else { 90 94 owner = thrd; 91 95 recursion_count = 1; 92 }93 unlock( lock ); 96 unlock( lock ); 97 } 94 98 } 95 99 … … 114 118 } 115 119 116 static inline void pop_node( blocking_lock & this ) with( this ) { 117 __handle_waituntil_OR( blocked_threads ); 118 select_node * node = &try_pop_front( blocked_threads ); 119 if ( node ) { 120 wait_count--; 121 owner = node->blocked_thread; 122 recursion_count = 1; 123 // if ( !node->clause_status || __make_select_node_available( *node ) ) unpark( node->blocked_thread ); 124 wake_one( blocked_threads, *node ); 125 } else { 126 owner = 0p; 127 recursion_count = 0; 128 } 120 static void pop_and_set_new_owner( blocking_lock & this ) with( this ) { 121 thread$ * t = &try_pop_front( blocked_threads ); 122 owner = t; 123 recursion_count = ( t ? 1 : 0 ); 124 if ( t ) wait_count--; 125 unpark( t ); 129 126 } 130 127 … … 138 135 recursion_count--; 139 136 if ( recursion_count == 0 ) { 140 pop_ node( this );137 pop_and_set_new_owner( this ); 141 138 } 142 139 unlock( lock ); … … 151 148 // lock held 152 149 if ( owner != 0p ) { 153 insert_last( blocked_threads, * (select_node *)t->link_node);150 insert_last( blocked_threads, *t ); 154 151 wait_count++; 152 unlock( lock ); 155 153 } 156 154 // lock not held … … 159 157 recursion_count = 1; 160 158 unpark( t ); 161 }162 unlock( lock ); 163 } 164 165 size_t on_wait( blocking_lock & this , __cfa_pre_park pp_fn, void * pp_datum) with( this ) {159 unlock( lock ); 160 } 161 } 162 163 size_t on_wait( blocking_lock & this ) with( this ) { 166 164 lock( lock __cfaabi_dbg_ctx2 ); 167 165 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); … … 170 168 size_t ret = recursion_count; 171 169 172 pop_node( this ); 173 174 select_node node; 175 active_thread()->link_node = (void *)&node; 170 pop_and_set_new_owner( this ); 176 171 unlock( lock ); 177 178 pre_park_then_park( pp_fn, pp_datum );179 180 172 return ret; 181 173 } … … 184 176 recursion_count = recursion; 185 177 } 186 187 // waituntil() support188 bool register_select( blocking_lock & this, select_node & node ) with(this) {189 lock( lock __cfaabi_dbg_ctx2 );190 thread$ * thrd = active_thread();191 192 // single acquisition lock is held by current thread193 /* paranoid */ verifyf( owner != thrd || multi_acquisition, "Single acquisition lock holder (%p) attempted to reacquire the lock %p resulting in a deadlock.", owner, &this );194 195 if ( !node.park_counter && ( (owner == thrd && multi_acquisition) || owner == 0p ) ) { // OR special case196 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering197 unlock( lock );198 return false;199 }200 }201 202 // lock is held by some other thread203 if ( owner != 0p && owner != thrd ) {204 insert_last( blocked_threads, node );205 wait_count++;206 unlock( lock );207 return false;208 } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread209 recursion_count++;210 } else { // lock isn't held211 owner = thrd;212 recursion_count = 1;213 }214 215 if ( node.park_counter ) __make_select_node_available( node );216 unlock( lock );217 return true;218 }219 220 bool unregister_select( blocking_lock & this, select_node & node ) with(this) {221 lock( lock __cfaabi_dbg_ctx2 );222 if ( node`isListed ) {223 remove( node );224 wait_count--;225 unlock( lock );226 return false;227 }228 229 if ( owner == active_thread() ) {230 /* paranoid */ verifyf( recursion_count == 1 || multi_acquisition, "Thread %p attempted to unlock owner lock %p in waituntil unregister, which is not recursive but has a recursive count of %zu", active_thread(), &this, recursion_count );231 // if recursion count is zero release lock and set new owner if one is waiting232 recursion_count--;233 if ( recursion_count == 0 ) {234 pop_node( this );235 }236 }237 unlock( lock );238 return false;239 }240 241 void on_selected( blocking_lock & this, select_node & node ) {}242 178 243 179 //----------------------------------------------------------------------------- … … 376 312 int counter( condition_variable(L) & this ) with(this) { return count; } 377 313 378 static void enqueue_thread( condition_variable(L) & this, info_thread(L) * i ) with(this) {314 static size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) { 379 315 // add info_thread to waiting queue 380 316 insert_last( blocked_threads, *i ); 381 317 count++; 382 } 383 384 static size_t block_and_get_recursion( info_thread(L) & i, __cfa_pre_park pp_fn, void * pp_datum ) { 385 size_t recursion_count = 0; 386 if ( i.lock ) // if lock was passed get recursion count to reset to after waking thread 387 recursion_count = on_wait( *i.lock, pp_fn, pp_datum ); // this call blocks 388 else 389 pre_park_then_park( pp_fn, pp_datum ); 390 return recursion_count; 391 } 392 static size_t block_and_get_recursion( info_thread(L) & i ) { return block_and_get_recursion( i, pre_park_noop, 0p ); } 318 size_t recursion_count = 0; 319 if (i->lock) { 320 // if lock was passed get recursion count to reset to after waking thread 321 recursion_count = on_wait( *i->lock ); 322 } 323 return recursion_count; 324 } 393 325 394 326 // helper for wait()'s' with no timeout 395 327 static void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) { 396 328 lock( lock __cfaabi_dbg_ctx2 ); 397 enqueue_thread( this, &i);329 size_t recursion_count = queue_and_get_recursion(this, &i); 398 330 unlock( lock ); 399 331 400 332 // blocks here 401 size_t recursion_count = block_and_get_recursion( i);333 park( ); 402 334 403 335 // resets recursion count here after waking 404 if ( i.lock ) on_wakeup( *i.lock, recursion_count);336 if (i.lock) on_wakeup(*i.lock, recursion_count); 405 337 } 406 338 … … 409 341 queue_info_thread( this, i ); 410 342 411 static void cond_alarm_register( void * node_ptr ) { register_self( (alarm_node_t *)node_ptr ); }412 413 343 // helper for wait()'s' with a timeout 414 344 static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 415 345 lock( lock __cfaabi_dbg_ctx2 ); 416 enqueue_thread( this, &info);346 size_t recursion_count = queue_and_get_recursion(this, &info); 417 347 alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info }; 418 348 unlock( lock ); 419 349 420 // blocks here and registers alarm node before blocking after releasing locks to avoid deadlock 421 size_t recursion_count = block_and_get_recursion( info, cond_alarm_register, (void *)(&node_wrap.alarm_node) ); 422 // park(); 350 // registers alarm outside cond lock to avoid deadlock 351 register_self( &node_wrap.alarm_node ); 352 353 // blocks here 354 park(); 423 355 424 356 // unregisters alarm so it doesn't go off if this happens first … … 426 358 427 359 // resets recursion count here after waking 428 if ( info.lock ) on_wakeup( *info.lock, recursion_count);360 if (info.lock) on_wakeup(*info.lock, recursion_count); 429 361 } 430 362 … … 486 418 info_thread( L ) i = { active_thread(), info, &l }; 487 419 insert_last( blocked_threads, i ); 488 size_t recursion_count = on_wait( *i.lock , pre_park_noop, 0p ); // blocks here489 //park( );420 size_t recursion_count = on_wait( *i.lock ); 421 park( ); 490 422 on_wakeup(*i.lock, recursion_count); 491 423 } … … 528 460 bool empty ( pthread_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty; } 529 461 462 static size_t queue_and_get_recursion( pthread_cond_var(L) & this, info_thread(L) * i ) with(this) { 463 // add info_thread to waiting queue 464 insert_last( blocked_threads, *i ); 465 size_t recursion_count = 0; 466 recursion_count = on_wait( *i->lock ); 467 return recursion_count; 468 } 469 530 470 static void queue_info_thread_timeout( pthread_cond_var(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 531 471 lock( lock __cfaabi_dbg_ctx2 ); 532 insert_last( blocked_threads, info);472 size_t recursion_count = queue_and_get_recursion(this, &info); 533 473 pthread_alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info }; 534 474 unlock( lock ); 535 475 536 // blocks here and registers alarm node before blocking after releasing locks to avoid deadlock 537 size_t recursion_count = block_and_get_recursion( info, cond_alarm_register, (void *)(&node_wrap.alarm_node) ); 538 539 // unregisters alarm so it doesn't go off if signal happens first 476 // registers alarm outside cond lock to avoid deadlock 477 register_self( &node_wrap.alarm_node ); 478 479 // blocks here 480 park(); 481 482 // unregisters alarm so it doesn't go off if this happens first 540 483 unregister_self( &node_wrap.alarm_node ); 541 484 542 485 // resets recursion count here after waking 543 if ( info.lock ) on_wakeup( *info.lock, recursion_count);486 if (info.lock) on_wakeup(*info.lock, recursion_count); 544 487 } 545 488 … … 551 494 lock( lock __cfaabi_dbg_ctx2 ); 552 495 info_thread( L ) i = { active_thread(), info, &l }; 553 insert_last( blocked_threads, i ); 554 unlock( lock ); 555 556 // blocks here 557 size_t recursion_count = block_and_get_recursion( i ); 558 559 on_wakeup( *i.lock, recursion_count ); 496 size_t recursion_count = queue_and_get_recursion(this, &i); 497 unlock( lock ); 498 park( ); 499 on_wakeup(*i.lock, recursion_count); 560 500 } 561 501 … … 645 585 return thrd != 0p; 646 586 } 647 -
libcfa/src/concurrency/locks.hfa
r24d6572 r34b4268 30 30 #include "time.hfa" 31 31 32 #include "select.hfa"33 34 32 #include <fstream.hfa> 33 35 34 36 35 // futex headers … … 39 38 #include <unistd.h> 40 39 41 typedef void (*__cfa_pre_park)( void * ); 42 43 static inline void pre_park_noop( void * ) {} 44 45 //----------------------------------------------------------------------------- 46 // is_blocking_lock 47 forall( L & | sized(L) ) 48 trait is_blocking_lock { 49 // For synchronization locks to use when acquiring 50 void on_notify( L &, struct thread$ * ); 51 52 // For synchronization locks to use when releasing 53 size_t on_wait( L &, __cfa_pre_park pp_fn, void * pp_datum ); 54 55 // to set recursion count after getting signalled; 56 void on_wakeup( L &, size_t recursion ); 57 }; 58 59 static inline void pre_park_then_park( __cfa_pre_park pp_fn, void * pp_datum ) { 60 pp_fn( pp_datum ); 61 park(); 62 } 63 64 // macros for default routine impls for is_blocking_lock trait that do not wait-morph 65 66 #define DEFAULT_ON_NOTIFY( lock_type ) \ 67 static inline void on_notify( lock_type & this, thread$ * t ){ unpark(t); } 68 69 #define DEFAULT_ON_WAIT( lock_type ) \ 70 static inline size_t on_wait( lock_type & this, __cfa_pre_park pp_fn, void * pp_datum ) { \ 71 unlock( this ); \ 72 pre_park_then_park( pp_fn, pp_datum ); \ 73 return 0; \ 74 } 75 76 // on_wakeup impl if lock should be reacquired after waking up 77 #define DEFAULT_ON_WAKEUP_REACQ( lock_type ) \ 78 static inline void on_wakeup( lock_type & this, size_t recursion ) { lock( this ); } 79 80 // on_wakeup impl if lock will not be reacquired after waking up 81 #define DEFAULT_ON_WAKEUP_NO_REACQ( lock_type ) \ 82 static inline void on_wakeup( lock_type & this, size_t recursion ) {} 83 84 40 // undef to make a number of the locks not reacquire upon waking from a condlock 41 #define REACQ 1 85 42 86 43 //----------------------------------------------------------------------------- … … 109 66 static inline bool try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); } 110 67 static inline void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 111 static inline size_t on_wait ( single_acquisition_lock & this , __cfa_pre_park pp_fn, void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum); }68 static inline size_t on_wait ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); } 112 69 static inline void on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 113 70 static inline void on_notify( single_acquisition_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); } 114 static inline bool register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }115 static inline bool unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }116 static inline void on_selected( single_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }117 71 118 72 //---------- … … 126 80 static inline bool try_lock ( owner_lock & this ) { return try_lock( (blocking_lock &)this ); } 127 81 static inline void unlock ( owner_lock & this ) { unlock ( (blocking_lock &)this ); } 128 static inline size_t on_wait ( owner_lock & this , __cfa_pre_park pp_fn, void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum); }82 static inline size_t on_wait ( owner_lock & this ) { return on_wait ( (blocking_lock &)this ); } 129 83 static inline void on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 130 84 static inline void on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); } 131 static inline bool register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }132 static inline bool unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }133 static inline void on_selected( owner_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }134 85 135 86 //----------------------------------------------------------------------------- … … 176 127 static inline void ?{}(mcs_spin_node & this) { this.next = 0p; this.locked = true; } 177 128 129 static inline mcs_spin_node * volatile & ?`next ( mcs_spin_node * node ) { 130 return node->next; 131 } 132 178 133 struct mcs_spin_lock { 179 134 mcs_spin_queue queue; … … 181 136 182 137 static inline void lock(mcs_spin_lock & l, mcs_spin_node & n) { 183 n.locked = true;184 138 mcs_spin_node * prev = __atomic_exchange_n(&l.queue.tail, &n, __ATOMIC_SEQ_CST); 185 if( prev == 0p ) return; 139 n.locked = true; 140 if(prev == 0p) return; 186 141 prev->next = &n; 187 while( __atomic_load_n(&n.locked, __ATOMIC_RELAXED)) Pause();142 while(__atomic_load_n(&n.locked, __ATOMIC_RELAXED)) Pause(); 188 143 } 189 144 … … 191 146 mcs_spin_node * n_ptr = &n; 192 147 if (__atomic_compare_exchange_n(&l.queue.tail, &n_ptr, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) return; 193 while (__atomic_load_n(&n.next, __ATOMIC_RELAXED) == 0p) Pause();148 while (__atomic_load_n(&n.next, __ATOMIC_RELAXED) == 0p) {} 194 149 n.next->locked = false; 195 150 } … … 198 153 // futex_mutex 199 154 155 // - No cond var support 200 156 // - Kernel thd blocking alternative to the spinlock 201 157 // - No ownership (will deadlock on reacq) 202 // - no reacq on wakeup203 158 struct futex_mutex { 204 159 // lock state any state other than UNLOCKED is locked … … 214 169 } 215 170 216 static inline void ?{}( futex_mutex & this ) with(this) { val = 0; }217 218 static inline bool internal_try_lock( futex_mutex & this, int & compare_val) with(this) {171 static inline void ?{}( futex_mutex & this ) with(this) { val = 0; } 172 173 static inline bool internal_try_lock(futex_mutex & this, int & compare_val) with(this) { 219 174 return __atomic_compare_exchange_n((int*)&val, (int*)&compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); 220 175 } 221 176 222 static inline int internal_exchange( futex_mutex & this) with(this) {177 static inline int internal_exchange(futex_mutex & this) with(this) { 223 178 return __atomic_exchange_n((int*)&val, 2, __ATOMIC_ACQUIRE); 224 179 } 225 180 226 181 // if this is called recursively IT WILL DEADLOCK!!!!! 227 static inline void lock( futex_mutex & this) with(this) {182 static inline void lock(futex_mutex & this) with(this) { 228 183 int state; 229 184 230 for( int spin = 4; spin < 1024; spin += spin) { 231 state = 0; 232 // if unlocked, lock and return 233 if (internal_try_lock(this, state)) return; 234 if (2 == state) break; 235 for (int i = 0; i < spin; i++) Pause(); 236 } 185 186 // // linear backoff omitted for now 187 // for( int spin = 4; spin < 1024; spin += spin) { 188 // state = 0; 189 // // if unlocked, lock and return 190 // if (internal_try_lock(this, state)) return; 191 // if (2 == state) break; 192 // for (int i = 0; i < spin; i++) Pause(); 193 // } 194 195 // no contention try to acquire 196 if (internal_try_lock(this, state)) return; 237 197 238 198 // if not in contended state, set to be in contended state … … 247 207 248 208 static inline void unlock(futex_mutex & this) with(this) { 249 // if uncontended do atomic unlock and then return250 if (__atomic_exchange_n(&val, 0, __ATOMIC_RELEASE) == 1) return; 209 // if uncontended do atomice unlock and then return 210 if (__atomic_fetch_sub(&val, 1, __ATOMIC_RELEASE) == 1) return; // TODO: try acq/rel 251 211 252 212 // otherwise threads are blocked so we must wake one 213 __atomic_store_n((int *)&val, 0, __ATOMIC_RELEASE); 253 214 futex((int *)&val, FUTEX_WAKE, 1); 254 215 } 255 216 256 DEFAULT_ON_NOTIFY( futex_mutex ) 257 DEFAULT_ON_WAIT( futex_mutex ) 258 DEFAULT_ON_WAKEUP_NO_REACQ( futex_mutex ) 259 260 //----------------------------------------------------------------------------- 261 // go_mutex 262 263 // - Kernel thd blocking alternative to the spinlock 264 // - No ownership (will deadlock on reacq) 265 // - Golang's flavour of mutex 266 // - Impl taken from Golang: src/runtime/lock_futex.go 267 struct go_mutex { 268 // lock state any state other than UNLOCKED is locked 269 // enum LockState { UNLOCKED = 0, LOCKED = 1, SLEEPING = 2 }; 270 271 // stores a lock state 272 int val; 273 }; 274 static inline void ?{}( go_mutex & this ) with(this) { val = 0; } 275 // static inline void ?{}( go_mutex & this, go_mutex this2 ) = void; // these don't compile correctly at the moment so they should be omitted 276 // static inline void ?=?( go_mutex & this, go_mutex this2 ) = void; 277 278 static inline bool internal_try_lock(go_mutex & this, int & compare_val, int new_val ) with(this) { 279 return __atomic_compare_exchange_n((int*)&val, (int*)&compare_val, new_val, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); 280 } 281 282 static inline int internal_exchange(go_mutex & this, int swap ) with(this) { 283 return __atomic_exchange_n((int*)&val, swap, __ATOMIC_ACQUIRE); 284 } 285 286 // if this is called recursively IT WILL DEADLOCK!!!!! 287 static inline void lock( go_mutex & this ) with( this ) { 288 int state, init_state; 289 290 // speculative grab 291 state = internal_exchange(this, 1); 292 if ( !state ) return; // state == 0 293 init_state = state; 294 for (;;) { 295 for( int i = 0; i < 4; i++ ) { 296 while( !val ) { // lock unlocked 297 state = 0; 298 if ( internal_try_lock( this, state, init_state ) ) return; 299 } 300 for (int i = 0; i < 30; i++) Pause(); 301 } 302 303 while( !val ) { // lock unlocked 304 state = 0; 305 if ( internal_try_lock( this, state, init_state ) ) return; 306 } 307 sched_yield(); 308 309 // if not in contended state, set to be in contended state 310 state = internal_exchange( this, 2 ); 311 if ( !state ) return; // state == 0 312 init_state = 2; 313 futex( (int*)&val, FUTEX_WAIT, 2 ); // if val is not 2 this returns with EWOULDBLOCK 314 } 315 } 316 317 static inline void unlock( go_mutex & this ) with(this) { 318 // if uncontended do atomic unlock and then return 319 if ( __atomic_exchange_n(&val, 0, __ATOMIC_RELEASE) == 1 ) return; 320 321 // otherwise threads are blocked so we must wake one 322 futex( (int *)&val, FUTEX_WAKE, 1 ); 323 } 324 325 DEFAULT_ON_NOTIFY( go_mutex ) 326 DEFAULT_ON_WAIT( go_mutex ) 327 DEFAULT_ON_WAKEUP_NO_REACQ( go_mutex ) 328 329 //----------------------------------------------------------------------------- 330 // Exponential backoff then block lock 331 struct exp_backoff_then_block_lock { 217 static inline void on_notify( futex_mutex & f, thread$ * t){ unpark(t); } 218 static inline size_t on_wait( futex_mutex & f ) {unlock(f); return 0;} 219 220 // to set recursion count after getting signalled; 221 static inline void on_wakeup( futex_mutex & f, size_t recursion ) {} 222 223 //----------------------------------------------------------------------------- 224 // CLH Spinlock 225 // - No recursive acquisition 226 // - Needs to be released by owner 227 228 struct clh_lock { 229 volatile bool * volatile tail; 230 }; 231 232 static inline void ?{}( clh_lock & this ) { this.tail = malloc(); *this.tail = true; } 233 static inline void ^?{}( clh_lock & this ) { free(this.tail); } 234 235 static inline void lock(clh_lock & l) { 236 thread$ * curr_thd = active_thread(); 237 *(curr_thd->clh_node) = false; 238 volatile bool * prev = __atomic_exchange_n((bool **)(&l.tail), (bool *)(curr_thd->clh_node), __ATOMIC_SEQ_CST); 239 while(!__atomic_load_n(prev, __ATOMIC_ACQUIRE)) Pause(); 240 curr_thd->clh_prev = prev; 241 } 242 243 static inline void unlock(clh_lock & l) { 244 thread$ * curr_thd = active_thread(); 245 __atomic_store_n(curr_thd->clh_node, true, __ATOMIC_RELEASE); 246 curr_thd->clh_node = curr_thd->clh_prev; 247 } 248 249 static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); } 250 static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; } 251 static inline void on_wakeup(clh_lock & this, size_t recursion ) { 252 #ifdef REACQ 253 lock(this); 254 #endif 255 } 256 257 258 //----------------------------------------------------------------------------- 259 // Linear backoff Spinlock 260 struct linear_backoff_then_block_lock { 332 261 // Spin lock used for mutual exclusion 333 262 __spinlock_t spinlock; … … 340 269 }; 341 270 342 static inline void ?{}( exp_backoff_then_block_lock & this ) {271 static inline void ?{}( linear_backoff_then_block_lock & this ) { 343 272 this.spinlock{}; 344 273 this.blocked_threads{}; 345 274 this.lock_value = 0; 346 275 } 347 static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void; 348 static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void; 349 350 static inline void ^?{}( exp_backoff_then_block_lock & this ){} 351 352 static inline bool internal_try_lock( exp_backoff_then_block_lock & this, size_t & compare_val ) with(this) { 353 return __atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); 354 } 355 356 static inline bool try_lock( exp_backoff_then_block_lock & this ) { size_t compare_val = 0; return internal_try_lock( this, compare_val ); } 357 358 static inline bool try_lock_contention( exp_backoff_then_block_lock & this ) with(this) { 359 return !__atomic_exchange_n( &lock_value, 2, __ATOMIC_ACQUIRE ); 360 } 361 362 static inline bool block( exp_backoff_then_block_lock & this ) with(this) { 363 lock( spinlock __cfaabi_dbg_ctx2 ); 364 if (__atomic_load_n( &lock_value, __ATOMIC_SEQ_CST) != 2) { 365 unlock( spinlock ); 366 return true; 367 } 368 insert_last( blocked_threads, *active_thread() ); 369 unlock( spinlock ); 276 static inline void ^?{}( linear_backoff_then_block_lock & this ) {} 277 // static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void; 278 // static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void; 279 280 static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) { 281 if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { 282 return true; 283 } 284 return false; 285 } 286 287 static inline bool try_lock(linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); } 288 289 static inline bool try_lock_contention(linear_backoff_then_block_lock & this) with(this) { 290 if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) { 291 return true; 292 } 293 return false; 294 } 295 296 static inline bool block(linear_backoff_then_block_lock & this) with(this) { 297 lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC) 298 if (lock_value != 2) { 299 unlock( spinlock ); 300 return true; 301 } 302 insert_last( blocked_threads, *active_thread() ); 303 unlock( spinlock ); 370 304 park( ); 371 305 return true; 372 306 } 373 307 374 static inline void lock( exp_backoff_then_block_lock & this) with(this) {308 static inline void lock(linear_backoff_then_block_lock & this) with(this) { 375 309 size_t compare_val = 0; 376 310 int spin = 4; 377 378 311 // linear backoff 379 312 for( ;; ) { … … 391 324 } 392 325 393 static inline void unlock( exp_backoff_then_block_lock & this) with(this) {326 static inline void unlock(linear_backoff_then_block_lock & this) with(this) { 394 327 if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return; 395 lock( spinlock __cfaabi_dbg_ctx2 ); 396 thread$ * t = &try_pop_front( blocked_threads ); 397 unlock( spinlock ); 398 unpark( t ); 399 } 400 401 DEFAULT_ON_NOTIFY( exp_backoff_then_block_lock ) 402 DEFAULT_ON_WAIT( exp_backoff_then_block_lock ) 403 DEFAULT_ON_WAKEUP_REACQ( exp_backoff_then_block_lock ) 328 lock( spinlock __cfaabi_dbg_ctx2 ); 329 thread$ * t = &try_pop_front( blocked_threads ); 330 unlock( spinlock ); 331 unpark( t ); 332 } 333 334 static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); } 335 static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; } 336 static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) { 337 #ifdef REACQ 338 lock(this); 339 #endif 340 } 404 341 405 342 //----------------------------------------------------------------------------- … … 431 368 432 369 // if this is called recursively IT WILL DEADLOCK!!!!! 433 static inline void lock( fast_block_lock & this) with(this) {370 static inline void lock(fast_block_lock & this) with(this) { 434 371 lock( lock __cfaabi_dbg_ctx2 ); 435 372 if ( held ) { … … 443 380 } 444 381 445 static inline void unlock( fast_block_lock & this) with(this) {382 static inline void unlock(fast_block_lock & this) with(this) { 446 383 lock( lock __cfaabi_dbg_ctx2 ); 447 384 /* paranoid */ verifyf( held != false, "Attempt to release lock %p that isn't held", &this ); … … 452 389 } 453 390 454 static inline void on_notify( fast_block_lock & this, struct thread$ * t ) with(this) { 455 lock( lock __cfaabi_dbg_ctx2 ); 456 insert_last( blocked_threads, *t ); 457 unlock( lock ); 458 } 459 DEFAULT_ON_WAIT( fast_block_lock ) 460 DEFAULT_ON_WAKEUP_NO_REACQ( fast_block_lock ) 391 static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) { 392 #ifdef REACQ 393 lock( lock __cfaabi_dbg_ctx2 ); 394 insert_last( blocked_threads, *t ); 395 unlock( lock ); 396 #else 397 unpark(t); 398 #endif 399 } 400 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; } 401 static inline void on_wakeup(fast_block_lock & this, size_t recursion ) { } 461 402 462 403 //----------------------------------------------------------------------------- … … 469 410 struct simple_owner_lock { 470 411 // List of blocked threads 471 dlist( select_node) blocked_threads;412 dlist( thread$ ) blocked_threads; 472 413 473 414 // Spin lock used for mutual exclusion … … 490 431 static inline void ?=?( simple_owner_lock & this, simple_owner_lock this2 ) = void; 491 432 492 static inline void lock( simple_owner_lock & this) with(this) {493 if ( owner == active_thread()) {433 static inline void lock(simple_owner_lock & this) with(this) { 434 if (owner == active_thread()) { 494 435 recursion_count++; 495 436 return; … … 497 438 lock( lock __cfaabi_dbg_ctx2 ); 498 439 499 if ( owner != 0p ) { 500 select_node node; 501 insert_last( blocked_threads, node ); 440 if (owner != 0p) { 441 insert_last( blocked_threads, *active_thread() ); 502 442 unlock( lock ); 503 443 park( ); … … 509 449 } 510 450 511 static inline void pop_node( simple_owner_lock & this ) with(this) { 512 __handle_waituntil_OR( blocked_threads ); 513 select_node * node = &try_pop_front( blocked_threads ); 514 if ( node ) { 515 owner = node->blocked_thread; 516 recursion_count = 1; 517 // if ( !node->clause_status || __make_select_node_available( *node ) ) unpark( node->blocked_thread ); 518 wake_one( blocked_threads, *node ); 519 } else { 520 owner = 0p; 521 recursion_count = 0; 522 } 523 } 524 525 static inline void unlock( simple_owner_lock & this ) with(this) { 451 // TODO: fix duplicate def issue and bring this back 452 // void pop_and_set_new_owner( simple_owner_lock & this ) with( this ) { 453 // thread$ * t = &try_pop_front( blocked_threads ); 454 // owner = t; 455 // recursion_count = ( t ? 1 : 0 ); 456 // unpark( t ); 457 // } 458 459 static inline void unlock(simple_owner_lock & this) with(this) { 526 460 lock( lock __cfaabi_dbg_ctx2 ); 527 461 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); … … 530 464 recursion_count--; 531 465 if ( recursion_count == 0 ) { 532 pop_node( this ); 466 // pop_and_set_new_owner( this ); 467 thread$ * t = &try_pop_front( blocked_threads ); 468 owner = t; 469 recursion_count = ( t ? 1 : 0 ); 470 unpark( t ); 533 471 } 534 472 unlock( lock ); 535 473 } 536 474 537 static inline void on_notify( simple_owner_lock & this,thread$ * t ) with(this) {475 static inline void on_notify(simple_owner_lock & this, struct thread$ * t ) with(this) { 538 476 lock( lock __cfaabi_dbg_ctx2 ); 539 477 // lock held 540 478 if ( owner != 0p ) { 541 insert_last( blocked_threads, * (select_node *)t->link_node);479 insert_last( blocked_threads, *t ); 542 480 } 543 481 // lock not held … … 550 488 } 551 489 552 static inline size_t on_wait( simple_owner_lock & this, __cfa_pre_park pp_fn, void * pp_datum) with(this) {490 static inline size_t on_wait(simple_owner_lock & this) with(this) { 553 491 lock( lock __cfaabi_dbg_ctx2 ); 554 492 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); … … 557 495 size_t ret = recursion_count; 558 496 559 pop_node( this ); 560 561 select_node node; 562 active_thread()->link_node = (void *)&node; 497 // pop_and_set_new_owner( this ); 498 499 thread$ * t = &try_pop_front( blocked_threads ); 500 owner = t; 501 recursion_count = ( t ? 1 : 0 ); 502 unpark( t ); 503 563 504 unlock( lock ); 564 565 pre_park_then_park( pp_fn, pp_datum );566 567 505 return ret; 568 506 } 569 507 570 static inline void on_wakeup( simple_owner_lock & this, size_t recursion ) with(this) { recursion_count = recursion; } 571 572 // waituntil() support 573 static inline bool register_select( simple_owner_lock & this, select_node & node ) with(this) { 574 lock( lock __cfaabi_dbg_ctx2 ); 575 576 // check if we can complete operation. If so race to establish winner in special OR case 577 if ( !node.park_counter && ( owner == active_thread() || owner == 0p ) ) { 578 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering 579 unlock( lock ); 580 return false; 581 } 582 } 583 584 if ( owner == active_thread() ) { 585 recursion_count++; 586 if ( node.park_counter ) __make_select_node_available( node ); 587 unlock( lock ); 588 return true; 589 } 590 591 if ( owner != 0p ) { 592 insert_last( blocked_threads, node ); 593 unlock( lock ); 594 return false; 595 } 596 597 owner = active_thread(); 598 recursion_count = 1; 599 600 if ( node.park_counter ) __make_select_node_available( node ); 601 unlock( lock ); 602 return true; 603 } 604 605 static inline bool unregister_select( simple_owner_lock & this, select_node & node ) with(this) { 606 lock( lock __cfaabi_dbg_ctx2 ); 607 if ( node`isListed ) { 608 remove( node ); 609 unlock( lock ); 610 return false; 611 } 612 613 if ( owner == active_thread() ) { 614 recursion_count--; 615 if ( recursion_count == 0 ) { 616 pop_node( this ); 617 } 618 } 619 unlock( lock ); 620 return false; 621 } 622 623 static inline void on_selected( simple_owner_lock & this, select_node & node ) {} 624 508 static inline void on_wakeup(simple_owner_lock & this, size_t recursion ) with(this) { recursion_count = recursion; } 625 509 626 510 //----------------------------------------------------------------------------- … … 637 521 // flag showing if lock is held 638 522 volatile bool held; 523 524 #ifdef __CFA_DEBUG__ 525 // for deadlock detection 526 struct thread$ * owner; 527 #endif 639 528 }; 640 529 … … 647 536 static inline void ?=?( spin_queue_lock & this, spin_queue_lock this2 ) = void; 648 537 649 // if this is called recursively IT WILL DEADLOCK! 650 static inline void lock( spin_queue_lock & this) with(this) {538 // if this is called recursively IT WILL DEADLOCK!!!!! 539 static inline void lock(spin_queue_lock & this) with(this) { 651 540 mcs_spin_node node; 652 541 lock( lock, node ); … … 656 545 } 657 546 658 static inline void unlock( spin_queue_lock & this) with(this) {547 static inline void unlock(spin_queue_lock & this) with(this) { 659 548 __atomic_store_n(&held, false, __ATOMIC_RELEASE); 660 549 } 661 550 662 DEFAULT_ON_NOTIFY( spin_queue_lock ) 663 DEFAULT_ON_WAIT( spin_queue_lock ) 664 DEFAULT_ON_WAKEUP_REACQ( spin_queue_lock ) 551 static inline void on_notify(spin_queue_lock & this, struct thread$ * t ) { 552 unpark(t); 553 } 554 static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; } 555 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { 556 #ifdef REACQ 557 lock(this); 558 #endif 559 } 560 665 561 666 562 //----------------------------------------------------------------------------- … … 688 584 689 585 // if this is called recursively IT WILL DEADLOCK!!!!! 690 static inline void lock( mcs_block_spin_lock & this) with(this) {586 static inline void lock(mcs_block_spin_lock & this) with(this) { 691 587 mcs_node node; 692 588 lock( lock, node ); … … 700 596 } 701 597 702 DEFAULT_ON_NOTIFY( mcs_block_spin_lock ) 703 DEFAULT_ON_WAIT( mcs_block_spin_lock ) 704 DEFAULT_ON_WAKEUP_REACQ( mcs_block_spin_lock ) 598 static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); } 599 static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; } 600 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) { 601 #ifdef REACQ 602 lock(this); 603 #endif 604 } 705 605 706 606 //----------------------------------------------------------------------------- … … 728 628 729 629 // if this is called recursively IT WILL DEADLOCK!!!!! 730 static inline void lock( block_spin_lock & this) with(this) {630 static inline void lock(block_spin_lock & this) with(this) { 731 631 lock( lock ); 732 632 while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause(); … … 735 635 } 736 636 737 static inline void unlock( block_spin_lock & this) with(this) {637 static inline void unlock(block_spin_lock & this) with(this) { 738 638 __atomic_store_n(&held, false, __ATOMIC_RELEASE); 739 639 } 740 640 741 static inline void on_notify( block_spin_lock & this, struct thread$ * t ) with(this.lock) { 641 static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) { 642 #ifdef REACQ 742 643 // first we acquire internal fast_block_lock 743 644 lock( lock __cfaabi_dbg_ctx2 ); … … 751 652 unlock( lock ); 752 653 654 #endif 753 655 unpark(t); 754 } 755 DEFAULT_ON_WAIT( block_spin_lock ) 756 static inline void on_wakeup( block_spin_lock & this, size_t recursion ) with(this) { 656 657 } 658 static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; } 659 static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) { 660 #ifdef REACQ 757 661 // now we acquire the entire block_spin_lock upon waking up 758 662 while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause(); 759 663 __atomic_store_n(&held, true, __ATOMIC_RELEASE); 760 664 unlock( lock ); // Now we release the internal fast_spin_lock 761 } 665 #endif 666 } 667 668 //----------------------------------------------------------------------------- 669 // is_blocking_lock 670 trait is_blocking_lock(L & | sized(L)) { 671 // For synchronization locks to use when acquiring 672 void on_notify( L &, struct thread$ * ); 673 674 // For synchronization locks to use when releasing 675 size_t on_wait( L & ); 676 677 // to set recursion count after getting signalled; 678 void on_wakeup( L &, size_t recursion ); 679 }; 762 680 763 681 //----------------------------------------------------------------------------- … … 767 685 forall(L & | is_blocking_lock(L)) { 768 686 struct info_thread; 687 688 // // for use by sequence 689 // info_thread(L) *& Back( info_thread(L) * this ); 690 // info_thread(L) *& Next( info_thread(L) * this ); 769 691 } 770 692 -
libcfa/src/concurrency/monitor.cfa
r24d6572 r34b4268 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Feb 19 17:00:59 202313 // Update Count : 1 212 // Last Modified On : Wed Dec 4 07:55:14 2019 13 // Update Count : 10 14 14 // 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #include "monitor.hfa" -
libcfa/src/concurrency/monitor.hfa
r24d6572 r34b4268 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:29:21 202313 // Update Count : 1 212 // Last Modified On : Wed Dec 4 07:55:32 2019 13 // Update Count : 11 14 14 // 15 15 … … 22 22 #include "stdlib.hfa" 23 23 24 forall( T & ) 25 trait is_monitor { 24 trait is_monitor(T &) { 26 25 monitor$ * get_monitor( T & ); 27 26 void ^?{}( T & mutex ); -
libcfa/src/concurrency/mutex.cfa
r24d6572 r34b4268 12 12 // Created On : Fri May 25 01:37:11 2018 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Sun Feb 19 17:01:36 202315 // Update Count : 314 // Last Modified On : Wed Dec 4 09:16:39 2019 15 // Update Count : 1 16 16 // 17 17 18 18 #define __cforall_thread__ 19 #define _GNU_SOURCE 19 20 20 21 #include "mutex.hfa" -
libcfa/src/concurrency/mutex.hfa
r24d6572 r34b4268 12 12 // Created On : Fri May 25 01:24:09 2018 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Thu Feb 2 11:46:08 202315 // Update Count : 214 // Last Modified On : Wed Dec 4 09:16:53 2019 15 // Update Count : 1 16 16 // 17 17 … … 70 70 void unlock(recursive_mutex_lock & this) __attribute__((deprecated("use concurrency/locks.hfa instead"))); 71 71 72 forall( L & | sized(L) ) 73 trait is_lock { 72 trait is_lock(L & | sized(L)) { 74 73 void lock (L &); 75 74 void unlock(L &); -
libcfa/src/concurrency/mutex_stmt.hfa
r24d6572 r34b4268 1 #pragma once2 3 1 #include "bits/algorithm.hfa" 4 2 #include "bits/defs.hfa" … … 6 4 //----------------------------------------------------------------------------- 7 5 // is_lock 8 forall(L & | sized(L)) 9 trait is_lock { 6 trait is_lock(L & | sized(L)) { 10 7 // For acquiring a lock 11 8 void lock( L & ); … … 14 11 void unlock( L & ); 15 12 }; 13 16 14 17 15 struct __mutex_stmt_lock_guard { … … 26 24 // Sort locks based on address 27 25 __libcfa_small_sort(this.lockarr, count); 26 27 // acquire locks in order 28 // for ( size_t i = 0; i < count; i++ ) { 29 // lock(*this.lockarr[i]); 30 // } 31 } 32 33 static inline void ^?{}( __mutex_stmt_lock_guard & this ) with(this) { 34 // for ( size_t i = count; i > 0; i-- ) { 35 // unlock(*lockarr[i - 1]); 36 // } 28 37 } 29 38 30 39 forall(L & | is_lock(L)) { 31 static inline void * __get_mutexstmt_lock_ptr( L & this ) { return &this; } 32 static inline L __get_mutexstmt_lock_type( L & this ) {} 33 static inline L __get_mutexstmt_lock_type( L * this ) {} 40 41 struct scoped_lock { 42 L * internal_lock; 43 }; 44 45 static inline void ?{}( scoped_lock(L) & this, L & internal_lock ) { 46 this.internal_lock = &internal_lock; 47 lock(internal_lock); 48 } 49 50 static inline void ^?{}( scoped_lock(L) & this ) with(this) { 51 unlock(*internal_lock); 52 } 53 54 static inline void * __get_mutexstmt_lock_ptr( L & this ) { 55 return &this; 56 } 57 58 static inline L __get_mutexstmt_lock_type( L & this ); 59 60 static inline L __get_mutexstmt_lock_type( L * this ); 34 61 } -
libcfa/src/concurrency/preemption.cfa
r24d6572 r34b4268 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 9 08:42:59 202313 // Update Count : 6012 // Last Modified On : Thu Feb 17 11:18:57 2022 13 // Update Count : 59 14 14 // 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 // #define __CFA_DEBUG_PRINT_PREEMPTION__ … … 117 118 __cfadbg_print_buffer_decl( preemption, " KERNEL: preemption tick %lu\n", currtime.tn); 118 119 Duration period = node->period; 119 if( period == 0 ) {120 if( period == 0) { 120 121 node->set = false; // Node is one-shot, just mark it as not pending 121 122 } -
libcfa/src/concurrency/pthread.cfa
r24d6572 r34b4268 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #include <signal.h> … … 34 35 struct pthread_values{ 35 36 inline Seqable; 36 void * value;37 void* value; 37 38 bool in_use; 38 39 }; … … 50 51 struct pthread_keys { 51 52 bool in_use; 52 void (* destructor)( void * );53 void (*destructor)( void * ); 53 54 Sequence(pthread_values) threads; 54 55 }; 55 56 56 static void ?{}(pthread_keys& k) {57 static void ?{}(pthread_keys& k){ 57 58 k.threads{}; 58 59 } … … 61 62 static pthread_keys cfa_pthread_keys_storage[PTHREAD_KEYS_MAX] __attribute__((aligned (16))); 62 63 63 static void init_pthread_storage() {64 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ){64 static void init_pthread_storage(){ 65 for (int i = 0; i < PTHREAD_KEYS_MAX; i++){ 65 66 cfa_pthread_keys_storage[i]{}; 66 67 } … … 95 96 96 97 /* condvar helper routines */ 97 static void init(pthread_cond_t * pcond){98 static void init(pthread_cond_t* pcond){ 98 99 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 99 cfa2pthr_cond_var_t * _cond = (cfa2pthr_cond_var_t*)pcond;100 cfa2pthr_cond_var_t* _cond = (cfa2pthr_cond_var_t*)pcond; 100 101 ?{}(*_cond); 101 102 } 102 103 103 static cfa2pthr_cond_var_t * get(pthread_cond_t * pcond){104 static cfa2pthr_cond_var_t* get(pthread_cond_t* pcond){ 104 105 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 105 return (cfa2pthr_cond_var_t *)pcond;106 } 107 108 static void destroy(pthread_cond_t * cond){106 return (cfa2pthr_cond_var_t*)pcond; 107 } 108 109 static void destroy(pthread_cond_t* cond){ 109 110 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 110 111 ^?{}(*get(cond)); … … 115 116 116 117 /* mutex helper routines */ 117 static void mutex_check(pthread_mutex_t * t){118 static void mutex_check(pthread_mutex_t* t){ 118 119 // Use double check to improve performance. 119 120 // Check is safe on x86; volatile prevents compiler reordering 120 volatile pthread_mutex_t * const mutex_ = t;121 volatile pthread_mutex_t *const mutex_ = t; 121 122 122 123 // SKULLDUGGERY: not a portable way to access the kind field, /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h … … 135 136 136 137 137 static void init(pthread_mutex_t * plock){138 static void init(pthread_mutex_t* plock){ 138 139 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 139 simple_owner_lock * _lock = (simple_owner_lock*)plock;140 simple_owner_lock* _lock = (simple_owner_lock*)plock; 140 141 ?{}(*_lock); 141 142 } 142 143 143 static simple_owner_lock * get(pthread_mutex_t * plock){144 static simple_owner_lock* get(pthread_mutex_t* plock){ 144 145 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 145 return (simple_owner_lock *)plock;146 } 147 148 static void destroy(pthread_mutex_t * plock){146 return (simple_owner_lock*)plock; 147 } 148 149 static void destroy(pthread_mutex_t* plock){ 149 150 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 150 151 ^?{}(*get(plock)); … … 152 153 153 154 //######################### Attr helpers ######################### 154 typedef struct cfaPthread_attr_t {// thread attributes155 struct cfaPthread_attr_t { // thread attributes 155 156 int contentionscope; 156 157 int detachstate; 157 158 size_t stacksize; 158 void * stackaddr;159 void *stackaddr; 159 160 int policy; 160 161 int inheritsched; 161 162 struct sched_param param; 162 } cfaPthread_attr_t;163 164 static const cfaPthread_attr_t default_attrs {163 } typedef cfaPthread_attr_t; 164 165 static const cfaPthread_attr_t default_attrs{ 165 166 0, 166 167 0, 167 65_000,168 NULL,168 (size_t)65000, 169 (void *)NULL, 169 170 0, 170 171 0, … … 172 173 }; 173 174 174 static cfaPthread_attr_t * get(const pthread_attr_t * attr){175 static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t), "sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)");176 return (cfaPthread_attr_t *)attr;175 static cfaPthread_attr_t* get(const pthread_attr_t* attr){ 176 static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t),"sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)"); 177 return (cfaPthread_attr_t*)attr; 177 178 } 178 179 … … 189 190 190 191 // pthreads return value 191 void * joinval;192 void *joinval; 192 193 193 194 // pthread attributes 194 195 pthread_attr_t pthread_attr; 195 196 196 void *(* start_routine)(void *);197 void * start_arg;197 void *(*start_routine)(void *); 198 void *start_arg; 198 199 199 200 // thread local data 200 pthread_values * pthreadData;201 pthread_values* pthreadData; 201 202 202 203 // flag used for tryjoin … … 206 207 /* thread part routines */ 207 208 // cfaPthread entry point 208 void main(cfaPthread & _thread) with(_thread){209 joinval = start_routine(start_arg);209 void main(cfaPthread& _thread) with(_thread){ 210 joinval = start_routine(start_arg); 210 211 isTerminated = true; 211 212 } 212 213 213 static cfaPthread * lookup( pthread_t p ){214 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *),"sizeof(pthread_t) < sizeof(cfaPthread*)");215 return (cfaPthread *)p;216 } 217 218 static void pthread_deletespecific_( pthread_values * values ) { // see uMachContext::invokeTask219 pthread_values * value;220 pthread_keys * key;214 static cfaPthread *lookup( pthread_t p ){ 215 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)"); 216 return (cfaPthread*)p; 217 } 218 219 static void pthread_deletespecific_( pthread_values* values ) { // see uMachContext::invokeTask 220 pthread_values* value; 221 pthread_keys* key; 221 222 bool destcalled = true; 222 if (values != NULL) {223 if (values != NULL){ 223 224 for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) { 224 225 destcalled = false; 225 226 lock(key_lock); 226 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ){227 for (int i = 0; i < PTHREAD_KEYS_MAX; i++){ 227 228 // for each valid key 228 if ( values[i].in_use) {229 if ( values[i].in_use){ 229 230 value = &values[i]; 230 231 key = &cfa_pthread_keys[i]; … … 233 234 // if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with that key, 234 235 // the value of the key is set to NULL, and then the function pointed to is called with the previously associated value as its sole argument. 235 if (value->value != NULL && key->destructor != NULL) {236 if (value->value != NULL && key->destructor != NULL){ 236 237 unlock(key_lock); 237 238 key->destructor(value->value); // run destructor … … 248 249 } 249 250 250 static void ^?{}(cfaPthread & mutex t) {251 static void ^?{}(cfaPthread & mutex t){ 251 252 // delete pthread local storage 252 253 pthread_values * values = t.pthreadData; … … 254 255 } 255 256 256 static void ?{}(cfaPthread & t, pthread_t * _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) {257 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread*)");257 static void ?{}(cfaPthread &t, pthread_t* _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) { 258 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread*)"); 258 259 259 260 // set up user thread stackSize … … 277 278 //######################### Pthread Attrs ######################### 278 279 279 int pthread_attr_init(pthread_attr_t * attr) libcfa_public __THROW {280 cfaPthread_attr_t * _attr = get(attr);280 int pthread_attr_init(pthread_attr_t *attr) libcfa_public __THROW { 281 cfaPthread_attr_t* _attr = get(attr); 281 282 ?{}(*_attr, default_attrs); 282 283 return 0; 283 284 } 284 int pthread_attr_destroy(pthread_attr_t * attr) libcfa_public __THROW {285 int pthread_attr_destroy(pthread_attr_t *attr) libcfa_public __THROW { 285 286 ^?{}(*get(attr)); 286 287 return 0; 287 288 } 288 289 289 int pthread_attr_setscope( pthread_attr_t * attr, int contentionscope ) libcfa_public __THROW {290 int pthread_attr_setscope( pthread_attr_t *attr, int contentionscope ) libcfa_public __THROW { 290 291 get( attr )->contentionscope = contentionscope; 291 292 return 0; 292 293 } // pthread_attr_setscope 293 294 294 int pthread_attr_getscope( const pthread_attr_t * attr, int *contentionscope ) libcfa_public __THROW {295 int pthread_attr_getscope( const pthread_attr_t *attr, int *contentionscope ) libcfa_public __THROW { 295 296 *contentionscope = get( attr )->contentionscope; 296 297 return 0; 297 298 } // pthread_attr_getscope 298 299 299 int pthread_attr_setdetachstate( pthread_attr_t * attr, int detachstate ) libcfa_public __THROW {300 int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate ) libcfa_public __THROW { 300 301 get( attr )->detachstate = detachstate; 301 302 return 0; 302 303 } // pthread_attr_setdetachstate 303 304 304 int pthread_attr_getdetachstate( const pthread_attr_t * attr, int *detachstate ) libcfa_public __THROW {305 int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ) libcfa_public __THROW { 305 306 *detachstate = get( attr )->detachstate; 306 307 return 0; 307 308 } // pthread_attr_getdetachstate 308 309 309 int pthread_attr_setstacksize( pthread_attr_t * attr, size_t stacksize ) libcfa_public __THROW {310 int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ) libcfa_public __THROW { 310 311 get( attr )->stacksize = stacksize; 311 312 return 0; 312 313 } // pthread_attr_setstacksize 313 314 314 int pthread_attr_getstacksize( const pthread_attr_t * attr, size_t *stacksize ) libcfa_public __THROW {315 int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ) libcfa_public __THROW { 315 316 *stacksize = get( attr )->stacksize; 316 317 return 0; … … 325 326 } // pthread_attr_setguardsize 326 327 327 int pthread_attr_setstackaddr( pthread_attr_t * attr, void *stackaddr ) libcfa_public __THROW {328 int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ) libcfa_public __THROW { 328 329 get( attr )->stackaddr = stackaddr; 329 330 return 0; 330 331 } // pthread_attr_setstackaddr 331 332 332 int pthread_attr_getstackaddr( const pthread_attr_t * attr, void **stackaddr ) libcfa_public __THROW {333 int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ) libcfa_public __THROW { 333 334 *stackaddr = get( attr )->stackaddr; 334 335 return 0; 335 336 } // pthread_attr_getstackaddr 336 337 337 int pthread_attr_setstack( pthread_attr_t * attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW {338 int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW { 338 339 get( attr )->stackaddr = stackaddr; 339 340 get( attr )->stacksize = stacksize; … … 341 342 } // pthread_attr_setstack 342 343 343 int pthread_attr_getstack( const pthread_attr_t * attr, void ** stackaddr, size_t *stacksize ) libcfa_public __THROW {344 int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize ) libcfa_public __THROW { 344 345 *stackaddr = get( attr )->stackaddr; 345 346 *stacksize = get( attr )->stacksize; … … 350 351 // already running thread threadID. It shall be called on unitialized attr 351 352 // and destroyed with pthread_attr_destroy when no longer needed. 352 int pthread_getattr_np( pthread_t threadID, pthread_attr_t * attr ) libcfa_public __THROW { // GNU extension353 int pthread_getattr_np( pthread_t threadID, pthread_attr_t *attr ) libcfa_public __THROW { // GNU extension 353 354 check_nonnull(attr); 354 355 … … 362 363 //######################### Threads ######################### 363 364 364 int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(* start_routine)(void *), void * arg) libcfa_public __THROW {365 cfaPthread * t = alloc();365 int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW { 366 cfaPthread *t = alloc(); 366 367 (*t){_thread, attr, start_routine, arg}; 367 368 return 0; 368 369 } 369 370 370 int pthread_join(pthread_t _thread, void ** value_ptr) libcfa_public __THROW { 371 372 int pthread_join(pthread_t _thread, void **value_ptr) libcfa_public __THROW { 371 373 // if thread is invalid 372 374 if (_thread == NULL) return EINVAL; … … 374 376 375 377 // get user thr pointer 376 cfaPthread * p = lookup(_thread);378 cfaPthread* p = lookup(_thread); 377 379 try { 378 380 join(*p); … … 387 389 } 388 390 389 int pthread_tryjoin_np(pthread_t _thread, void ** value_ptr) libcfa_public __THROW {391 int pthread_tryjoin_np(pthread_t _thread, void **value_ptr) libcfa_public __THROW { 390 392 // if thread is invalid 391 393 if (_thread == NULL) return EINVAL; 392 394 if (_thread == pthread_self()) return EDEADLK; 393 395 394 cfaPthread * p = lookup(_thread);396 cfaPthread* p = lookup(_thread); 395 397 396 398 // thread not finished ? … … 410 412 void pthread_exit(void * status) libcfa_public __THROW { 411 413 pthread_t pid = pthread_self(); 412 cfaPthread * _thread = (cfaPthread*)pid;414 cfaPthread* _thread = (cfaPthread*)pid; 413 415 _thread->joinval = status; // set return value 414 416 _thread->isTerminated = 1; // set terminated flag … … 424 426 //######################### Mutex ######################### 425 427 426 int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t * attr) libcfa_public __THROW {428 int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t *attr) libcfa_public __THROW { 427 429 check_nonnull(_mutex); 428 430 init(_mutex); … … 433 435 int pthread_mutex_destroy(pthread_mutex_t *_mutex) libcfa_public __THROW { 434 436 check_nonnull(_mutex); 435 simple_owner_lock * _lock = get(_mutex);436 if (_lock->owner != NULL) {437 simple_owner_lock* _lock = get(_mutex); 438 if (_lock->owner != NULL){ 437 439 return EBUSY; 438 440 } … … 444 446 check_nonnull(_mutex); 445 447 mutex_check(_mutex); 446 simple_owner_lock * _lock = get(_mutex);448 simple_owner_lock* _lock = get(_mutex); 447 449 lock(*_lock); 448 450 return 0; … … 451 453 int pthread_mutex_unlock(pthread_mutex_t *_mutex) libcfa_public __THROW { 452 454 check_nonnull(_mutex); 453 simple_owner_lock * _lock = get(_mutex);454 if (_lock->owner != active_thread()) {455 simple_owner_lock* _lock = get(_mutex); 456 if (_lock->owner != active_thread()){ 455 457 return EPERM; 456 458 } // current thread does not hold the mutex … … 461 463 int pthread_mutex_trylock(pthread_mutex_t *_mutex) libcfa_public __THROW { 462 464 check_nonnull(_mutex); 463 simple_owner_lock * _lock = get(_mutex);464 if (_lock->owner != active_thread() && _lock->owner != NULL) {465 simple_owner_lock* _lock = get(_mutex); 466 if (_lock->owner != active_thread() && _lock->owner != NULL){ 465 467 return EBUSY; 466 468 } // if mutex is owned … … 472 474 473 475 /* conditional variable routines */ 474 int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t *attr) libcfa_public __THROW {476 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) libcfa_public __THROW { 475 477 check_nonnull(cond); 476 478 init(cond); … … 478 480 } //pthread_cond_init 479 481 480 int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t *_mutex) libcfa_public __THROW {482 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *_mutex) libcfa_public __THROW { 481 483 check_nonnull(_mutex); 482 484 check_nonnull(cond); … … 492 494 } // pthread_cond_timedwait 493 495 494 int pthread_cond_signal(pthread_cond_t * cond) libcfa_public __THROW {496 int pthread_cond_signal(pthread_cond_t *cond) libcfa_public __THROW { 495 497 check_nonnull(cond); 496 498 return notify_one(*get(cond)); 497 499 } // pthread_cond_signal 498 500 499 int pthread_cond_broadcast(pthread_cond_t * cond) libcfa_public __THROW {501 int pthread_cond_broadcast(pthread_cond_t *cond) libcfa_public __THROW { 500 502 check_nonnull(cond); 501 503 return notify_all(*get(cond)); 502 504 } // pthread_cond_broadcast 503 505 504 int pthread_cond_destroy(pthread_cond_t * cond) libcfa_public __THROW {506 int pthread_cond_destroy(pthread_cond_t *cond) libcfa_public __THROW { 505 507 check_nonnull(cond); 506 508 destroy(cond); … … 512 514 //######################### Local storage ######################### 513 515 514 int pthread_once(pthread_once_t * once_control, void (*init_routine)(void)) libcfa_public __THROW {516 int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) libcfa_public __THROW { 515 517 static_assert(sizeof(pthread_once_t) >= sizeof(int),"sizeof(pthread_once_t) < sizeof(int)"); 516 518 check_nonnull(once_control); … … 525 527 } // pthread_once 526 528 527 int pthread_key_create( pthread_key_t * key, void (*destructor)( void * ) ) libcfa_public __THROW {529 int pthread_key_create( pthread_key_t *key, void (*destructor)( void * ) ) libcfa_public __THROW { 528 530 lock(key_lock); 529 531 for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) { … … 560 562 } // pthread_key_delete 561 563 562 int pthread_setspecific( pthread_key_t key, const void * value ) libcfa_public __THROW {564 int pthread_setspecific( pthread_key_t key, const void *value ) libcfa_public __THROW { 563 565 // get current thread 564 cfaPthread * t = lookup(pthread_self());566 cfaPthread* t = lookup(pthread_self()); 565 567 // if current thread's pthreadData is NULL; initialize it 566 pthread_values * values;567 if (t->pthreadData == NULL) {568 pthread_values* values; 569 if (t->pthreadData == NULL){ 568 570 values = anew( PTHREAD_KEYS_MAX); 569 571 t->pthreadData = values; 570 for ( int i = 0;i < PTHREAD_KEYS_MAX; i++ ){572 for (int i = 0;i < PTHREAD_KEYS_MAX; i++){ 571 573 t->pthreadData[i].in_use = false; 572 574 } // for … … 591 593 } //pthread_setspecific 592 594 593 void * pthread_getspecific(pthread_key_t key) libcfa_public __THROW {595 void* pthread_getspecific(pthread_key_t key) libcfa_public __THROW { 594 596 if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL; 595 597 596 598 // get current thread 597 cfaPthread * t = lookup(pthread_self());599 cfaPthread* t = lookup(pthread_self()); 598 600 if (t->pthreadData == NULL) return NULL; 599 601 lock(key_lock); 600 pthread_values & entry = ((pthread_values *)t->pthreadData)[key];602 pthread_values &entry = ((pthread_values *)t->pthreadData)[key]; 601 603 if ( ! entry.in_use ) { 602 604 unlock( key_lock ); 603 605 return NULL; 604 606 } // if 605 void * value = entry.value;607 void *value = entry.value; 606 608 unlock(key_lock); 607 609 … … 873 875 //######################### Parallelism ######################### 874 876 875 //int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {876 //abort( "pthread_setaffinity_np" );877 //} // pthread_setaffinity_np878 879 //int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {880 //abort( "pthread_getaffinity_np" );881 //} // pthread_getaffinity_np882 883 //int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {884 //abort( "pthread_attr_setaffinity_np" );885 //} // pthread_attr_setaffinity_np886 887 //int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {888 //abort( "pthread_attr_getaffinity_np" );889 //} // pthread_attr_getaffinity_np877 int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 878 abort( "pthread_setaffinity_np" ); 879 } // pthread_setaffinity_np 880 881 int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 882 abort( "pthread_getaffinity_np" ); 883 } // pthread_getaffinity_np 884 885 int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 886 abort( "pthread_attr_setaffinity_np" ); 887 } // pthread_attr_setaffinity_np 888 889 int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 890 abort( "pthread_attr_getaffinity_np" ); 891 } // pthread_attr_getaffinity_np 890 892 891 893 //######################### Cancellation ######################### … … 904 906 } // pthread_cancel 905 907 906 int pthread_setcancelstate( int state, int * oldstate ) libcfa_public __THROW {908 int pthread_setcancelstate( int state, int *oldstate ) libcfa_public __THROW { 907 909 abort("pthread_setcancelstate not implemented"); 908 910 return 0; 909 911 } // pthread_setcancelstate 910 912 911 int pthread_setcanceltype( int type, int * oldtype ) libcfa_public __THROW {913 int pthread_setcanceltype( int type, int *oldtype ) libcfa_public __THROW { 912 914 abort("pthread_setcanceltype not implemented"); 913 915 return 0; … … 916 918 917 919 #pragma GCC diagnostic pop 920 -
libcfa/src/concurrency/ready_queue.cfa
r24d6572 r34b4268 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 // #define __CFA_DEBUG_PRINT_READY_QUEUE__ -
libcfa/src/concurrency/thread.cfa
r24d6572 r34b4268 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 9 08:42:33 202313 // Update Count : 10 312 // Last Modified On : Sun Dec 11 20:56:54 2022 13 // Update Count : 102 14 14 // 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE 17 18 18 19 #include "thread.hfa" … … 53 54 preferred = ready_queue_new_preferred(); 54 55 last_proc = 0p; 55 link_node = 0p;56 56 PRNG_SET_SEED( random_state, __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl() ); 57 57 #if defined( __CFA_WITH_VERIFY__ ) … … 60 60 #endif 61 61 62 clh_node = malloc( ); 63 *clh_node = false; 64 62 65 doregister(curr_cluster, this); 63 66 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 68 71 canary = 0xDEADDEADDEADDEADp; 69 72 #endif 73 free(clh_node); 70 74 unregister(curr_cluster, this); 71 75 ^self_cor{}; -
libcfa/src/concurrency/thread.hfa
r24d6572 r34b4268 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 2 11:27:59 202313 // Update Count : 3 712 // Last Modified On : Tue Nov 22 22:18:34 2022 13 // Update Count : 35 14 14 // 15 15 … … 27 27 //----------------------------------------------------------------------------- 28 28 // thread trait 29 forall( T & ) 30 trait is_thread { 29 trait is_thread(T &) { 31 30 void ^?{}(T& mutex this); 32 31 void main(T& this); -
libcfa/src/containers/array.hfa
r24d6572 r34b4268 9 9 10 10 11 // 12 // The `array` macro is the public interface. 13 // It computes the type of a dense (trivially strided) array. 14 // All user-declared objects are dense arrays. 15 // 16 // The `arpk` (ARray with PacKing info explicit) type is, generally, a slice with _any_ striding. 17 // This type is meant for internal use. 18 // CFA programmers should not instantiate it directly, nor access its field. 19 // CFA programmers should call ?[?] on it. 20 // Yet user-given `array(stuff)` expands to `arpk(stuff')`. 21 // The comments here explain the resulting internals. 22 // 23 // Just as a plain-C "multidimesional" array is really array-of-array-of-..., 24 // so does arpk generally show up as arpk-of-arpk-of... 25 // 26 // In the example of `array(float, 3, 4, 5) a;`, 27 // `typeof(a)` is an `arpk` instantiation. 28 // These comments explain _its_ arguments, i.e. those of the topmost `arpk` level. 29 // 30 // [N] : the number of elements in `a`; 3 in the example 31 // S : carries the stride size (distance in bytes between &myA[0] and &myA[1]), in sizeof(S); 32 // same as Timmed when striding is trivial, same as Timmed in the example 33 // Timmed : (T-immediate) the inner type; conceptually, `typeof(a)` is "arpk of Timmed"; 34 // array(float, 4, 5) in the example 35 // Tbase : (T-base) the deepest element type that is not arpk; float in the example 36 // 11 // 12 // Single-dim array sruct (with explicit packing and atom) 13 // 14 37 15 forall( [N], S & | sized(S), Timmed &, Tbase & ) { 38 39 //40 // Single-dim array sruct (with explicit packing and atom)41 //42 16 struct arpk { 43 17 S strides[N]; -
libcfa/src/containers/list.hfa
r24d6572 r34b4268 9 9 // Author : Michael Brooks 10 10 // Created On : Wed Apr 22 18:00:00 2020 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Feb 2 11:32:26 202313 // Update Count : 211 // Last Modified By : Michael Brooks 12 // Last Modified On : Wed Apr 22 18:00:00 2020 13 // Update Count : 1 14 14 // 15 15 … … 23 23 }; 24 24 25 forall( tOuter &, tMid &, tInner & ) 26 trait embedded { 25 trait embedded( tOuter &, tMid &, tInner & ) { 27 26 tytagref( tMid, tInner ) ?`inner( tOuter & ); 28 27 }; … … 32 31 static inline tytagref(void, T) ?`inner ( T & this ) { tytagref( void, T ) ret = {this}; return ret; } 33 32 34 35 // 36 // P9_EMBEDDED: Use on every case of plan-9 inheritance, to make "implements embedded" be a closure of plan-9 inheritance. 37 // 38 // struct foo { 39 // int a, b, c; 40 // inline (bar); 41 // }; 42 // P9_EMBEDDED( foo, bar ) 43 // 44 45 // usual version, for structs that are top-level declarations 46 #define P9_EMBEDDED( derived, immedBase ) P9_EMBEDDED_DECL_( derived, immedBase, static ) P9_EMBEDDED_BDY_( immedBase ) 47 48 // special version, for structs that are declared in functions 49 #define P9_EMBEDDED_INFUNC( derived, immedBase ) P9_EMBEDDED_DECL_( derived, immedBase, ) P9_EMBEDDED_BDY_( immedBase ) 50 51 // forward declarations of both the above; generally not needed 52 // may help you control where the P9_EMBEEDED cruft goes, in case "right after the stuct" isn't where you want it 53 #define P9_EMBEDDED_FWD( derived, immedBase ) P9_EMBEDDED_DECL_( derived, immedBase, static ) ; 54 #define P9_EMBEDDED_FWD_INFUNC( derived, immedBase ) auto P9_EMBEDDED_DECL_( derived, immedBase, ) ; 55 56 // private helpers 57 #define P9_EMBEDDED_DECL_( derived, immedBase, STORAGE ) \ 58 forall( Tbase &, TdiscardPath & | { tytagref( TdiscardPath, Tbase ) ?`inner( immedBase & ); } ) \ 59 STORAGE inline tytagref(immedBase, Tbase) ?`inner( derived & this ) 60 61 #define P9_EMBEDDED_BDY_( immedBase ) { \ 33 // use this on every case of plan-9 inheritance, to make embedded a closure of plan-9 inheritance 34 #define P9_EMBEDDED( derived, immedBase ) \ 35 forall( Tbase &, TdiscardPath & | { tytagref( TdiscardPath, Tbase ) ?`inner( immedBase & ); } ) \ 36 static inline tytagref(immedBase, Tbase) ?`inner( derived & this ) { \ 62 37 immedBase & ib = this; \ 63 38 Tbase & b = ib`inner; \ -
libcfa/src/containers/vector.hfa
r24d6572 r34b4268 10 10 // Created On : Tue Jul 5 18:00:07 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:41:24 202313 // Update Count : 512 // Last Modified On : Wed Jun 17 11:02:46 2020 13 // Update Count : 4 14 14 // 15 15 … … 50 50 //------------------------------------------------------------------------------ 51 51 //Declaration 52 forall( T, allocator_t)53 trait allocator_c{52 trait allocator_c(T, allocator_t) 53 { 54 54 void realloc_storage(allocator_t*, size_t); 55 55 T* data(allocator_t*); -
libcfa/src/containers/vector2.hfa
r24d6572 r34b4268 9 9 // Author : Michael Brooks 10 10 // Created On : Thu Jun 23 22:00:00 2021 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 14 08:40:53 2023 13 // Update Count : 2 14 // 15 16 #pragma once 11 // Last Modified By : Michael Brooks 12 // Last Modified On : Thu Jun 23 22:00:00 2021 13 // Update Count : 1 14 // 17 15 18 16 #include <stdlib.hfa> -
libcfa/src/exception.h
r24d6572 r34b4268 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Th u Feb 2 11:20:19 202313 // Update Count : 1 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Apr 8 15:20:00 2021 13 // Update Count : 12 14 14 // 15 15 … … 101 101 // implemented in the .c file either so they all have to be inline. 102 102 103 forall( exceptT &, virtualT & ) 104 trait is_exception { 103 trait is_exception(exceptT &, virtualT &) { 105 104 /* The first field must be a pointer to a virtual table. 106 105 * That virtual table must be a decendent of the base exception virtual table. … … 110 109 }; 111 110 112 forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) ) 113 trait is_termination_exception { 111 trait is_termination_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) { 114 112 void defaultTerminationHandler(exceptT &); 115 113 }; 116 114 117 forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) ) 118 trait is_resumption_exception { 115 trait is_resumption_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) { 119 116 void defaultResumptionHandler(exceptT &); 120 117 }; -
libcfa/src/heap.cfa
r24d6572 r34b4268 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 30 08:37:37202213 // Update Count : 1 60512 // Last Modified On : Sun Oct 30 20:56:20 2022 13 // Update Count : 1584 14 14 // 15 15 … … 17 17 #include <string.h> // memset, memcpy 18 18 #include <limits.h> // ULONG_MAX 19 #include <stdlib.h> // EXIT_FAILURE 19 20 #include <errno.h> // errno, ENOMEM, EINVAL 20 #include <unistd.h> // STDERR_FILENO, sbrk, sysconf, write 21 #include <unistd.h> // STDERR_FILENO, sbrk, sysconf 22 #include <malloc.h> // memalign, malloc_usable_size 21 23 #include <sys/mman.h> // mmap, munmap 22 24 extern "C" { … … 24 26 } // extern "C" 25 27 26 #include "heap.hfa"27 28 #include "bits/align.hfa" // libAlign 28 29 #include "bits/defs.hfa" // likely, unlikely … … 139 140 #endif 140 141 141 typedef volatile uintptr_t SpinLock_t ;142 typedef volatile uintptr_t SpinLock_t CALIGN; // aligned addressable word-size 142 143 143 144 static inline __attribute__((always_inline)) void lock( volatile SpinLock_t & slock ) { … … 146 147 147 148 for ( unsigned int i = 1;; i += 1 ) { 148 if ( slock == 0 && __atomic_test_and_set( &slock, __ATOMIC_ ACQUIRE) == 0 ) break; // Fence149 if ( slock == 0 && __atomic_test_and_set( &slock, __ATOMIC_SEQ_CST ) == 0 ) break; // Fence 149 150 for ( volatile unsigned int s = 0; s < spin; s += 1 ) Pause(); // exponential spin 150 151 spin += spin; // powers of 2 … … 155 156 156 157 static inline __attribute__((always_inline)) void unlock( volatile SpinLock_t & slock ) { 157 __atomic_clear( &slock, __ATOMIC_ RELEASE); // Fence158 __atomic_clear( &slock, __ATOMIC_SEQ_CST ); // Fence 158 159 } // spin_unlock 159 160 … … 260 261 static_assert( libAlign() >= sizeof( Storage ), "minimum alignment < sizeof( Storage )" ); 261 262 262 struct CALIGNFreeHeader {263 size_t blockSize CALIGN;// size of allocations on this list263 struct __attribute__(( aligned (8) )) FreeHeader { 264 size_t blockSize __attribute__(( aligned(8) )); // size of allocations on this list 264 265 #ifdef OWNERSHIP 265 266 #ifdef RETURNSPIN … … 283 284 284 285 #ifdef __CFA_DEBUG__ 285 ptrdiff_t allocUnfreed; // running total of allocations minus frees; can be negative286 int64_t allocUnfreed; // running total of allocations minus frees; can be negative 286 287 #endif // __CFA_DEBUG__ 287 288 … … 368 369 // Thread-local storage is allocated lazily when the storage is accessed. 369 370 static __thread size_t PAD1 CALIGN TLSMODEL __attribute__(( unused )); // protect false sharing 370 static __thread Heap * heapManager CALIGN TLSMODEL;371 static __thread Heap * volatile heapManager CALIGN TLSMODEL; 371 372 static __thread size_t PAD2 CALIGN TLSMODEL __attribute__(( unused )); // protect further false sharing 372 373 … … 442 443 // 12K ~= 120K byte superblock. Where 128-heap superblock handles a medium sized multi-processor server. 443 444 size_t remaining = heapManagersStorageEnd - heapManagersStorage; // remaining free heaps in superblock 444 if ( ! heapManagersStorage || remaining == 0 ) {445 if ( ! heapManagersStorage || remaining != 0 ) { 445 446 // Each block of heaps is a multiple of the number of cores on the computer. 446 447 int HeapDim = get_nprocs(); // get_nprocs_conf does not work … … 561 562 // allocUnfreed is set to 0 when a heap is created and it accumulates any unfreed storage during its multiple thread 562 563 // usages. At the end, add up each heap allocUnfreed value across all heaps to get the total unfreed storage. 563 ptrdiff_t allocUnfreed = 0;564 int64_t allocUnfreed = 0; 564 565 for ( Heap * heap = heapMaster.heapManagersList; heap; heap = heap->nextHeapManager ) { 565 566 allocUnfreed += heap->allocUnfreed; … … 571 572 char helpText[512]; 572 573 __cfaabi_bits_print_buffer( STDERR_FILENO, helpText, sizeof(helpText), 573 "CFA warning (UNIX pid:%ld) : program terminating with % td(%#tx) bytes of storage allocated but not freed.\n"574 "CFA warning (UNIX pid:%ld) : program terminating with %ju(0x%jx) bytes of storage allocated but not freed.\n" 574 575 "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n", 575 576 (long int)getpid(), allocUnfreed, allocUnfreed ); // always print the UNIX pid … … 805 806 806 807 ptrdiff_t rem = heapRemaining - size; 807 if ( unlikely( rem < 0 ) ) { // negative ?808 if ( unlikely( rem < 0 ) ) { 808 809 // If the size requested is bigger than the current remaining storage, increase the size of the heap. 809 810 … … 841 842 ptrdiff_t rem = heapReserve - size; 842 843 843 if ( unlikely( rem < 0 ) ) { // negative ?844 if ( unlikely( rem < 0 ) ) { // negative 844 845 // If the size requested is bigger than the current remaining reserve, use the current reserve to populate 845 846 // smaller freeLists, and increase the reserve. … … 847 848 rem = heapReserve; // positive 848 849 849 if ( (unsigned int)rem >= bucketSizes[0] ) {// minimal size ? otherwise ignore850 if ( rem >= bucketSizes[0] ) { // minimal size ? otherwise ignore 850 851 size_t bucket; 851 852 #ifdef FASTLOOKUP … … 856 857 Heap.FreeHeader * freeHead = &(freeLists[bucket]); 857 858 858 // The remaining storage ma y not be bucket size, whereas all other allocations are. Round down to previous859 // The remaining storage many not be bucket size, whereas all other allocations are. Round down to previous 859 860 // bucket size in this case. 860 861 if ( unlikely( freeHead->blockSize > (size_t)rem ) ) freeHead -= 1; … … 949 950 block = freeHead->freeList; // remove node from stack 950 951 if ( unlikely( block == 0p ) ) { // no free block ? 951 // Freelist for this size is empty, so check return list (OWNERSHIP), or carve it out of the heapif there952 // Freelist for this size is empty, so check return list (OWNERSHIP), carve it out of the heap, if there 952 953 // is enough left, or get some more heap storage and carve it off. 953 954 #ifdef OWNERSHIP … … 1114 1115 while ( ! __atomic_compare_exchange_n( &freeHead->returnList, &header->kind.real.next, (Heap.Storage *)header, 1115 1116 false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ); 1116 1117 #ifdef __STATISTICS__1118 stats.return_pushes += 1;1119 stats.return_storage_request += rsize;1120 stats.return_storage_alloc += size;1121 #endif // __STATISTICS__1122 1117 #endif // RETURNSPIN 1123 1118 } // if … … 1130 1125 freeHead->freeList = (Heap.Storage *)header; 1131 1126 #endif // ! OWNERSHIP 1127 1128 #ifdef __U_STATISTICS__ 1129 stats.return_pushes += 1; 1130 stats.return_storage_request += rsize; 1131 stats.return_storage_alloc += size; 1132 #endif // __U_STATISTICS__ 1132 1133 1133 1134 // OK TO BE PREEMPTED HERE AS heapManager IS NO LONGER ACCESSED. … … 1179 1180 1180 1181 #ifdef __STATISTICS__ 1181 static void incCalls( size_t statName ) libcfa_nopreempt {1182 static void incCalls( intptr_t statName ) libcfa_nopreempt { 1182 1183 heapManager->stats.counters[statName].calls += 1; 1183 1184 } // incCalls 1184 1185 1185 static void incZeroCalls( size_t statName ) libcfa_nopreempt {1186 static void incZeroCalls( intptr_t statName ) libcfa_nopreempt { 1186 1187 heapManager->stats.counters[statName].calls_0 += 1; 1187 1188 } // incZeroCalls … … 1455 1456 // 0p, no operation is performed. 1456 1457 void free( void * addr ) libcfa_public { 1458 // verify( heapManager ); 1459 1457 1460 if ( unlikely( addr == 0p ) ) { // special case 1458 1461 #ifdef __STATISTICS__ -
libcfa/src/interpose.cfa
r24d6572 r34b4268 10 10 // Created On : Wed Mar 29 16:10:31 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 27 21:09:03 2023 13 // Update Count : 196 14 // 15 12 // Last Modified On : Fri Mar 13 17:35:37 2020 13 // Update Count : 178 14 // 15 16 #include <stdarg.h> // va_start, va_end 16 17 #include <stdio.h> 18 #include <string.h> // strlen 17 19 #include <unistd.h> // _exit, getpid 20 #define __USE_GNU 21 #include <signal.h> 22 #undef __USE_GNU 18 23 extern "C" { 19 24 #include <dlfcn.h> // dlopen, dlsym … … 21 26 } 22 27 28 #include "bits/debug.hfa" 23 29 #include "bits/defs.hfa" 24 30 #include "bits/signal.hfa" // sigHandler_? … … 36 42 37 43 typedef void (* generic_fptr_t)(void); 38 39 44 static generic_fptr_t do_interpose_symbol( void * library, const char symbol[], const char version[] ) { 45 const char * error; 46 40 47 union { generic_fptr_t fptr; void * ptr; } originalFunc; 41 48 42 49 #if defined( _GNU_SOURCE ) 43 if ( version ) { 44 originalFunc.ptr = dlvsym( library, symbol, version ); 45 } else { 50 if ( version ) { 51 originalFunc.ptr = dlvsym( library, symbol, version ); 52 } else { 53 originalFunc.ptr = dlsym( library, symbol ); 54 } 55 #else 46 56 originalFunc.ptr = dlsym( library, symbol ); 57 #endif // _GNU_SOURCE 58 59 error = dlerror(); 60 if ( error ) abort( "interpose_symbol : internal error, %s\n", error ); 61 62 return originalFunc.fptr; 63 } 64 65 static generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) { 66 const char * error; 67 68 static void * library; 69 static void * pthread_library; 70 if ( ! library ) { 71 #if defined( RTLD_NEXT ) 72 library = RTLD_NEXT; 73 #else 74 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 75 library = dlopen( "libc.so.6", RTLD_LAZY ); 76 error = dlerror(); 77 if ( error ) { 78 abort( "interpose_symbol : failed to open libc, %s\n", error ); 79 } 80 #endif 47 81 } // if 48 #else 49 originalFunc.ptr = dlsym( library, symbol ); 50 #endif // _GNU_SOURCE 51 52 if ( ! originalFunc.ptr ) { // == nullptr 53 abort( "interpose_symbol : internal error, %s\n", dlerror() ); 82 if ( ! pthread_library ) { 83 #if defined( RTLD_NEXT ) 84 pthread_library = RTLD_NEXT; 85 #else 86 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 87 pthread_library = dlopen( "libpthread.so", RTLD_LAZY ); 88 error = dlerror(); 89 if ( error ) { 90 abort( "interpose_symbol : failed to open libpthread, %s\n", error ); 91 } 92 #endif 54 93 } // if 55 return originalFunc.fptr; 56 } 57 58 static generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) { 59 void * library; 60 61 #if defined( RTLD_NEXT ) 62 library = RTLD_NEXT; 63 #else 64 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 65 library = dlopen( "libc.so.6", RTLD_LAZY ); 66 if ( ! library ) { // == nullptr 67 abort( "interpose_symbol : failed to open libc, %s\n", dlerror() ); 68 } // if 69 #endif // RTLD_NEXT 70 71 return do_interpose_symbol( library, symbol, version ); 94 95 return do_interpose_symbol(library, symbol, version); 72 96 } 73 97 … … 99 123 preload_libgcc(); 100 124 101 #pragma GCC diagnostic push102 #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"125 #pragma GCC diagnostic push 126 #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" 103 127 INTERPOSE_LIBC( abort, version ); 104 128 INTERPOSE_LIBC( exit , version ); 105 #pragma GCC diagnostic pop129 #pragma GCC diagnostic pop 106 130 107 131 if(__cfathreadabi_interpose_startup) __cfathreadabi_interpose_startup( do_interpose_symbol ); 108 109 // SKULLDUGGERY: In Ubuntu 22.04, someone augmented signal.h to allow SIGSTKSZ to be "sysconf(_SC_SIGSTKSZ)" in110 // sigstksz.h, as well as 8192 in sigstack.h. HOWEVER, they forgot to provide a mechanism to tell signal.h to111 // use sigstack.h rather than sigstksz.h. (I'm not happy.) By undefining _GNU_SOURCE before signal.h and112 // redefining it afterwards, you can get 8192, but then nothing works correctly inside of signal.h without113 // _GNU_SOURCE defined. So what is needed is a way to get signal.h to use sigstack.h WITH _GNU_SOURCE defined.114 // Basically something is wrong with features.h and its use in signal.h.115 116 #undef SIGSTKSZ117 #define SIGSTKSZ 8192118 132 119 133 // As a precaution (and necessity), errors that result in termination are delivered on a separate stack because … … 281 295 va_start( args, fmt ); 282 296 __abort( false, fmt, args ); 283 // CONTROL NEVER REACHES HERE!297 // CONTROL NEVER REACHES HERE! 284 298 va_end( args ); 285 299 } 286 300 287 301 void abort( bool signalAbort, const char fmt[], ... ) { 288 va_list args;289 va_start( args, fmt );290 __abort( signalAbort, fmt, args );291 // CONTROL NEVER REACHES HERE!292 va_end( args );302 va_list args; 303 va_start( args, fmt ); 304 __abort( signalAbort, fmt, args ); 305 // CONTROL NEVER REACHES HERE! 306 va_end( args ); 293 307 } 294 308 -
libcfa/src/interpose_thread.cfa
r24d6572 r34b4268 14 14 // 15 15 16 // BUG in 32-bit gcc with interpose: fixed in >= gcc-9.5, gcc-10.4, gcc-12.2 17 #ifdef __i386__ // 32-bit architecture 18 #undef _GNU_SOURCE 19 #endif // __i386__ 20 16 #include <stdarg.h> // va_start, va_end 17 #include <stdio.h> 18 #include <string.h> // strlen 21 19 #include <signal.h> 22 20 #include <pthread.h> 23 #include <signal.h>24 21 extern "C" { 25 22 #include <dlfcn.h> // dlopen, dlsym 23 #include <execinfo.h> // backtrace, messages 26 24 } 27 25 26 #include "bits/debug.hfa" 28 27 #include "bits/defs.hfa" 28 #include <assert.h> 29 29 30 30 //============================================================================================= … … 34 34 typedef void (* generic_fptr_t)(void); 35 35 36 generic_fptr_t libcfa_publicinterpose_symbol(36 generic_fptr_t interpose_symbol( 37 37 generic_fptr_t (*do_interpose_symbol)( void * library, const char symbol[], const char version[] ), 38 38 const char symbol[], 39 39 const char version[] 40 ) {41 void * library;40 ) libcfa_public { 41 const char * error; 42 42 43 #if defined( RTLD_NEXT ) 44 library = RTLD_NEXT; 45 #else 46 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 47 library = dlopen( "libpthread.so", RTLD_LAZY ); 48 if ( ! library ) { // == nullptr 49 abort( "interpose_symbol : failed to open libpthread, %s\n", dlerror() ); 43 static void * library; 44 if ( ! library ) { 45 #if defined( RTLD_NEXT ) 46 library = RTLD_NEXT; 47 #else 48 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 49 library = dlopen( "libpthread.so", RTLD_LAZY ); 50 error = dlerror(); 51 if ( error ) { 52 abort( "interpose_symbol : failed to open libpthread, %s\n", error ); 53 } 54 #endif 50 55 } // if 51 #endif // RTLD_NEXT52 56 53 return do_interpose_symbol( library, symbol, version);57 return do_interpose_symbol(library, symbol, version); 54 58 } 55 59 … … 79 83 #pragma GCC diagnostic push 80 84 #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" 81 INTERPOSE( pthread_create , version );82 INTERPOSE( pthread_join , version );83 INTERPOSE( pthread_self , version );84 INTERPOSE( pthread_attr_init , version );85 INTERPOSE( pthread_attr_destroy , version );86 INTERPOSE( pthread_attr_setstack , version );87 INTERPOSE( pthread_attr_getstacksize , version );88 INTERPOSE( pthread_sigmask , version );89 INTERPOSE( pthread_sigqueue , version );90 INTERPOSE( pthread_once , version );85 INTERPOSE( pthread_create , version ); 86 INTERPOSE( pthread_join , version ); 87 INTERPOSE( pthread_self , version ); 88 INTERPOSE( pthread_attr_init , version ); 89 INTERPOSE( pthread_attr_destroy , version ); 90 INTERPOSE( pthread_attr_setstack , version ); 91 INTERPOSE( pthread_attr_getstacksize , version ); 92 INTERPOSE( pthread_sigmask , version ); 93 INTERPOSE( pthread_sigqueue , version ); 94 INTERPOSE( pthread_once , version ); 91 95 #pragma GCC diagnostic pop 92 96 } -
libcfa/src/iostream.cfa
r24d6572 r34b4268 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 9 09:27:58 202313 // Update Count : 13 6112 // Last Modified On : Sat Aug 27 15:04:15 2022 13 // Update Count : 1358 14 14 // 15 15 … … 667 667 } /* if */ \ 668 668 if ( ! f.flags.nobsdp || (exp10 < SUFFIXES_START) || (exp10 > SUFFIXES_END) ) { \ 669 len2 = snprintf( &buf[len], size - len, "e%d", (int)exp10 /* ambiguity with function exp10 */); \669 len2 = snprintf( &buf[len], size - len, "e%d", exp10 ); \ 670 670 } else { \ 671 671 len2 = snprintf( &buf[len], size - len, "%s", suffixes[(exp10 - SUFFIXES_START) / 3] ); \ -
libcfa/src/iostream.hfa
r24d6572 r34b4268 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:25:39 202313 // Update Count : 4 1012 // Last Modified On : Sun Oct 10 10:02:07 2021 13 // Update Count : 407 14 14 // 15 15 … … 22 22 23 23 24 forall( ostype & ) 25 trait basic_ostream { 24 trait basic_ostream( ostype & ) { 26 25 // private 27 26 bool sepPrt$( ostype & ); // get separator state (on/off) … … 52 51 }; // basic_ostream 53 52 54 forall( ostype & | basic_ostream( ostype ) ) 55 trait ostream { 53 trait ostream( ostype & | basic_ostream( ostype ) ) { 56 54 bool fail( ostype & ); // operation failed? 57 55 void clear( ostype & ); … … 62 60 }; // ostream 63 61 64 // forall( T ) 65 // trait writeable { 62 // trait writeable( T ) { 66 63 // forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype &, T ); 67 64 // }; // writeable 68 65 69 forall( T, ostype & | ostream( ostype ) ) 70 trait writeable { 66 trait writeable( T, ostype & | ostream( ostype ) ) { 71 67 ostype & ?|?( ostype &, T ); 72 68 }; // writeable … … 294 290 295 291 296 forall( istype & ) 297 trait basic_istream { 292 trait basic_istream( istype & ) { 298 293 // private 299 294 bool getANL$( istype & ); // get scan newline (on/off) … … 307 302 }; // basic_istream 308 303 309 forall( istype & | basic_istream( istype ) ) 310 trait istream { 304 trait istream( istype & | basic_istream( istype ) ) { 311 305 bool fail( istype & ); 312 306 void clear( istype & ); … … 316 310 }; // istream 317 311 318 forall( T ) 319 trait readable { 312 trait readable( T ) { 320 313 forall( istype & | istream( istype ) ) istype & ?|?( istype &, T ); 321 314 }; // readable -
libcfa/src/iterator.hfa
r24d6572 r34b4268 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:21:50 202313 // Update Count : 1 112 // Last Modified On : Fri Jul 7 08:37:25 2017 13 // Update Count : 10 14 14 // 15 15 … … 17 17 18 18 // An iterator can be used to traverse a data structure. 19 forall( iterator_type, elt_type ) 20 trait iterator { 19 trait iterator( iterator_type, elt_type ) { 21 20 // point to the next element 22 21 // iterator_type ?++( iterator_type & ); … … 32 31 }; 33 32 34 forall( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) 35 trait iterator_for { 33 trait iterator_for( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) { 36 34 // [ iterator_type begin, iterator_type end ] get_iterators( collection_type ); 37 35 iterator_type begin( collection_type ); -
libcfa/src/limits.cfa
r24d6572 r34b4268 10 10 // Created On : Wed Apr 6 18:06:52 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 17 12:25:39 202313 // Update Count : 8712 // Last Modified On : Thu Mar 1 16:22:51 2018 13 // Update Count : 74 14 14 // 15 15 16 16 #include <limits.h> 17 17 #include <float.h> 18 #define __USE_GNU // get M_* constants 18 19 #include <math.h> 19 20 #include <complex.h> -
libcfa/src/math.trait.hfa
r24d6572 r34b4268 10 10 // Created On : Fri Jul 16 15:40:52 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 2 11:36:56 202313 // Update Count : 2012 // Last Modified On : Tue Jul 20 17:47:19 2021 13 // Update Count : 19 14 14 // 15 15 16 16 #pragma once 17 17 18 forall( U ) 19 trait Not { 18 trait Not( U ) { 20 19 void ?{}( U &, zero_t ); 21 20 int !?( U ); 22 21 }; // Not 23 22 24 forall( T | Not( T ) ) 25 trait Equality { 23 trait Equality( T | Not( T ) ) { 26 24 int ?==?( T, T ); 27 25 int ?!=?( T, T ); 28 26 }; // Equality 29 27 30 forall( U | Equality( U ) ) 31 trait Relational { 28 trait Relational( U | Equality( U ) ) { 32 29 int ?<?( U, U ); 33 30 int ?<=?( U, U ); … … 36 33 }; // Relational 37 34 38 forall ( T ) 39 trait Signed { 35 trait Signed( T ) { 40 36 T +?( T ); 41 37 T -?( T ); … … 43 39 }; // Signed 44 40 45 forall( U | Signed( U ) ) 46 trait Additive { 41 trait Additive( U | Signed( U ) ) { 47 42 U ?+?( U, U ); 48 43 U ?-?( U, U ); … … 51 46 }; // Additive 52 47 53 forall( T | Additive( T ) ) 54 trait Incdec { 48 trait Incdec( T | Additive( T ) ) { 55 49 void ?{}( T &, one_t ); 56 50 // T ?++( T & ); … … 60 54 }; // Incdec 61 55 62 forall( U | Incdec( U ) ) 63 trait Multiplicative { 56 trait Multiplicative( U | Incdec( U ) ) { 64 57 U ?*?( U, U ); 65 58 U ?/?( U, U ); … … 68 61 }; // Multiplicative 69 62 70 forall( T | Relational( T ) | Multiplicative( T ) ) 71 trait Arithmetic { 63 trait Arithmetic( T | Relational( T ) | Multiplicative( T ) ) { 72 64 }; // Arithmetic 73 65 -
libcfa/src/stdlib.cfa
r24d6572 r34b4268 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 16 16:31:34 202313 // Update Count : 63 312 // Last Modified On : Fri Dec 9 15:11:30 2022 13 // Update Count : 631 14 14 // 15 15 … … 20 20 //--------------------------------------- 21 21 22 #define _XOPEN_SOURCE 600 // posix_memalign, *rand48 22 23 #include <string.h> // memcpy, memset 23 24 //#include <math.h> // fabsf, fabs, fabsl -
libcfa/src/stdlib.hfa
r24d6572 r34b4268 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:30:04 202313 // Update Count : 76 612 // Last Modified On : Sun Dec 11 18:25:53 2022 13 // Update Count : 765 14 14 // 15 15 … … 367 367 368 368 char random( void ) { return (unsigned long int)random(); } 369 char random( char u ) { return (unsigned long int)random( (unsigned long int)u ); } // [0,u)369 char random( char u ) { return random( (unsigned long int)u ); } // [0,u) 370 370 char random( char l, char u ) { return random( (unsigned long int)l, (unsigned long int)u ); } // [l,u) 371 371 int random( void ) { return (long int)random(); } 372 int random( int u ) { return (long int)random( (long int)u ); } // [0,u]372 int random( int u ) { return random( (long int)u ); } // [0,u] 373 373 int random( int l, int u ) { return random( (long int)l, (long int)u ); } // [l,u) 374 374 unsigned int random( void ) { return (unsigned long int)random(); } 375 unsigned int random( unsigned int u ) { return (unsigned long int)random( (unsigned long int)u ); } // [0,u]375 unsigned int random( unsigned int u ) { return random( (unsigned long int)u ); } // [0,u] 376 376 unsigned int random( unsigned int l, unsigned int u ) { return random( (unsigned long int)l, (unsigned long int)u ); } // [l,u) 377 377 } // distribution … … 404 404 // calls( sprng ); 405 405 406 forall( PRNG &, R ) 407 trait basic_prng { 406 trait basic_prng( PRNG &, R ) { 408 407 void set_seed( PRNG & prng, R seed ); // set seed 409 408 R get_seed( PRNG & prng ); // get seed -
libcfa/src/vec/vec.hfa
r24d6572 r34b4268 18 18 #include <math.hfa> 19 19 20 forall(T) 21 trait fromint { 20 trait fromint(T) { 22 21 void ?{}(T&, int); 23 22 }; 24 forall(T) 25 trait zeroinit { 23 trait zeroinit(T) { 26 24 void ?{}(T&, zero_t); 27 25 }; 28 forall(T) 29 trait zero_assign { 26 trait zero_assign(T) { 30 27 T ?=?(T&, zero_t); 31 28 }; 32 forall(T) 33 trait subtract { 29 trait subtract(T) { 34 30 T ?-?(T, T); 35 31 }; 36 forall(T) 37 trait negate { 32 trait negate(T) { 38 33 T -?(T); 39 34 }; 40 forall(T) 41 trait add { 35 trait add(T) { 42 36 T ?+?(T, T); 43 37 }; 44 forall(T) 45 trait multiply { 38 trait multiply(T) { 46 39 T ?*?(T, T); 47 40 }; 48 forall(T) 49 trait divide { 41 trait divide(T) { 50 42 T ?/?(T, T); 51 43 }; 52 forall(T) 53 trait lessthan { 44 trait lessthan(T) { 54 45 int ?<?(T, T); 55 46 }; 56 forall(T) 57 trait equality { 47 trait equality(T) { 58 48 int ?==?(T, T); 59 49 }; 60 forall(T) 61 trait sqrt { 50 trait sqrt(T) { 62 51 T sqrt(T); 63 52 }; -
src/AST/Attribute.hpp
r24d6572 r34b4268 27 27 class Expr; 28 28 29 /// An entry in an attribute list: `__attribute__(( ... ))`30 29 class Attribute final : public Node { 31 30 public: -
src/AST/Convert.cpp
r24d6572 r34b4268 559 559 auto stmt = new SuspendStmt(); 560 560 stmt->then = get<CompoundStmt>().accept1( node->then ); 561 switch (node->kind) {561 switch(node->type) { 562 562 case ast::SuspendStmt::None : stmt->type = SuspendStmt::None ; break; 563 563 case ast::SuspendStmt::Coroutine: stmt->type = SuspendStmt::Coroutine; break; … … 565 565 } 566 566 return stmtPostamble( stmt, node ); 567 }568 569 const ast::WhenClause * visit( const ast::WhenClause * node ) override final {570 // There is no old-AST WhenClause, so this should never be called.571 assert( !node );572 return nullptr;573 567 } 574 568 … … 579 573 for ( auto clause : node->clauses ) { 580 574 stmt->clauses.push_back({{ 581 get<Expression>().accept1( clause->target ),575 get<Expression>().accept1( clause->target_func ), 582 576 get<Expression>().acceptL( clause->target_args ), 583 577 }, 584 578 get<Statement>().accept1( clause->stmt ), 585 get<Expression>().accept1( clause-> when_cond ),579 get<Expression>().accept1( clause->cond ), 586 580 }); 587 581 } … … 600 594 const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final { 601 595 // There is no old-AST WaitForClause, so this should never be called. 602 assert( !node );603 return nullptr;604 }605 606 const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {607 // There is no old-AST WaitUntilStmt, so this should never be called.608 596 assert( !node ); 609 597 return nullptr; … … 1695 1683 GET_ACCEPT_V(attributes, Attribute), 1696 1684 { old->get_funcSpec().val }, 1697 (old->type->isVarArgs) ? ast::VariableArgs : ast::FixedArgs1685 old->type->isVarArgs 1698 1686 }; 1699 1687 … … 2001 1989 GET_ACCEPT_1(else_, Stmt), 2002 1990 GET_ACCEPT_V(initialization, Stmt), 2003 (old->isDoWhile) ? ast::DoWhile : ast::While,1991 old->isDoWhile, 2004 1992 GET_LABELS_V(old->labels) 2005 1993 ); … … 2143 2131 virtual void visit( const SuspendStmt * old ) override final { 2144 2132 if ( inCache( old ) ) return; 2145 ast::SuspendStmt:: Kindtype;2133 ast::SuspendStmt::Type type; 2146 2134 switch (old->type) { 2147 2135 case SuspendStmt::Coroutine: type = ast::SuspendStmt::Coroutine; break; … … 2170 2158 auto clause = new ast::WaitForClause( old->location ); 2171 2159 2172 clause->target = GET_ACCEPT_1(clauses[i].target.function, Expr);2160 clause->target_func = GET_ACCEPT_1(clauses[i].target.function, Expr); 2173 2161 clause->target_args = GET_ACCEPT_V(clauses[i].target.arguments, Expr); 2174 2162 clause->stmt = GET_ACCEPT_1(clauses[i].statement, Stmt); 2175 clause-> when_cond = GET_ACCEPT_1(clauses[i].condition, Expr);2163 clause->cond = GET_ACCEPT_1(clauses[i].condition, Expr); 2176 2164 2177 2165 stmt->clauses.push_back( clause ); -
src/AST/Create.cpp
r24d6572 r34b4268 20 20 #include "AST/Decl.hpp" 21 21 #include "AST/Type.hpp" 22 #include "Common/Iterate.hpp"23 22 24 23 namespace ast { -
src/AST/Decl.cpp
r24d6572 r34b4268 20 20 #include <unordered_map> 21 21 22 #include "Common/ Eval.h" // for eval22 #include "Common/utility.h" 23 23 24 24 #include "Fwd.hpp" // for UniqueId … … 57 57 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 58 58 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 59 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, ArgumentFlag isVarArgs)59 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 60 60 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), 61 61 type_params(std::move(forall)), assertions(), 62 62 params(std::move(params)), returns(std::move(returns)), stmts( stmts ) { 63 FunctionType * ftype = new FunctionType( isVarArgs);63 FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs)); 64 64 for (auto & param : this->params) { 65 65 ftype->params.emplace_back(param->get_type()); … … 81 81 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 82 82 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 83 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, ArgumentFlag isVarArgs)83 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 84 84 : DeclWithType( location, name, storage, linkage, std::move(attrs), fs ), 85 85 type_params( std::move( forall) ), assertions( std::move( assertions ) ), 86 86 params( std::move(params) ), returns( std::move(returns) ), 87 87 type( nullptr ), stmts( stmts ) { 88 FunctionType * type = new FunctionType( isVarArgs );88 FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs ); 89 89 for ( auto & param : this->params ) { 90 90 type->params.emplace_back( param->get_type() ); -
src/AST/Decl.hpp
r24d6572 r34b4268 10 10 // Created On : Thu May 9 10:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Apr 5 10:42:00 202313 // Update Count : 3 512 // Last Modified On : Thu Nov 24 9:44:00 2022 13 // Update Count : 34 14 14 // 15 15 … … 122 122 }; 123 123 124 /// Function variable arguments flag125 enum ArgumentFlag { FixedArgs, VariableArgs };126 127 124 /// Object declaration `int foo()` 128 125 class FunctionDecl : public DeclWithType { … … 147 144 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 148 145 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall, 149 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, ArgumentFlag isVarArgs = FixedArgs);146 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false); 150 147 151 148 FunctionDecl( const CodeLocation & location, const std::string & name, … … 153 150 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 154 151 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall, 155 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, ArgumentFlag isVarArgs = FixedArgs);152 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false); 156 153 157 154 const Type * get_type() const override; … … 316 313 public: 317 314 bool isTyped; // isTyped indicated if the enum has a declaration like: 318 // enum (type_optional) Name {...} 315 // enum (type_optional) Name {...} 319 316 ptr<Type> base; // if isTyped == true && base.get() == nullptr, it is a "void" type enum 320 317 enum class EnumHiding { Visible, Hide } hide; … … 374 371 }; 375 372 376 /// Assembly declaration: `asm ... ( "..." : ... )`377 373 class AsmDecl : public Decl { 378 374 public: -
src/AST/Expr.cpp
r24d6572 r34b4268 30 30 #include "Common/SemanticError.h" 31 31 #include "GenPoly/Lvalue.h" // for referencesPermissable 32 #include "ResolvExpr/ Unify.h"// for extractResultType32 #include "ResolvExpr/typeops.h" // for extractResultType 33 33 #include "Tuples/Tuples.h" // for makeTupleType 34 34 -
src/AST/Expr.hpp
r24d6572 r34b4268 256 256 }; 257 257 258 /// A name qualified by a namespace or type.259 258 class QualifiedNameExpr final : public Expr { 260 259 public: … … 262 261 std::string name; 263 262 264 QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const std::string & n ) 263 QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const std::string & n ) 265 264 : Expr( loc ), type_decl( d ), name( n ) {} 266 265 … … 632 631 }; 633 632 634 /// A name that refers to a generic dimension parameter.635 633 class DimensionExpr final : public Expr { 636 634 public: … … 922 920 }; 923 921 922 924 923 } 925 924 -
src/AST/Fwd.hpp
r24d6572 r34b4268 15 15 16 16 #pragma once 17 18 template<typename> struct bitfield;19 17 20 18 #include "AST/Node.hpp" … … 58 56 class FinallyClause; 59 57 class SuspendStmt; 60 class WhenClause;61 58 class WaitForStmt; 62 59 class WaitForClause; 63 class WaitUntilStmt;64 60 class WithStmt; 65 61 class DeclStmt; … … 151 147 class TranslationGlobal; 152 148 153 // For the following types, only use the using type.154 namespace CV {155 struct qualifier_flags;156 using Qualifiers = bitfield<qualifier_flags>;157 149 } 158 namespace Function {159 struct spec_flags;160 using Specs = bitfield<spec_flags>;161 }162 namespace Storage {163 struct class_flags;164 using Classes = bitfield<class_flags>;165 }166 namespace Linkage {167 struct spec_flags;168 using Spec = bitfield<spec_flags>;169 }170 171 } -
src/AST/Init.hpp
r24d6572 r34b4268 117 117 ptr<Init> init; 118 118 119 ConstructorInit( 119 ConstructorInit( 120 120 const CodeLocation & loc, const Stmt * ctor, const Stmt * dtor, const Init * init ) 121 121 : Init( loc, MaybeConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {} -
src/AST/Inspect.cpp
r24d6572 r34b4268 10 10 // Created On : Fri Jun 24 13:16:31 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Apr 14 15:09:00 202313 // Update Count : 412 // Last Modified On : Mon Oct 3 11:04:00 2022 13 // Update Count : 3 14 14 // 15 15 … … 168 168 } 169 169 170 bool isUnnamedBitfield( const ast::ObjectDecl * obj ) {171 return obj && obj->name.empty() && obj->bitfieldWidth;172 }173 174 170 } // namespace ast -
src/AST/Inspect.hpp
r24d6572 r34b4268 10 10 // Created On : Fri Jun 24 13:16:31 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Apr 14 15:09:00 202313 // Update Count : 312 // Last Modified On : Thr Sep 22 13:44:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 38 38 const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr ); 39 39 40 /// Returns true if obj's name is the empty string and it has a bitfield width.41 bool isUnnamedBitfield( const ObjectDecl * obj );42 43 40 } -
src/AST/Node.cpp
r24d6572 r34b4268 174 174 template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::weak >; 175 175 template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::strong >; 176 template class ast::ptr_base< ast::WhenClause, ast::Node::ref_type::weak >;177 template class ast::ptr_base< ast::WhenClause, ast::Node::ref_type::strong >;178 176 template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::weak >; 179 177 template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::strong >; 180 178 template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::weak >; 181 179 template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::strong >; 182 template class ast::ptr_base< ast::WaitUntilStmt, ast::Node::ref_type::weak >;183 template class ast::ptr_base< ast::WaitUntilStmt, ast::Node::ref_type::strong >;184 180 template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::weak >; 185 181 template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::strong >; -
src/AST/Node.hpp
r24d6572 r34b4268 19 19 #include <cstddef> // for nullptr_t 20 20 #include <iosfwd> 21 #include <type_traits> // for remove_reference 21 22 22 23 #include "Common/ErrorObjects.h" // for SemanticErrorException … … 35 36 Node(const Node&) : strong_count(0), weak_count(0) {} 36 37 Node(Node&&) : strong_count(0), weak_count(0) {} 37 Node& operator= (const Node&) = delete;38 Node& operator= (Node&&) = delete;38 Node& operator= (const Node&) = delete; 39 Node& operator= (Node&&) = delete; 39 40 virtual ~Node() {} 40 41 -
src/AST/ParseNode.hpp
r24d6572 r34b4268 40 40 template<typename node_t> 41 41 friend node_t * mutate(const node_t * node); 42 template<typename node_t>43 friend node_t * shallowCopy(const node_t * node);44 42 }; 45 43 -
src/AST/Pass.hpp
r24d6572 r34b4268 66 66 // 67 67 // Other Special Members: 68 // | beginScope - A method with no parameters or return value, called each time the69 // visitor enters a block.70 // | endScope - A method with no parameters or return value, called each time the71 // visitor leaves a block.72 68 // | result - Either a method that takes no parameters or a field. If a method (or 73 69 // callable field) get_result calls it, otherwise the value is returned. … … 86 82 { 87 83 // After the pass is constructed, check if it wants the have a pointer to the wrapping visitor 88 type * const * visitor = __pass::visitor( core, 0);89 if ( visitor) {84 type * const * visitor = __pass::visitor(core, 0); 85 if(visitor) { 90 86 *const_cast<type **>( visitor ) = this; 91 87 } … … 98 94 99 95 /// If the core defines a result, call it if possible, otherwise return it. 100 inline auto get_result() -> decltype( __pass:: result::get( core, '0' ) ) {101 return __pass:: result::get( core, '0' );96 inline auto get_result() -> decltype( __pass::get_result( core, '0' ) ) { 97 return __pass::get_result( core, '0' ); 102 98 } 103 99 … … 162 158 const ast::FinallyClause * visit( const ast::FinallyClause * ) override final; 163 159 const ast::Stmt * visit( const ast::SuspendStmt * ) override final; 164 const ast::WhenClause * visit( const ast::WhenClause * ) override final;165 160 const ast::Stmt * visit( const ast::WaitForStmt * ) override final; 166 161 const ast::WaitForClause * visit( const ast::WaitForClause * ) override final; 167 const ast::Stmt * visit( const ast::WaitUntilStmt * ) override final;168 162 const ast::Decl * visit( const ast::WithStmt * ) override final; 169 163 const ast::NullStmt * visit( const ast::NullStmt * ) override final; -
src/AST/Pass.impl.hpp
r24d6572 r34b4268 20 20 #include <unordered_map> 21 21 22 #include "AST/Copy.hpp"23 22 #include "AST/TranslationUnit.hpp" 24 23 #include "AST/TypeSubstitution.hpp" … … 46 45 47 46 #ifdef PEDANTIC_PASS_ASSERT 48 #define __pedantic_pass_assert(...) assert (__VA_ARGS__)47 #define __pedantic_pass_assert(...) assert (__VA_ARGS__) 49 48 #define __pedantic_pass_assertf(...) assertf(__VA_ARGS__) 50 49 #else … … 125 124 return !new_val.empty(); 126 125 } 126 } 127 128 template< typename node_t > 129 template< typename object_t, typename super_t, typename field_t > 130 void __pass::result1< node_t >::apply( object_t * object, field_t super_t::* field ) { 131 object->*field = value; 127 132 } 128 133 … … 228 233 229 234 return {true, compound}; 235 } 236 237 template< template <class...> class container_t > 238 template< typename object_t, typename super_t, typename field_t > 239 void __pass::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) { 240 auto & container = object->*field; 241 __pedantic_pass_assert( container.size() <= values.size() ); 242 243 auto cit = enumerate(container).begin(); 244 245 container_t<ptr<Stmt>> nvals; 246 for (delta & d : values) { 247 if ( d.is_old ) { 248 __pedantic_pass_assert( cit.idx <= d.old_idx ); 249 std::advance( cit, d.old_idx - cit.idx ); 250 nvals.push_back( std::move( (*cit).val) ); 251 } else { 252 nvals.push_back( std::move(d.new_val) ); 253 } 254 } 255 256 container = std::move(nvals); 257 } 258 259 template< template <class...> class container_t > 260 template< template <class...> class incontainer_t > 261 void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Stmt>> * stmts ) { 262 if (!stmts || stmts->empty()) return; 263 264 std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ), 265 [](ast::ptr<ast::Stmt>& stmt) -> delta { 266 return delta( stmt.release(), -1, false ); 267 }); 268 stmts->clear(); 269 differs = true; 270 } 271 272 template< template<class...> class container_t > 273 template< template<class...> class incontainer_t > 274 void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Decl>> * decls ) { 275 if (!decls || decls->empty()) return; 276 277 std::transform(decls->begin(), decls->end(), std::back_inserter( values ), 278 [](ast::ptr<ast::Decl>& decl) -> delta { 279 auto loc = decl->location; 280 auto stmt = new DeclStmt( loc, decl.release() ); 281 return delta( stmt, -1, false ); 282 }); 283 decls->clear(); 284 differs = true; 230 285 } 231 286 … … 297 352 298 353 return new_kids; 354 } 355 356 template< template <class...> class container_t, typename node_t > 357 template< typename object_t, typename super_t, typename field_t > 358 void __pass::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) { 359 auto & container = object->*field; 360 __pedantic_pass_assert( container.size() == values.size() ); 361 362 for(size_t i = 0; i < container.size(); i++) { 363 // Take all the elements that are different in 'values' 364 // and swap them into 'container' 365 if( values[i] != nullptr ) swap(container[i], values[i]); 366 } 367 368 // Now the original containers should still have the unchanged values 369 // but also contain the new values 299 370 } 300 371 … … 765 836 if ( enterScope ) { 766 837 __pass::symtab::enter(core, 0); 838 __pass::scope::enter(core, 0); 767 839 } 768 840 }, [this, leaveScope = !this->atFunctionTop]() { 769 841 if ( leaveScope ) { 770 842 __pass::symtab::leave(core, 0); 843 __pass::scope::leave(core, 0); 771 844 } 772 845 }); … … 994 1067 995 1068 //-------------------------------------------------------------------------- 996 // WhenClause997 template< typename core_t >998 const ast::WhenClause * ast::Pass< core_t >::visit( const ast::WhenClause * node ) {999 VISIT_START( node );1000 1001 if ( __visit_children() ) {1002 maybe_accept( node, &WhenClause::target );1003 maybe_accept( node, &WhenClause::stmt );1004 maybe_accept( node, &WhenClause::when_cond );1005 }1006 1007 VISIT_END( WhenClause, node );1008 }1009 1010 //--------------------------------------------------------------------------1011 1069 // WaitForStmt 1012 1070 template< typename core_t > … … 1033 1091 1034 1092 if ( __visit_children() ) { 1035 maybe_accept( node, &WaitForClause::target );1093 maybe_accept( node, &WaitForClause::target_func ); 1036 1094 maybe_accept( node, &WaitForClause::target_args ); 1037 1095 maybe_accept( node, &WaitForClause::stmt ); 1038 maybe_accept( node, &WaitForClause:: when_cond );1096 maybe_accept( node, &WaitForClause::cond ); 1039 1097 } 1040 1098 1041 1099 VISIT_END( WaitForClause, node ); 1042 }1043 1044 //--------------------------------------------------------------------------1045 // WaitUntilStmt1046 template< typename core_t >1047 const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitUntilStmt * node ) {1048 VISIT_START( node );1049 1050 if ( __visit_children() ) {1051 maybe_accept( node, &WaitUntilStmt::clauses );1052 maybe_accept( node, &WaitUntilStmt::timeout_time );1053 maybe_accept( node, &WaitUntilStmt::timeout_stmt );1054 maybe_accept( node, &WaitUntilStmt::timeout_cond );1055 maybe_accept( node, &WaitUntilStmt::else_stmt );1056 maybe_accept( node, &WaitUntilStmt::else_cond );1057 }1058 1059 VISIT_END( Stmt, node );1060 1100 } 1061 1101 … … 2003 2043 if ( __visit_children() ) { 2004 2044 maybe_accept( node, &TupleType::types ); 2045 maybe_accept( node, &TupleType::members ); 2005 2046 } 2006 2047 … … 2164 2205 } 2165 2206 2166 #undef __pedantic_pass_assertf2167 #undef __pedantic_pass_assert2168 2207 #undef VISIT_START 2169 2208 #undef VISIT_END -
src/AST/Pass.proto.hpp
r24d6572 r34b4268 17 17 // IWYU pragma: private, include "Pass.hpp" 18 18 19 #include "Common/Iterate.hpp"20 19 #include "Common/Stats/Heap.h" 20 21 21 namespace ast { 22 template<typename core_t> class Pass; 23 class TranslationUnit; 24 struct PureVisitor; 25 template<typename node_t> node_t * deepCopy( const node_t * ); 26 } 27 28 #ifdef PEDANTIC_PASS_ASSERT 29 #define __pedantic_pass_assert(...) assert(__VA_ARGS__) 30 #define __pedantic_pass_assertf(...) assertf(__VA_ARGS__) 31 #else 32 #define __pedantic_pass_assert(...) 33 #define __pedantic_pass_assertf(...) 34 #endif 35 36 namespace ast::__pass { 37 38 typedef std::function<void( void * )> cleanup_func_t; 39 typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t; 40 41 // boolean reference that may be null 42 // either refers to a boolean value or is null and returns true 43 class bool_ref { 44 public: 45 bool_ref() = default; 46 ~bool_ref() = default; 47 48 operator bool() { return m_ref ? *m_ref : true; } 49 bool operator=( bool val ) { assert(m_ref); return *m_ref = val; } 50 51 private: 52 53 friend class visit_children_guard; 54 55 bool * set( bool * val ) { 56 bool * prev = m_ref; 57 m_ref = val; 58 return prev; 59 } 60 61 bool * m_ref = nullptr; 62 }; 63 64 // Implementation of the guard value 65 // Created inside the visit scope 66 class guard_value { 67 public: 68 /// Push onto the cleanup 69 guard_value( at_cleanup_t * at_cleanup ) { 70 if( at_cleanup ) { 71 *at_cleanup = [this]( cleanup_func_t && func, void* val ) { 72 push( std::move( func ), val ); 73 }; 74 } 75 } 76 77 ~guard_value() { 78 while( !cleanups.empty() ) { 79 auto& cleanup = cleanups.top(); 80 cleanup.func( cleanup.val ); 81 cleanups.pop(); 82 } 83 } 84 85 void push( cleanup_func_t && func, void* val ) { 86 cleanups.emplace( std::move(func), val ); 87 } 88 89 private: 90 struct cleanup_t { 91 cleanup_func_t func; 92 void * val; 93 94 cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {} 95 }; 96 97 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups; 98 }; 99 100 // Guard structure implementation for whether or not children should be visited 101 class visit_children_guard { 102 public: 103 104 visit_children_guard( bool_ref * ref ) 105 : m_val ( true ) 106 , m_prev( ref ? ref->set( &m_val ) : nullptr ) 107 , m_ref ( ref ) 108 {} 109 110 ~visit_children_guard() { 111 if( m_ref ) { 112 m_ref->set( m_prev ); 113 } 114 } 115 116 operator bool() { return m_val; } 117 118 private: 119 bool m_val; 120 bool * m_prev; 121 bool_ref * m_ref; 122 }; 123 124 /// "Short hand" to check if this is a valid previsit function 125 /// Mostly used to make the static_assert look (and print) prettier 126 template<typename core_t, typename node_t> 127 struct is_valid_previsit { 128 using ret_t = decltype( std::declval<core_t*>()->previsit( std::declval<const node_t *>() ) ); 129 130 static constexpr bool value = std::is_void< ret_t >::value || 131 std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value; 132 }; 133 134 /// The result is a single node. 135 template< typename node_t > 136 struct result1 { 137 bool differs = false; 138 const node_t * value = nullptr; 139 140 template< typename object_t, typename super_t, typename field_t > 141 void apply( object_t * object, field_t super_t::* field ) { 142 object->*field = value; 143 } 144 }; 145 146 /// The result is a container of statements. 147 template< template<class...> class container_t > 148 struct resultNstmt { 149 /// The delta/change on a single node. 150 struct delta { 151 ptr<Stmt> new_val; 152 ssize_t old_idx; 153 bool is_old; 154 155 delta(const Stmt * s, ssize_t i, bool old) : 156 new_val(s), old_idx(i), is_old(old) {} 157 }; 158 159 bool differs = false; 160 container_t< delta > values; 161 162 template< typename object_t, typename super_t, typename field_t > 163 void apply( object_t * object, field_t super_t::* field ) { 164 field_t & container = object->*field; 165 __pedantic_pass_assert( container.size() <= values.size() ); 166 167 auto cit = enumerate(container).begin(); 168 169 container_t<ptr<Stmt>> nvals; 170 for ( delta & d : values ) { 171 if ( d.is_old ) { 172 __pedantic_pass_assert( cit.idx <= d.old_idx ); 173 std::advance( cit, d.old_idx - cit.idx ); 174 nvals.push_back( std::move( (*cit).val ) ); 175 } else { 176 nvals.push_back( std::move( d.new_val ) ); 177 } 178 } 179 180 container = std::move(nvals); 181 } 182 183 template< template<class...> class incontainer_t > 184 void take_all( incontainer_t<ptr<Stmt>> * stmts ) { 185 if ( !stmts || stmts->empty() ) return; 186 187 std::transform( stmts->begin(), stmts->end(), std::back_inserter( values ), 188 [](ast::ptr<ast::Stmt>& stmt) -> delta { 189 return delta( stmt.release(), -1, false ); 190 }); 191 stmts->clear(); 192 differs = true; 193 } 194 195 template< template<class...> class incontainer_t > 196 void take_all( incontainer_t<ptr<Decl>> * decls ) { 197 if ( !decls || decls->empty() ) return; 198 199 std::transform( decls->begin(), decls->end(), std::back_inserter( values ), 200 [](ast::ptr<ast::Decl>& decl) -> delta { 201 ast::Decl const * d = decl.release(); 202 return delta( new DeclStmt( d->location, d ), -1, false ); 203 }); 204 decls->clear(); 205 differs = true; 206 } 207 }; 208 209 /// The result is a container of nodes. 210 template< template<class...> class container_t, typename node_t > 211 struct resultN { 212 bool differs = false; 213 container_t<ptr<node_t>> values; 214 215 template< typename object_t, typename super_t, typename field_t > 216 void apply( object_t * object, field_t super_t::* field ) { 217 field_t & container = object->*field; 218 __pedantic_pass_assert( container.size() == values.size() ); 219 220 for ( size_t i = 0; i < container.size(); ++i ) { 221 // Take all the elements that are different in 'values' 222 // and swap them into 'container' 223 if ( values[i] != nullptr ) swap(container[i], values[i]); 224 } 225 // Now the original containers should still have the unchanged values 226 // but also contain the new values. 227 } 228 }; 229 230 /// Used by previsit implementation 231 /// We need to reassign the result to 'node', unless the function 232 /// returns void, then we just leave 'node' unchanged 233 template<bool is_void> 234 struct __assign; 235 236 template<> 237 struct __assign<true> { 22 template<typename core_t> 23 class Pass; 24 25 class TranslationUnit; 26 27 struct PureVisitor; 28 29 template<typename node_t> 30 node_t * deepCopy( const node_t * localRoot ); 31 32 namespace __pass { 33 typedef std::function<void( void * )> cleanup_func_t; 34 typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t; 35 36 37 // boolean reference that may be null 38 // either refers to a boolean value or is null and returns true 39 class bool_ref { 40 public: 41 bool_ref() = default; 42 ~bool_ref() = default; 43 44 operator bool() { return m_ref ? *m_ref : true; } 45 bool operator=( bool val ) { assert(m_ref); return *m_ref = val; } 46 47 private: 48 49 friend class visit_children_guard; 50 51 bool * set( bool * val ) { 52 bool * prev = m_ref; 53 m_ref = val; 54 return prev; 55 } 56 57 bool * m_ref = nullptr; 58 }; 59 60 // Implementation of the guard value 61 // Created inside the visit scope 62 class guard_value { 63 public: 64 /// Push onto the cleanup 65 guard_value( at_cleanup_t * at_cleanup ) { 66 if( at_cleanup ) { 67 *at_cleanup = [this]( cleanup_func_t && func, void* val ) { 68 push( std::move( func ), val ); 69 }; 70 } 71 } 72 73 ~guard_value() { 74 while( !cleanups.empty() ) { 75 auto& cleanup = cleanups.top(); 76 cleanup.func( cleanup.val ); 77 cleanups.pop(); 78 } 79 } 80 81 void push( cleanup_func_t && func, void* val ) { 82 cleanups.emplace( std::move(func), val ); 83 } 84 85 private: 86 struct cleanup_t { 87 cleanup_func_t func; 88 void * val; 89 90 cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {} 91 }; 92 93 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups; 94 }; 95 96 // Guard structure implementation for whether or not children should be visited 97 class visit_children_guard { 98 public: 99 100 visit_children_guard( bool_ref * ref ) 101 : m_val ( true ) 102 , m_prev( ref ? ref->set( &m_val ) : nullptr ) 103 , m_ref ( ref ) 104 {} 105 106 ~visit_children_guard() { 107 if( m_ref ) { 108 m_ref->set( m_prev ); 109 } 110 } 111 112 operator bool() { return m_val; } 113 114 private: 115 bool m_val; 116 bool * m_prev; 117 bool_ref * m_ref; 118 }; 119 120 /// "Short hand" to check if this is a valid previsit function 121 /// Mostly used to make the static_assert look (and print) prettier 238 122 template<typename core_t, typename node_t> 239 static inline void result( core_t & core, const node_t * & node ) { 240 core.previsit( node ); 241 } 242 }; 243 244 template<> 245 struct __assign<false> { 123 struct is_valid_previsit { 124 using ret_t = decltype( std::declval<core_t*>()->previsit( std::declval<const node_t *>() ) ); 125 126 static constexpr bool value = std::is_void< ret_t >::value || 127 std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value; 128 }; 129 130 /// The result is a single node. 131 template< typename node_t > 132 struct result1 { 133 bool differs = false; 134 const node_t * value = nullptr; 135 136 template< typename object_t, typename super_t, typename field_t > 137 void apply( object_t *, field_t super_t::* field ); 138 }; 139 140 /// The result is a container of statements. 141 template< template<class...> class container_t > 142 struct resultNstmt { 143 /// The delta/change on a single node. 144 struct delta { 145 ptr<Stmt> new_val; 146 ssize_t old_idx; 147 bool is_old; 148 149 delta(const Stmt * s, ssize_t i, bool old) : 150 new_val(s), old_idx(i), is_old(old) {} 151 }; 152 153 bool differs = false; 154 container_t< delta > values; 155 156 template< typename object_t, typename super_t, typename field_t > 157 void apply( object_t *, field_t super_t::* field ); 158 159 template< template<class...> class incontainer_t > 160 void take_all( incontainer_t<ptr<Stmt>> * stmts ); 161 162 template< template<class...> class incontainer_t > 163 void take_all( incontainer_t<ptr<Decl>> * decls ); 164 }; 165 166 /// The result is a container of nodes. 167 template< template<class...> class container_t, typename node_t > 168 struct resultN { 169 bool differs = false; 170 container_t<ptr<node_t>> values; 171 172 template< typename object_t, typename super_t, typename field_t > 173 void apply( object_t *, field_t super_t::* field ); 174 }; 175 176 /// Used by previsit implementation 177 /// We need to reassign the result to 'node', unless the function 178 /// returns void, then we just leave 'node' unchanged 179 template<bool is_void> 180 struct __assign; 181 182 template<> 183 struct __assign<true> { 184 template<typename core_t, typename node_t> 185 static inline void result( core_t & core, const node_t * & node ) { 186 core.previsit( node ); 187 } 188 }; 189 190 template<> 191 struct __assign<false> { 192 template<typename core_t, typename node_t> 193 static inline void result( core_t & core, const node_t * & node ) { 194 node = core.previsit( node ); 195 assertf(node, "Previsit must not return NULL"); 196 } 197 }; 198 199 /// Used by postvisit implementation 200 /// We need to return the result unless the function 201 /// returns void, then we just return the original node 202 template<bool is_void> 203 struct __return; 204 205 template<> 206 struct __return<true> { 207 template<typename core_t, typename node_t> 208 static inline const node_t * result( core_t & core, const node_t * & node ) { 209 core.postvisit( node ); 210 return node; 211 } 212 }; 213 214 template<> 215 struct __return<false> { 216 template<typename core_t, typename node_t> 217 static inline auto result( core_t & core, const node_t * & node ) { 218 return core.postvisit( node ); 219 } 220 }; 221 222 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 223 // Deep magic (a.k.a template meta programming) to make the templated visitor work 224 // Basically the goal is to make 2 previsit 225 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 226 // 'pass.previsit( node )' that compiles will be used for that node for that type 227 // This requires that this option only compile for passes that actually define an appropriate visit. 228 // SFINAE will make sure the compilation errors in this function don't halt the build. 229 // See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE 230 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing. 231 // This is needed only to eliminate the need for passes to specify any kind of handlers. 232 // The second implementation only works because it has a lower priority. This is due to the bogus last parameter. 233 // The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0 234 // the first implementation takes priority in regards to overloading. 235 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 236 // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call 246 237 template<typename core_t, typename node_t> 247 static inline void result( core_t & core, const node_t * & node ) { 248 node = core.previsit( node ); 249 assertf(node, "Previsit must not return NULL"); 250 } 251 }; 252 253 /// Used by postvisit implementation 254 /// We need to return the result unless the function 255 /// returns void, then we just return the original node 256 template<bool is_void> 257 struct __return; 258 259 template<> 260 struct __return<true> { 238 static inline auto previsit( core_t & core, const node_t * & node, int ) -> decltype( core.previsit( node ), void() ) { 239 static_assert( 240 is_valid_previsit<core_t, node_t>::value, 241 "Previsit may not change the type of the node. It must return its paremeter or void." 242 ); 243 244 __assign< 245 std::is_void< 246 decltype( core.previsit( node ) ) 247 >::value 248 >::result( core, node ); 249 } 250 261 251 template<typename core_t, typename node_t> 262 static inline const node_t * result( core_t & core, const node_t * & node ) { 263 core.postvisit( node ); 264 return node; 265 } 266 }; 267 268 template<> 269 struct __return<false> { 252 static inline auto previsit( core_t &, const node_t *, long ) {} 253 254 // PostVisit : never mutates the passed pointer but may return a different node 270 255 template<typename core_t, typename node_t> 271 static inline auto result( core_t & core, const node_t * & node ) { 272 return core.postvisit( node ); 273 } 274 }; 275 276 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 277 // Deep magic (a.k.a template meta programming) to make the templated visitor work 278 // Basically the goal is to make 2 previsit 279 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 280 // 'pass.previsit( node )' that compiles will be used for that node for that type 281 // This requires that this option only compile for passes that actually define an appropriate visit. 282 // SFINAE will make sure the compilation errors in this function don't halt the build. 283 // See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE 284 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing. 285 // This is needed only to eliminate the need for passes to specify any kind of handlers. 286 // The second implementation only works because it has a lower priority. This is due to the bogus last parameter. 287 // The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0 288 // the first implementation takes priority in regards to overloading. 289 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 290 // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call 291 template<typename core_t, typename node_t> 292 static inline auto previsit( core_t & core, const node_t * & node, int ) -> decltype( core.previsit( node ), void() ) { 293 static_assert( 294 is_valid_previsit<core_t, node_t>::value, 295 "Previsit may not change the type of the node. It must return its paremeter or void." 296 ); 297 298 __assign< 299 std::is_void< 300 decltype( core.previsit( node ) ) 301 >::value 302 >::result( core, node ); 303 } 304 305 template<typename core_t, typename node_t> 306 static inline auto previsit( core_t &, const node_t *, long ) {} 307 308 // PostVisit : never mutates the passed pointer but may return a different node 309 template<typename core_t, typename node_t> 310 static inline auto postvisit( core_t & core, const node_t * node, int ) -> 311 decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) ) 312 { 313 return __return< 314 std::is_void< 315 decltype( core.postvisit( node ) ) 316 >::value 317 >::result( core, node ); 318 } 319 320 template<typename core_t, typename node_t> 321 static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; } 322 323 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 324 // Deep magic (a.k.a template meta programming) continued 325 // To make the templated visitor be more expressive, we allow 'accessories' : classes/structs the implementation can inherit 326 // from in order to get extra functionallity for example 327 // class ErrorChecker : WithShortCircuiting { ... }; 328 // Pass<ErrorChecker> checker; 329 // this would define a pass that uses the templated visitor with the additionnal feature that it has short circuiting 330 // Note that in all cases the accessories are not required but guarantee the requirements of the feature is matched 331 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 332 // For several accessories, the feature is enabled by detecting that a specific field is present 333 // Use a macro the encapsulate the logic of detecting a particular field 334 // The type is not strictly enforced but does match the accessory 335 #define FIELD_PTR( name, default_type ) \ 336 template< typename core_t > \ 337 static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \ 338 \ 339 template< typename core_t > \ 340 static inline default_type * name( core_t &, long ) { return nullptr; } 341 342 // List of fields and their expected types 343 FIELD_PTR( typeSubs, const ast::TypeSubstitution * ) 344 FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > ) 345 FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > ) 346 FIELD_PTR( declsToAddBefore, std::list< ast::ptr< ast::Decl > > ) 347 FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > ) 348 FIELD_PTR( visit_children, __pass::bool_ref ) 349 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 350 FIELD_PTR( visitor, ast::Pass<core_t> * const ) 351 352 // Remove the macro to make sure we don't clash 353 #undef FIELD_PTR 354 355 template< typename core_t > 356 static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) { 357 // Stats::Heap::stacktrace_push(core_t::traceId); 358 } 359 360 template< typename core_t > 361 static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) { 362 // Stats::Heap::stacktrace_pop(); 363 } 364 365 template< typename core_t > 366 static void beginTrace(core_t &, long) {} 367 368 template< typename core_t > 369 static void endTrace(core_t &, long) {} 370 371 // Allows visitor to handle an error on top-level declarations, and possibly suppress the error. 372 // If on_error() returns false, the error will be ignored. By default, it returns true. 373 374 template< typename core_t > 375 static bool on_error (core_t &, ptr<Decl> &, long) { return true; } 376 377 template< typename core_t > 378 static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) { 379 return core.on_error(decl); 380 } 381 382 template< typename core_t, typename node_t > 383 static auto make_location_guard( core_t & core, node_t * node, int ) 384 -> decltype( node->location, ValueGuardPtr<const CodeLocation *>( &core.location ) ) { 385 ValueGuardPtr<const CodeLocation *> guard( &core.location ); 386 core.location = &node->location; 387 return guard; 388 } 389 390 template< typename core_t, typename node_t > 391 static auto make_location_guard( core_t &, node_t *, long ) -> int { 392 return 0; 393 } 394 395 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 396 // All passes which have such functions are assumed desire this behaviour 397 // detect it using the same strategy 398 namespace scope { 256 static inline auto postvisit( core_t & core, const node_t * node, int ) -> 257 decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) ) 258 { 259 return __return< 260 std::is_void< 261 decltype( core.postvisit( node ) ) 262 >::value 263 >::result( core, node ); 264 } 265 266 template<typename core_t, typename node_t> 267 static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; } 268 269 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 270 // Deep magic (a.k.a template meta programming) continued 271 // To make the templated visitor be more expressive, we allow 'accessories' : classes/structs the implementation can inherit 272 // from in order to get extra functionallity for example 273 // class ErrorChecker : WithShortCircuiting { ... }; 274 // Pass<ErrorChecker> checker; 275 // this would define a pass that uses the templated visitor with the additionnal feature that it has short circuiting 276 // Note that in all cases the accessories are not required but guarantee the requirements of the feature is matched 277 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 278 // For several accessories, the feature is enabled by detecting that a specific field is present 279 // Use a macro the encapsulate the logic of detecting a particular field 280 // The type is not strictly enforced but does match the accessory 281 #define FIELD_PTR( name, default_type ) \ 282 template< typename core_t > \ 283 static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \ 284 \ 285 template< typename core_t > \ 286 static inline default_type * name( core_t &, long ) { return nullptr; } 287 288 // List of fields and their expected types 289 FIELD_PTR( typeSubs, const ast::TypeSubstitution * ) 290 FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > ) 291 FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > ) 292 FIELD_PTR( declsToAddBefore, std::list< ast::ptr< ast::Decl > > ) 293 FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > ) 294 FIELD_PTR( visit_children, __pass::bool_ref ) 295 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 296 FIELD_PTR( visitor, ast::Pass<core_t> * const ) 297 298 // Remove the macro to make sure we don't clash 299 #undef FIELD_PTR 300 301 template< typename core_t > 302 static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) { 303 // Stats::Heap::stacktrace_push(core_t::traceId); 304 } 305 306 template< typename core_t > 307 static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) { 308 // Stats::Heap::stacktrace_pop(); 309 } 310 311 template< typename core_t > 312 static void beginTrace(core_t &, long) {} 313 314 template< typename core_t > 315 static void endTrace(core_t &, long) {} 316 317 // Allows visitor to handle an error on top-level declarations, and possibly suppress the error. 318 // If onError() returns false, the error will be ignored. By default, it returns true. 319 320 template< typename core_t > 321 static bool on_error (core_t &, ptr<Decl> &, long) { return true; } 322 323 template< typename core_t > 324 static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) { 325 return core.on_error(decl); 326 } 327 328 template< typename core_t, typename node_t > 329 static auto make_location_guard( core_t & core, node_t * node, int ) 330 -> decltype( node->location, ValueGuardPtr<const CodeLocation *>( &core.location ) ) { 331 ValueGuardPtr<const CodeLocation *> guard( &core.location ); 332 core.location = &node->location; 333 return guard; 334 } 335 336 template< typename core_t, typename node_t > 337 static auto make_location_guard( core_t &, node_t *, long ) -> int { 338 return 0; 339 } 340 341 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 342 // All passes which have such functions are assumed desire this behaviour 343 // detect it using the same strategy 344 namespace scope { 345 template<typename core_t> 346 static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) { 347 core.beginScope(); 348 } 349 350 template<typename core_t> 351 static inline void enter( core_t &, long ) {} 352 353 template<typename core_t> 354 static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) { 355 core.endScope(); 356 } 357 358 template<typename core_t> 359 static inline void leave( core_t &, long ) {} 360 } // namespace scope 361 362 // Certain passes desire an up to date symbol table automatically 363 // detect the presence of a member name `symtab` and call all the members appropriately 364 namespace symtab { 365 // Some simple scoping rules 366 template<typename core_t> 367 static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) { 368 core.symtab.enterScope(); 369 } 370 371 template<typename core_t> 372 static inline auto enter( core_t &, long ) {} 373 374 template<typename core_t> 375 static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) { 376 core.symtab.leaveScope(); 377 } 378 379 template<typename core_t> 380 static inline auto leave( core_t &, long ) {} 381 382 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments 383 // Create macro to condense these common patterns 384 #define SYMTAB_FUNC1( func, type ) \ 385 template<typename core_t> \ 386 static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\ 387 core.symtab.func( arg ); \ 388 } \ 389 \ 390 template<typename core_t> \ 391 static inline void func( core_t &, long, type ) {} 392 393 #define SYMTAB_FUNC2( func, type1, type2 ) \ 394 template<typename core_t> \ 395 static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\ 396 core.symtab.func( arg1, arg2 ); \ 397 } \ 398 \ 399 template<typename core_t> \ 400 static inline void func( core_t &, long, type1, type2 ) {} 401 402 SYMTAB_FUNC1( addId , const DeclWithType * ); 403 SYMTAB_FUNC1( addType , const NamedTypeDecl * ); 404 SYMTAB_FUNC1( addStruct , const StructDecl * ); 405 SYMTAB_FUNC1( addEnum , const EnumDecl * ); 406 SYMTAB_FUNC1( addUnion , const UnionDecl * ); 407 SYMTAB_FUNC1( addTrait , const TraitDecl * ); 408 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Decl * ); 409 410 // A few extra functions have more complicated behaviour, they are hand written 411 template<typename core_t> 412 static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) { 413 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 414 for ( const auto & param : decl->params ) { 415 fwd->params.push_back( deepCopy( param.get() ) ); 416 } 417 core.symtab.addStruct( fwd ); 418 } 419 420 template<typename core_t> 421 static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {} 422 423 template<typename core_t> 424 static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) { 425 ast::UnionDecl * fwd = new ast::UnionDecl( decl->location, decl->name ); 426 for ( const auto & param : decl->params ) { 427 fwd->params.push_back( deepCopy( param.get() ) ); 428 } 429 core.symtab.addUnion( fwd ); 430 } 431 432 template<typename core_t> 433 static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {} 434 435 template<typename core_t> 436 static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) { 437 if ( ! core.symtab.lookupStruct( str ) ) { 438 core.symtab.addStruct( str ); 439 } 440 } 441 442 template<typename core_t> 443 static inline void addStruct( core_t &, long, const std::string & ) {} 444 445 template<typename core_t> 446 static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) { 447 if ( ! core.symtab.lookupUnion( str ) ) { 448 core.symtab.addUnion( str ); 449 } 450 } 451 452 template<typename core_t> 453 static inline void addUnion( core_t &, long, const std::string & ) {} 454 455 #undef SYMTAB_FUNC1 456 #undef SYMTAB_FUNC2 457 } // namespace symtab 458 459 // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType. 460 // Detect the presence of a member name `subs` and call all members appropriately 461 namespace forall { 462 // Some simple scoping rules 463 template<typename core_t> 464 static inline auto enter( core_t & core, int, const ast::FunctionType * type ) 465 -> decltype( core.subs, void() ) { 466 if ( ! type->forall.empty() ) core.subs.beginScope(); 467 } 468 469 template<typename core_t> 470 static inline auto enter( core_t &, long, const ast::FunctionType * ) {} 471 472 template<typename core_t> 473 static inline auto leave( core_t & core, int, const ast::FunctionType * type ) 474 -> decltype( core.subs, void() ) { 475 if ( ! type->forall.empty() ) { core.subs.endScope(); } 476 } 477 478 template<typename core_t> 479 static inline auto leave( core_t &, long, const ast::FunctionType * ) {} 480 481 // Replaces a TypeInstType's base TypeDecl according to the table 482 template<typename core_t> 483 static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst ) 484 -> decltype( core.subs, void() ) { 485 inst = ast::mutate_field( 486 inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) ); 487 } 488 489 template<typename core_t> 490 static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {} 491 492 } // namespace forall 493 494 // For passes that need access to the global context. Sreaches `translationUnit` 495 namespace translation_unit { 496 template<typename core_t> 497 static inline auto get_cptr( core_t & core, int ) 498 -> decltype( &core.translationUnit ) { 499 return &core.translationUnit; 500 } 501 502 template<typename core_t> 503 static inline const TranslationUnit ** get_cptr( core_t &, long ) { 504 return nullptr; 505 } 506 } 507 399 508 template<typename core_t> 400 static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) {401 core.beginScope();509 static inline auto get_result( core_t & core, char ) -> decltype( core.result() ) { 510 return core.result(); 402 511 } 403 512 404 513 template<typename core_t> 405 static inline void enter( core_t &, long ) {} 514 static inline auto get_result( core_t & core, int ) -> decltype( core.result ) { 515 return core.result; 516 } 406 517 407 518 template<typename core_t> 408 static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) { 409 core.endScope(); 410 } 411 412 template<typename core_t> 413 static inline void leave( core_t &, long ) {} 414 } // namespace scope 415 416 // Certain passes desire an up to date symbol table automatically 417 // detect the presence of a member name `symtab` and call all the members appropriately 418 namespace symtab { 419 // Some simple scoping rules 420 template<typename core_t> 421 static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) { 422 core.symtab.enterScope(); 423 } 424 425 template<typename core_t> 426 static inline auto enter( core_t &, long ) {} 427 428 template<typename core_t> 429 static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) { 430 core.symtab.leaveScope(); 431 } 432 433 template<typename core_t> 434 static inline auto leave( core_t &, long ) {} 435 436 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments 437 // Create macro to condense these common patterns 438 #define SYMTAB_FUNC1( func, type ) \ 439 template<typename core_t> \ 440 static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\ 441 core.symtab.func( arg ); \ 442 } \ 443 \ 444 template<typename core_t> \ 445 static inline void func( core_t &, long, type ) {} 446 447 #define SYMTAB_FUNC2( func, type1, type2 ) \ 448 template<typename core_t> \ 449 static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\ 450 core.symtab.func( arg1, arg2 ); \ 451 } \ 452 \ 453 template<typename core_t> \ 454 static inline void func( core_t &, long, type1, type2 ) {} 455 456 SYMTAB_FUNC1( addId , const DeclWithType * ); 457 SYMTAB_FUNC1( addType , const NamedTypeDecl * ); 458 SYMTAB_FUNC1( addStruct , const StructDecl * ); 459 SYMTAB_FUNC1( addEnum , const EnumDecl * ); 460 SYMTAB_FUNC1( addUnion , const UnionDecl * ); 461 SYMTAB_FUNC1( addTrait , const TraitDecl * ); 462 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Decl * ); 463 464 // A few extra functions have more complicated behaviour, they are hand written 465 template<typename core_t> 466 static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) { 467 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 468 for ( const auto & param : decl->params ) { 469 fwd->params.push_back( deepCopy( param.get() ) ); 470 } 471 core.symtab.addStruct( fwd ); 472 } 473 474 template<typename core_t> 475 static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {} 476 477 template<typename core_t> 478 static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) { 479 ast::UnionDecl * fwd = new ast::UnionDecl( decl->location, decl->name ); 480 for ( const auto & param : decl->params ) { 481 fwd->params.push_back( deepCopy( param.get() ) ); 482 } 483 core.symtab.addUnion( fwd ); 484 } 485 486 template<typename core_t> 487 static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {} 488 489 template<typename core_t> 490 static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) { 491 if ( ! core.symtab.lookupStruct( str ) ) { 492 core.symtab.addStruct( str ); 493 } 494 } 495 496 template<typename core_t> 497 static inline void addStruct( core_t &, long, const std::string & ) {} 498 499 template<typename core_t> 500 static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) { 501 if ( ! core.symtab.lookupUnion( str ) ) { 502 core.symtab.addUnion( str ); 503 } 504 } 505 506 template<typename core_t> 507 static inline void addUnion( core_t &, long, const std::string & ) {} 508 509 #undef SYMTAB_FUNC1 510 #undef SYMTAB_FUNC2 511 } // namespace symtab 512 513 // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType. 514 // Detect the presence of a member name `subs` and call all members appropriately 515 namespace forall { 516 // Some simple scoping rules 517 template<typename core_t> 518 static inline auto enter( core_t & core, int, const ast::FunctionType * type ) 519 -> decltype( core.subs, void() ) { 520 if ( ! type->forall.empty() ) core.subs.beginScope(); 521 } 522 523 template<typename core_t> 524 static inline auto enter( core_t &, long, const ast::FunctionType * ) {} 525 526 template<typename core_t> 527 static inline auto leave( core_t & core, int, const ast::FunctionType * type ) 528 -> decltype( core.subs, void() ) { 529 if ( ! type->forall.empty() ) { core.subs.endScope(); } 530 } 531 532 template<typename core_t> 533 static inline auto leave( core_t &, long, const ast::FunctionType * ) {} 534 535 // Replaces a TypeInstType's base TypeDecl according to the table 536 template<typename core_t> 537 static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst ) 538 -> decltype( core.subs, void() ) { 539 inst = ast::mutate_field( 540 inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) ); 541 } 542 543 template<typename core_t> 544 static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {} 545 } // namespace forall 546 547 // For passes that need access to the global context. Searches `translationUnit` 548 namespace translation_unit { 549 template<typename core_t> 550 static inline auto get_cptr( core_t & core, int ) 551 -> decltype( &core.translationUnit ) { 552 return &core.translationUnit; 553 } 554 555 template<typename core_t> 556 static inline const TranslationUnit ** get_cptr( core_t &, long ) { 557 return nullptr; 558 } 559 } 560 561 // For passes, usually utility passes, that have a result. 562 namespace result { 563 template<typename core_t> 564 static inline auto get( core_t & core, char ) -> decltype( core.result() ) { 565 return core.result(); 566 } 567 568 template<typename core_t> 569 static inline auto get( core_t & core, int ) -> decltype( core.result ) { 570 return core.result; 571 } 572 573 template<typename core_t> 574 static inline void get( core_t &, long ) {} 575 } 576 577 } // namespace ast::__pass 578 579 #undef __pedantic_pass_assertf 580 #undef __pedantic_pass_assert 519 static inline void get_result( core_t &, long ) {} 520 } // namespace __pass 521 } // namespace ast -
src/AST/Print.cpp
r24d6572 r34b4268 16 16 #include "Print.hpp" 17 17 18 #include "Attribute.hpp"19 18 #include "Decl.hpp" 20 19 #include "Expr.hpp" 21 #include "Init.hpp"22 20 #include "Stmt.hpp" 23 21 #include "Type.hpp" 24 22 #include "TypeSubstitution.hpp" 25 23 #include "CompilationState.h" 26 #include "Common/Iterate.hpp" 24 25 #include "Common/utility.h" // for group_iterate 27 26 28 27 using namespace std; … … 30 29 namespace ast { 31 30 32 namespace { 33 34 template<typename C, typename... T> 35 constexpr array<C, sizeof...(T)> make_array( T&&... values ) { 36 return array<C, sizeof...(T)>{ std::forward<T>( values )... }; 37 } 38 39 namespace Names { 40 static constexpr auto FuncSpecifiers = make_array<const char*>( 41 "inline", "_Noreturn", "fortran" 42 ); 43 44 static constexpr auto StorageClasses = make_array<const char*>( 45 "extern", "static", "auto", "register", "__thread", "_Thread_local" 46 ); 47 48 static constexpr auto Qualifiers = make_array<const char*>( 49 "const", "restrict", "volatile", "mutex", "_Atomic" 50 ); 51 } 52 53 template<typename bits_t, size_t N> 54 void print( ostream & os, const bits_t & bits, 55 const array<const char *, N> & names ) { 56 if ( !bits.any() ) return; 57 for ( size_t i = 0 ; i < N ; i += 1 ) { 58 if ( bits[i] ) { 59 os << names[i] << ' '; 60 } 61 } 31 template <typename C, typename... T> 32 constexpr array<C,sizeof...(T)> make_array(T&&... values) 33 { 34 return array<C,sizeof...(T)>{ 35 std::forward<T>(values)... 36 }; 62 37 } 63 38 … … 105 80 static const char* Names[]; 106 81 82 struct Names { 83 static constexpr auto FuncSpecifiers = make_array<const char*>( 84 "inline", "_Noreturn", "fortran" 85 ); 86 87 static constexpr auto StorageClasses = make_array<const char*>( 88 "extern", "static", "auto", "register", "__thread", "_Thread_local" 89 ); 90 91 static constexpr auto Qualifiers = make_array<const char*>( 92 "const", "restrict", "volatile", "mutex", "_Atomic" 93 ); 94 }; 95 96 template<typename storage_t, size_t N> 97 void print(const storage_t & storage, const array<const char *, N> & Names ) { 98 if ( storage.any() ) { 99 for ( size_t i = 0; i < Names.size(); i += 1 ) { 100 if ( storage[i] ) { 101 os << Names[i] << ' '; 102 } 103 } 104 } 105 } 106 107 void print( const ast::Function::Specs & specs ) { 108 print(specs, Names::FuncSpecifiers); 109 } 110 111 void print( const ast::Storage::Classes & storage ) { 112 print(storage, Names::StorageClasses); 113 } 114 115 void print( const ast::CV::Qualifiers & qualifiers ) { 116 print(qualifiers, Names::Qualifiers); 117 } 118 107 119 void print( const std::vector<ast::Label> & labels ) { 108 120 if ( labels.empty() ) return; … … 209 221 } 210 222 211 void print( const ast::WaitStmt * node ) {212 if ( node->timeout_time ) {213 os << indent-1 << "timeout of:" << endl;214 node->timeout_time->accept( *this );215 216 if ( node->timeout_stmt ) {217 os << indent-1 << "... with statment:" << endl;218 node->timeout_stmt->accept( *this );219 }220 221 if ( node->timeout_cond ) {222 os << indent-1 << "... with condition:" << endl;223 node->timeout_cond->accept( *this );224 }225 }226 227 if ( node->else_stmt ) {228 os << indent-1 << "else:" << endl;229 node->else_stmt->accept( *this );230 231 if ( node->else_cond ) {232 os << indent-1 << "... with condition:" << endl;233 node->else_cond->accept( *this );234 }235 }236 }237 238 223 void preprint( const ast::NamedTypeDecl * node ) { 239 224 if ( ! node->name.empty() ) { … … 245 230 } 246 231 247 ast::print( os,node->storage );232 print( node->storage ); 248 233 os << node->typeString(); 249 234 … … 287 272 288 273 void preprint( const ast::Type * node ) { 289 ast::print( os,node->qualifiers );274 print( node->qualifiers ); 290 275 } 291 276 … … 293 278 print( node->forall ); 294 279 print( node->assertions ); 295 ast::print( os,node->qualifiers );280 print( node->qualifiers ); 296 281 } 297 282 298 283 void preprint( const ast::BaseInstType * node ) { 299 284 print( node->attributes ); 300 ast::print( os,node->qualifiers );285 print( node->qualifiers ); 301 286 } 302 287 … … 309 294 } 310 295 311 ast::print( os,node->storage );296 print( node->storage ); 312 297 313 298 if ( node->type ) { … … 353 338 if ( ! short_mode ) printAll( node->attributes ); 354 339 355 ast::print( os, node->storage ); 356 ast::print( os, node->funcSpec ); 340 print( node->storage ); 341 print( node->funcSpec ); 342 343 357 344 358 345 if ( node->type && node->isTypeFixed ) { … … 397 384 --indent; 398 385 } 399 }400 401 if ( ! node->withExprs.empty() ) {402 // Not with a clause, but the 'with clause'.403 ++indent;404 os << " with clause" << endl << indent;405 printAll( node->withExprs );406 --indent;407 386 } 408 387 … … 767 746 virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final { 768 747 os << "Suspend Statement"; 769 switch (node-> kind) {770 case ast::SuspendStmt::None : os << " with implicit target"; break;771 case ast::SuspendStmt::Generator: os << " for generator"; break;772 case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;748 switch (node->type) { 749 case ast::SuspendStmt::None : os << " with implicit target"; break; 750 case ast::SuspendStmt::Generator: os << " for generator"; break; 751 case ast::SuspendStmt::Coroutine: os << " for coroutine"; break; 773 752 } 774 753 os << endl; … … 780 759 } 781 760 ++indent; 782 783 return node;784 }785 786 virtual const ast::WhenClause * visit( const ast::WhenClause * node ) override final {787 os << indent-1 << "target: ";788 safe_print( node->target );789 790 if ( node->stmt ) {791 os << indent-1 << "... with statment:" << endl;792 node->stmt->accept( *this );793 }794 795 if ( node->when_cond ) {796 os << indent-1 << "... with when condition:" << endl;797 node->when_cond->accept( *this );798 }799 761 800 762 return node; … … 838 800 virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final { 839 801 os << indent-1 << "target function: "; 840 safe_print( node->target );802 safe_print( node->target_func ); 841 803 842 804 if ( !node->target_args.empty() ) { … … 852 814 } 853 815 854 if ( node-> when_cond ) {816 if ( node->cond ) { 855 817 os << indent-1 << "... with condition:" << endl; 856 node->when_cond->accept( *this ); 857 } 858 859 return node; 860 } 861 862 virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final { 863 os << "Waituntil Statement" << endl; 864 indent += 2; 865 for( const auto & clause : node->clauses ) { 866 clause->accept( *this ); 867 } 868 print(node); // calls print( const ast::WaitStmt * node ) 818 node->cond->accept( *this ); 819 } 820 869 821 return node; 870 822 } … … 1675 1627 }; 1676 1628 1677 } // namespace1678 1679 1629 void print( ostream & os, const ast::Node * node, Indenter indent ) { 1680 1630 Printer printer { os, indent, false }; … … 1687 1637 } 1688 1638 1689 void print( ostream & os, Function::Specs specs ) { 1690 print( os, specs, Names::FuncSpecifiers ); 1639 // Annoyingly these needed to be defined out of line to avoid undefined references. 1640 // The size here needs to be explicit but at least the compiler will produce an error 1641 // if the wrong size is specified 1642 constexpr array<const char*, 3> Printer::Names::FuncSpecifiers; 1643 constexpr array<const char*, 6> Printer::Names::StorageClasses; 1644 constexpr array<const char*, 5> Printer::Names::Qualifiers; 1691 1645 } 1692 1693 void print( ostream & os, Storage::Classes storage ) {1694 print( os, storage, Names::StorageClasses );1695 }1696 1697 void print( ostream & os, CV::Qualifiers qualifiers ) {1698 print( os, qualifiers, Names::Qualifiers );1699 }1700 1701 } // namespace ast -
src/AST/Print.hpp
r24d6572 r34b4268 16 16 #pragma once 17 17 18 #include <iosfwd> 18 #include <iostream> 19 #include <utility> // for forward 19 20 20 #include "AST/ Fwd.hpp"21 #include "AST/Node.hpp" 21 22 #include "Common/Indenter.h" 22 23 23 24 namespace ast { 25 26 class Decl; 24 27 25 28 /// Print a node with the given indenter … … 41 44 } 42 45 43 /// Print each cv-qualifier used in the set, followed by a space.44 void print( std::ostream & os, CV::Qualifiers );45 /// Print each function specifier used in the set, followed by a space.46 void print( std::ostream & os, Function::Specs );47 /// Print each storage class used in the set, followed by a space.48 void print( std::ostream & os, Storage::Classes );49 50 46 } -
src/AST/Stmt.hpp
r24d6572 r34b4268 10 10 // Created On : Wed May 8 13:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Apr 5 10:34:00 202313 // Update Count : 3 712 // Last Modified On : Wed Apr 20 14:34:00 2022 13 // Update Count : 36 14 14 // 15 15 … … 205 205 }; 206 206 207 // A while loop or a do-while loop:208 enum WhileDoKind { While, DoWhile };209 210 207 // While loop: while (...) ... else ... or do ... while (...) else ...; 211 208 class WhileDoStmt final : public Stmt { … … 215 212 ptr<Stmt> else_; 216 213 std::vector<ptr<Stmt>> inits; 217 WhileDoKindisDoWhile;214 bool isDoWhile; 218 215 219 216 WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, 220 const std::vector<ptr<Stmt>> && inits, WhileDoKind isDoWhile = While, const std::vector<Label> && labels = {} )217 const std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, const std::vector<Label> && labels = {} ) 221 218 : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(nullptr), inits(std::move(inits)), isDoWhile(isDoWhile) {} 222 219 223 220 WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, const Stmt * else_, 224 const std::vector<ptr<Stmt>> && inits, WhileDoKind isDoWhile = While, const std::vector<Label> && labels = {} )221 const std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, const std::vector<Label> && labels = {} ) 225 222 : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(else_), inits(std::move(inits)), isDoWhile(isDoWhile) {} 226 223 … … 367 364 public: 368 365 ptr<CompoundStmt> then; 369 enum Kind { None, Coroutine, Generator } kind= None;370 371 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Kind kind, const std::vector<Label> && labels = {} )372 : Stmt(loc, std::move(labels)), then(then), kind(kind) {}366 enum Type { None, Coroutine, Generator } type = None; 367 368 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, const std::vector<Label> && labels = {} ) 369 : Stmt(loc, std::move(labels)), then(then), type(type) {} 373 370 374 371 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } … … 378 375 }; 379 376 380 // Base class of WaitFor/WaitUntil statements381 // form: KEYWORD(...) ... timeout(...) ... else ... 382 class WaitStmt : public Stmt { 383 public: 384 ptr<Expr> timeout_time;377 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ... 378 class WaitForStmt final : public Stmt { 379 public: 380 std::vector<ptr<WaitForClause>> clauses; 381 ptr<Expr> timeout_time; 385 382 ptr<Stmt> timeout_stmt; 386 383 ptr<Expr> timeout_cond; … … 388 385 ptr<Expr> else_cond; 389 386 390 WaitStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )387 WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 391 388 : Stmt(loc, std::move(labels)) {} 392 389 393 private: 394 WaitStmt * clone() const override = 0;395 MUTATE_FRIEND396 }; 397 398 // Base class for WaitFor/WaitUntil clauses 399 // form: when( when_cond ) KEYWORD( target ) stmt 400 class WhenClause : public StmtClause { 401 public: 402 ptr<Expr> target;390 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 391 private: 392 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; } 393 MUTATE_FRIEND 394 }; 395 396 class WaitForClause final : public StmtClause { 397 public: 398 ptr<Expr> target_func; 399 std::vector<ptr<Expr>> target_args; 403 400 ptr<Stmt> stmt; 404 ptr<Expr> when_cond;405 406 W henClause( const CodeLocation & loc )401 ptr<Expr> cond; 402 403 WaitForClause( const CodeLocation & loc ) 407 404 : StmtClause( loc ) {} 408 405 409 const WhenClause * accept( Visitor & v ) const override { return v.visit( this ); }410 private:411 WhenClause * clone() const override { return new WhenClause{ *this }; }412 MUTATE_FRIEND413 };414 415 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...416 class WaitForStmt final : public WaitStmt {417 public:418 std::vector<ptr<WaitForClause>> clauses;419 420 WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )421 : WaitStmt(loc, std::move(labels)) {}422 423 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }424 private:425 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; }426 MUTATE_FRIEND427 };428 429 // Clause in a waitfor statement: waitfor (..., ...) ...430 class WaitForClause final : public WhenClause {431 public:432 std::vector<ptr<Expr>> target_args;433 434 WaitForClause( const CodeLocation & loc )435 : WhenClause( loc ) {}436 437 406 const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); } 438 407 private: 439 408 WaitForClause * clone() const override { return new WaitForClause{ *this }; } 440 MUTATE_FRIEND441 };442 443 // waituntil statement: when (...) waituntil (...) ... timeout(...) ... else ...444 class WaitUntilStmt final : public WaitStmt {445 public:446 // Non-ast node used during compilation to store data needed to generate predicates447 // and set initial status values for clauses448 // Used to create a tree corresponding to the structure of the clauses in a WaitUntil449 struct ClauseNode {450 enum Op { AND, OR, LEFT_OR, LEAF, ELSE, TIMEOUT } op; // operation/type tag451 // LEFT_OR used with TIMEOUT/ELSE to indicate that we ignore right hand side after parsing452 453 ClauseNode * left;454 ClauseNode * right;455 WhenClause * leaf; // only set if this node is a leaf (points into vector of clauses)456 457 bool ambiguousWhen; // used to paint nodes of predicate tree based on when() clauses458 bool whenState; // used to track if when_cond is toggled on or off for generating init values459 bool childOfAnd; // true on leaf nodes that are children of AND, false otherwise460 461 ClauseNode( Op op, ClauseNode * left, ClauseNode * right )462 : op(op), left(left), right(right), leaf(nullptr),463 ambiguousWhen(false), whenState(true), childOfAnd(false) {}464 ClauseNode( Op op, WhenClause * leaf )465 : op(op), left(nullptr), right(nullptr), leaf(leaf),466 ambiguousWhen(false), whenState(true), childOfAnd(false) {}467 ClauseNode( WhenClause * leaf ) : ClauseNode(LEAF, leaf) {}468 469 ~ClauseNode() {470 if ( left ) delete left;471 if ( right ) delete right;472 }473 };474 475 std::vector<ptr<WhenClause>> clauses;476 ClauseNode * predicateTree;477 478 WaitUntilStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )479 : WaitStmt(loc, std::move(labels)) {}480 481 ~WaitUntilStmt() { delete predicateTree; }482 483 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }484 private:485 WaitUntilStmt * clone() const override { return new WaitUntilStmt{ *this }; }486 409 MUTATE_FRIEND 487 410 }; … … 531 454 MUTATE_FRIEND 532 455 }; 533 534 456 } // namespace ast 535 457 -
src/AST/SymbolTable.cpp
r24d6572 r34b4268 18 18 #include <cassert> 19 19 20 #include "Copy.hpp"21 #include <iostream>22 #include <algorithm>23 24 20 #include "Decl.hpp" 25 21 #include "Expr.hpp" 26 22 #include "Inspect.hpp" 27 23 #include "Type.hpp" 28 #include "CodeGen/OperatorTable.h" // for isCtorDtorAssign24 #include "CodeGen/OperatorTable.h" // for isCtorDtorAssign 29 25 #include "Common/SemanticError.h" 30 26 #include "Common/Stats/Counter.h" … … 32 28 #include "InitTweak/InitTweak.h" 33 29 #include "ResolvExpr/Cost.h" 34 #include "ResolvExpr/CandidateFinder.hpp" // for referenceToRvalueConversion 35 #include "ResolvExpr/Unify.h" 30 #include "ResolvExpr/typeops.h" 36 31 #include "SymTab/Mangler.h" 37 32 … … 74 69 if ( baseExpr ) { 75 70 if (baseExpr->env) { 76 Expr * base = deepCopy(baseExpr);71 Expr * base = shallowCopy(baseExpr); 77 72 const TypeSubstitution * subs = baseExpr->env; 78 73 base->env = nullptr; … … 198 193 out.push_back(decl.second); 199 194 } 200 201 // std::cerr << otypeKey << ' ' << out.size() << std::endl;202 195 } 203 196 … … 266 259 void SymbolTable::addId( const DeclWithType * decl, const Expr * baseExpr ) { 267 260 // default handling of conflicts is to raise an error 268 addId Common( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );261 addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr ); 269 262 } 270 263 271 264 void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) { 272 265 // default handling of conflicts is to raise an error 273 addId Common( decl, OnConflict::error(), nullptr, deleter );266 addId( decl, OnConflict::error(), nullptr, deleter ); 274 267 } 275 268 … … 283 276 } else { 284 277 // typedef redeclarations are errors only if types are different 285 if ( ! ResolvExpr::typesCompatible( existing->base, added->base ) ) {278 if ( ! ResolvExpr::typesCompatible( existing->base, added->base, SymbolTable{} ) ) { 286 279 SemanticError( added->location, "redeclaration of " + added->name ); 287 280 } … … 648 641 } else if ( existing.id->linkage.is_mangled 649 642 || ResolvExpr::typesCompatible( 650 added->get_type(), existing.id->get_type() ) ) {643 added->get_type(), existing.id->get_type(), SymbolTable{} ) ) { 651 644 652 645 // it is a conflict if one declaration is deleted and the other is not … … 683 676 } 684 677 685 void SymbolTable::addId Common(686 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, 687 const Expr * baseExpr, constDecl * deleter ) {678 void SymbolTable::addId( 679 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 680 const Decl * deleter ) { 688 681 SpecialFunctionKind kind = getSpecialFunctionKind(decl->name); 689 682 if (kind == NUMBER_OF_KINDS) { // not a special decl 690 addId ToTable(decl, decl->name, idTable, handleConflicts, baseExpr, deleter);683 addId(decl, decl->name, idTable, handleConflicts, baseExpr, deleter); 691 684 } 692 685 else { … … 701 694 assertf(false, "special decl with non-function type"); 702 695 } 703 addIdToTable(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter); 704 } 705 } 706 707 void SymbolTable::addIdToTable( 708 const DeclWithType * decl, const std::string & lookupKey, 709 IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts, 710 const Expr * baseExpr, const Decl * deleter ) { 696 addId(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter); 697 } 698 } 699 700 void SymbolTable::addId( 701 const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 702 const Decl * deleter ) { 711 703 ++*stats().add_calls; 712 704 const std::string &name = decl->name; … … 785 777 void SymbolTable::addMembers( 786 778 const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) { 787 for ( const ptr<Decl> &decl : aggr->members ) {788 auto dwt = decl.as<DeclWithType>();789 if ( nullptr == dwt ) continue;790 addIdCommon( dwt, handleConflicts, expr );791 // Inline through unnamed struct/union members.792 if ( "" != dwt->name ) continue;793 const Type * t = dwt->get_type()->stripReferences();794 if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) {795 if ( ! dynamic_cast<const StructInstType *>(rty)796 && ! dynamic_cast<const UnionInstType *>(rty) ) continue;797 ResolvExpr::Cost cost = ResolvExpr::Cost::zero;798 ast::ptr<ast::TypeSubstitution> tmp = expr->env;799 expr = mutate_field(expr, &Expr::env, nullptr);800 const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost ); 801 base = mutate_field(base, &Expr::env, tmp);802 803 addMembers(804 rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts );779 for ( const Decl * decl : aggr->members ) { 780 if ( auto dwt = dynamic_cast< const DeclWithType * >( decl ) ) { 781 addId( dwt, handleConflicts, expr ); 782 if ( dwt->name == "" ) { 783 const Type * t = dwt->get_type()->stripReferences(); 784 if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) { 785 if ( ! dynamic_cast<const StructInstType *>(rty) 786 && ! dynamic_cast<const UnionInstType *>(rty) ) continue; 787 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; 788 ast::ptr<ast::TypeSubstitution> tmp = expr->env; 789 expr = mutate_field(expr, &Expr::env, nullptr); 790 const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost ); 791 base = mutate_field(base, &Expr::env, tmp); 792 793 addMembers( 794 rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts ); 795 } 796 } 805 797 } 806 798 } -
src/AST/SymbolTable.hpp
r24d6572 r34b4268 192 192 193 193 /// common code for addId, addDeletedId, etc. 194 void addId Common(195 const DeclWithType * decl, OnConflict handleConflicts, 196 const Expr * baseExpr = nullptr, constDecl * deleter = nullptr );194 void addId( 195 const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr, 196 const Decl * deleter = nullptr ); 197 197 198 198 /// common code for addId when special decls are placed into separate tables 199 void addIdToTable( 200 const DeclWithType * decl, const std::string & lookupKey, 201 IdTable::Ptr & idTable, OnConflict handleConflicts, 199 void addId( 200 const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & idTable, OnConflict handleConflicts, 202 201 const Expr * baseExpr = nullptr, const Decl * deleter = nullptr); 203 202 204 203 /// adds all of the members of the Aggregate (addWith helper) 205 204 void addMembers( const AggregateDecl * aggr, const Expr * expr, OnConflict handleConflicts ); -
src/AST/TranslationUnit.hpp
r24d6572 r34b4268 10 10 // Created On : Tue Jun 11 15:30:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Mar 9 16:41:00 202313 // Update Count : 212 // Last Modified On : Tue Mar 11 11:19:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 17 17 18 18 #include <map> 19 #include < list>19 #include <vector> 20 20 21 21 #include "Fwd.hpp" … … 28 28 29 29 ptr<Type> sizeType; 30 const FunctionDecl * dereference = nullptr;31 const StructDecl * dtorStruct = nullptr;32 const FunctionDecl * dtorDestroy = nullptr;30 const FunctionDecl * dereference; 31 const StructDecl * dtorStruct; 32 const FunctionDecl * dtorDestroy; 33 33 }; 34 34 -
src/AST/Type.cpp
r24d6572 r34b4268 10 10 // Created On : Mon May 13 15:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Apr 6 15:59:00 202313 // Update Count : 712 // Last Modified On : Thu Nov 24 9:49:00 2022 13 // Update Count : 6 14 14 // 15 15 … … 199 199 200 200 TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q ) 201 : Type( q ), types( std::move(ts) ) {} 201 : Type( q ), types( std::move(ts) ), members() { 202 // This constructor is awkward. `TupleType` needs to contain objects so that members can be 203 // named, but members without initializer nodes end up getting constructors, which breaks 204 // things. This happens because the object decls have to be visited so that their types are 205 // kept in sync with the types listed here. Ultimately, the types listed here should perhaps 206 // be eliminated and replaced with a list-view over members. The temporary solution is to 207 // make a `ListInit` with `maybeConstructed = false`, so when the object is visited it is not 208 // constructed. Potential better solutions include: 209 // a) Separate `TupleType` from its declarations, into `TupleDecl` and `Tuple{Inst?}Type`, 210 // similar to the aggregate types. 211 // b) Separate initializer nodes better, e.g. add a `MaybeConstructed` node that is replaced 212 // by `genInit`, rather than the current boolean flag. 213 members.reserve( types.size() ); 214 for ( const Type * ty : types ) { 215 members.emplace_back( new ObjectDecl{ 216 CodeLocation(), "", ty, new ListInit( CodeLocation(), {}, {}, NoConstruct ), 217 Storage::Classes{}, Linkage::Cforall } ); 218 } 219 } 202 220 203 221 bool isUnboundType(const Type * type) { -
src/AST/Type.hpp
r24d6572 r34b4268 10 10 // Created On : Thu May 9 10:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Apr 6 15:58:00 202313 // Update Count : 912 // Last Modified On : Thu Nov 24 9:47:00 2022 13 // Update Count : 8 14 14 // 15 15 … … 265 265 }; 266 266 267 /// Function variable arguments flag 268 enum ArgumentFlag { FixedArgs, VariableArgs }; 269 267 270 /// Type of a function `[R1, R2](*)(P1, P2, P3)` 268 271 class FunctionType final : public Type { … … 459 462 public: 460 463 std::vector<ptr<Type>> types; 464 std::vector<ptr<Decl>> members; 461 465 462 466 TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q = {} ); -
src/AST/TypeEnvironment.cpp
r24d6572 r34b4268 178 178 179 179 bool TypeEnvironment::combine( 180 const TypeEnvironment & o, OpenVarSet & open ) {180 const TypeEnvironment & o, OpenVarSet & open, const SymbolTable & symtab ) { 181 181 // short-circuit easy cases 182 182 if ( o.empty() ) return true; … … 201 201 EqvClass & r = *rt; 202 202 // merge bindings 203 if ( ! mergeBound( r, c, open ) ) return false;203 if ( ! mergeBound( r, c, open, symtab ) ) return false; 204 204 // merge previous unbound variables into this class, checking occurs if needed 205 205 if ( r.bound ) for ( const auto & u : c.vars ) { … … 216 216 } else if ( st != rt ) { 217 217 // bound, but not to the same class 218 if ( ! mergeClasses( rt, st, open ) ) return false;218 if ( ! mergeClasses( rt, st, open, symtab ) ) return false; 219 219 } // ignore bound into the same class 220 220 } … … 280 280 bool TypeEnvironment::bindVar( 281 281 const TypeInstType * typeInst, const Type * bindTo, const TypeData & data, 282 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen 282 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen, 283 const SymbolTable & symtab 283 284 ) { 284 285 // remove references from bound type, so that type variables can only bind to value types … … 299 300 if ( unifyInexact( 300 301 newType, target, *this, need, have, open, 301 widen & WidenMode{ it->allowWidening, true }, common ) ) {302 widen & WidenMode{ it->allowWidening, true }, symtab, common ) ) { 302 303 if ( common ) { 303 304 it->bound = std::move(common); … … 320 321 const TypeInstType * var1, const TypeInstType * var2, TypeData && data, 321 322 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, 322 WidenMode widen 323 WidenMode widen, const SymbolTable & symtab 323 324 ) { 324 325 auto c1 = internal_lookup( *var1 ); … … 357 358 358 359 if ( unifyInexact( 359 newType1, newType2, *this, need, have, open, newWidenMode, common ) ) {360 newType1, newType2, *this, need, have, open, newWidenMode, symtab, common ) ) { 360 361 c1->vars.insert( c2->vars.begin(), c2->vars.end() ); 361 362 c1->allowWidening = widen1 && widen2; … … 408 409 409 410 bool TypeEnvironment::mergeBound( 410 EqvClass & to, const EqvClass & from, OpenVarSet & open ) {411 EqvClass & to, const EqvClass & from, OpenVarSet & open, const SymbolTable & symtab ) { 411 412 if ( from.bound ) { 412 413 if ( to.bound ) { … … 418 419 419 420 if ( unifyInexact( 420 toType, fromType, *this, need, have, open, widen, common ) ) {421 toType, fromType, *this, need, have, open, widen, symtab, common ) ) { 421 422 // unifies, set common type if necessary 422 423 if ( common ) { … … 436 437 437 438 bool TypeEnvironment::mergeClasses( 438 ClassList::iterator to, ClassList::iterator from, OpenVarSet & open 439 ClassList::iterator to, ClassList::iterator from, OpenVarSet & open, const SymbolTable & symtab 439 440 ) { 440 441 EqvClass & r = *to, & s = *from; 441 442 442 443 // ensure bounds match 443 if ( ! mergeBound( r, s, open ) ) return false;444 if ( ! mergeBound( r, s, open, symtab ) ) return false; 444 445 445 446 // check safely bindable -
src/AST/TypeEnvironment.hpp
r24d6572 r34b4268 63 63 64 64 int cmp = d1->var->name.compare( d2->var->name ); 65 return cmp >0 || ( cmp == 0 && d1->result < d2->result );65 return cmp < 0 || ( cmp == 0 && d1->result < d2->result ); 66 66 } 67 67 }; … … 169 169 /// Merge environment with this one, checking compatibility. 170 170 /// Returns false if fails, but does NOT roll back partial changes. 171 bool combine( const TypeEnvironment & o, OpenVarSet & openVars );171 bool combine( const TypeEnvironment & o, OpenVarSet & openVars, const SymbolTable & symtab ); 172 172 173 173 /// Add all type variables in environment to open var list … … 183 183 const TypeInstType * typeInst, const Type * bindTo, const TypeData & data, 184 184 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 185 ResolvExpr::WidenMode widen );185 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); 186 186 187 187 /// Binds the type classes represented by `var1` and `var2` together; will add one or both … … 190 190 const TypeInstType * var1, const TypeInstType * var2, TypeData && data, 191 191 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 192 ResolvExpr::WidenMode widen );192 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); 193 193 194 194 /// Disallows widening for all bindings in the environment … … 205 205 /// Unifies the type bound of `to` with the type bound of `from`, returning false if fails 206 206 bool mergeBound( 207 EqvClass & to, const EqvClass & from, OpenVarSet & openVars );207 EqvClass & to, const EqvClass & from, OpenVarSet & openVars, const SymbolTable & symtab ); 208 208 209 209 /// Merges two type classes from local environment, returning false if fails 210 210 bool mergeClasses( 211 ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars); 211 ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars, 212 const SymbolTable & symtab ); 212 213 213 214 /// Private lookup API; returns array index of string, or env.size() for not found -
src/AST/TypeSubstitution.cpp
r24d6572 r34b4268 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr May 25 11:24:00 2023 13 // Update Count : 6 14 // 15 12 // Last Modified On : Mon Jun 3 13:26:00 2017 13 // Update Count : 5 14 // 15 16 #include "Type.hpp" // for TypeInstType, Type, StructInstType, UnionInstType 16 17 #include "TypeSubstitution.hpp" 17 18 18 #include "Type.hpp" // for TypeInstType, Type, StructInstType, UnionInstType19 #include "Pass.hpp" // for Pass, PureVisitor, WithGuards, WithVisitorRef20 21 19 namespace ast { 20 21 22 // size_t TypeSubstitution::Substituter::traceId = Stats::Heap::new_stacktrace_id("TypeSubstitution"); 22 23 23 24 TypeSubstitution::TypeSubstitution() { … … 118 119 } 119 120 120 // definitition must happen after PassVisitor is included so that WithGuards can be used121 struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter>, public PureVisitor {122 //static size_t traceId;123 124 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}125 126 const Type * postvisit( const TypeInstType * aggregateUseType );127 128 /// Records type variable bindings from forall-statements129 void previsit( const FunctionType * type );130 /// Records type variable bindings from forall-statements and instantiations of generic types131 // void handleAggregateType( const BaseInstType * type );132 133 // void previsit( const StructInstType * aggregateUseType );134 // void previsit( const UnionInstType * aggregateUseType );135 136 const TypeSubstitution & sub;137 int subCount = 0;138 bool freeOnly;139 typedef std::unordered_set< TypeEnvKey > BoundVarsType;140 BoundVarsType boundVars;141 };142 143 // size_t TypeSubstitution::Substituter::traceId = Stats::Heap::new_stacktrace_id("TypeSubstitution");144 145 121 void TypeSubstitution::normalize() { 146 122 Pass<Substituter> sub( *this, true ); … … 152 128 } 153 129 } while ( sub.core.subCount ); 154 }155 156 TypeSubstitution::ApplyResult<Node> TypeSubstitution::applyBase(157 const Node * input, bool isFree ) const {158 assert( input );159 Pass<Substituter> sub( *this, isFree );160 const Node * output = input->accept( sub );161 return { output, sub.core.subCount };162 130 } 163 131 -
src/AST/TypeSubstitution.hpp
r24d6572 r34b4268 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : T hr May 25 12:31:00 202313 // Update Count : 1011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 30 22:52:47 2019 13 // Update Count : 9 14 14 // 15 15 … … 46 46 TypeSubstitution &operator=( const TypeSubstitution &other ); 47 47 48 template< typename node_t>48 template< typename SynTreeClass > 49 49 struct ApplyResult { 50 ast::ptr< node_t> node;50 ast::ptr<SynTreeClass> node; 51 51 int count; 52 52 }; 53 53 54 template< typename node_t > 55 ApplyResult<node_t> apply( const node_t * input ) const { 56 ApplyResult<Node> ret = applyBase( input, false ); 57 return { ret.node.strict_as<node_t>(), ret.count }; 58 } 54 template< typename SynTreeClass > ApplyResult<SynTreeClass> apply( const SynTreeClass * input ) const; 55 template< typename SynTreeClass > ApplyResult<SynTreeClass> applyFree( const SynTreeClass * input ) const; 59 56 60 57 template< typename node_t, enum Node::ref_type ref_t > 61 58 int apply( ptr_base< node_t, ref_t > & input ) const { 62 ApplyResult<Node> ret = applyBase( input.get(), false ); 63 input = ret.node.strict_as<node_t>(); 59 const node_t * p = input.get(); 60 auto ret = apply(p); 61 input = ret.node; 64 62 return ret.count; 65 63 } 66 64 67 template< typename node_t >68 ApplyResult<node_t> applyFree( const node_t * input ) const {69 ApplyResult<Node> ret = applyBase( input, true );70 return { ret.node.strict_as<node_t>(), ret.count };71 }72 73 65 template< typename node_t, enum Node::ref_type ref_t > 74 66 int applyFree( ptr_base< node_t, ref_t > & input ) const { 75 ApplyResult<Node> ret = applyBase( input.get(), true ); 76 input = ret.node.strict_as<node_t>(); 67 const node_t * p = input.get(); 68 auto ret = applyFree(p); 69 input = ret.node; 77 70 return ret.count; 78 71 } … … 104 97 // Mutator that performs the substitution 105 98 struct Substituter; 106 ApplyResult<Node> applyBase( const Node * input, bool isFree ) const;107 99 108 100 // TODO: worry about traversing into a forall-qualified function type or type decl with assertions … … 166 158 } // namespace ast 167 159 160 // include needs to happen after TypeSubstitution is defined so that both TypeSubstitution and 161 // PassVisitor are defined before PassVisitor implementation accesses TypeSubstitution internals. 162 #include "Pass.hpp" 163 #include "Copy.hpp" 164 165 namespace ast { 166 167 // definitition must happen after PassVisitor is included so that WithGuards can be used 168 struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter>, public PureVisitor { 169 static size_t traceId; 170 171 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {} 172 173 const Type * postvisit( const TypeInstType * aggregateUseType ); 174 175 /// Records type variable bindings from forall-statements 176 void previsit( const FunctionType * type ); 177 /// Records type variable bindings from forall-statements and instantiations of generic types 178 // void handleAggregateType( const BaseInstType * type ); 179 180 // void previsit( const StructInstType * aggregateUseType ); 181 // void previsit( const UnionInstType * aggregateUseType ); 182 183 const TypeSubstitution & sub; 184 int subCount = 0; 185 bool freeOnly; 186 typedef std::unordered_set< TypeEnvKey > BoundVarsType; 187 BoundVarsType boundVars; 188 189 }; 190 191 template< typename SynTreeClass > 192 TypeSubstitution::ApplyResult<SynTreeClass> TypeSubstitution::apply( const SynTreeClass * input ) const { 193 assert( input ); 194 Pass<Substituter> sub( *this, false ); 195 input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) ); 196 return { input, sub.core.subCount }; 197 } 198 199 template< typename SynTreeClass > 200 TypeSubstitution::ApplyResult<SynTreeClass> TypeSubstitution::applyFree( const SynTreeClass * input ) const { 201 assert( input ); 202 Pass<Substituter> sub( *this, true ); 203 input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) ); 204 return { input, sub.core.subCount }; 205 } 206 207 } // namespace ast 208 168 209 // Local Variables: // 169 210 // tab-width: 4 // -
src/AST/Visitor.hpp
r24d6572 r34b4268 50 50 virtual const ast::FinallyClause * visit( const ast::FinallyClause * ) = 0; 51 51 virtual const ast::Stmt * visit( const ast::SuspendStmt * ) = 0; 52 virtual const ast::WhenClause * visit( const ast::WhenClause * ) = 0;53 52 virtual const ast::Stmt * visit( const ast::WaitForStmt * ) = 0; 54 53 virtual const ast::WaitForClause * visit( const ast::WaitForClause * ) = 0; 55 virtual const ast::Stmt * visit( const ast::WaitUntilStmt * ) = 0;56 54 virtual const ast::Decl * visit( const ast::WithStmt * ) = 0; 57 55 virtual const ast::NullStmt * visit( const ast::NullStmt * ) = 0; -
src/AST/porting.md
r24d6572 r34b4268 213 213 * `get_statement()` exclusively used for code location, replaced with `CodeLocation` field 214 214 215 `CaseStmt` => `CaseClause`215 `CaseStmt` 216 216 * `_isDefault` has been removed 217 217 * `isDefault` calculates value from `cond` … … 227 227 * `block` -> `body` and `finallyBlock` -> `finally` 228 228 229 `ThrowStmt` and `CatchStmt` => `CatchClause`229 `ThrowStmt` `CatchStmt` 230 230 * moved `Kind` enums to shared `ast::ExceptionKind` enum 231 231 232 `FinallyStmt` => `FinallyClause`232 `FinallyStmt` 233 233 * `block` -> `body` 234 234 … … 280 280 * Template class, with specializations and using to implement some other types: 281 281 * `StructInstType`, `UnionInstType` & `EnumInstType` 282 * `baseStruct`, `baseUnion` & `baseEnum` => `base`283 282 284 283 `TypeInstType` -
src/CodeGen/CodeGenerator.cc
r24d6572 r34b4268 17 17 #include <cassert> // for assert, assertf 18 18 #include <list> // for _List_iterator, list, list<>::it... 19 #include <sstream> // for stringstream20 19 21 20 #include "AST/Decl.hpp" // for DeclWithType 22 21 #include "Common/UniqueName.h" // for UniqueName 22 #include "Common/utility.h" // for CodeLocation, toString 23 23 #include "GenType.h" // for genType 24 24 #include "InitTweak/InitTweak.h" // for getPointerBase … … 273 273 } 274 274 275 template<typename pass_type>276 inline void genEnumInitializer( PassVisitor<pass_type> * visitor, Type * baseType, std::ostream & output,277 Initializer * init, long long * cur_val, Options options) {278 auto baseTypeAsBasic = baseType ? dynamic_cast<BasicType *>( baseType ) : nullptr;279 if ( init ) { // If value has an explicit initiazatior280 output << " = ";281 output << "(" << genType(baseType, "", options) << ")";282 init->accept( *visitor );283 if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // if it is an integral type and initilizer offered,284 // need to update the cur_val285 Expression* expr = ((SingleInit *)(init))->value;286 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast287 expr = temp->arg;288 }289 *cur_val = ((ConstantExpr *)expr)->constant.get_ival()+1;290 }291 } else if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // integral implicitly init to cur_val + 1292 output << " = " << "(" << genType(baseType, "", options) << ")";293 output << (*cur_val)++;294 }295 }296 297 275 void CodeGenerator::postvisit( EnumDecl * enumDecl ) { 298 276 extension( enumDecl ); 299 277 std::list< Declaration* > &memb = enumDecl->get_members(); 300 278 if (enumDecl->base && ! memb.empty()) { 301 long long cur_val = 0; 279 unsigned long long last_val = -1; // if the first enum value has no explicit initializer, 280 // as other 302 281 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 303 282 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 304 283 assert( obj ); 305 284 output << "static "; 306 output << genType(enumDecl->base, mangleName( obj ), options); 307 genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options); 285 output << genType(enumDecl->base, "", options) << " const "; 286 output << mangleName( obj ) << " "; 287 output << " = "; 288 output << "(" << genType(enumDecl->base, "", options) << ")"; 289 if ( (BasicType *)(enumDecl->base) && ((BasicType *)(enumDecl->base))->isWholeNumber() ) { 290 if ( obj->get_init() ) { 291 obj->get_init()->accept( *visitor ); 292 Expression* expr = ((SingleInit *)(obj->init))->value; 293 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { 294 expr = temp->arg; 295 } 296 last_val = ((ConstantExpr *)expr)->constant.get_ival(); 297 } else { 298 output << ++last_val; 299 } // if 300 } else { 301 if ( obj->get_init() ) { 302 obj->get_init()->accept( *visitor ); 303 } else { 304 // Should not reach here! 305 } 306 } 308 307 output << ";" << endl; 309 308 } // for -
src/CodeGen/GenType.cc
r24d6572 r34b4268 255 255 void GenType::postvisit( EnumInstType * enumInst ) { 256 256 if ( enumInst->baseEnum && enumInst->baseEnum->base ) { 257 typeString = genType(enumInst->baseEnum->base, typeString, options);257 typeString = genType(enumInst->baseEnum->base, "", options) + typeString; 258 258 } else { 259 259 typeString = enumInst->name + " " + typeString; -
src/Common/CodeLocationTools.cpp
r24d6572 r34b4268 128 128 macro(FinallyClause, FinallyClause) \ 129 129 macro(SuspendStmt, Stmt) \ 130 macro(WhenClause, WhenClause) \131 130 macro(WaitForStmt, Stmt) \ 132 131 macro(WaitForClause, WaitForClause) \ 133 macro(WaitUntilStmt, Stmt) \134 132 macro(WithStmt, Decl) \ 135 133 macro(NullStmt, NullStmt) \ … … 210 208 211 209 struct LeafKindVisitor : public ast::Visitor { 212 LeafKind result;210 LeafKind kind; 213 211 214 212 #define VISIT(node_type, return_type) \ 215 213 const ast::return_type * visit( const ast::node_type * ) final { \ 216 result= LeafKind::node_type; \214 kind = LeafKind::node_type; \ 217 215 return nullptr; \ 218 216 } … … 224 222 225 223 LeafKind get_leaf_kind( ast::Node const * node ) { 226 return ast::Pass<LeafKindVisitor>::read( node ); 224 LeafKindVisitor visitor; 225 node->accept( visitor ); 226 return visitor.kind; 227 227 } 228 228 -
src/Common/DeclStats.cpp
r24d6572 r34b4268 23 23 #include <iostream> 24 24 #include <map> 25 #include <sstream>26 25 #include <unordered_map> 27 26 #include <unordered_set> -
src/Common/Eval.cc
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Eval.cc -- Evaluate parts of the ast at compile time.7 // utility.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 13 13 // Update Count : 119 14 14 // 15 16 #include "Eval.h"17 15 18 16 #include <utility> // for pair -
src/Common/ResolvProtoDump.cpp
r24d6572 r34b4268 19 19 #include <iostream> 20 20 #include <set> 21 #include <sstream>22 21 #include <unordered_set> 23 22 … … 27 26 #include "AST/Type.hpp" 28 27 #include "CodeGen/OperatorTable.h" 28 #include "Common/utility.h" 29 29 30 30 namespace { -
src/Common/ScopedMap.h
r24d6572 r34b4268 37 37 template<typename N> 38 38 Scope(N && n) : map(), note(std::forward<N>(n)) {} 39 39 40 40 Scope() = default; 41 41 Scope(const Scope &) = default; … … 46 46 typedef std::vector< Scope > ScopeList; 47 47 48 /// Scoped list of maps. 49 ScopeList scopes; 48 ScopeList scopes; ///< scoped list of maps 50 49 public: 51 50 typedef typename MapType::key_type key_type; … … 59 58 typedef typename MapType::const_pointer const_pointer; 60 59 61 // Both iterator types are complete bidrectional iterators, see below. 62 class iterator; 63 class const_iterator; 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > { 61 friend class ScopedMap; 62 friend class const_iterator; 63 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 64 typedef typename ScopedMap::ScopeList scope_list; 65 typedef typename scope_list::size_type size_type; 66 67 /// Checks if this iterator points to a valid item 68 bool is_valid() const { 69 return it != (*scopes)[level].map.end(); 70 } 71 72 /// Increments on invalid 73 iterator & next_valid() { 74 if ( ! is_valid() ) { ++(*this); } 75 return *this; 76 } 77 78 /// Decrements on invalid 79 iterator & prev_valid() { 80 if ( ! is_valid() ) { --(*this); } 81 return *this; 82 } 83 84 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 85 : scopes(&_scopes), it(_it), level(inLevel) {} 86 public: 87 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 88 iterator & operator= (const iterator & that) { 89 scopes = that.scopes; level = that.level; it = that.it; 90 return *this; 91 } 92 93 reference operator* () { return *it; } 94 pointer operator-> () const { return it.operator->(); } 95 96 iterator & operator++ () { 97 if ( it == (*scopes)[level].map.end() ) { 98 if ( level == 0 ) return *this; 99 --level; 100 it = (*scopes)[level].map.begin(); 101 } else { 102 ++it; 103 } 104 return next_valid(); 105 } 106 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 107 108 iterator & operator-- () { 109 // may fail if this is the begin iterator; allowed by STL spec 110 if ( it == (*scopes)[level].map.begin() ) { 111 ++level; 112 it = (*scopes)[level].map.end(); 113 } 114 --it; 115 return prev_valid(); 116 } 117 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 118 119 bool operator== (const iterator & that) const { 120 return scopes == that.scopes && level == that.level && it == that.it; 121 } 122 bool operator!= (const iterator & that) const { return !( *this == that ); } 123 124 size_type get_level() const { return level; } 125 126 Note & get_note() { return (*scopes)[level].note; } 127 const Note & get_note() const { return (*scopes)[level].note; } 128 129 private: 130 scope_list *scopes; 131 wrapped_iterator it; 132 size_type level; 133 }; 134 135 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 136 value_type > { 137 friend class ScopedMap; 138 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 139 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator; 140 typedef typename ScopedMap::ScopeList scope_list; 141 typedef typename scope_list::size_type size_type; 142 143 /// Checks if this iterator points to a valid item 144 bool is_valid() const { 145 return it != (*scopes)[level].map.end(); 146 } 147 148 /// Increments on invalid 149 const_iterator & next_valid() { 150 if ( ! is_valid() ) { ++(*this); } 151 return *this; 152 } 153 154 /// Decrements on invalid 155 const_iterator & prev_valid() { 156 if ( ! is_valid() ) { --(*this); } 157 return *this; 158 } 159 160 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 161 : scopes(&_scopes), it(_it), level(inLevel) {} 162 public: 163 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 164 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 165 const_iterator & operator= (const iterator & that) { 166 scopes = that.scopes; level = that.level; it = that.it; 167 return *this; 168 } 169 const_iterator & operator= (const const_iterator & that) { 170 scopes = that.scopes; level = that.level; it = that.it; 171 return *this; 172 } 173 174 const_reference operator* () { return *it; } 175 const_pointer operator-> () { return it.operator->(); } 176 177 const_iterator & operator++ () { 178 if ( it == (*scopes)[level].map.end() ) { 179 if ( level == 0 ) return *this; 180 --level; 181 it = (*scopes)[level].map.begin(); 182 } else { 183 ++it; 184 } 185 return next_valid(); 186 } 187 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 188 189 const_iterator & operator-- () { 190 // may fail if this is the begin iterator; allowed by STL spec 191 if ( it == (*scopes)[level].map.begin() ) { 192 ++level; 193 it = (*scopes)[level].map.end(); 194 } 195 --it; 196 return prev_valid(); 197 } 198 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 199 200 bool operator== (const const_iterator & that) const { 201 return scopes == that.scopes && level == that.level && it == that.it; 202 } 203 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 204 205 size_type get_level() const { return level; } 206 207 const Note & get_note() const { return (*scopes)[level].note; } 208 209 private: 210 scope_list const *scopes; 211 wrapped_const_iterator it; 212 size_type level; 213 }; 64 214 65 215 /// Starts a new scope … … 147 297 } 148 298 299 template< typename value_type_t > 300 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) { 301 MapType & scope = (*at.scopes)[ at.level ].map; 302 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) ); 303 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) ); 304 } 305 149 306 template< typename value_t > 150 307 std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); } … … 167 324 } 168 325 169 /// Erases element with key in the innermost scope that has it. 170 size_type erase( const Key & key ) { 171 for ( auto it = scopes.rbegin() ; it != scopes.rend() ; ++it ) { 172 size_type i = it->map.erase( key ); 173 if ( 0 != i ) return i; 174 } 175 return 0; 326 iterator erase( iterator pos ) { 327 MapType & scope = (*pos.scopes)[ pos.level ].map; 328 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it ); 329 iterator it( *pos.scopes, new_it, pos.level ); 330 return it.next_valid(); 176 331 } 177 332 … … 188 343 return c; 189 344 } 190 191 bool contains( const Key & key ) const {192 return find( key ) != cend();193 }194 };195 196 template<typename Key, typename Value, typename Note>197 class ScopedMap<Key, Value, Note>::iterator :198 public std::iterator< std::bidirectional_iterator_tag, value_type > {199 friend class ScopedMap;200 friend class const_iterator;201 typedef typename ScopedMap::MapType::iterator wrapped_iterator;202 typedef typename ScopedMap::ScopeList scope_list;203 typedef typename scope_list::size_type size_type;204 205 /// Checks if this iterator points to a valid item206 bool is_valid() const {207 return it != (*scopes)[level].map.end();208 }209 210 /// Increments on invalid211 iterator & next_valid() {212 if ( ! is_valid() ) { ++(*this); }213 return *this;214 }215 216 /// Decrements on invalid217 iterator & prev_valid() {218 if ( ! is_valid() ) { --(*this); }219 return *this;220 }221 222 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel)223 : scopes(&_scopes), it(_it), level(inLevel) {}224 public:225 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}226 iterator & operator= (const iterator & that) {227 scopes = that.scopes; level = that.level; it = that.it;228 return *this;229 }230 231 reference operator* () { return *it; }232 pointer operator-> () const { return it.operator->(); }233 234 iterator & operator++ () {235 if ( it == (*scopes)[level].map.end() ) {236 if ( level == 0 ) return *this;237 --level;238 it = (*scopes)[level].map.begin();239 } else {240 ++it;241 }242 return next_valid();243 }244 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }245 246 iterator & operator-- () {247 // may fail if this is the begin iterator; allowed by STL spec248 if ( it == (*scopes)[level].map.begin() ) {249 ++level;250 it = (*scopes)[level].map.end();251 }252 --it;253 return prev_valid();254 }255 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }256 257 bool operator== (const iterator & that) const {258 return scopes == that.scopes && level == that.level && it == that.it;259 }260 bool operator!= (const iterator & that) const { return !( *this == that ); }261 262 size_type get_level() const { return level; }263 264 Note & get_note() { return (*scopes)[level].note; }265 const Note & get_note() const { return (*scopes)[level].note; }266 267 private:268 scope_list *scopes;269 wrapped_iterator it;270 size_type level;271 };272 273 template<typename Key, typename Value, typename Note>274 class ScopedMap<Key, Value, Note>::const_iterator :275 public std::iterator< std::bidirectional_iterator_tag, value_type > {276 friend class ScopedMap;277 typedef typename ScopedMap::MapType::iterator wrapped_iterator;278 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;279 typedef typename ScopedMap::ScopeList scope_list;280 typedef typename scope_list::size_type size_type;281 282 /// Checks if this iterator points to a valid item283 bool is_valid() const {284 return it != (*scopes)[level].map.end();285 }286 287 /// Increments on invalid288 const_iterator & next_valid() {289 if ( ! is_valid() ) { ++(*this); }290 return *this;291 }292 293 /// Decrements on invalid294 const_iterator & prev_valid() {295 if ( ! is_valid() ) { --(*this); }296 return *this;297 }298 299 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel)300 : scopes(&_scopes), it(_it), level(inLevel) {}301 public:302 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}303 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}304 const_iterator & operator= (const iterator & that) {305 scopes = that.scopes; level = that.level; it = that.it;306 return *this;307 }308 const_iterator & operator= (const const_iterator & that) {309 scopes = that.scopes; level = that.level; it = that.it;310 return *this;311 }312 313 const_reference operator* () { return *it; }314 const_pointer operator-> () { return it.operator->(); }315 316 const_iterator & operator++ () {317 if ( it == (*scopes)[level].map.end() ) {318 if ( level == 0 ) return *this;319 --level;320 it = (*scopes)[level].map.begin();321 } else {322 ++it;323 }324 return next_valid();325 }326 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }327 328 const_iterator & operator-- () {329 // may fail if this is the begin iterator; allowed by STL spec330 if ( it == (*scopes)[level].map.begin() ) {331 ++level;332 it = (*scopes)[level].map.end();333 }334 --it;335 return prev_valid();336 }337 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }338 339 bool operator== (const const_iterator & that) const {340 return scopes == that.scopes && level == that.level && it == that.it;341 }342 bool operator!= (const const_iterator & that) const { return !( *this == that ); }343 344 size_type get_level() const { return level; }345 346 const Note & get_note() const { return (*scopes)[level].note; }347 348 private:349 scope_list const *scopes;350 wrapped_const_iterator it;351 size_type level;352 345 }; 353 346 -
src/Common/SemanticError.h
r24d6572 r34b4268 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 25 12:01:31 202313 // Update Count : 3 712 // Last Modified On : Wed May 4 14:08:26 2022 13 // Update Count : 35 14 14 // 15 15 … … 54 54 55 55 constexpr WarningData WarningFormats[] = { 56 {"self-assign" , Severity::Warn , "self assignment of expression: %s" }, 57 {"reference-conversion" , Severity::Warn , "rvalue to reference conversion of rvalue: %s" }, 58 {"qualifiers-zero_t-one_t" , Severity::Warn , "questionable use of type qualifier(s) with %s" }, 59 {"aggregate-forward-decl" , Severity::Warn , "forward declaration of nested aggregate: %s" }, 60 {"superfluous-decl" , Severity::Warn , "declaration does not allocate storage: %s" }, 61 {"superfluous-else" , Severity::Warn , "else clause never executed for empty loop conditional" }, 62 {"gcc-attributes" , Severity::Warn , "invalid attribute: %s" }, 63 {"c++-like-copy" , Severity::Warn , "Constructor from reference is not a valid copy constructor" }, 64 {"depreciated-trait-syntax" , Severity::Warn , "trait type-parameters are now specified using the forall clause" }, 56 {"self-assign" , Severity::Warn , "self assignment of expression: %s" }, 57 {"reference-conversion" , Severity::Warn , "rvalue to reference conversion of rvalue: %s" }, 58 {"qualifiers-zero_t-one_t", Severity::Warn , "questionable use of type qualifier %s with %s" }, 59 {"aggregate-forward-decl" , Severity::Warn , "forward declaration of nested aggregate: %s" }, 60 {"superfluous-decl" , Severity::Warn , "declaration does not allocate storage: %s" }, 61 {"superfluous-else" , Severity::Warn , "else clause never executed for empty loop conditional" }, 62 {"gcc-attributes" , Severity::Warn , "invalid attribute: %s" }, 63 {"c++-like-copy" , Severity::Warn , "Constructor from reference is not a valid copy constructor" }, 65 64 }; 66 65 … … 74 73 GccAttributes, 75 74 CppCopy, 76 DeprecTraitSyntax,77 75 NUMBER_OF_WARNINGS, // This MUST be the last warning 78 76 }; -
src/Common/module.mk
r24d6572 r34b4268 20 20 Common/CodeLocationTools.hpp \ 21 21 Common/CodeLocationTools.cpp \ 22 Common/CompilerError.h \ 23 Common/Debug.h \ 22 24 Common/DeclStats.hpp \ 23 25 Common/DeclStats.cpp \ 24 26 Common/ErrorObjects.h \ 25 27 Common/Eval.cc \ 26 Common/Eval.h \27 28 Common/Examine.cc \ 28 29 Common/Examine.h \ … … 30 31 Common/Indenter.h \ 31 32 Common/Indenter.cc \ 32 Common/Iterate.hpp \33 33 Common/PassVisitor.cc \ 34 34 Common/PassVisitor.h \ … … 52 52 Common/Stats/Time.cc \ 53 53 Common/Stats/Time.h \ 54 Common/ ToString.hpp\54 Common/UnimplementedError.h \ 55 55 Common/UniqueName.cc \ 56 56 Common/UniqueName.h \ -
src/Common/utility.h
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // utility.h -- General utilities used across the compiler.7 // utility.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Feb 17 15:25:00 202313 // Update Count : 5 312 // Last Modified On : Mon Apr 25 14:26:00 2022 13 // Update Count : 51 14 14 // 15 15 … … 19 19 #include <cctype> 20 20 #include <algorithm> 21 #include <functional> 21 22 #include <iostream> 23 #include <iterator> 22 24 #include <list> 23 25 #include <memory> 26 #include <sstream> 24 27 #include <string> 25 28 #include <type_traits> 29 #include <utility> 26 30 #include <vector> 27 31 #include <cstring> // memcmp … … 45 49 return 0; 46 50 } // if 51 } 52 53 template< typename T, typename U > 54 struct maybeBuild_t { 55 static T * doit( const U *orig ) { 56 if ( orig ) { 57 return orig->build(); 58 } else { 59 return 0; 60 } // if 61 } 62 }; 63 64 template< typename T, typename U > 65 static inline T * maybeBuild( const U *orig ) { 66 return maybeBuild_t<T,U>::doit(orig); 67 } 68 69 template< typename T, typename U > 70 static inline T * maybeMoveBuild( const U *orig ) { 71 T* ret = maybeBuild<T>(orig); 72 delete orig; 73 return ret; 47 74 } 48 75 … … 141 168 splice( src, dst ); 142 169 dst.swap( src ); 170 } 171 172 template < typename T > 173 void toString_single( std::ostream & os, const T & value ) { 174 os << value; 175 } 176 177 template < typename T, typename... Params > 178 void toString_single( std::ostream & os, const T & value, const Params & ... params ) { 179 os << value; 180 toString_single( os, params ... ); 181 } 182 183 template < typename ... Params > 184 std::string toString( const Params & ... params ) { 185 std::ostringstream os; 186 toString_single( os, params... ); 187 return os.str(); 188 } 189 190 #define toCString( ... ) toString( __VA_ARGS__ ).c_str() 191 192 // replace element of list with all elements of another list 193 template< typename T > 194 void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) { 195 typename std::list< T >::iterator next = pos; advance( next, 1 ); 196 197 //if ( next != org.end() ) { 198 org.erase( pos ); 199 org.splice( next, with ); 200 //} 201 202 return; 203 } 204 205 // replace range of a list with a single element 206 template< typename T > 207 void replace( std::list< T > &org, typename std::list< T >::iterator begin, typename std::list< T >::iterator end, const T & with ) { 208 org.insert( begin, with ); 209 org.erase( begin, end ); 143 210 } 144 211 … … 169 236 } 170 237 238 template< typename... Args > 239 auto zip(Args&&... args) -> decltype(zipWith(std::forward<Args>(args)..., std::make_pair)) { 240 return zipWith(std::forward<Args>(args)..., std::make_pair); 241 } 242 243 template< class InputIterator1, class InputIterator2, class OutputIterator, class BinFunction > 244 void zipWith( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out, BinFunction func ) { 245 while ( b1 != e1 && b2 != e2 ) 246 *out++ = func(*b1++, *b2++); 247 } 248 249 // it's nice to actually be able to increment iterators by an arbitrary amount 250 template< class InputIt, class Distance > 251 InputIt operator+( InputIt it, Distance n ) { 252 advance(it, n); 253 return it; 254 } 255 256 template< typename T > 257 void warn_single( const T & arg ) { 258 std::cerr << arg << std::endl; 259 } 260 261 template< typename T, typename... Params > 262 void warn_single(const T & arg, const Params & ... params ) { 263 std::cerr << arg; 264 warn_single( params... ); 265 } 266 267 template< typename... Params > 268 void warn( const Params & ... params ) { 269 std::cerr << "Warning: "; 270 warn_single( params... ); 271 } 272 171 273 // determines if pref is a prefix of str 172 274 static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) { 173 275 if ( pref.size() > str.size() ) return false; 174 return pref == str.substr(start, pref.size()); 175 } 276 return 0 == memcmp( str.c_str() + start, pref.c_str(), pref.size() ); 277 // return prefix == full.substr(0, prefix.size()); // for future, requires c++17 278 } 279 280 // ----------------------------------------------------------------------------- 281 // Ref Counted Singleton class 282 // Objects that inherit from this class will have at most one reference to it 283 // but if all references die, the object will be deleted. 284 285 template< typename ThisType > 286 class RefCountSingleton { 287 public: 288 static std::shared_ptr<ThisType> get() { 289 if( global_instance.expired() ) { 290 std::shared_ptr<ThisType> new_instance = std::make_shared<ThisType>(); 291 global_instance = new_instance; 292 return std::move(new_instance); 293 } 294 return global_instance.lock(); 295 } 296 private: 297 static std::weak_ptr<ThisType> global_instance; 298 }; 299 300 template< typename ThisType > 301 std::weak_ptr<ThisType> RefCountSingleton<ThisType>::global_instance; 176 302 177 303 // ----------------------------------------------------------------------------- … … 230 356 ~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } } 231 357 }; 358 359 // ----------------------------------------------------------------------------- 360 // Helper struct and function to support 361 // for ( val : reverseIterate( container ) ) {} 362 // syntax to have a for each that iterates backwards 363 364 template< typename T > 365 struct reverse_iterate_t { 366 T& ref; 367 368 reverse_iterate_t( T & ref ) : ref(ref) {} 369 370 // this does NOT work on const T!!! 371 // typedef typename T::reverse_iterator iterator; 372 auto begin() { return ref.rbegin(); } 373 auto end() { return ref.rend(); } 374 }; 375 376 template< typename T > 377 reverse_iterate_t< T > reverseIterate( T & ref ) { 378 return reverse_iterate_t< T >( ref ); 379 } 380 381 template< typename T > 382 struct enumerate_t { 383 template<typename val_t> 384 struct value_t { 385 val_t & val; 386 size_t idx; 387 }; 388 389 template< typename iter_t, typename val_t > 390 struct iterator_t { 391 iter_t it; 392 size_t idx; 393 394 iterator_t( iter_t _it, size_t _idx ) : it(_it), idx(_idx) {} 395 396 value_t<val_t> operator*() const { return value_t<val_t>{ *it, idx }; } 397 398 bool operator==(const iterator_t & o) const { return o.it == it; } 399 bool operator!=(const iterator_t & o) const { return o.it != it; } 400 401 iterator_t & operator++() { 402 it++; 403 idx++; 404 return *this; 405 } 406 407 using difference_type = typename std::iterator_traits< iter_t >::difference_type; 408 using value_type = value_t<val_t>; 409 using pointer = value_t<val_t> *; 410 using reference = value_t<val_t> &; 411 using iterator_category = std::forward_iterator_tag; 412 }; 413 414 T & ref; 415 416 using iterator = iterator_t< typename T::iterator, typename T::value_type >; 417 using const_iterator = iterator_t< typename T::const_iterator, const typename T::value_type >; 418 419 iterator begin() { return iterator( ref.begin(), 0 ); } 420 iterator end() { return iterator( ref.end(), ref.size() ); } 421 422 const_iterator begin() const { return const_iterator( ref.cbegin(), 0 ); } 423 const_iterator end() const { return const_iterator( ref.cend(), ref.size() ); } 424 425 const_iterator cbegin() const { return const_iterator( ref.cbegin(), 0 ); } 426 const_iterator cend() const { return const_iterator( ref.cend(), ref.size() ); } 427 }; 428 429 template< typename T > 430 enumerate_t<T> enumerate( T & ref ) { 431 return enumerate_t< T >{ ref }; 432 } 433 434 template< typename T > 435 const enumerate_t< const T > enumerate( const T & ref ) { 436 return enumerate_t< const T >{ ref }; 437 } 438 439 template< typename OutType, typename Range, typename Functor > 440 OutType map_range( const Range& range, Functor&& functor ) { 441 OutType out; 442 443 std::transform( 444 begin( range ), 445 end( range ), 446 std::back_inserter( out ), 447 std::forward< Functor >( functor ) 448 ); 449 450 return out; 451 } 452 453 // ----------------------------------------------------------------------------- 454 // Helper struct and function to support: 455 // for ( auto val : group_iterate( container1, container2, ... ) ) { ... } 456 // This iteraters through multiple containers of the same size. 457 458 template<typename... Args> 459 class group_iterate_t { 460 using Iterables = std::tuple<Args...>; 461 Iterables iterables; 462 463 // Getting the iterator and value types this way preserves const. 464 template<size_t I> using Iter = decltype(std::get<I>(iterables).begin()); 465 template<size_t I> using Data = decltype(*std::get<I>(iterables).begin()); 466 template<typename> struct base_iterator; 467 468 // This inner template puts the sequence of `0, 1, ... sizeof...(Args)-1` 469 // into a pack. These are the indexes into the tuples, so unpacking can 470 // go over each element of the tuple. 471 // The std::integer_sequence is just used to build that sequence. 472 // A library reference will probably explain it better than I can. 473 template<std::size_t... Indices> 474 struct base_iterator<std::integer_sequence<std::size_t, Indices...>> { 475 using value_type = std::tuple< Data<Indices>... >; 476 std::tuple<Iter<Indices>...> iterators; 477 478 base_iterator( Iter<Indices>... is ) : iterators( is... ) {} 479 base_iterator operator++() { 480 return base_iterator( ++std::get<Indices>( iterators )... ); 481 } 482 bool operator!=( const base_iterator& other ) const { 483 return iterators != other.iterators; 484 } 485 value_type operator*() const { 486 return std::tie( *std::get<Indices>( iterators )... ); 487 } 488 489 static base_iterator make_begin( Iterables & data ) { 490 return base_iterator( std::get<Indices>( data ).begin()... ); 491 } 492 static base_iterator make_end( Iterables & data ) { 493 return base_iterator( std::get<Indices>( data ).end()... ); 494 } 495 }; 496 497 public: 498 group_iterate_t( const Args &... args ) : iterables( args... ) {} 499 500 using iterator = base_iterator<decltype( 501 std::make_integer_sequence<std::size_t, sizeof...(Args)>())>; 502 503 iterator begin() { return iterator::make_begin( iterables ); } 504 iterator end() { return iterator::make_end( iterables ); } 505 }; 506 507 // Helpers for the bounds checks (the non-varatic part of group_iterate): 508 static inline void runGroupBoundsCheck(size_t size0, size_t size1) { 509 assertf( size0 == size1, 510 "group iteration requires containers of the same size: <%zd, %zd>.", 511 size0, size1 ); 512 } 513 514 static inline void runGroupBoundsCheck(size_t size0, size_t size1, size_t size2) { 515 assertf( size0 == size1 && size1 == size2, 516 "group iteration requires containers of the same size: <%zd, %zd, %zd>.", 517 size0, size1, size2 ); 518 } 519 520 /// Performs bounds check to ensure that all arguments are of the same length. 521 template< typename... Args > 522 group_iterate_t<Args...> group_iterate( Args &&... args ) { 523 runGroupBoundsCheck( args.size()... ); 524 return group_iterate_t<Args...>( std::forward<Args>( args )... ); 525 } 526 527 /// Does not perform a bounds check - requires user to ensure that iteration terminates when appropriate. 528 template< typename... Args > 529 group_iterate_t<Args...> unsafe_group_iterate( Args &&... args ) { 530 return group_iterate_t<Args...>( std::forward<Args>( args )... ); 531 } 532 533 // ----------------------------------------------------------------------------- 534 // Helper struct and function to support 535 // for ( val : lazy_map( container1, f ) ) {} 536 // syntax to have a for each that iterates a container, mapping each element by applying f 537 template< typename T, typename Func > 538 struct lambda_iterate_t { 539 const T & ref; 540 std::function<Func> f; 541 542 struct iterator { 543 typedef decltype(begin(ref)) Iter; 544 Iter it; 545 std::function<Func> f; 546 iterator( Iter it, std::function<Func> f ) : it(it), f(f) {} 547 iterator & operator++() { 548 ++it; return *this; 549 } 550 bool operator!=( const iterator &other ) const { return it != other.it; } 551 auto operator*() const -> decltype(f(*it)) { return f(*it); } 552 }; 553 554 lambda_iterate_t( const T & ref, std::function<Func> f ) : ref(ref), f(f) {} 555 556 auto begin() const -> decltype(iterator(std::begin(ref), f)) { return iterator(std::begin(ref), f); } 557 auto end() const -> decltype(iterator(std::end(ref), f)) { return iterator(std::end(ref), f); } 558 }; 559 560 template< typename... Args > 561 lambda_iterate_t<Args...> lazy_map( const Args &... args ) { 562 return lambda_iterate_t<Args...>( args...); 563 } 232 564 233 565 // ----------------------------------------------------------------------------- … … 251 583 } // ilog2 252 584 585 // ----------------------------------------------------------------------------- 586 /// evaluates expr as a long long int. If second is false, expr could not be evaluated 587 std::pair<long long int, bool> eval(const Expression * expr); 588 589 namespace ast { 590 class Expr; 591 } 592 593 std::pair<long long int, bool> eval(const ast::Expr * expr); 594 595 // ----------------------------------------------------------------------------- 596 /// Reorders the input range in-place so that the minimal-value elements according to the 597 /// comparator are in front; 598 /// returns the iterator after the last minimal-value element. 599 template<typename Iter, typename Compare> 600 Iter sort_mins( Iter begin, Iter end, Compare& lt ) { 601 if ( begin == end ) return end; 602 603 Iter min_pos = begin; 604 for ( Iter i = begin + 1; i != end; ++i ) { 605 if ( lt( *i, *min_pos ) ) { 606 // new minimum cost; swap into first position 607 min_pos = begin; 608 std::iter_swap( min_pos, i ); 609 } else if ( ! lt( *min_pos, *i ) ) { 610 // duplicate minimum cost; swap into next minimum position 611 ++min_pos; 612 std::iter_swap( min_pos, i ); 613 } 614 } 615 return ++min_pos; 616 } 617 618 template<typename Iter, typename Compare> 619 inline Iter sort_mins( Iter begin, Iter end, Compare&& lt ) { 620 return sort_mins( begin, end, lt ); 621 } 622 623 /// sort_mins defaulted to use std::less 624 template<typename Iter> 625 inline Iter sort_mins( Iter begin, Iter end ) { 626 return sort_mins( begin, end, std::less<typename std::iterator_traits<Iter>::value_type>{} ); 627 } 628 253 629 // Local Variables: // 254 630 // tab-width: 4 // -
src/CompilationState.cc
r24d6572 r34b4268 9 9 // Author : Rob Schluntz 10 10 // Created On : Mon Ju1 30 10:47:01 2018 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Apr 10 19:12:50 202313 // Update Count : 611 // Last Modified By : Henry Xue 12 // Last Modified On : Tue Jul 20 04:27:35 2021 13 // Update Count : 5 14 14 // 15 15 … … 27 27 expraltp = false, 28 28 genericsp = false, 29 invariant = false,30 29 libcfap = false, 31 30 nopreludep = false, … … 34 33 useNewAST = true, 35 34 nomainp = false, 35 parsep = false, 36 36 resolvep = false, 37 37 resolvprotop = false, -
src/CompilationState.h
r24d6572 r34b4268 9 9 // Author : Rob Schluntz 10 10 // Created On : Mon Ju1 30 10:47:01 2018 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Apr 10 19:12:53 202313 // Update Count : 611 // Last Modified By : Henry Xue 12 // Last Modified On : Tue Jul 20 04:27:35 2021 13 // Update Count : 5 14 14 // 15 15 … … 26 26 expraltp, 27 27 genericsp, 28 invariant,29 28 libcfap, 30 29 nopreludep, … … 33 32 useNewAST, 34 33 nomainp, 34 parsep, 35 35 resolvep, 36 36 resolvprotop, -
src/Concurrency/KeywordsNew.cpp
r24d6572 r34b4268 779 779 780 780 const ast::Stmt * SuspendKeyword::postvisit( const ast::SuspendStmt * stmt ) { 781 switch ( stmt-> kind) {781 switch ( stmt->type ) { 782 782 case ast::SuspendStmt::None: 783 783 // Use the context to determain the implicit target. -
src/Concurrency/WaitforNew.cpp
r24d6572 r34b4268 305 305 306 306 const ast::VariableExpr * variableExpr = 307 clause->target .as<ast::VariableExpr>();307 clause->target_func.as<ast::VariableExpr>(); 308 308 ast::Expr * castExpr = new ast::CastExpr( 309 309 location, 310 310 new ast::CastExpr( 311 311 location, 312 clause->target ,312 clause->target_func, 313 313 ast::deepCopy( variableExpr->result.get() ), 314 314 ast::GeneratedCast ), … … 325 325 326 326 ResolveContext context{ symtab, transUnit().global }; 327 out->push_back( maybeCond( location, clause-> when_cond.get(), {327 out->push_back( maybeCond( location, clause->cond.get(), { 328 328 makeAccStmt( location, acceptables, index, "is_dtor", 329 detectIsDtor( location, clause->target ), context ),329 detectIsDtor( location, clause->target_func ), context ), 330 330 makeAccStmt( location, acceptables, index, "func", 331 331 funcExpr, context ), -
src/Concurrency/module.mk
r24d6572 r34b4268 16 16 17 17 SRC += \ 18 Concurrency/Actors.cpp \19 Concurrency/Actors.hpp \20 18 Concurrency/KeywordsNew.cpp \ 21 19 Concurrency/Keywords.cc \ … … 23 21 Concurrency/WaitforNew.cpp \ 24 22 Concurrency/Waitfor.cc \ 25 Concurrency/Waitfor.h \ 26 Concurrency/Waituntil.cpp \ 27 Concurrency/Waituntil.hpp 23 Concurrency/Waitfor.h -
src/ControlStruct/ExceptDeclNew.cpp
r24d6572 r34b4268 16 16 #include "ExceptDecl.h" 17 17 18 #include <sstream>19 20 #include "AST/Copy.hpp"21 18 #include "AST/Decl.hpp" 22 19 #include "AST/Pass.hpp" -
src/ControlStruct/ExceptTranslateNew.cpp
r24d6572 r34b4268 314 314 nullptr, 315 315 ast::Storage::Classes{}, 316 ast::Linkage::Cforall, 317 {}, 318 { ast::Function::Inline } 316 ast::Linkage::Cforall 319 317 ); 320 318 } -
src/ControlStruct/MLEMutator.cc
r24d6572 r34b4268 25 25 #include <memory> // for allocator_traits<>::value_... 26 26 27 #include "Common/ ToString.hpp" // for toString27 #include "Common/utility.h" // for toString, operator+ 28 28 #include "ControlStruct/LabelGenerator.h" // for LabelGenerator 29 29 #include "MLEMutator.h" -
src/GenPoly/Box.cc
r24d6572 r34b4268 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Dec 19 16:36:00 202213 // Update Count : 34 811 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 23:40:34 2019 13 // Update Count : 347 14 14 // 15 16 #include "Box.h"17 15 18 16 #include <algorithm> // for mismatch … … 26 24 #include <utility> // for pair 27 25 26 #include "Box.h" 27 28 28 #include "CodeGen/OperatorTable.h" 29 29 #include "Common/PassVisitor.h" // for PassVisitor … … 31 31 #include "Common/SemanticError.h" // for SemanticError 32 32 #include "Common/UniqueName.h" // for UniqueName 33 #include "Common/ ToString.hpp" // for toCString33 #include "Common/utility.h" // for toString 34 34 #include "FindFunction.h" // for findFunction, findAndReplace... 35 35 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_i... … … 37 37 #include "InitTweak/InitTweak.h" // for getFunctionName, isAssignment 38 38 #include "Lvalue.h" // for generalizedLvalue 39 #include "ResolvExpr/ Unify.h"// for typesCompatible39 #include "ResolvExpr/typeops.h" // for typesCompatible 40 40 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iter... 41 41 #include "ScrubTyVars.h" // for ScrubTyVars … … 72 72 }; 73 73 74 /// Updates the call sites of polymorphic functions.75 74 /// Replaces polymorphic return types with out-parameters, 76 75 /// replaces calls to polymorphic functions with adapter calls, 77 76 /// and adds appropriate type variables to the function call. 78 class CallAdapter final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<CallAdapter>, public WithShortCircuiting {77 class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting { 79 78 public: 80 CallAdapter(); 81 82 void premutate( Declaration * declaration ); 79 Pass1(); 80 83 81 void premutate( FunctionDecl * functionDecl ); 84 82 void premutate( TypeDecl * typeDecl ); … … 140 138 }; 141 139 142 /// Updates declarations (and types) that require adapters.143 140 /// * Moves polymorphic returns in function types to pointer-type parameters 144 141 /// * adds type size and assertion parameters to parameter lists 145 struct DeclAdapterfinal : public BoxPass, public WithGuards {142 struct Pass2 final : public BoxPass, public WithGuards { 146 143 void handleAggDecl(); 147 144 … … 213 210 }; 214 211 215 /// Erases unneeded/unwanted polymorphic information.216 212 /// Replaces initialization of polymorphic values with alloca, 217 213 /// declaration of dtype/ftype with appropriate void expression, 218 214 /// sizeof expressions of polymorphic types with the proper variable, 219 215 /// and strips fields from generic struct declarations. 220 struct Eraser final { 216 struct Pass3 final : public BoxPass, public WithGuards { 217 template< typename DeclClass > 218 void handleDecl( DeclClass * decl, Type * type ); 219 221 220 void premutate( ObjectDecl * objectDecl ); 222 221 void premutate( FunctionDecl * functionDecl ); … … 224 223 void premutate( StructDecl * structDecl ); 225 224 void premutate( UnionDecl * unionDecl ); 225 void premutate( TypeDecl * typeDecl ); 226 void premutate( PointerType * pointerType ); 227 void premutate( FunctionType * funcType ); 226 228 }; 227 229 } // anonymous namespace … … 229 231 void box( std::list< Declaration *>& translationUnit ) { 230 232 PassVisitor<LayoutFunctionBuilder> layoutBuilder; 231 PassVisitor< CallAdapter> callAdapter;232 PassVisitor< DeclAdapter> declAdapter;233 PassVisitor<Pass1> pass1; 234 PassVisitor<Pass2> pass2; 233 235 PassVisitor<PolyGenericCalculator> polyCalculator; 234 PassVisitor< Eraser> eraser;236 PassVisitor<Pass3> pass3; 235 237 236 238 acceptAll( translationUnit, layoutBuilder ); 237 mutateAll( translationUnit, callAdapter);238 mutateAll( translationUnit, declAdapter);239 mutateAll( translationUnit, pass1 ); 240 mutateAll( translationUnit, pass2 ); 239 241 mutateAll( translationUnit, polyCalculator ); 240 mutateAll( translationUnit, eraser);242 mutateAll( translationUnit, pass3 ); 241 243 } 242 244 243 ////////////////////////////////// LayoutFunctionBuilder////////////////////////////////////////245 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 244 246 245 247 /// Get a list of type declarations that will affect a layout function … … 421 423 } 422 424 423 ////////////////////////////////////////////// CallAdapter//////////////////////////////////////425 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 424 426 425 427 namespace { 426 428 std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) { 429 std::stringstream name; 430 427 431 // NOTE: this function previously used isPolyObj, which failed to produce 428 432 // the correct thing in some situations. It's not clear to me why this wasn't working. … … 431 435 // to take those polymorphic types as pointers. Therefore, there can be two different functions 432 436 // with the same mangled name, so we need to further mangle the names. 433 std::stringstream name;434 437 for ( DeclarationWithType const * const ret : function->returnVals ) { 435 name << ( isPolyType( ret->get_type(), tyVars ) ? 'P' : 'M' ); 436 } 437 name << '_'; 438 if ( isPolyType( ret->get_type(), tyVars ) ) { 439 name << "P"; 440 } else { 441 name << "M"; 442 } 443 } 444 name << "_"; 438 445 for ( DeclarationWithType const * const arg : function->parameters ) { 439 name << ( isPolyType( arg->get_type(), tyVars ) ? 'P' : 'M' ); 440 } 446 if ( isPolyType( arg->get_type(), tyVars ) ) { 447 name << "P"; 448 } else { 449 name << "M"; 450 } 451 } // for 441 452 return name.str(); 442 453 } … … 454 465 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true ); 455 466 456 CallAdapter::CallAdapter() : tempNamer( "_temp" ) {} 457 458 void CallAdapter::premutate( Declaration * ) { 459 // Prevent type declaration information from leaking out. 460 GuardScope( scopeTyVars ); 461 } 462 463 void CallAdapter::premutate( FunctionDecl *functionDecl ) { 467 Pass1::Pass1() : tempNamer( "_temp" ) {} 468 469 void Pass1::premutate( FunctionDecl *functionDecl ) { 464 470 if ( functionDecl->get_statements() ) { // empty routine body ? 465 471 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; … … 494 500 for ( FunctionType const * const funType : functions ) { 495 501 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 496 if ( !adapters.contains( mangleName) ) {502 if ( adapters.find( mangleName ) == adapters.end() ) { 497 503 std::string adapterName = makeAdapterName( mangleName ); 498 504 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) ); … … 503 509 } 504 510 505 void CallAdapter::premutate( TypeDecl *typeDecl ) {511 void Pass1::premutate( TypeDecl *typeDecl ) { 506 512 addToTyVarMap( typeDecl, scopeTyVars ); 507 513 } 508 514 509 void CallAdapter::premutate( CommaExpr *commaExpr ) {515 void Pass1::premutate( CommaExpr *commaExpr ) { 510 516 // Attempting to find application expressions that were mutated by the copy constructor passes 511 517 // to use an explicit return variable, so that the variable can be reused as a parameter to the … … 525 531 } 526 532 527 std::list< Expression *>::iterator CallAdapter::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {533 std::list< Expression *>::iterator Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 528 534 Type *polyType = isPolyType( parmType, exprTyVars ); 529 535 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { … … 552 558 } 553 559 554 std::list< Expression *>::iterator CallAdapter::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) {560 std::list< Expression *>::iterator Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) { 555 561 assert( env ); 556 562 std::list< Expression *>::iterator arg = appExpr->args.begin(); … … 562 568 // even when converted to strings, sort in the original order. 563 569 // (At least, that is the best explination I have.) 564 for ( std::pair< conststd::string, TypeDecl::Data> const & tyParam : exprTyVars ) {570 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 565 571 if ( !tyParam.second.isComplete ) continue; 566 572 Type *concrete = env->lookup( tyParam.first ); … … 605 611 } 606 612 607 ObjectDecl * CallAdapter::makeTemporary( Type *type ) {613 ObjectDecl *Pass1::makeTemporary( Type *type ) { 608 614 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 ); 609 615 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); … … 611 617 } 612 618 613 Expression * CallAdapter::addRetParam( ApplicationExpr *appExpr, Type *retType ) {619 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) { 614 620 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 615 621 // using a comma expression. … … 674 680 } 675 681 676 Expression * CallAdapter::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) {682 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) { 677 683 Type *concrete = replaceWithConcrete( dynType, env ); 678 684 // add out-parameter for return value … … 680 686 } 681 687 682 Expression * CallAdapter::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) {688 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 683 689 Expression *ret = appExpr; 684 690 if ( isDynRet( function, scopeTyVars ) ) { … … 729 735 } 730 736 731 void CallAdapter::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) {737 void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) { 732 738 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 733 739 addCast( arg, param, exprTyVars ); … … 764 770 } 765 771 766 void CallAdapter::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) {772 void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) { 767 773 for ( DeclarationWithType * param : function->parameters ) { 768 774 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); … … 772 778 } 773 779 774 void CallAdapter::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {780 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 775 781 for ( TypeDecl * const tyVar : functionType->forall ) { 776 782 for ( DeclarationWithType * const assert : tyVar->assertions ) { … … 840 846 } 841 847 842 FunctionDecl * CallAdapter::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {848 FunctionDecl *Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 843 849 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 844 850 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); … … 900 906 } 901 907 902 void CallAdapter::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) {908 void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) { 903 909 // collect a list of function types passed as parameters or implicit parameters (assertions) 904 910 std::list<FunctionType const *> functions; … … 917 923 918 924 for ( FunctionType const * const funType : functions ) { 919 std::string mangleName = SymTab::Mangler::mangle( funType ); 925 FunctionType *originalFunction = funType->clone(); 926 FunctionType *realFunction = funType->clone(); 927 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 920 928 921 929 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 922 930 // pre-substitution parameter function type. 923 931 // The second part of the insert result is "is the value new". 924 if ( !adaptersDone.insert( mangleName ).second ) continue; 925 926 // Apply substitution to type variables to figure out what the adapter's type should look like. 927 assert( env ); 928 FunctionType *realType = funType->clone(); 929 env->apply( realType ); 930 mangleName = SymTab::Mangler::mangle( realType ); 931 mangleName += makePolyMonoSuffix( funType, exprTyVars ); 932 933 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 934 AdapterIter adapter = adapters.find( mangleName ); 935 if ( adapter == adapters.end() ) { 936 // Adapter has not been created yet in the current scope, so define it. 937 FunctionDecl *newAdapter = makeAdapter( funType, realType, mangleName, exprTyVars ); 938 std::pair< AdapterIter, bool > answer = adapters.insert( mangleName, newAdapter ); 939 adapter = answer.first; 940 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 932 if ( adaptersDone.insert( mangleName ).second ) { 933 934 // apply substitution to type variables to figure out what the adapter's type should look like 935 assert( env ); 936 env->apply( realFunction ); 937 mangleName = SymTab::Mangler::mangle( realFunction ); 938 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 939 940 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 941 AdapterIter adapter = adapters.find( mangleName ); 942 if ( adapter == adapters.end() ) { 943 // adapter has not been created yet in the current scope, so define it 944 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars ); 945 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 946 adapter = answer.first; 947 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 948 } // if 949 assert( adapter != adapters.end() ); 950 951 // add the appropriate adapter as a parameter 952 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 941 953 } // if 942 assert( adapter != adapters.end() );943 944 // Add the appropriate adapter as a parameter.945 appExpr->args.push_front( new VariableExpr( adapter->second ) );946 954 } // for 947 955 } // passAdapters … … 966 974 } 967 975 968 Expression * CallAdapter::handleIntrinsics( ApplicationExpr *appExpr ) {976 Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) { 969 977 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->function ) ) { 970 978 if ( varExpr->var->linkage == LinkageSpec::Intrinsic ) { … … 1089 1097 } 1090 1098 1091 Expression * CallAdapter::postmutate( ApplicationExpr *appExpr ) {1099 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) { 1092 1100 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1093 1101 // for ( auto tyVar : scopeTyVars ) { … … 1161 1169 } 1162 1170 1163 Expression * CallAdapter::postmutate( UntypedExpr *expr ) {1171 Expression * Pass1::postmutate( UntypedExpr *expr ) { 1164 1172 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1165 1173 Expression *ret = expr->args.front(); … … 1171 1179 } 1172 1180 1173 void CallAdapter::premutate( AddressExpr * ) { visit_children = false; }1174 1175 Expression * CallAdapter::postmutate( AddressExpr * addrExpr ) {1181 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1182 1183 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1176 1184 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); 1177 1185 … … 1204 1212 } 1205 1213 1206 void CallAdapter::premutate( ReturnStmt *returnStmt ) {1214 void Pass1::premutate( ReturnStmt *returnStmt ) { 1207 1215 if ( retval && returnStmt->expr ) { 1208 1216 assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() ); … … 1212 1220 } 1213 1221 1214 void CallAdapter::premutate( PointerType *pointerType ) {1222 void Pass1::premutate( PointerType *pointerType ) { 1215 1223 GuardScope( scopeTyVars ); 1216 1224 makeTyVarMap( pointerType, scopeTyVars ); 1217 1225 } 1218 1226 1219 void CallAdapter::premutate( FunctionType *functionType ) {1227 void Pass1::premutate( FunctionType *functionType ) { 1220 1228 GuardScope( scopeTyVars ); 1221 1229 makeTyVarMap( functionType, scopeTyVars ); 1222 1230 } 1223 1231 1224 void CallAdapter::beginScope() {1232 void Pass1::beginScope() { 1225 1233 adapters.beginScope(); 1226 1234 } 1227 1235 1228 void CallAdapter::endScope() {1236 void Pass1::endScope() { 1229 1237 adapters.endScope(); 1230 1238 } 1231 1239 1232 ////////////////////////////////////////// DeclAdapter//////////////////////////////////////////1233 1234 void DeclAdapter::addAdapters( FunctionType *functionType ) {1240 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 1241 1242 void Pass2::addAdapters( FunctionType *functionType ) { 1235 1243 std::list< FunctionType const *> functions; 1236 1244 for ( DeclarationWithType * const arg : functionType->parameters ) { … … 1252 1260 } 1253 1261 1254 DeclarationWithType * DeclAdapter::postmutate( FunctionDecl *functionDecl ) {1262 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) { 1255 1263 FunctionType * ftype = functionDecl->type; 1256 1264 if ( ! ftype->returnVals.empty() && functionDecl->statements ) { … … 1277 1285 } 1278 1286 1279 void DeclAdapter::premutate( StructDecl * ) {1287 void Pass2::premutate( StructDecl * ) { 1280 1288 // prevent tyVars from leaking into containing scope 1281 1289 GuardScope( scopeTyVars ); 1282 1290 } 1283 1291 1284 void DeclAdapter::premutate( UnionDecl * ) {1292 void Pass2::premutate( UnionDecl * ) { 1285 1293 // prevent tyVars from leaking into containing scope 1286 1294 GuardScope( scopeTyVars ); 1287 1295 } 1288 1296 1289 void DeclAdapter::premutate( TraitDecl * ) {1297 void Pass2::premutate( TraitDecl * ) { 1290 1298 // prevent tyVars from leaking into containing scope 1291 1299 GuardScope( scopeTyVars ); 1292 1300 } 1293 1301 1294 void DeclAdapter::premutate( TypeDecl *typeDecl ) {1302 void Pass2::premutate( TypeDecl *typeDecl ) { 1295 1303 addToTyVarMap( typeDecl, scopeTyVars ); 1296 1304 } 1297 1305 1298 void DeclAdapter::premutate( PointerType *pointerType ) {1306 void Pass2::premutate( PointerType *pointerType ) { 1299 1307 GuardScope( scopeTyVars ); 1300 1308 makeTyVarMap( pointerType, scopeTyVars ); 1301 1309 } 1302 1310 1303 void DeclAdapter::premutate( FunctionType *funcType ) {1311 void Pass2::premutate( FunctionType *funcType ) { 1304 1312 GuardScope( scopeTyVars ); 1305 1313 makeTyVarMap( funcType, scopeTyVars ); … … 1385 1393 } 1386 1394 1387 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////// 1395 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////////////////////////// 1388 1396 1389 1397 PolyGenericCalculator::PolyGenericCalculator() … … 1466 1474 // make sure that any type information passed into the function is accounted for 1467 1475 for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) { 1468 // condition here duplicates that in DeclAdapter::mutate( FunctionType* )1476 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1469 1477 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars ); 1470 1478 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { … … 1493 1501 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 1494 1502 // do not try to monomorphize generic parameters 1495 if ( scopeTyVars. contains( typeInst->get_name()) && ! genericParams.count( typeInst->name ) ) {1503 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() && ! genericParams.count( typeInst->name ) ) { 1496 1504 // polymorphic aggregate members should be converted into monomorphic members. 1497 1505 // Using char[size_T] here respects the expected sizing rules of an aggregate type. … … 1702 1710 1703 1711 if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) { 1704 if ( scopeTyVars. contains( typeInst->get_name()) ) {1712 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 1705 1713 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set 1706 1714 return true; … … 1710 1718 // check if this type already has a layout generated for it 1711 1719 std::string typeName = mangleType( ty ); 1712 if ( knownLayouts. contains( typeName) ) return true;1720 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true; 1713 1721 1714 1722 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 1747 1755 // check if this type already has a layout generated for it 1748 1756 std::string typeName = mangleType( ty ); 1749 if ( knownLayouts. contains( typeName) ) return true;1757 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true; 1750 1758 1751 1759 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 1838 1846 } else { 1839 1847 std::string offsetName = offsetofName( mangleType( ty ) ); 1840 if ( knownOffsets. contains( offsetName) ) {1848 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) { 1841 1849 // use the already-generated offsets for this type 1842 1850 ret = new NameExpr( offsetName ); … … 1876 1884 } 1877 1885 1878 ////////////////////////////////////////// Eraser /////////////////////////////////////////////// 1879 1880 void Eraser::premutate( ObjectDecl * objectDecl ) { 1881 ScrubTyVars::scrubAll( objectDecl ); 1882 } 1883 1884 void Eraser::premutate( FunctionDecl * functionDecl ) { 1885 ScrubTyVars::scrubAll( functionDecl ); 1886 } 1887 1888 void Eraser::premutate( TypedefDecl * typedefDecl ) { 1889 ScrubTyVars::scrubAll( typedefDecl ); 1886 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 1887 1888 template< typename DeclClass > 1889 void Pass3::handleDecl( DeclClass * decl, Type * type ) { 1890 GuardScope( scopeTyVars ); 1891 makeTyVarMap( type, scopeTyVars ); 1892 ScrubTyVars::scrubAll( decl ); 1893 } 1894 1895 void Pass3::premutate( ObjectDecl * objectDecl ) { 1896 handleDecl( objectDecl, objectDecl->type ); 1897 } 1898 1899 void Pass3::premutate( FunctionDecl * functionDecl ) { 1900 handleDecl( functionDecl, functionDecl->type ); 1901 } 1902 1903 void Pass3::premutate( TypedefDecl * typedefDecl ) { 1904 handleDecl( typedefDecl, typedefDecl->base ); 1890 1905 } 1891 1906 1892 1907 /// Strips the members from a generic aggregate 1893 static void stripGenericMembers( AggregateDecl * decl) {1908 void stripGenericMembers(AggregateDecl * decl) { 1894 1909 if ( ! decl->parameters.empty() ) decl->members.clear(); 1895 1910 } 1896 1911 1897 void Eraser::premutate( StructDecl * structDecl ) {1912 void Pass3::premutate( StructDecl * structDecl ) { 1898 1913 stripGenericMembers( structDecl ); 1899 1914 } 1900 1915 1901 void Eraser::premutate( UnionDecl * unionDecl ) {1916 void Pass3::premutate( UnionDecl * unionDecl ) { 1902 1917 stripGenericMembers( unionDecl ); 1918 } 1919 1920 void Pass3::premutate( TypeDecl * typeDecl ) { 1921 addToTyVarMap( typeDecl, scopeTyVars ); 1922 } 1923 1924 void Pass3::premutate( PointerType * pointerType ) { 1925 GuardScope( scopeTyVars ); 1926 makeTyVarMap( pointerType, scopeTyVars ); 1927 } 1928 1929 void Pass3::premutate( FunctionType * functionType ) { 1930 GuardScope( scopeTyVars ); 1931 makeTyVarMap( functionType, scopeTyVars ); 1903 1932 } 1904 1933 } // anonymous namespace … … 1910 1939 // compile-command: "make install" // 1911 1940 // End: // 1941 -
src/GenPoly/ErasableScopedMap.h
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ErasableScopedMap.h --7 // ScopedMap.h -- 8 8 // 9 9 // Author : Aaron B. Moss … … 51 51 typedef typename Scope::const_pointer const_pointer; 52 52 53 // Both iterator types are complete bidirection al iterators, seebelow.53 // Both iterator types are complete bidirection iterators, defined below. 54 54 class iterator; 55 55 class const_iterator; … … 118 118 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 119 119 120 Value& operator[] ( const Key &key ) {121 iterator slot = find( key );122 if ( slot != end() ) return slot->second;123 return insert( key, Value() ).first->second;124 }125 126 120 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 127 121 size_type erase( const Key &key ) { … … 136 130 } 137 131 138 bool contains( const Key & key ) const { 139 return find( key ) != cend(); 132 Value& operator[] ( const Key &key ) { 133 iterator slot = find( key ); 134 if ( slot != end() ) return slot->second; 135 return insert( key, Value() ).first->second; 140 136 } 141 137 }; -
src/GenPoly/FindFunction.cc
r24d6572 r34b4268 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Oct 7 17:05:20 202213 // Update Count : 711 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Feb 05 12:22:20 2016 13 // Update Count : 6 14 14 // 15 15 … … 18 18 #include <utility> // for pair 19 19 20 #include "AST/Pass.hpp" // for Pass21 #include "AST/Type.hpp"22 20 #include "Common/PassVisitor.h" // for PassVisitor 23 21 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::iterator … … 91 89 handleForall( pointerType->get_forall() ); 92 90 } 93 94 namespace {95 96 struct FindFunctionCore :97 public ast::WithGuards,98 public ast::WithShortCircuiting,99 public ast::WithVisitorRef<FindFunctionCore> {100 FindFunctionCore(101 std::vector<ast::ptr<ast::FunctionType>> & functions,102 const TypeVarMap & typeVars, FindFunctionPred predicate,103 bool replaceMode );104 105 void previsit( ast::FunctionType const * type );106 ast::Type const * postvisit( ast::FunctionType const * type );107 void previsit( ast::PointerType const * type );108 private:109 void handleForall( const ast::FunctionType::ForallList & forall );110 111 std::vector<ast::ptr<ast::FunctionType>> &functions;112 TypeVarMap typeVars;113 FindFunctionPred predicate;114 bool replaceMode;115 };116 117 FindFunctionCore::FindFunctionCore(118 std::vector<ast::ptr<ast::FunctionType>> & functions,119 const TypeVarMap &typeVars, FindFunctionPred predicate,120 bool replaceMode ) :121 functions( functions ), typeVars( typeVars ),122 predicate( predicate ), replaceMode( replaceMode ) {}123 124 void FindFunctionCore::handleForall( const ast::FunctionType::ForallList & forall ) {125 for ( const ast::ptr<ast::TypeInstType> & td : forall ) {126 TypeVarMap::iterator var = typeVars.find( *td );127 if ( var != typeVars.end() ) {128 typeVars.erase( var->first );129 } // if130 } // for131 }132 133 void FindFunctionCore::previsit( ast::FunctionType const * type ) {134 visit_children = false;135 GuardScope( typeVars );136 handleForall( type->forall );137 //ast::accept_all( type->returns, *visitor );138 // This might have to become ast::mutate_each with return.139 ast::accept_each( type->returns, *visitor );140 }141 142 ast::Type const * FindFunctionCore::postvisit( ast::FunctionType const * type ) {143 ast::Type const * ret = type;144 if ( predicate( type, typeVars ) ) {145 functions.push_back( type );146 if ( replaceMode ) {147 // replace type parameters in function type with void*148 ret = scrubTypeVars( ast::deepCopy( type ), typeVars );149 } // if150 } // if151 return ret;152 }153 154 void FindFunctionCore::previsit( ast::PointerType const * /*type*/ ) {155 GuardScope( typeVars );156 //handleForall( type->forall );157 }158 159 } // namespace160 161 void findFunction( const ast::Type * type,162 std::vector<ast::ptr<ast::FunctionType>> & functions,163 const TypeVarMap & typeVars, FindFunctionPred predicate ) {164 ast::Pass<FindFunctionCore> pass( functions, typeVars, predicate, false );165 type->accept( pass );166 //(void)type;167 //(void)functions;168 //(void)typeVars;169 //(void)predicate;170 }171 172 const ast::Type * findAndReplaceFunction( const ast::Type * type,173 std::vector<ast::ptr<ast::FunctionType>> & functions,174 const TypeVarMap & typeVars, FindFunctionPred predicate ) {175 ast::Pass<FindFunctionCore> pass( functions, typeVars, predicate, true );176 return type->accept( pass );177 //(void)functions;178 //(void)typeVars;179 //(void)predicate;180 //return type;181 }182 183 91 } // namespace GenPoly 184 92 -
src/GenPoly/FindFunction.h
r24d6572 r34b4268 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Oct 7 10:30:00 202213 // Update Count : 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:23:36 2017 13 // Update Count : 2 14 14 // 15 15 … … 30 30 /// like `findFunction`, but also replaces the function type with void ()(void) 31 31 void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 32 33 typedef bool (*FindFunctionPred)( const ast::FunctionType *, const TypeVarMap & );34 35 /// Recursively walks `type`, placing all functions that match `predicate`36 /// under `typeVars` into `functions`.37 void findFunction( const ast::Type * type,38 std::vector<ast::ptr<ast::FunctionType>> & functions,39 const TypeVarMap & typeVars, FindFunctionPred predicate );40 /// Like findFunction, but also replaces the function type with `void ()(void)`.41 const ast::Type * findAndReplaceFunction( const ast::Type * type,42 std::vector<ast::ptr<ast::FunctionType>> & functions,43 const TypeVarMap & typeVars, FindFunctionPred predicate );44 45 32 } // namespace GenPoly 46 33 -
src/GenPoly/GenPoly.cc
r24d6572 r34b4268 24 24 #include <vector> // for vector 25 25 26 #include "AST/Expr.hpp"27 26 #include "AST/Type.hpp" 28 #include "AST/TypeSubstitution.hpp"29 27 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 30 28 #include "ResolvExpr/typeops.h" // for flatten … … 172 170 173 171 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 174 if ( tyVars. contains( typeInst->get_name()) ) {172 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 175 173 return type; 176 174 } … … 189 187 190 188 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 191 if ( tyVars.contains( typeInst->typeString() ) ) return type;189 return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr; 192 190 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) { 193 191 return isPolyType( arrayType->base, env ); … … 205 203 206 204 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 207 if ( typeVars. contains( *inst) ) return type;205 if ( typeVars.find( *inst ) != typeVars.end() ) return type; 208 206 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 209 207 return isPolyType( array->base, subst ); … … 274 272 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes ); 275 273 } 276 277 const ast::BaseInstType *isDynRet( const ast::FunctionType * func ) {278 if ( func->returns.empty() ) return nullptr;279 280 TypeVarMap forallTypes = { ast::TypeData() };281 makeTypeVarMap( func, forallTypes );282 return isDynType( func->returns.front(), forallTypes );283 }284 274 285 275 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { … … 327 317 return 0; 328 318 } 329 330 const ast::Type * isPolyPtr(331 const ast::Type * type, const TypeVarMap & typeVars,332 const ast::TypeSubstitution * typeSubs ) {333 type = replaceTypeInst( type, typeSubs );334 335 if ( auto * ptr = dynamic_cast<ast::PointerType const *>( type ) ) {336 return isPolyType( ptr->base, typeVars, typeSubs );337 }338 return nullptr;339 }340 319 341 320 Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) { … … 412 391 413 392 if ( TypeInstType *typeInstType = dynamic_cast< TypeInstType * >( type ) ) { 414 if ( tyVars. contains( typeInstType->get_name()) ) {393 if ( tyVars.find( typeInstType->get_name() ) != tyVars.end() ) { 415 394 return true; 416 395 } … … 511 490 } 512 491 513 /// Flattens a list of types.514 // There is another flattenList in Unify.515 492 void flattenList( vector<ast::ptr<ast::Type>> const & src, 516 493 vector<ast::ptr<ast::Type>> & out ) { … … 815 792 } 816 793 817 void addToTypeVarMap( const ast::TypeDecl * decl, TypeVarMap & typeVars ) {818 typeVars.insert( ast::TypeEnvKey( decl, 0, 0 ), ast::TypeData( decl ) );819 }820 821 794 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 822 typeVars.insert( ast::TypeEnvKey( *type ), ast::TypeData( type->base ) );795 typeVars.insert( *type, ast::TypeData( type->base ) ); 823 796 } 824 797 … … 845 818 } 846 819 847 void makeTypeVarMap( const ast::FunctionDecl * decl, TypeVarMap & typeVars ) {848 for ( auto & typeDecl : decl->type_params ) {849 addToTypeVarMap( typeDecl, typeVars );850 }851 }852 853 820 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { 854 821 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) { -
src/GenPoly/GenPoly.h
r24d6572 r34b4268 111 111 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); 112 112 void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars ); 113 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars );114 113 115 114 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` 116 115 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 117 116 void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ); 118 void makeTypeVarMap( const ast::FunctionDecl * decl, TypeVarMap & typeVars );119 117 120 118 /// Prints type variable map -
src/GenPoly/InstantiateGeneric.cc
r24d6572 r34b4268 28 28 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 29 29 #include "InitTweak/InitTweak.h" 30 #include "ResolvExpr/AdjustExprType.hpp" // for adjustExprType 31 #include "ResolvExpr/Unify.h" // for typesCompatible 30 #include "ResolvExpr/typeops.h" 32 31 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 33 32 #include "ScrubTyVars.h" // for ScrubTyVars -
src/GenPoly/InstantiateGenericNew.cpp
r24d6572 r34b4268 32 32 #include "GenPoly/GenPoly.h" // for isPolyType, typesPolyCompatible 33 33 #include "GenPoly/ScrubTyVars.h" // for scrubAll 34 #include "ResolvExpr/AdjustExprType.hpp" // for adjustExprType 35 #include "ResolvExpr/Unify.h" // for typesCompatible 34 #include "ResolvExpr/typeops.h" // for typesCompatible 36 35 37 36 namespace GenPoly { … … 362 361 ResolvExpr::typesCompatible( 363 362 memberExpr->result, 364 memberExpr->member->get_type() ) ) {363 memberExpr->member->get_type(), ast::SymbolTable() ) ) { 365 364 return memberExpr; 366 365 } -
src/GenPoly/Lvalue.cc
r24d6572 r34b4268 17 17 #include <string> // for string 18 18 19 #include "Common/ToString.hpp" // for toCString20 19 #include "Common/UniqueName.h" 21 20 #include "Common/PassVisitor.h" -
src/GenPoly/LvalueNew.cpp
r24d6572 r34b4268 25 25 #include "AST/Pass.hpp" 26 26 #include "Common/SemanticError.h" // for SemanticWarning 27 #include "Common/ToString.hpp" // for toCString28 27 #include "Common/UniqueName.h" // for UniqueName 29 28 #include "GenPoly/GenPoly.h" // for genFunctionType … … 359 358 !ResolvExpr::typesCompatible( 360 359 srcType, 361 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) { 360 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base, 361 ast::SymbolTable() ) ) { 362 362 // Must keep cast if cast-to type is different from the actual type. 363 363 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); … … 376 376 if ( !ResolvExpr::typesCompatibleIgnoreQualifiers( 377 377 dstType->stripReferences(), 378 srcType->stripReferences() ) ) { 378 srcType->stripReferences(), 379 ast::SymbolTable() ) ) { 379 380 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); 380 381 } … … 391 392 ResolvExpr::typesCompatible( 392 393 expr->result, 393 expr->arg->result ) ) {394 expr->arg->result, ast::SymbolTable() ) ) { 394 395 PRINT( 395 396 std::cerr << "types are compatible, removing cast: " << expr << '\n'; … … 588 589 ast::OpenVarSet openVars; 589 590 ResolvExpr::unify( ret->arg2->result, ret->arg3->result, newEnv, 590 needAssertions, haveAssertions, openVars, common ); 591 needAssertions, haveAssertions, openVars, 592 ast::SymbolTable(), common ); 591 593 ret->result = common ? common : ast::deepCopy( ret->arg2->result ); 592 594 return ret; -
src/GenPoly/ScopedSet.h
r24d6572 r34b4268 21 21 22 22 namespace GenPoly { 23 24 /// A set where the items are placed into nested scopes; 25 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 26 template<typename Value> 27 class ScopedSet { 28 typedef std::set< Value > Scope; 29 typedef std::vector< Scope > ScopeList; 30 31 /// Scoped list of sets. 32 ScopeList scopes; 33 public: 34 typedef typename Scope::key_type key_type; 35 typedef typename Scope::value_type value_type; 36 typedef typename ScopeList::size_type size_type; 37 typedef typename ScopeList::difference_type difference_type; 38 typedef typename Scope::reference reference; 39 typedef typename Scope::const_reference const_reference; 40 typedef typename Scope::pointer pointer; 41 typedef typename Scope::const_pointer const_pointer; 42 43 // Both iterator types are complete bidirectional iterators, see below. 44 class iterator; 45 class const_iterator; 46 47 /// Starts a new scope 48 void beginScope() { 49 Scope scope; 50 scopes.push_back(scope); 51 } 52 53 /// Ends a scope; invalidates any iterators pointing to elements of that scope 54 void endScope() { 55 scopes.pop_back(); 56 } 57 58 /// Default constructor initializes with one scope 59 ScopedSet() { beginScope(); } 60 61 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 62 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 63 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 64 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 65 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 66 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 67 68 /// Gets the index of the current scope (counted from 1) 69 size_type currentScope() const { return scopes.size(); } 70 71 /// Finds the given key in the outermost scope it occurs; returns end() for none such 72 iterator find( const Value &key ) { 73 for ( size_type i = scopes.size() - 1; ; --i ) { 74 typename Scope::iterator val = scopes[i].find( key ); 75 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 76 if ( i == 0 ) break; 77 } 78 return end(); 79 } 80 const_iterator find( const Value &key ) const { 81 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 82 } 83 84 /// Finds the given key in the outermost scope inside the given scope where it occurs 85 iterator findNext( const_iterator &it, const Value &key ) { 86 if ( it.i == 0 ) return end(); 23 /// A set where the items are placed into nested scopes; 24 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 25 template<typename Value> 26 class ScopedSet { 27 typedef std::set< Value > Scope; 28 typedef std::vector< Scope > ScopeList; 29 30 ScopeList scopes; ///< scoped list of sets 31 public: 32 typedef typename Scope::key_type key_type; 33 typedef typename Scope::value_type value_type; 34 typedef typename ScopeList::size_type size_type; 35 typedef typename ScopeList::difference_type difference_type; 36 typedef typename Scope::reference reference; 37 typedef typename Scope::const_reference const_reference; 38 typedef typename Scope::pointer pointer; 39 typedef typename Scope::const_pointer const_pointer; 40 41 class iterator : public std::iterator< std::bidirectional_iterator_tag, 42 value_type > { 43 friend class ScopedSet; 44 friend class const_iterator; 45 typedef typename std::set< Value >::iterator wrapped_iterator; 46 typedef typename std::vector< std::set< Value > > scope_list; 47 typedef typename scope_list::size_type size_type; 48 49 /// Checks if this iterator points to a valid item 50 bool is_valid() const { 51 return it != (*scopes)[i].end(); 52 } 53 54 /// Increments on invalid 55 iterator& next_valid() { 56 if ( ! is_valid() ) { ++(*this); } 57 return *this; 58 } 59 60 /// Decrements on invalid 61 iterator& prev_valid() { 62 if ( ! is_valid() ) { --(*this); } 63 return *this; 64 } 65 66 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 67 : scopes(&_scopes), it(_it), i(_i) {} 68 public: 69 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 70 iterator& operator= (const iterator &that) { 71 scopes = that.scopes; i = that.i; it = that.it; 72 return *this; 73 } 74 75 reference operator* () { return *it; } 76 pointer operator-> () { return it.operator->(); } 77 78 iterator& operator++ () { 79 if ( it == (*scopes)[i].end() ) { 80 if ( i == 0 ) return *this; 81 --i; 82 it = (*scopes)[i].begin(); 83 } else { 84 ++it; 85 } 86 return next_valid(); 87 } 88 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 89 90 iterator& operator-- () { 91 // may fail if this is the begin iterator; allowed by STL spec 92 if ( it == (*scopes)[i].begin() ) { 93 ++i; 94 it = (*scopes)[i].end(); 95 } 96 --it; 97 return prev_valid(); 98 } 99 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 100 101 bool operator== (const iterator &that) { 102 return scopes == that.scopes && i == that.i && it == that.it; 103 } 104 bool operator!= (const iterator &that) { return !( *this == that ); } 105 106 size_type get_level() const { return i; } 107 108 private: 109 scope_list const *scopes; 110 wrapped_iterator it; 111 size_type i; 112 }; 113 114 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 115 value_type > { 116 friend class ScopedSet; 117 typedef typename std::set< Value >::iterator wrapped_iterator; 118 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 119 typedef typename std::vector< std::set< Value > > scope_list; 120 typedef typename scope_list::size_type size_type; 121 122 /// Checks if this iterator points to a valid item 123 bool is_valid() const { 124 return it != (*scopes)[i].end(); 125 } 126 127 /// Increments on invalid 128 const_iterator& next_valid() { 129 if ( ! is_valid() ) { ++(*this); } 130 return *this; 131 } 132 133 /// Decrements on invalid 134 const_iterator& prev_valid() { 135 if ( ! is_valid() ) { --(*this); } 136 return *this; 137 } 138 139 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 140 : scopes(&_scopes), it(_it), i(_i) {} 141 public: 142 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 143 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 144 const_iterator& operator= (const iterator &that) { 145 scopes = that.scopes; i = that.i; it = that.it; 146 return *this; 147 } 148 const_iterator& operator= (const const_iterator &that) { 149 scopes = that.scopes; i = that.i; it = that.it; 150 return *this; 151 } 152 153 const_reference operator* () { return *it; } 154 const_pointer operator-> () { return it.operator->(); } 155 156 const_iterator& operator++ () { 157 if ( it == (*scopes)[i].end() ) { 158 if ( i == 0 ) return *this; 159 --i; 160 it = (*scopes)[i].begin(); 161 } else { 162 ++it; 163 } 164 return next_valid(); 165 } 166 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 167 168 const_iterator& operator-- () { 169 // may fail if this is the begin iterator; allowed by STL spec 170 if ( it == (*scopes)[i].begin() ) { 171 ++i; 172 it = (*scopes)[i].end(); 173 } 174 --it; 175 return prev_valid(); 176 } 177 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 178 179 bool operator== (const const_iterator &that) { 180 return scopes == that.scopes && i == that.i && it == that.it; 181 } 182 bool operator!= (const const_iterator &that) { return !( *this == that ); } 183 184 size_type get_level() const { return i; } 185 186 private: 187 scope_list const *scopes; 188 wrapped_const_iterator it; 189 size_type i; 190 }; 191 192 /// Starts a new scope 193 void beginScope() { 194 Scope scope; 195 scopes.push_back(scope); 196 } 197 198 /// Ends a scope; invalidates any iterators pointing to elements of that scope 199 void endScope() { 200 scopes.pop_back(); 201 } 202 203 /// Default constructor initializes with one scope 204 ScopedSet() { beginScope(); } 205 206 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 207 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 208 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 209 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 210 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 211 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 212 213 /// Gets the index of the current scope (counted from 1) 214 size_type currentScope() const { return scopes.size(); } 215 216 /// Finds the given key in the outermost scope it occurs; returns end() for none such 217 iterator find( const Value &key ) { 218 for ( size_type i = scopes.size() - 1; ; --i ) { 219 typename Scope::iterator val = scopes[i].find( key ); 220 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 221 if ( i == 0 ) break; 222 } 223 return end(); 224 } 225 const_iterator find( const Value &key ) const { 226 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 227 } 228 229 /// Finds the given key in the outermost scope inside the given scope where it occurs 230 iterator findNext( const_iterator &it, const Value &key ) { 231 if ( it.i == 0 ) return end(); 87 232 for ( size_type i = it.i - 1; ; --i ) { 88 typename Scope::iterator val = scopes[i].find( key ); 89 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 90 if ( i == 0 ) break; 91 } 92 return end(); 93 } 94 const_iterator findNext( const_iterator &it, const Value &key ) const { 95 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 96 } 97 98 /// Inserts the given value into the outermost scope 99 std::pair< iterator, bool > insert( const value_type &value ) { 100 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 101 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 102 } 103 104 bool contains( const Value & key ) const { 105 return find( key ) != cend(); 106 } 107 }; 108 109 template<typename Value> 110 class ScopedSet<Value>::iterator : 111 public std::iterator< std::bidirectional_iterator_tag, value_type > { 112 friend class ScopedSet; 113 friend class const_iterator; 114 typedef typename std::set< Value >::iterator wrapped_iterator; 115 typedef typename std::vector< std::set< Value > > scope_list; 116 typedef typename scope_list::size_type size_type; 117 118 /// Checks if this iterator points to a valid item 119 bool is_valid() const { 120 return it != (*scopes)[i].end(); 121 } 122 123 /// Increments on invalid 124 iterator& next_valid() { 125 if ( ! is_valid() ) { ++(*this); } 126 return *this; 127 } 128 129 /// Decrements on invalid 130 iterator& prev_valid() { 131 if ( ! is_valid() ) { --(*this); } 132 return *this; 133 } 134 135 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 136 : scopes(&_scopes), it(_it), i(_i) {} 137 public: 138 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 139 iterator& operator= (const iterator &that) { 140 scopes = that.scopes; i = that.i; it = that.it; 141 return *this; 142 } 143 144 reference operator* () { return *it; } 145 pointer operator-> () { return it.operator->(); } 146 147 iterator& operator++ () { 148 if ( it == (*scopes)[i].end() ) { 149 if ( i == 0 ) return *this; 150 --i; 151 it = (*scopes)[i].begin(); 152 } else { 153 ++it; 154 } 155 return next_valid(); 156 } 157 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 158 159 iterator& operator-- () { 160 // may fail if this is the begin iterator; allowed by STL spec 161 if ( it == (*scopes)[i].begin() ) { 162 ++i; 163 it = (*scopes)[i].end(); 164 } 165 --it; 166 return prev_valid(); 167 } 168 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 169 170 bool operator== (const iterator &that) { 171 return scopes == that.scopes && i == that.i && it == that.it; 172 } 173 bool operator!= (const iterator &that) { return !( *this == that ); } 174 175 size_type get_level() const { return i; } 176 177 private: 178 scope_list const *scopes; 179 wrapped_iterator it; 180 size_type i; 181 }; 182 183 template<typename Value> 184 class ScopedSet<Value>::const_iterator : 185 public std::iterator< std::bidirectional_iterator_tag, value_type > { 186 friend class ScopedSet; 187 typedef typename std::set< Value >::iterator wrapped_iterator; 188 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 189 typedef typename std::vector< std::set< Value > > scope_list; 190 typedef typename scope_list::size_type size_type; 191 192 /// Checks if this iterator points to a valid item 193 bool is_valid() const { 194 return it != (*scopes)[i].end(); 195 } 196 197 /// Increments on invalid 198 const_iterator& next_valid() { 199 if ( ! is_valid() ) { ++(*this); } 200 return *this; 201 } 202 203 /// Decrements on invalid 204 const_iterator& prev_valid() { 205 if ( ! is_valid() ) { --(*this); } 206 return *this; 207 } 208 209 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 210 : scopes(&_scopes), it(_it), i(_i) {} 211 public: 212 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 213 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 214 const_iterator& operator= (const iterator &that) { 215 scopes = that.scopes; i = that.i; it = that.it; 216 return *this; 217 } 218 const_iterator& operator= (const const_iterator &that) { 219 scopes = that.scopes; i = that.i; it = that.it; 220 return *this; 221 } 222 223 const_reference operator* () { return *it; } 224 const_pointer operator-> () { return it.operator->(); } 225 226 const_iterator& operator++ () { 227 if ( it == (*scopes)[i].end() ) { 228 if ( i == 0 ) return *this; 229 --i; 230 it = (*scopes)[i].begin(); 231 } else { 232 ++it; 233 } 234 return next_valid(); 235 } 236 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 237 238 const_iterator& operator-- () { 239 // may fail if this is the begin iterator; allowed by STL spec 240 if ( it == (*scopes)[i].begin() ) { 241 ++i; 242 it = (*scopes)[i].end(); 243 } 244 --it; 245 return prev_valid(); 246 } 247 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 248 249 bool operator== (const const_iterator &that) { 250 return scopes == that.scopes && i == that.i && it == that.it; 251 } 252 bool operator!= (const const_iterator &that) { return !( *this == that ); } 253 254 size_type get_level() const { return i; } 255 256 private: 257 scope_list const *scopes; 258 wrapped_const_iterator it; 259 size_type i; 260 }; 261 233 typename Scope::iterator val = scopes[i].find( key ); 234 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 235 if ( i == 0 ) break; 236 } 237 return end(); 238 } 239 const_iterator findNext( const_iterator &it, const Value &key ) const { 240 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 241 } 242 243 /// Inserts the given value into the outermost scope 244 std::pair< iterator, bool > insert( const value_type &value ) { 245 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 246 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 247 } 248 249 }; 262 250 } // namespace GenPoly 263 251 -
src/GenPoly/ScrubTyVars.cc
r24d6572 r34b4268 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Dec 7 17:01:00 202213 // Update Count : 612 // Last Modified On : Fri Oct 7 15:42:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 117 117 namespace { 118 118 119 enum class ScrubMode { 120 FromMap, 121 DynamicFromMap, 122 All, 123 }; 124 119 125 struct ScrubTypeVars : 120 126 public ast::WithGuards, … … 178 184 179 185 ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) { 180 ast::TypeDecl::Kind kind;181 186 // This implies that mode == ScrubMode::All. 182 187 if ( !typeVars ) { 183 kind = type->kind; 184 } else { 185 // Otherwise, only scrub the type var if it is in map. 186 auto typeVar = typeVars->find( *type ); 187 if ( typeVar == typeVars->end() ) { 188 return type; 189 } 190 kind = typeVar->second.kind; 191 } 192 193 switch ( kind ) { 194 case ast::TypeDecl::Dtype: 195 case ast::TypeDecl::Ttype: 188 if ( ast::TypeDecl::Ftype == type->kind ) { 189 return new ast::PointerType( 190 new ast::FunctionType( ast::FixedArgs ) ); 191 } else { 192 return new ast::PointerType( 193 new ast::VoidType( type->qualifiers ) ); 194 } 195 } 196 197 auto typeVar = typeVars->find( *type ); 198 if ( typeVar == typeVars->end() ) { 199 return type; 200 } 201 202 switch ( typeVar->second.kind ) { 203 case ::TypeDecl::Dtype: 204 case ::TypeDecl::Ttype: 196 205 return new ast::PointerType( 197 206 new ast::VoidType( type->qualifiers ) ); 198 case ast::TypeDecl::Ftype:207 case ::TypeDecl::Ftype: 199 208 return new ast::PointerType( 200 209 new ast::FunctionType( ast::VariableArgs ) ); 201 210 default: 202 assertf( false, "Unhandled type variable kind: %d", kind ); 211 assertf( false, 212 "Unhandled type variable kind: %d", typeVar->second.kind ); 203 213 throw; // Just in case the assert is removed, stop here. 204 214 } … … 243 253 } 244 254 245 } // namespace246 247 255 const ast::Node * scrubTypeVarsBase( 248 const ast::Node * node, const TypeVarMap * typeVars, ScrubMode mode ) { 256 const ast::Node * target, 257 ScrubMode mode, const TypeVarMap * typeVars ) { 249 258 if ( ScrubMode::All == mode ) { 250 259 assert( nullptr == typeVars ); … … 253 262 } 254 263 ast::Pass<ScrubTypeVars> visitor( mode, typeVars ); 255 return node->accept( visitor ); 264 return target->accept( visitor ); 265 } 266 267 } // namespace 268 269 template<> 270 ast::Node const * scrubTypeVars<ast::Node>( 271 const ast::Node * target, const TypeVarMap & typeVars ) { 272 return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars ); 273 } 274 275 template<> 276 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 277 ast::Node const * target, const TypeVarMap & typeVars ) { 278 return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars ); 279 } 280 281 template<> 282 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ) { 283 return scrubTypeVarsBase( target, ScrubMode::All, nullptr ); 256 284 } 257 285 -
src/GenPoly/ScrubTyVars.h
r24d6572 r34b4268 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Dec 7 16:57:00 202213 // Update Count : 512 // Last Modified On : Fri Oct 7 15:51:00 2022 13 // Update Count : 4 14 14 // 15 15 … … 109 109 } 110 110 111 // ScrubMode and scrubTypeVarsBase are internal.112 enum class ScrubMode { FromMap, DynamicFromMap, All };113 114 const ast::Node * scrubTypeVarsBase(115 const ast::Node * target, const TypeVarMap * typeVars, ScrubMode mode );116 117 118 111 /// For all polymorphic types with type variables in `typeVars`, 119 112 /// replaces generic types, dtypes, and ftypes with the appropriate void type, … … 123 116 node_t const * target, const TypeVarMap & typeVars ) { 124 117 return strict_dynamic_cast<node_t const *>( 125 scrubTypeVars Base( target, &typeVars, ScrubMode::FromMap) );118 scrubTypeVars<ast::Node>( target, typeVars ) ); 126 119 } 127 120 … … 130 123 /// and sizeof/alignof expressions with the proper variable. 131 124 template<typename node_t> 132 node_tconst * scrubTypeVarsDynamic(125 ast::Node const * scrubTypeVarsDynamic( 133 126 node_t const * target, const TypeVarMap & typeVars ) { 134 127 return strict_dynamic_cast<node_t const *>( 135 scrubTypeVars Base( target, &typeVars, ScrubMode::DynamicFromMap) );128 scrubTypeVarsDynamic<ast::Node>( target, typeVars ) ); 136 129 } 137 130 … … 141 134 node_t const * scrubAllTypeVars( node_t const * target ) { 142 135 return strict_dynamic_cast<node_t const *>( 143 scrub TypeVarsBase( target, nullptr, ScrubMode::All) );136 scrubAllTypeVars<ast::Node>( target ) ); 144 137 } 138 139 // We specialize for Node as a base case. 140 template<> 141 ast::Node const * scrubTypeVars<ast::Node>( 142 const ast::Node * target, const TypeVarMap & typeVars ); 143 144 template<> 145 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 146 ast::Node const * target, const TypeVarMap & typeVars ); 147 148 template<> 149 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ); 145 150 146 151 } // namespace GenPoly -
src/GenPoly/SpecializeNew.cpp
r24d6572 r34b4268 16 16 #include "Specialize.h" 17 17 18 #include "AST/Copy.hpp" // for deepCopy19 18 #include "AST/Inspect.hpp" // for isIntrinsicCallExpr 20 19 #include "AST/Pass.hpp" // for Pass -
src/InitTweak/FixInit.cc
r24d6572 r34b4268 32 32 #include "Common/PassVisitor.h" // for PassVisitor, WithStmtsToAdd 33 33 #include "Common/SemanticError.h" // for SemanticError 34 #include "Common/ToString.hpp" // for toCString35 34 #include "Common/UniqueName.h" // for UniqueName 35 #include "Common/utility.h" // for CodeLocation, ValueGuard, toSt... 36 36 #include "FixGlobalInit.h" // for fixGlobalInit 37 37 #include "GenInit.h" // for genCtorDtor … … 39 39 #include "InitTweak.h" // for getFunctionName, getCallArg 40 40 #include "ResolvExpr/Resolver.h" // for findVoidExpression 41 #include "ResolvExpr/ Unify.h"// for typesCompatible41 #include "ResolvExpr/typeops.h" // for typesCompatible 42 42 #include "SymTab/Autogen.h" // for genImplicitCall 43 43 #include "SymTab/Indexer.h" // for Indexer … … 1233 1233 } 1234 1234 1235 template< typename Visitor, typename... Params > 1236 void error( Visitor & v, CodeLocation loc, const Params &... params ) { 1237 SemanticErrorException err( loc, toString( params... ) ); 1238 v.errors.append( err ); 1239 } 1240 1235 1241 template< typename... Params > 1236 1242 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) { 1237 SemanticErrorException err( loc, toString( params... ) ); 1238 errors.append( err ); 1243 // toggle warnings vs. errors here. 1244 // warn( params... ); 1245 error( *this, loc, params... ); 1239 1246 } 1240 1247 -
src/InitTweak/FixInitNew.cpp
r24d6572 r34b4268 14 14 #include <utility> // for pair 15 15 16 #include "AST/DeclReplacer.hpp"17 #include "AST/Expr.hpp"18 16 #include "AST/Inspect.hpp" // for getFunction, getPointerBase, g... 19 #include "AST/Node.hpp"20 #include "AST/Pass.hpp"21 #include "AST/Print.hpp"22 #include "AST/SymbolTable.hpp"23 #include "AST/Type.hpp"24 17 #include "CodeGen/GenType.h" // for genPrettyType 25 18 #include "CodeGen/OperatorTable.h" 19 #include "Common/CodeLocationTools.hpp" 26 20 #include "Common/PassVisitor.h" // for PassVisitor, WithStmtsToAdd 27 21 #include "Common/SemanticError.h" // for SemanticError 28 #include "Common/ToString.hpp" // for toCString29 22 #include "Common/UniqueName.h" // for UniqueName 23 #include "Common/utility.h" // for CodeLocation, ValueGuard, toSt... 30 24 #include "FixGlobalInit.h" // for fixGlobalInit 31 25 #include "GenInit.h" // for genCtorDtor 32 26 #include "GenPoly/GenPoly.h" // for getFunctionType 33 27 #include "ResolvExpr/Resolver.h" // for findVoidExpression 34 #include "ResolvExpr/ Unify.h"// for typesCompatible28 #include "ResolvExpr/typeops.h" // for typesCompatible 35 29 #include "SymTab/Autogen.h" // for genImplicitCall 36 #include "SymTab/GenImplicitCall.hpp" // for genImplicitCall37 30 #include "SymTab/Indexer.h" // for Indexer 38 31 #include "SymTab/Mangler.h" // for Mangler … … 52 45 #include "Validate/FindSpecialDecls.h" // for dtorStmt, dtorStructDestroy 53 46 47 #include "AST/Expr.hpp" 48 #include "AST/Node.hpp" 49 #include "AST/Pass.hpp" 50 #include "AST/Print.hpp" 51 #include "AST/SymbolTable.hpp" 52 #include "AST/Type.hpp" 53 #include "AST/DeclReplacer.hpp" 54 54 55 extern bool ctordtorp; // print all debug 55 56 extern bool ctorp; // print ctor debug … … 62 63 namespace InitTweak { 63 64 namespace { 64 65 // Shallow copy the pointer list for return.66 std::vector<ast::ptr<ast::TypeDecl>> getGenericParams( const ast::Type * t ) {67 if ( auto inst = dynamic_cast<const ast::StructInstType *>( t ) ) {68 return inst->base->params;69 }70 if ( auto inst = dynamic_cast<const ast::UnionInstType *>( t ) ) {71 return inst->base->params;72 }73 return {};74 }75 76 /// Given type T, generate type of default ctor/dtor, i.e. function type void (*) (T &).77 ast::FunctionDecl * genDefaultFunc(78 const CodeLocation loc,79 const std::string fname,80 const ast::Type * paramType,81 bool maybePolymorphic = true) {82 std::vector<ast::ptr<ast::TypeDecl>> typeParams;83 if ( maybePolymorphic ) typeParams = getGenericParams( paramType );84 auto dstParam = new ast::ObjectDecl( loc,85 "_dst",86 new ast::ReferenceType( paramType ),87 nullptr,88 {},89 ast::Linkage::Cforall90 );91 return new ast::FunctionDecl( loc,92 fname,93 std::move(typeParams),94 {dstParam},95 {},96 new ast::CompoundStmt(loc),97 {},98 ast::Linkage::Cforall99 );100 }101 102 65 struct SelfAssignChecker { 103 66 void previsit( const ast::ApplicationExpr * appExpr ); … … 144 107 private: 145 108 /// hack to implement WithTypeSubstitution while conforming to mutation safety. 146 ast::TypeSubstitution * env = nullptr;147 bool envModified = false;109 ast::TypeSubstitution * env; 110 bool envModified; 148 111 }; 149 112 … … 158 121 void previsit( const ast::FunctionDecl * ) { visit_children = false; } 159 122 160 protected:123 protected: 161 124 ObjectSet curVars; 162 125 }; … … 239 202 240 203 SemanticErrorException errors; 241 private:204 private: 242 205 template< typename... Params > 243 206 void emit( CodeLocation, const Params &... params ); … … 325 288 static UniqueName dtorNamer( "__cleanup_dtor" ); 326 289 std::string name = dtorNamer.newName(); 327 ast::FunctionDecl * dtorFunc = genDefaultFunc( loc, name, objDecl->type->stripReferences(), false );290 ast::FunctionDecl * dtorFunc = SymTab::genDefaultFunc( loc, name, objDecl->type->stripReferences(), false ); 328 291 stmtsToAdd.push_back( new ast::DeclStmt(loc, dtorFunc ) ); 329 292 … … 559 522 { 560 523 static UniqueName tempNamer("_tmp_cp"); 524 assert( env ); 561 525 const CodeLocation loc = impCpCtorExpr->location; 562 526 // CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) … … 570 534 571 535 // xxx - this originally mutates arg->result in place. is it correct? 572 assert( env );573 536 result = env->applyFree( result.get() ).node; 574 537 auto mutResult = result.get_and_mutate(); … … 1117 1080 void InsertDtors::previsit( const ast::BranchStmt * stmt ) { 1118 1081 switch( stmt->kind ) { 1119 case ast::BranchStmt::Continue:1120 case ast::BranchStmt::Break:1082 case ast::BranchStmt::Continue: 1083 case ast::BranchStmt::Break: 1121 1084 // could optimize the break/continue case, because the S_L-S_G check is unnecessary (this set should 1122 1085 // always be empty), but it serves as a small sanity check. 1123 case ast::BranchStmt::Goto:1086 case ast::BranchStmt::Goto: 1124 1087 handleGoto( stmt ); 1125 1088 break; 1126 default:1089 default: 1127 1090 assert( false ); 1128 1091 } // switch … … 1340 1303 } 1341 1304 1305 template< typename Visitor, typename... Params > 1306 void error( Visitor & v, CodeLocation loc, const Params &... params ) { 1307 SemanticErrorException err( loc, toString( params... ) ); 1308 v.errors.append( err ); 1309 } 1310 1342 1311 template< typename... Params > 1343 1312 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) { 1344 SemanticErrorException err( loc, toString( params... ) ); 1345 errors.append( err ); 1313 // toggle warnings vs. errors here. 1314 // warn( params... ); 1315 error( *this, loc, params... ); 1346 1316 } 1347 1317 … … 1349 1319 // xxx - functions returning ast::ptr seems wrong... 1350 1320 auto res = ResolvExpr::findVoidExpression( untypedExpr, { symtab, transUnit().global } ); 1351 return res.release(); 1321 // Fix CodeLocation (at least until resolver is fixed). 1322 auto fix = localFillCodeLocations( untypedExpr->location, res.release() ); 1323 return strict_dynamic_cast<const ast::Expr *>( fix ); 1352 1324 } 1353 1325 -
src/InitTweak/GenInit.cc
r24d6572 r34b4268 31 31 #include "Common/PassVisitor.h" // for PassVisitor, WithGuards, WithShort... 32 32 #include "Common/SemanticError.h" // for SemanticError 33 #include "Common/ToString.hpp" // for toCString34 33 #include "Common/UniqueName.h" // for UniqueName 35 34 #include "Common/utility.h" // for ValueGuard, maybeClone … … 39 38 #include "ResolvExpr/Resolver.h" 40 39 #include "SymTab/Autogen.h" // for genImplicitCall 41 #include "SymTab/GenImplicitCall.hpp" // for genImplicitCall42 40 #include "SymTab/Mangler.h" // for Mangler 43 41 #include "SynTree/LinkageSpec.h" // for isOverridable, C -
src/InitTweak/InitTweak.cc
r24d6572 r34b4268 35 35 #include "GenPoly/GenPoly.h" // for getFunctionType 36 36 #include "InitTweak.h" 37 #include "ResolvExpr/ Unify.h"// for typesCompatibleIgnoreQualifiers37 #include "ResolvExpr/typeops.h" // for typesCompatibleIgnoreQualifiers 38 38 #include "SymTab/Autogen.h" 39 39 #include "SymTab/Indexer.h" // for Indexer … … 1066 1066 const ast::Type * t2 = ftype->params.back(); 1067 1067 1068 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2 );1068 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable() ); 1069 1069 } 1070 1070 -
src/MakeLibCfaNew.cpp
r24d6572 r34b4268 16 16 #include "MakeLibCfa.h" 17 17 18 #include "AST/Copy.hpp"19 18 #include "AST/Fwd.hpp" 20 19 #include "AST/Pass.hpp" -
src/Parser/DeclarationNode.cc
r24d6572 r34b4268 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Apr 20 11:46:00 202313 // Update Count : 1 39311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Aug 8 17:07:00 2022 13 // Update Count : 1185 14 14 // 15 16 #include "DeclarationNode.h"17 15 18 16 #include <cassert> // for assert, assertf, strict_dynamic_cast … … 23 21 #include <string> // for string, operator+, allocator, char... 24 22 25 #include "AST/Attribute.hpp" // for Attribute26 #include "AST/Copy.hpp" // for shallowCopy27 #include "AST/Decl.hpp" // for Decl28 #include "AST/Expr.hpp" // for Expr29 #include "AST/Print.hpp" // for print30 #include "AST/Stmt.hpp" // for AsmStmt, DirectiveStmt31 #include "AST/StorageClasses.hpp" // for Storage::Class32 #include "AST/Type.hpp" // for Type33 #include "Common/CodeLocation.h" // for CodeLocation34 #include "Common/Iterate.hpp" // for reverseIterate35 23 #include "Common/SemanticError.h" // for SemanticError 36 24 #include "Common/UniqueName.h" // for UniqueName 37 #include "Common/utility.h" // for maybeClone 38 #include "Parser/ExpressionNode.h" // for ExpressionNode 39 #include "Parser/InitializerNode.h"// for InitializerNode 40 #include "Parser/StatementNode.h" // for StatementNode 25 #include "Common/utility.h" // for maybeClone, maybeBuild, CodeLocation 26 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 27 #include "SynTree/LinkageSpec.h" // for Spec, linkageName, Cforall 28 #include "SynTree/Attribute.h" // for Attribute 29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration 30 #include "SynTree/Expression.h" // for Expression, ConstantExpr 31 #include "SynTree/Statement.h" // for AsmStmt 32 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Type::... 41 33 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 42 34 #include "TypedefTable.h" // for TypedefTable … … 49 41 50 42 // These must harmonize with the corresponding DeclarationNode enumerations. 51 const char * DeclarationNode::basicTypeNames[] = { 52 "void", "_Bool", "char", "int", "int128", 53 "float", "double", "long double", "float80", "float128", 54 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" 55 }; 56 const char * DeclarationNode::complexTypeNames[] = { 57 "_Complex", "NoComplexTypeNames", "_Imaginary" 58 }; // Imaginary unsupported => parse, but make invisible and print error message 59 const char * DeclarationNode::signednessNames[] = { 60 "signed", "unsigned", "NoSignednessNames" 61 }; 62 const char * DeclarationNode::lengthNames[] = { 63 "short", "long", "long long", "NoLengthNames" 64 }; 65 const char * DeclarationNode::builtinTypeNames[] = { 66 "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" 67 }; 43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128", 44 "float", "double", "long double", "float80", "float128", 45 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" }; 46 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message 47 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; 48 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" }; 49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" }; 68 50 69 51 UniqueName DeclarationNode::anonymous( "__anonymous" ); 70 52 71 extern ast::Linkage::Spec linkage; // defined in parser.yy53 extern LinkageSpec::Spec linkage; // defined in parser.yy 72 54 73 55 DeclarationNode::DeclarationNode() : … … 75 57 76 58 // variable.name = nullptr; 77 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;59 variable.tyClass = TypeDecl::NUMBER_OF_KINDS; 78 60 variable.assertions = nullptr; 79 61 variable.initializer = nullptr; 80 62 63 // attr.name = nullptr; 64 attr.expr = nullptr; 65 attr.type = nullptr; 66 81 67 assert.condition = nullptr; 82 68 assert.message = nullptr; … … 84 70 85 71 DeclarationNode::~DeclarationNode() { 72 // delete attr.name; 73 delete attr.expr; 74 delete attr.type; 75 86 76 // delete variable.name; 87 77 delete variable.assertions; 88 78 delete variable.initializer; 89 79 90 // delete type;80 // delete type; 91 81 delete bitfieldWidth; 92 82 … … 113 103 newnode->hasEllipsis = hasEllipsis; 114 104 newnode->linkage = linkage; 115 newnode->asmName = maybeC opy( asmName );116 newnode->attributes = attributes;105 newnode->asmName = maybeClone( asmName ); 106 cloneAll( attributes, newnode->attributes ); 117 107 newnode->initializer = maybeClone( initializer ); 118 108 newnode->extension = extension; … … 125 115 newnode->variable.initializer = maybeClone( variable.initializer ); 126 116 117 // newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr; 118 newnode->attr.expr = maybeClone( attr.expr ); 119 newnode->attr.type = maybeClone( attr.type ); 120 127 121 newnode->assert.condition = maybeClone( assert.condition ); 128 newnode->assert.message = maybeC opy( assert.message );122 newnode->assert.message = maybeClone( assert.message ); 129 123 return newnode; 130 124 } // DeclarationNode::clone … … 136 130 } // if 137 131 138 if ( linkage != ast::Linkage::Cforall ) {139 os << ast::Linkage::name( linkage ) << " ";140 } // if 141 142 ast::print( os, storageClasses );143 ast::print( os, funcSpecs );132 if ( linkage != LinkageSpec::Cforall ) { 133 os << LinkageSpec::name( linkage ) << " "; 134 } // if 135 136 storageClasses.print( os ); 137 funcSpecs.print( os ); 144 138 145 139 if ( type ) { … … 160 154 } // if 161 155 162 if ( ! attributes.empty() ) { 163 os << string( indent + 2, ' ' ) << "with attributes " << endl; 164 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) { 165 os << string( indent + 4, ' ' ) << attr->name.c_str() << endl; 166 } // for 167 } // if 156 for ( Attribute * attr: reverseIterate( attributes ) ) { 157 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str(); 158 } // for 168 159 169 160 os << endl; … … 177 168 } 178 169 179 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {170 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) { 180 171 DeclarationNode * newnode = new DeclarationNode; 181 172 newnode->storageClasses = sc; … … 183 174 } // DeclarationNode::newStorageClass 184 175 185 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {176 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) { 186 177 DeclarationNode * newnode = new DeclarationNode; 187 178 newnode->funcSpecs = fs; … … 189 180 } // DeclarationNode::newFuncSpecifier 190 181 191 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {182 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) { 192 183 DeclarationNode * newnode = new DeclarationNode; 193 184 newnode->type = new TypeData(); … … 249 240 } 250 241 251 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {242 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 252 243 DeclarationNode * newnode = new DeclarationNode; 253 244 newnode->type = new TypeData( TypeData::Aggregate ); 254 245 newnode->type->aggregate.kind = kind; 255 newnode->type->aggregate.anon = name == nullptr; 256 newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 246 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 257 247 newnode->type->aggregate.actuals = actuals; 258 248 newnode->type->aggregate.fields = fields; … … 260 250 newnode->type->aggregate.tagged = false; 261 251 newnode->type->aggregate.parent = nullptr; 252 newnode->type->aggregate.anon = name == nullptr; 262 253 return newnode; 263 254 } // DeclarationNode::newAggregate … … 266 257 DeclarationNode * newnode = new DeclarationNode; 267 258 newnode->type = new TypeData( TypeData::Enum ); 268 newnode->type->enumeration.anon = name == nullptr; 269 newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 259 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 270 260 newnode->type->enumeration.constants = constants; 271 261 newnode->type->enumeration.body = body; 262 newnode->type->enumeration.anon = name == nullptr; 272 263 newnode->type->enumeration.typed = typed; 273 264 newnode->type->enumeration.hiding = hiding; 274 if ( base && base->type ) {265 if ( base && base->type) { 275 266 newnode->type->base = base->type; 276 267 } // if … … 278 269 return newnode; 279 270 } // DeclarationNode::newEnum 271 272 280 273 281 274 DeclarationNode * DeclarationNode::newName( const string * name ) { … … 330 323 } // DeclarationNode::newFromTypeGen 331 324 332 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {325 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) { 333 326 DeclarationNode * newnode = newName( name ); 334 327 newnode->type = nullptr; … … 342 335 newnode->type = new TypeData( TypeData::Aggregate ); 343 336 newnode->type->aggregate.name = name; 344 newnode->type->aggregate.kind = ast::AggregateDecl::Trait;337 newnode->type->aggregate.kind = AggregateDecl::Trait; 345 338 newnode->type->aggregate.params = params; 346 339 newnode->type->aggregate.fields = asserts; … … 352 345 newnode->type = new TypeData( TypeData::AggregateInst ); 353 346 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate ); 354 newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;347 newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait; 355 348 newnode->type->aggInst.aggregate->aggregate.name = name; 356 349 newnode->type->aggInst.params = params; … … 387 380 newnode->type->array.dimension = size; 388 381 newnode->type->array.isStatic = isStatic; 389 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType< ast::ConstantExpr *>() ) {382 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) { 390 383 newnode->type->array.isVarLen = false; 391 384 } else { … … 457 450 DeclarationNode * newnode = new DeclarationNode; 458 451 newnode->type = nullptr; 459 std:: vector<ast::ptr<ast::Expr>> exprs;452 std::list< Expression * > exprs; 460 453 buildList( expr, exprs ); 461 newnode->attributes.push_back( 462 new ast::Attribute( *name, std::move( exprs ) ) ); 454 newnode->attributes.push_back( new Attribute( *name, exprs ) ); 463 455 delete name; 464 456 return newnode; … … 477 469 } 478 470 479 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr* message ) {471 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) { 480 472 DeclarationNode * newnode = new DeclarationNode; 481 473 newnode->assert.condition = condition; … … 484 476 } 485 477 486 static void appendError( string & dst, const string & src ) { 478 479 void appendError( string & dst, const string & src ) { 487 480 if ( src.empty() ) return; 488 481 if ( dst.empty() ) { dst = src; return; } … … 491 484 492 485 void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) { 493 const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 494 const ast::CV::Qualifiers duplicates = qsrc & qdst; 495 496 if ( duplicates.any() ) { 497 std::stringstream str; 498 str << "duplicate "; 499 ast::print( str, duplicates ); 500 str << "qualifier(s)"; 501 appendError( error, str.str() ); 486 const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 487 488 if ( (qsrc & qdst).any() ) { // duplicates ? 489 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates 490 if ( qsrc[i] && qdst[i] ) { 491 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] ); 492 } // if 493 } // for 502 494 } // for 503 495 } // DeclarationNode::checkQualifiers 504 496 505 497 void DeclarationNode::checkSpecifiers( DeclarationNode * src ) { 506 ast::Function::Specs fsDups = funcSpecs & src->funcSpecs; 507 if ( fsDups.any() ) { 508 std::stringstream str; 509 str << "duplicate "; 510 ast::print( str, fsDups ); 511 str << "function specifier(s)"; 512 appendError( error, str.str() ); 513 } // if 514 515 // Skip if everything is unset. 516 if ( storageClasses.any() && src->storageClasses.any() ) { 517 ast::Storage::Classes dups = storageClasses & src->storageClasses; 518 // Check for duplicates. 519 if ( dups.any() ) { 520 std::stringstream str; 521 str << "duplicate "; 522 ast::print( str, dups ); 523 str << "storage class(es)"; 524 appendError( error, str.str() ); 525 // Check for conflicts. 526 } else if ( !src->storageClasses.is_threadlocal_any() ) { 527 std::stringstream str; 528 str << "conflicting "; 529 ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) ); 530 str << "& "; 531 ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) ); 532 str << "storage classes"; 533 appendError( error, str.str() ); 534 // FIX to preserve invariant of one basic storage specifier 535 src->storageClasses.reset(); 536 } 498 if ( (funcSpecs & src->funcSpecs).any() ) { // duplicates ? 499 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates 500 if ( funcSpecs[i] && src->funcSpecs[i] ) { 501 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] ); 502 } // if 503 } // for 504 } // if 505 506 if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ? 507 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ? 508 for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates 509 if ( storageClasses[i] && src->storageClasses[i] ) { 510 appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] ); 511 } // if 512 } // for 513 // src is the new item being added and has a single bit 514 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ? 515 appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] + 516 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] ); 517 src->storageClasses.reset(); // FIX to preserve invariant of one basic storage specifier 518 } // if 537 519 } // if 538 520 … … 544 526 storageClasses |= q->storageClasses; 545 527 546 std::vector<ast::ptr<ast::Attribute>> tmp; 547 tmp.reserve( q->attributes.size() ); 548 for ( auto const & attr : q->attributes ) { 549 tmp.emplace_back( ast::shallowCopy( attr.get() ) ); 550 } 551 spliceBegin( attributes, tmp ); 552 528 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 529 attributes.push_front( attr->clone() ); 530 } // for 553 531 return this; 554 532 } // DeclarationNode::copySpecifiers … … 598 576 599 577 checkQualifiers( type, q->type ); 600 if ( (builtin == Zero || builtin == One) && q->type->qualifiers. any()&& error.length() == 0 ) {601 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );578 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.val != 0 && error.length() == 0 ) { 579 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )], builtinTypeNames[builtin] ); 602 580 } // if 603 581 addQualifiersToType( q->type, type ); … … 620 598 } else { 621 599 switch ( dst->kind ) { 622 case TypeData::Unknown:600 case TypeData::Unknown: 623 601 src->qualifiers |= dst->qualifiers; 624 602 dst = src; 625 603 src = nullptr; 626 604 break; 627 case TypeData::Basic:605 case TypeData::Basic: 628 606 dst->qualifiers |= src->qualifiers; 629 607 if ( src->kind != TypeData::Unknown ) { … … 653 631 } // if 654 632 break; 655 default:633 default: 656 634 switch ( src->kind ) { 657 case TypeData::Aggregate:658 case TypeData::Enum:635 case TypeData::Aggregate: 636 case TypeData::Enum: 659 637 dst->base = new TypeData( TypeData::AggregateInst ); 660 638 dst->base->aggInst.aggregate = src; … … 665 643 src = nullptr; 666 644 break; 667 default:645 default: 668 646 if ( dst->forall ) { 669 647 dst->forall->appendList( src->forall ); … … 736 714 737 715 DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) { 738 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {739 if ( variable.assertions ) {740 variable.assertions->appendList( assertions );741 } else {742 variable.assertions = assertions;743 } // if744 return this;716 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 717 if ( variable.assertions ) { 718 variable.assertions->appendList( assertions ); 719 } else { 720 variable.assertions = assertions; 721 } // if 722 return this; 745 723 } // if 746 724 747 725 assert( type ); 748 726 switch ( type->kind ) { 749 case TypeData::Symbolic:727 case TypeData::Symbolic: 750 728 if ( type->symbolic.assertions ) { 751 729 type->symbolic.assertions->appendList( assertions ); … … 754 732 } // if 755 733 break; 756 default:734 default: 757 735 assert( false ); 758 736 } // switch … … 818 796 DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) { 819 797 if ( a ) { 820 spliceBegin( attributes, a->attributes ); 798 for ( Attribute *attr: reverseIterate( a->attributes ) ) { 799 attributes.push_front( attr ); 800 } // for 821 801 a->attributes.clear(); 822 802 } // if … … 851 831 if ( type ) { 852 832 switch ( type->kind ) { 853 case TypeData::Aggregate:854 case TypeData::Enum:833 case TypeData::Aggregate: 834 case TypeData::Enum: 855 835 p->type->base = new TypeData( TypeData::AggregateInst ); 856 836 p->type->base->aggInst.aggregate = type; … … 861 841 break; 862 842 863 default:843 default: 864 844 p->type->base = type; 865 845 } // switch … … 883 863 884 864 DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) { 885 if ( ! a ) return this;865 if ( ! a ) return this; 886 866 assert( a->type->kind == TypeData::Array ); 887 867 TypeData * lastArray = findLast( a->type ); 888 868 if ( type ) { 889 869 switch ( type->kind ) { 890 case TypeData::Aggregate:891 case TypeData::Enum:870 case TypeData::Aggregate: 871 case TypeData::Enum: 892 872 lastArray->base = new TypeData( TypeData::AggregateInst ); 893 873 lastArray->base->aggInst.aggregate = type; … … 897 877 lastArray->base->qualifiers |= type->qualifiers; 898 878 break; 899 default:879 default: 900 880 lastArray->base = type; 901 881 } // switch … … 939 919 940 920 DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) { 941 assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );921 assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." ); 942 922 variable.initializer = init; 943 923 return this; … … 1003 983 } 1004 984 1005 // If a typedef wraps an anonymous declaration, name the inner declaration 1006 // so it has a consistent name across translation units. 1007 static void nameTypedefedDecl( 1008 DeclarationNode * innerDecl, 1009 const DeclarationNode * outerDecl ) { 1010 TypeData * outer = outerDecl->type; 1011 assert( outer ); 1012 // First make sure this is a typedef: 1013 if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) { 1014 return; 1015 } 1016 TypeData * inner = innerDecl->type; 1017 assert( inner ); 1018 // Always clear any CVs associated with the aggregate: 1019 inner->qualifiers.reset(); 1020 // Handle anonymous aggregates: typedef struct { int i; } foo 1021 if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) { 1022 delete inner->aggregate.name; 1023 inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name ); 1024 inner->aggregate.anon = false; 1025 assert( outer->base ); 1026 delete outer->base->aggInst.aggregate->aggregate.name; 1027 outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name ); 1028 outer->base->aggInst.aggregate->aggregate.anon = false; 1029 outer->base->aggInst.aggregate->qualifiers.reset(); 1030 // Handle anonymous enumeration: typedef enum { A, B, C } foo 1031 } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) { 1032 delete inner->enumeration.name; 1033 inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name ); 1034 inner->enumeration.anon = false; 1035 assert( outer->base ); 1036 delete outer->base->aggInst.aggregate->enumeration.name; 1037 outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name ); 1038 outer->base->aggInst.aggregate->enumeration.anon = false; 1039 // No qualifiers.reset() here. 1040 } 1041 } 1042 1043 // This code handles a special issue with the attribute transparent_union. 1044 // 1045 // typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union )) 1046 // 1047 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are 1048 // aligned. However, the attribute transparent_union must be moved from the typedef_name to 1049 // alias union U. Currently, this is the only know attribute that must be moved from typedef to 1050 // alias. 1051 static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) { 1052 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) { 1053 // Is the typedef alias a union aggregate? 1054 if ( nullptr == unionDecl ) return; 1055 1056 // If typedef is an alias for a union, then its alias type was hoisted above and remembered. 1057 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) { 1058 auto instType = ast::mutate( unionInstType ); 1059 // Remove all transparent_union attributes from typedef and move to alias union. 1060 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { 1061 assert( *attr ); 1062 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) { 1063 unionDecl->attributes.emplace_back( attr->release() ); 1064 attr = instType->attributes.erase( attr ); 1065 } else { 1066 attr++; 1067 } 1068 } 1069 typedefDecl->base = instType; 1070 } 1071 } 1072 } 1073 1074 // Get the non-anonymous name of the instance type of the declaration, 1075 // if one exists. 1076 static const std::string * getInstTypeOfName( ast::Decl * decl ) { 1077 if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1078 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) { 1079 if ( aggr->name.find("anonymous") == std::string::npos ) { 1080 return &aggr->name; 1081 } 1082 } 1083 } 1084 return nullptr; 1085 } 1086 1087 void buildList( DeclarationNode * firstNode, 1088 std::vector<ast::ptr<ast::Decl>> & outputList ) { 985 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 1089 986 SemanticErrorException errors; 1090 std::back_insert_iterator< std::vector<ast::ptr<ast::Decl>>> out( outputList );1091 1092 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur) ) {987 std::back_insert_iterator< std::list< Declaration * > > out( outputList ); 988 989 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1093 990 try { 1094 bool extracted_named = false; 1095 ast::UnionDecl * unionDecl = nullptr; 1096 991 bool extracted = false; 992 bool anon = false; 1097 993 if ( DeclarationNode * extr = cur->extractAggregate() ) { 1098 assert( cur->type ); 1099 nameTypedefedDecl( extr, cur ); 1100 1101 if ( ast::Decl * decl = extr->build() ) { 1102 // Remember the declaration if it is a union aggregate ? 1103 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 1104 1105 *out++ = decl; 994 // handle the case where a structure declaration is contained within an object or type declaration 995 Declaration * decl = extr->build(); 996 if ( decl ) { 997 // hoist the structure declaration 998 decl->location = cur->location; 999 * out++ = decl; 1106 1000 1107 1001 // need to remember the cases where a declaration contains an anonymous aggregate definition 1002 extracted = true; 1108 1003 assert( extr->type ); 1109 1004 if ( extr->type->kind == TypeData::Aggregate ) { 1110 // typedef struct { int A } B is the only case? 1111 extracted_named = !extr->type->aggregate.anon; 1005 anon = extr->type->aggregate.anon; 1112 1006 } else if ( extr->type->kind == TypeData::Enum ) { 1113 // typedef enum { A } B is the only case? 1114 extracted_named = !extr->type->enumeration.anon; 1115 } else { 1116 extracted_named = true; 1007 // xxx - is it useful to have an implicit anonymous enum member? 1008 anon = extr->type->enumeration.anon; 1117 1009 } 1118 1010 } // if … … 1120 1012 } // if 1121 1013 1122 if ( ast::Decl * decl = cur->build() ) { 1123 moveUnionAttribute( decl, unionDecl ); 1124 1125 if ( "" == decl->name && !cur->get_inLine() ) { 1126 // Don't include anonymous declaration for named aggregates, 1127 // but do include them for anonymous aggregates, e.g.: 1128 // struct S { 1129 // struct T { int x; }; // no anonymous member 1130 // struct { int y; }; // anonymous member 1131 // struct T; // anonymous member 1132 // }; 1133 if ( extracted_named ) { 1134 continue; 1135 } 1136 1137 if ( auto name = getInstTypeOfName( decl ) ) { 1138 // Temporary: warn about anonymous member declarations of named types, since 1139 // this conflicts with the syntax for the forward declaration of an anonymous type. 1140 SemanticWarning( cur->location, Warning::AggrForwardDecl, name->c_str() ); 1141 } 1014 Declaration * decl = cur->build(); 1015 if ( decl ) { 1016 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.: 1017 // struct S { 1018 // struct T { int x; }; // no anonymous member 1019 // struct { int y; }; // anonymous member 1020 // struct T; // anonymous member 1021 // }; 1022 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 1023 if ( decl->name == "" ) { 1024 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) { 1025 if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) { 1026 if ( aggr->name.find("anonymous") == std::string::npos ) { 1027 if ( ! cur->get_inLine() ) { 1028 // temporary: warn about anonymous member declarations of named types, since 1029 // this conflicts with the syntax for the forward declaration of an anonymous type 1030 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() ); 1031 } // if 1032 } // if 1033 } // if 1034 } // if 1035 } // if 1036 decl->location = cur->location; 1037 *out++ = decl; 1142 1038 } // if 1143 *out++ = decl;1144 1039 } // if 1145 } catch ( SemanticErrorException & e ) {1040 } catch( SemanticErrorException & e ) { 1146 1041 errors.append( e ); 1147 1042 } // try … … 1154 1049 1155 1050 // currently only builds assertions, function parameters, and return values 1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {1051 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) { 1157 1052 SemanticErrorException errors; 1158 std::back_insert_iterator< std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );1159 1160 for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur) ) {1053 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList ); 1054 1055 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1161 1056 try { 1162 ast::Decl* decl = cur->build();1163 assert f( decl, "buildList: build for ast::DeclWithType.");1164 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {1057 Declaration * decl = cur->build(); 1058 assert( decl ); 1059 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 1165 1060 dwt->location = cur->location; 1166 1061 *out++ = dwt; 1167 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {1062 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1168 1063 // e.g., int foo(struct S) {} 1169 auto inst = new ast::StructInstType(agg->name );1170 auto obj = new ast::ObjectDecl( cur->location, "", inst);1171 obj->l inkage = linkage;1064 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name ); 1065 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1066 obj->location = cur->location; 1172 1067 *out++ = obj; 1173 1068 delete agg; 1174 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {1069 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 1175 1070 // e.g., int foo(union U) {} 1176 auto inst = new ast::UnionInstType( agg->name ); 1177 auto obj = new ast::ObjectDecl( cur->location, 1178 "", inst, nullptr, ast::Storage::Classes(), 1179 linkage ); 1071 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name ); 1072 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1073 obj->location = cur->location; 1180 1074 *out++ = obj; 1181 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {1075 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) { 1182 1076 // e.g., int foo(enum E) {} 1183 auto inst = new ast::EnumInstType( agg->name ); 1184 auto obj = new ast::ObjectDecl( cur->location, 1185 "", 1186 inst, 1187 nullptr, 1188 ast::Storage::Classes(), 1189 linkage 1190 ); 1077 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name ); 1078 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1079 obj->location = cur->location; 1191 1080 *out++ = obj; 1192 } else {1193 assertf( false, "buildList: Could not convert to ast::DeclWithType." );1194 1081 } // if 1195 } catch ( SemanticErrorException & e ) {1082 } catch( SemanticErrorException & e ) { 1196 1083 errors.append( e ); 1197 1084 } // try … … 1203 1090 } // buildList 1204 1091 1205 void buildTypeList( const DeclarationNode * firstNode, 1206 std::vector<ast::ptr<ast::Type>> & outputList ) { 1092 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1207 1093 SemanticErrorException errors; 1208 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList ); 1209 1210 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) { 1094 std::back_insert_iterator< std::list< Type * > > out( outputList ); 1095 const DeclarationNode * cur = firstNode; 1096 1097 while ( cur ) { 1211 1098 try { 1212 1099 * out++ = cur->buildType(); 1213 } catch ( SemanticErrorException & e ) {1100 } catch( SemanticErrorException & e ) { 1214 1101 errors.append( e ); 1215 1102 } // try 1216 } // for 1103 cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); 1104 } // while 1217 1105 1218 1106 if ( ! errors.isEmpty() ) { … … 1221 1109 } // buildTypeList 1222 1110 1223 ast::Decl* DeclarationNode::build() const {1111 Declaration * DeclarationNode::build() const { 1224 1112 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1225 1113 1226 1114 if ( asmStmt ) { 1227 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() ); 1228 return new ast::AsmDecl( stmt->location, stmt ); 1115 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) ); 1229 1116 } // if 1230 1117 if ( directiveStmt ) { 1231 auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() ); 1232 return new ast::DirectiveDecl( stmt->location, stmt ); 1233 } // if 1234 1235 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 1118 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) ); 1119 } // if 1120 1121 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 1236 1122 // otype is internally converted to dtype + otype parameters 1237 static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };1238 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );1123 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension }; 1124 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." ); 1239 1125 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." ); 1240 ast::TypeDecl * ret = new ast::TypeDecl( location, 1241 *name, 1242 ast::Storage::Classes(), 1243 (ast::Type *)nullptr, 1244 kindMap[ variable.tyClass ], 1245 variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype, 1246 variable.initializer ? variable.initializer->buildType() : nullptr 1247 ); 1248 buildList( variable.assertions, ret->assertions ); 1126 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr ); 1127 buildList( variable.assertions, ret->get_assertions() ); 1249 1128 return ret; 1250 1129 } // if … … 1268 1147 } // if 1269 1148 bool isDelete = initializer && initializer->get_isDelete(); 1270 ast::Decl * decl = buildDecl( 1271 type, 1272 name ? *name : string( "" ), 1273 storageClasses, 1274 maybeBuild( bitfieldWidth ), 1275 funcSpecs, 1276 linkage, 1277 asmName, 1278 isDelete ? nullptr : maybeBuild( initializer ), 1279 copy( attributes ) 1280 )->set_extension( extension ); 1149 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1281 1150 if ( isDelete ) { 1282 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );1151 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl ); 1283 1152 dwt->isDeleted = true; 1284 1153 } … … 1287 1156 1288 1157 if ( assert.condition ) { 1289 auto cond = maybeBuild( assert.condition ); 1290 auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) ); 1291 return new ast::StaticAssertDecl( location, cond, msg ); 1158 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 1292 1159 } 1293 1160 … … 1300 1167 } // if 1301 1168 if ( enumInLine ) { 1302 return new ast::InlineMemberDecl( location, 1303 *name, (ast::Type*)nullptr, storageClasses, linkage ); 1169 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1304 1170 } // if 1305 1171 assertf( name, "ObjectDecl must a have name\n" ); 1306 auto ret = new ast::ObjectDecl( location, 1307 *name, 1308 (ast::Type*)nullptr, 1309 maybeBuild( initializer ), 1310 storageClasses, 1311 linkage, 1312 maybeBuild( bitfieldWidth ) 1313 ); 1314 ret->asmName = asmName; 1315 ret->extension = extension; 1316 return ret; 1317 } 1318 1319 ast::Type * DeclarationNode::buildType() const { 1172 return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension ); 1173 } 1174 1175 Type * DeclarationNode::buildType() const { 1320 1176 assert( type ); 1321 1177 1178 if ( attr.expr ) { 1179 return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes ); 1180 } else if ( attr.type ) { 1181 return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes ); 1182 } // if 1183 1322 1184 switch ( type->kind ) { 1323 case TypeData::Enum: 1324 case TypeData::Aggregate: { 1325 ast::BaseInstType * ret = 1326 buildComAggInst( type, copy( attributes ), linkage ); 1327 buildList( type->aggregate.actuals, ret->params ); 1328 return ret; 1329 } 1330 case TypeData::Symbolic: { 1331 ast::TypeInstType * ret = new ast::TypeInstType( 1332 *type->symbolic.name, 1333 // This is just a default, the true value is not known yet. 1334 ast::TypeDecl::Dtype, 1335 buildQualifiers( type ), 1336 copy( attributes ) ); 1337 buildList( type->symbolic.actuals, ret->params ); 1338 return ret; 1339 } 1340 default: 1341 ast::Type * simpletypes = typebuild( type ); 1342 // copy because member is const 1343 simpletypes->attributes = attributes; 1185 case TypeData::Enum: 1186 case TypeData::Aggregate: { 1187 ReferenceToType * ret = buildComAggInst( type, attributes, linkage ); 1188 buildList( type->aggregate.actuals, ret->get_parameters() ); 1189 return ret; 1190 } 1191 case TypeData::Symbolic: { 1192 TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes ); 1193 buildList( type->symbolic.actuals, ret->get_parameters() ); 1194 return ret; 1195 } 1196 default: 1197 Type * simpletypes = typebuild( type ); 1198 simpletypes->get_attributes() = attributes; // copy because member is const 1344 1199 return simpletypes; 1345 1200 } // switch -
src/Parser/ExpressionNode.cc
r24d6572 r34b4268 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 13:17:07 2015 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 11:07:00 2023 13 // Update Count : 1083 14 // 15 16 #include "ExpressionNode.h" 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 7 09:18:56 2021 13 // Update Count : 1077 14 // 17 15 18 16 #include <cassert> // for assert … … 23 21 #include <string> // for string, operator+, operator== 24 22 25 #include "AST/Expr.hpp" // for NameExpr26 #include "AST/Type.hpp" // for BaseType, SueInstType27 23 #include "Common/SemanticError.h" // for SemanticError 28 24 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 29 #include "DeclarationNode.h" // for DeclarationNode 30 #include "InitializerNode.h" // for InitializerNode 25 #include "ParseNode.h" // for ExpressionNode, maybeMoveBuildType 26 #include "SynTree/Constant.h" // for Constant 27 #include "SynTree/Declaration.h" // for EnumDecl, StructDecl, UnionDecl 28 #include "SynTree/Expression.h" // for Expression, ConstantExpr, NameExpr 29 #include "SynTree/Statement.h" // for CompoundStmt, Statement 30 #include "SynTree/Type.h" // for BasicType, Type, Type::Qualifiers 31 31 #include "parserutility.h" // for notZeroExpr 32 33 class Initializer; 32 34 33 35 using namespace std; … … 46 48 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 47 49 // type. 50 51 extern const Type::Qualifiers noQualifiers; // no qualifiers on constants 48 52 49 53 // static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } … … 67 71 size_t end = str.length() - 1; 68 72 if ( posn == end ) { type = 3; return; } // no length after 'l' => long 69 73 70 74 string::size_type next = posn + 1; // advance to length 71 75 if ( str[next] == '3' ) { // 32 … … 118 122 if ( str[i] == '1' ) v |= 1; 119 123 i += 1; 120 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;124 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 121 125 v <<= 1; 122 126 } // for 123 127 } // scanbin 124 128 125 ast::Expr * build_constantInteger( 126 const CodeLocation & location, string & str ) { 127 static const ast::BasicType::Kind kind[2][6] = { 129 Expression * build_constantInteger( string & str ) { 130 static const BasicType::Kind kind[2][6] = { 128 131 // short (h) must be before char (hh) because shorter type has the longer suffix 129 { ast::BasicType::ShortSignedInt, ast::BasicType::SignedChar, ast::BasicType::SignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ ast::BasicType::LongLongSignedInt, },130 { ast::BasicType::ShortUnsignedInt, ast::BasicType::UnsignedChar, ast::BasicType::UnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ ast::BasicType::LongLongUnsignedInt, },132 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, }, 133 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ BasicType::LongLongUnsignedInt, }, 131 134 }; 132 135 … … 138 141 string str2( "0x0" ); 139 142 unsigned long long int v, v2 = 0; // converted integral value 140 ast::Expr* ret, * ret2;143 Expression * ret, * ret2; 141 144 142 145 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 … … 146 149 // special constants 147 150 if ( str == "0" ) { 148 ret = new ast::ConstantExpr( location, new ast::ZeroType(), str, 0);151 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) ); 149 152 goto CLEANUP; 150 153 } // if 151 154 if ( str == "1" ) { 152 ret = new ast::ConstantExpr( location, new ast::OneType(), str, 1);155 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) ); 153 156 goto CLEANUP; 154 157 } // if 158 159 string::size_type posn; 155 160 156 161 // 'u' can appear before or after length suffix … … 161 166 } else { 162 167 // At least one digit in integer constant, so safe to backup while looking for suffix. 163 // This declaration and the comma expressions in the conditions mimic 164 // the declare and check pattern allowed in later compiler versions. 165 // (Only some early compilers/C++ standards do not support it.) 166 string::size_type posn; 167 // pointer value 168 if ( posn = str.find_last_of( "pP" ), posn != string::npos ) { 169 ltype = 5; str.erase( posn, 1 ); 170 // size_t 171 } else if ( posn = str.find_last_of( "zZ" ), posn != string::npos ) { 172 Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); 173 // signed char 174 } else if ( posn = str.rfind( "hh" ), posn != string::npos ) { 175 type = 1; str.erase( posn, 2 ); 176 // signed char 177 } else if ( posn = str.rfind( "HH" ), posn != string::npos ) { 178 type = 1; str.erase( posn, 2 ); 179 // short 180 } else if ( posn = str.find_last_of( "hH" ), posn != string::npos ) { 181 type = 0; str.erase( posn, 1 ); 182 // int (natural number) 183 } else if ( posn = str.find_last_of( "nN" ), posn != string::npos ) { 184 type = 2; str.erase( posn, 1 ); 185 } else if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { 186 type = 4; 187 } else { 188 lnthSuffix( str, type, ltype ); 189 } // if 168 169 posn = str.find_last_of( "pP" ); // pointer value 170 if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; } 171 172 posn = str.find_last_of( "zZ" ); // size_t 173 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 174 175 posn = str.rfind( "hh" ); // char 176 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 177 178 posn = str.rfind( "HH" ); // char 179 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 180 181 posn = str.find_last_of( "hH" ); // short 182 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 183 184 posn = str.find_last_of( "nN" ); // int (natural number) 185 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 186 187 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 188 189 lnthSuffix( str, type, ltype ); // must be after check for "ll" 190 FINI: ; 190 191 } // if 191 192 … … 195 196 if ( type == 5 ) SemanticError( yylloc, "int128 constant is not supported on this target " + str ); 196 197 #endif // ! __SIZEOF_INT128__ 197 198 198 199 if ( str[0] == '0' ) { // radix character ? 199 200 dec = false; … … 205 206 unsigned int len = str.length(); 206 207 if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str ); 207 // hex digits < 2^64 208 if ( len > (2 + 16) ) { 209 str2 = "0x" + str.substr( len - 16 ); 210 sscanf( (char *)str2.c_str(), "%llx", &v2 ); 211 str = str.substr( 0, len - 16 ); 212 } // if 208 if ( len <= (2 + 16) ) goto FHEX1; // hex digits < 2^64 209 str2 = "0x" + str.substr( len - 16 ); 210 sscanf( (char *)str2.c_str(), "%llx", &v2 ); 211 str = str.substr( 0, len - 16 ); 212 FHEX1: ; 213 213 sscanf( (char *)str.c_str(), "%llx", &v ); 214 214 #endif // __SIZEOF_INT128__ … … 301 301 302 302 // Constant type is correct for overload resolving. 303 ret = new ast::ConstantExpr( location, 304 new ast::BasicType( kind[Unsigned][type] ), str, v ); 303 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) ); 305 304 if ( Unsigned && type < 2 ) { // hh or h, less than int ? 306 305 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 307 ret = new ast::CastExpr( location, 308 ret, 309 new ast::BasicType( kind[Unsigned][type] ), 310 ast::ExplicitCast ); 306 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 311 307 } else if ( ltype != -1 ) { // explicit length ? 312 308 if ( ltype == 6 ) { // int128, (int128)constant 313 ret2 = new ast::ConstantExpr( location, 314 new ast::BasicType( ast::BasicType::LongLongSignedInt ), 315 str2, 316 v2 ); 317 ret = build_compoundLiteral( location, 318 DeclarationNode::newBasicType( 319 DeclarationNode::Int128 320 )->addType( 321 DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 322 new InitializerNode( 323 (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) 324 ); 309 // ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 310 ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) ); 311 ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 312 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) ); 325 313 } else { // explicit length, (length_type)constant 326 ret = new ast::CastExpr( location, 327 ret, 328 new ast::TypeInstType( lnthsInt[Unsigned][ltype], ast::TypeDecl::Dtype ), 329 ast::ExplicitCast ); 314 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); 330 315 if ( ltype == 5 ) { // pointer, intptr( (uintptr_t)constant ) 331 ret = build_func( location, 332 new ExpressionNode( 333 build_varref( location, new string( "intptr" ) ) ), 334 new ExpressionNode( ret ) ); 316 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) ); 335 317 } // if 336 318 } // if … … 376 358 377 359 378 ast::Expr * build_constantFloat( 379 const CodeLocation & location, string & str ) { 380 static const ast::BasicType::Kind kind[2][12] = { 381 { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x }, 382 { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex }, 360 Expression * build_constantFloat( string & str ) { 361 static const BasicType::Kind kind[2][12] = { 362 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x }, 363 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex }, 383 364 }; 384 365 … … 417 398 418 399 assert( 0 <= type && type < 12 ); 419 ast::Expr * ret = new ast::ConstantExpr( location, 420 new ast::BasicType( kind[complx][type] ), 421 str, 422 v ); 423 // explicit length ? 424 if ( explnth ) { 425 ret = new ast::CastExpr( location, 426 ret, 427 new ast::BasicType( kind[complx][type] ), 428 ast::ExplicitCast ); 400 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) ); 401 if ( explnth ) { // explicit length ? 402 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false ); 429 403 } // if 430 404 … … 441 415 } // sepString 442 416 443 ast::Expr * build_constantChar( const CodeLocation & location,string & str ) {417 Expression * build_constantChar( string & str ) { 444 418 string units; // units 445 419 sepString( str, units, '\'' ); // separate constant from units 446 420 447 ast::Expr * ret = new ast::ConstantExpr( location, 448 new ast::BasicType( ast::BasicType::Char ), 449 str, 450 (unsigned long long int)(unsigned char)str[1] ); 421 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) ); 451 422 if ( units.length() != 0 ) { 452 ret = new ast::UntypedExpr( location, 453 new ast::NameExpr( location, units ), 454 { ret } ); 423 ret = new UntypedExpr( new NameExpr( units ), { ret } ); 455 424 } // if 456 425 … … 459 428 } // build_constantChar 460 429 461 ast::Expr * build_constantStr( 462 const CodeLocation & location, 463 string & str ) { 430 Expression * build_constantStr( string & str ) { 464 431 assert( str.length() > 0 ); 465 432 string units; // units 466 433 sepString( str, units, '"' ); // separate constant from units 467 434 468 ast::Type * strtype;435 Type * strtype; 469 436 switch ( str[0] ) { // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1 470 case 'u':437 case 'u': 471 438 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char 472 439 // lookup type of associated typedef 473 strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype );440 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false ); 474 441 break; 475 case 'U':476 strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype );442 case 'U': 443 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false ); 477 444 break; 478 case 'L':479 strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype );445 case 'L': 446 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false ); 480 447 break; 481 Default: // char default string type482 default:483 strtype = new ast::BasicType( ast::BasicType::Char );448 Default: // char default string type 449 default: 450 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char ); 484 451 } // switch 485 ast::ArrayType * at = new ast::ArrayType( 486 strtype, 487 // Length is adjusted: +1 for '\0' and -2 for '"' 488 ast::ConstantExpr::from_ulong( location, str.size() + 1 - 2 ), 489 ast::FixedLen, 490 ast::DynamicDim ); 491 ast::Expr * ret = new ast::ConstantExpr( location, at, str, std::nullopt ); 452 ArrayType * at = new ArrayType( noQualifiers, strtype, 453 new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"' 454 false, false ); 455 Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) ); 492 456 if ( units.length() != 0 ) { 493 ret = new ast::UntypedExpr( location, 494 new ast::NameExpr( location, units ), 495 { ret } ); 457 ret = new UntypedExpr( new NameExpr( units ), { ret } ); 496 458 } // if 497 459 … … 500 462 } // build_constantStr 501 463 502 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( 503 const CodeLocation & location, const string & str ) { 464 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) { 504 465 if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str ); 505 ast::Expr * ret = build_constantInteger( location, 506 *new string( str.substr(1) ) ); 466 Expression * ret = build_constantInteger( *new string( str.substr(1) ) ); 507 467 delete &str; 508 468 return ret; 509 469 } // build_field_name_FLOATING_FRACTIONconstant 510 470 511 ast::Expr * build_field_name_FLOATING_DECIMALconstant( 512 const CodeLocation & location, const string & str ) { 471 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) { 513 472 if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str ); 514 ast::Expr * ret = build_constantInteger( 515 location, *new string( str.substr( 0, str.size()-1 ) ) ); 473 Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) ); 516 474 delete &str; 517 475 return ret; 518 476 } // build_field_name_FLOATING_DECIMALconstant 519 477 520 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location, 521 const string & str ) { 478 Expression * build_field_name_FLOATINGconstant( const string & str ) { 522 479 // str is of the form A.B -> separate at the . and return member expression 523 480 int a, b; … … 525 482 stringstream ss( str ); 526 483 ss >> a >> dot >> b; 527 auto ret = new ast::UntypedMemberExpr( location, 528 ast::ConstantExpr::from_int( location, b ), 529 ast::ConstantExpr::from_int( location, a ) 530 ); 484 UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) ); 531 485 delete &str; 532 486 return ret; 533 487 } // build_field_name_FLOATINGconstant 534 488 535 ast::Expr * make_field_name_fraction_constants( const CodeLocation & location, 536 ast::Expr * fieldName, 537 ast::Expr * fracts ) { 538 if ( nullptr == fracts ) { 539 return fieldName; 540 } else if ( auto memberExpr = dynamic_cast<ast::UntypedMemberExpr *>( fracts ) ) { 541 memberExpr->member = make_field_name_fraction_constants( location, 542 fieldName, 543 ast::mutate( memberExpr->aggregate.get() ) ); 544 return memberExpr; 545 } else { 546 return new ast::UntypedMemberExpr( location, fracts, fieldName ); 547 } // if 489 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) { 490 if ( fracts ) { 491 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) { 492 memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) ); 493 return memberExpr; 494 } else { 495 return new UntypedMemberExpr( fracts, fieldName ); 496 } // if 497 } // if 498 return fieldName; 548 499 } // make_field_name_fraction_constants 549 500 550 ast::Expr * build_field_name_fraction_constants( const CodeLocation & location, 551 ast::Expr * fieldName, 552 ExpressionNode * fracts ) { 553 return make_field_name_fraction_constants( location, fieldName, maybeMoveBuild( fracts ) ); 501 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) { 502 return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) ); 554 503 } // build_field_name_fraction_constants 555 504 556 ast::NameExpr * build_varref( const CodeLocation & location, 557 const string * name ) { 558 ast::NameExpr * expr = new ast::NameExpr( location, *name ); 505 NameExpr * build_varref( const string * name ) { 506 NameExpr * expr = new NameExpr( *name ); 559 507 delete name; 560 508 return expr; 561 509 } // build_varref 562 510 563 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location, 564 const DeclarationNode * decl_node, 565 const ast::NameExpr * name ) { 566 ast::Decl * newDecl = maybeBuild( decl_node ); 567 if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) { 568 if ( const ast::Type * t = newDeclWithType->get_type() ) { 569 if ( auto typeInst = dynamic_cast<const ast::TypeInstType *>( t ) ) { 570 newDecl = new ast::EnumDecl( location, typeInst->name ); 511 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) { 512 Declaration * newDecl = maybeBuild< Declaration >(decl_node); 513 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { 514 const Type * t = newDeclWithType->get_type(); 515 if ( t ) { 516 if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) { 517 newDecl= new EnumDecl( typeInst->name ); 571 518 } 572 519 } 573 520 } 574 return new ast::QualifiedNameExpr( location,newDecl, name->name );521 return new QualifiedNameExpr( newDecl, name->name ); 575 522 } 576 523 577 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location, 578 const ast::EnumDecl * decl, 579 const ast::NameExpr * name ) { 580 return new ast::QualifiedNameExpr( location, decl, name->name ); 524 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) { 525 EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node ); 526 return new QualifiedNameExpr( newDecl, name->name ); 581 527 } 582 528 583 ast::DimensionExpr * build_dimensionref( const CodeLocation & location, 584 const string * name ) { 585 ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name ); 529 DimensionExpr * build_dimensionref( const string * name ) { 530 DimensionExpr * expr = new DimensionExpr( *name ); 586 531 delete name; 587 532 return expr; … … 599 544 }; // OperName 600 545 601 ast::Expr * build_cast( const CodeLocation & location, 602 DeclarationNode * decl_node, 603 ExpressionNode * expr_node, 604 ast::CastExpr::CastKind kind ) { 605 ast::Type * targetType = maybeMoveBuildType( decl_node ); 606 if ( dynamic_cast<ast::VoidType *>( targetType ) ) { 546 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node, CastExpr::CastKind kind ) { 547 Type * targetType = maybeMoveBuildType( decl_node ); 548 if ( dynamic_cast< VoidType * >( targetType ) ) { 607 549 delete targetType; 608 return new ast::CastExpr( location, 609 maybeMoveBuild( expr_node ), 610 ast::ExplicitCast, kind ); 550 return new CastExpr( maybeMoveBuild< Expression >(expr_node), false, kind ); 611 551 } else { 612 return new ast::CastExpr( location, 613 maybeMoveBuild( expr_node ), 614 targetType, 615 ast::ExplicitCast, kind ); 552 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType, false, kind ); 616 553 } // if 617 554 } // build_cast 618 555 619 ast::Expr * build_keyword_cast( const CodeLocation & location, 620 ast::AggregateDecl::Aggregate target, 621 ExpressionNode * expr_node ) { 622 return new ast::KeywordCastExpr( location, 623 maybeMoveBuild( expr_node ), 624 target 625 ); 556 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) { 557 return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target ); 626 558 } 627 559 628 ast::Expr * build_virtual_cast( const CodeLocation & location, 629 DeclarationNode * decl_node, 630 ExpressionNode * expr_node ) { 631 return new ast::VirtualCastExpr( location, 632 maybeMoveBuild( expr_node ), 633 maybeMoveBuildType( decl_node ) 634 ); 560 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) { 561 return new VirtualCastExpr( maybeMoveBuild< Expression >( expr_node ), maybeMoveBuildType( decl_node ) ); 635 562 } // build_virtual_cast 636 563 637 ast::Expr * build_fieldSel( const CodeLocation & location, 638 ExpressionNode * expr_node, 639 ast::Expr * member ) { 640 return new ast::UntypedMemberExpr( location, 641 member, 642 maybeMoveBuild( expr_node ) 643 ); 564 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) { 565 return new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) ); 644 566 } // build_fieldSel 645 567 646 ast::Expr * build_pfieldSel( const CodeLocation & location, 647 ExpressionNode * expr_node, 648 ast::Expr * member ) { 649 auto deref = new ast::UntypedExpr( location, 650 new ast::NameExpr( location, "*?" ) 651 ); 568 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) { 569 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 652 570 deref->location = expr_node->location; 653 deref-> args.push_back( maybeMoveBuild( expr_node) );654 auto ret = new ast::UntypedMemberExpr( location,member, deref );571 deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) ); 572 UntypedMemberExpr * ret = new UntypedMemberExpr( member, deref ); 655 573 return ret; 656 574 } // build_pfieldSel 657 575 658 ast::Expr * build_offsetOf( const CodeLocation & location, 659 DeclarationNode * decl_node, 660 ast::NameExpr * member ) { 661 ast::Expr * ret = new ast::UntypedOffsetofExpr( location, 662 maybeMoveBuildType( decl_node ), 663 member->name 664 ); 665 ret->result = new ast::BasicType( ast::BasicType::LongUnsignedInt ); 576 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) { 577 Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() ); 666 578 delete member; 667 579 return ret; 668 580 } // build_offsetOf 669 581 670 ast::Expr * build_and_or( const CodeLocation & location, 671 ExpressionNode * expr_node1, 672 ExpressionNode * expr_node2, 673 ast::LogicalFlag flag ) { 674 return new ast::LogicalExpr( location, 675 notZeroExpr( maybeMoveBuild( expr_node1 ) ), 676 notZeroExpr( maybeMoveBuild( expr_node2 ) ), 677 flag 678 ); 582 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) { 583 return new LogicalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), notZeroExpr( maybeMoveBuild< Expression >(expr_node2) ), kind ); 679 584 } // build_and_or 680 585 681 ast::Expr * build_unary_val( const CodeLocation & location, 682 OperKinds op, 683 ExpressionNode * expr_node ) { 684 std::vector<ast::ptr<ast::Expr>> args; 685 args.push_back( maybeMoveBuild( expr_node ) ); 686 return new ast::UntypedExpr( location, 687 new ast::NameExpr( location, OperName[ (int)op ] ), 688 std::move( args ) 689 ); 586 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) { 587 list< Expression * > args; 588 args.push_back( maybeMoveBuild< Expression >(expr_node) ); 589 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 690 590 } // build_unary_val 691 591 692 ast::Expr * build_binary_val( const CodeLocation & location, 693 OperKinds op,694 ExpressionNode * expr_node1,695 ExpressionNode * expr_node2 ) {696 std::vector<ast::ptr<ast::Expr>> args; 697 args.push_back( maybeMoveBuild( expr_node1 ) ); 698 args.push_back( maybeMoveBuild( expr_node2 ) ); 699 return new ast::UntypedExpr( location,700 new ast::NameExpr( location, OperName[ (int)op ] ),701 std::move( args )702 );592 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) { 593 list< Expression * > args; 594 args.push_back( maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code. 595 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 596 } // build_unary_ptr 597 598 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 599 list< Expression * > args; 600 args.push_back( maybeMoveBuild< Expression >(expr_node1) ); 601 args.push_back( maybeMoveBuild< Expression >(expr_node2) ); 602 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 703 603 } // build_binary_val 704 604 705 ast::Expr * build_cond( const CodeLocation & location, 706 ExpressionNode * expr_node1,707 ExpressionNode * expr_node2,708 ExpressionNode * expr_node3 ) {709 return new ast::ConditionalExpr( location,710 notZeroExpr( maybeMoveBuild( expr_node1 ) ), 711 maybeMoveBuild( expr_node2 ), 712 maybeMoveBuild( expr_node3 ) 713 );605 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 606 list< Expression * > args; 607 args.push_back( maybeMoveBuild< Expression >(expr_node1) ); 608 args.push_back( maybeMoveBuild< Expression >(expr_node2) ); 609 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 610 } // build_binary_ptr 611 612 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) { 613 return new ConditionalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), maybeMoveBuild< Expression >(expr_node2), maybeMoveBuild< Expression >(expr_node3) ); 714 614 } // build_cond 715 615 716 ast::Expr * build_tuple( const CodeLocation & location, 717 ExpressionNode * expr_node ) { 718 std::vector<ast::ptr<ast::Expr>> exprs; 616 Expression * build_tuple( ExpressionNode * expr_node ) { 617 list< Expression * > exprs; 719 618 buildMoveList( expr_node, exprs ); 720 return new ast::UntypedTupleExpr( location, std::move( exprs ) );619 return new UntypedTupleExpr( exprs );; 721 620 } // build_tuple 722 621 723 ast::Expr * build_func( const CodeLocation & location, 724 ExpressionNode * function, 725 ExpressionNode * expr_node ) { 726 std::vector<ast::ptr<ast::Expr>> args; 622 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) { 623 list< Expression * > args; 727 624 buildMoveList( expr_node, args ); 728 return new ast::UntypedExpr( location, 729 maybeMoveBuild( function ), 730 std::move( args ) 731 ); 625 return new UntypedExpr( maybeMoveBuild< Expression >(function), args ); 732 626 } // build_func 733 627 734 ast::Expr * build_compoundLiteral( const CodeLocation & location, 735 DeclarationNode * decl_node, 736 InitializerNode * kids ) { 737 // compound literal type 738 ast::Decl * newDecl = maybeBuild( decl_node ); 739 // non-sue compound-literal type 740 if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) { 741 return new ast::CompoundLiteralExpr( location, 742 newDeclWithType->get_type(), 743 maybeMoveBuild( kids ) ); 628 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) { 629 Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type 630 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type 631 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild< Initializer >(kids) ); 744 632 // these types do not have associated type information 745 } else if ( auto newDeclStructDecl = dynamic_cast<ast::StructDecl *>( newDecl ) ) { 746 if ( newDeclStructDecl->body ) { 747 return new ast::CompoundLiteralExpr( location, 748 new ast::StructInstType( newDeclStructDecl ), 749 maybeMoveBuild( kids ) ); 633 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) { 634 if ( newDeclStructDecl->has_body() ) { 635 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild< Initializer >(kids) ); 750 636 } else { 751 return new ast::CompoundLiteralExpr( location, 752 new ast::StructInstType( newDeclStructDecl->name ), 753 maybeMoveBuild( kids ) ); 754 } // if 755 } else if ( auto newDeclUnionDecl = dynamic_cast<ast::UnionDecl *>( newDecl ) ) { 756 if ( newDeclUnionDecl->body ) { 757 return new ast::CompoundLiteralExpr( location, 758 new ast::UnionInstType( newDeclUnionDecl ), 759 maybeMoveBuild( kids ) ); 637 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild< Initializer >(kids) ); 638 } // if 639 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) { 640 if ( newDeclUnionDecl->has_body() ) { 641 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild< Initializer >(kids) ); 760 642 } else { 761 return new ast::CompoundLiteralExpr( location, 762 new ast::UnionInstType( newDeclUnionDecl->name ), 763 maybeMoveBuild( kids ) ); 764 } // if 765 } else if ( auto newDeclEnumDecl = dynamic_cast<ast::EnumDecl *>( newDecl ) ) { 766 if ( newDeclEnumDecl->body ) { 767 return new ast::CompoundLiteralExpr( location, 768 new ast::EnumInstType( newDeclEnumDecl ), 769 maybeMoveBuild( kids ) ); 643 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild< Initializer >(kids) ); 644 } // if 645 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) { 646 if ( newDeclEnumDecl->has_body() ) { 647 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild< Initializer >(kids) ); 770 648 } else { 771 return new ast::CompoundLiteralExpr( location, 772 new ast::EnumInstType( newDeclEnumDecl->name ), 773 maybeMoveBuild( kids ) ); 649 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild< Initializer >(kids) ); 774 650 } // if 775 651 } else { … … 780 656 // Local Variables: // 781 657 // tab-width: 4 // 658 // mode: c++ // 659 // compile-command: "make install" // 782 660 // End: // -
src/Parser/InitializerNode.cc
r24d6572 r34b4268 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:20:24 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Apr 4 11:18:00 202313 // Update Count : 2 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 28 23:27:20 2017 13 // Update Count : 26 14 14 // 15 16 #include "InitializerNode.h"17 15 18 16 #include <iostream> // for operator<<, ostream, basic_ostream … … 20 18 #include <string> // for operator<<, string 21 19 22 #include "AST/Expr.hpp" // for Expr 23 #include "AST/Init.hpp" // for Designator, Init, ListInit, Sing... 20 using namespace std; 21 24 22 #include "Common/SemanticError.h" // for SemanticError 25 23 #include "Common/utility.h" // for maybeBuild 26 #include "ExpressionNode.h" // for ExpressionNode 27 #include "DeclarationNode.h" // for buildList 28 29 using namespace std; 30 31 static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) { 32 return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct; 33 } 24 #include "ParseNode.h" // for InitializerNode, ExpressionNode 25 #include "SynTree/Expression.h" // for Expression 26 #include "SynTree/Initializer.h" // for Initializer, ListInit, SingleInit 34 27 35 28 InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des ) … … 40 33 if ( kids ) 41 34 set_last( nullptr ); 42 } // InitializerNode::InitializerNode 35 } // InitializerNode::InitializerNode 43 36 44 37 InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des ) … … 92 85 } // InitializerNode::printOneLine 93 86 94 ast::Init* InitializerNode::build() const {87 Initializer * InitializerNode::build() const { 95 88 assertf( ! isDelete, "Should not build delete stmt InitializerNode" ); 96 89 if ( aggregate ) { 97 90 // steal designators from children 98 std:: vector<ast::ptr<ast::Designation>> designlist;91 std::list< Designation * > designlist; 99 92 InitializerNode * child = next_init(); 100 for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) { 101 std::deque<ast::ptr<ast::Expr>> desList; 102 buildList( child->designator, desList ); 103 designlist.push_back( 104 new ast::Designation( location, std::move( desList ) ) ); 93 for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) { 94 std::list< Expression * > desList; 95 buildList< Expression, ExpressionNode >( child->designator, desList ); 96 designlist.push_back( new Designation( desList ) ); 105 97 } // for 106 std::vector<ast::ptr<ast::Init>> initlist; 107 buildList( next_init(), initlist ); 108 return new ast::ListInit( location, 109 std::move( initlist ), 110 std::move( designlist ), 111 toConstructFlag( maybeConstructed ) 112 ); 113 } else if ( get_expression() ) { 114 assertf( get_expression()->expr, "The expression of initializer must have value" ); 115 return new ast::SingleInit( location, 116 maybeBuild( get_expression() ), 117 toConstructFlag( maybeConstructed ) 118 ); 98 std::list< Initializer * > initlist; 99 buildList< Initializer, InitializerNode >( next_init(), initlist ); 100 return new ListInit( initlist, designlist, maybeConstructed ); 101 } else { 102 if ( get_expression() ) { 103 assertf( get_expression()->expr, "The expression of initializer must have value" ); 104 return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed ); 105 } // if 119 106 } // if 120 107 return nullptr; -
src/Parser/ParseNode.h
r24d6572 r34b4268 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:28:16 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Apr 3 17:55:00 202313 // Update Count : 9 4211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Nov 2 21:27:07 2022 13 // Update Count : 939 14 14 // 15 15 … … 24 24 #include <string> // for string 25 25 26 #include "AST/Expr.hpp" // for Expr, NameExpr LogicalFlag27 #include "AST/Fwd.hpp" // for ptr, Decl, DeclWithType,28 #include "AST/Stmt.hpp" // for Stmt29 26 #include "Common/CodeLocation.h" // for CodeLocation 30 27 #include "Common/SemanticError.h" // for SemanticError 31 28 #include "Common/UniqueName.h" // for UniqueName 32 #include "Common/utility.h" // for maybeClone 33 #include "Parser/parserutility.h" // for maybeBuild, maybeCopy 29 #include "Common/utility.h" // for maybeClone, maybeBuild 30 #include "SynTree/LinkageSpec.h" // for Spec 31 #include "SynTree/Declaration.h" // for Aggregate 32 #include "SynTree/Expression.h" // for Expression, ConstantExpr (ptr only) 33 #include "SynTree/Label.h" // for Label 34 #include "SynTree/Statement.h" // for Statement, BranchStmt, BranchStmt:... 35 #include "SynTree/Type.h" // for Type, Type::FuncSpecifiers, Type::... 34 36 35 37 class Attribute; … … 38 40 class DeclarationWithType; 39 41 class Initializer; 40 class InitializerNode;41 42 class ExpressionNode; 42 43 struct StatementNode; … … 80 81 CodeLocation location = yylloc; 81 82 }; // ParseNode 83 84 //############################################################################## 85 86 class InitializerNode : public ParseNode { 87 public: 88 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 89 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 90 InitializerNode( bool isDelete ); 91 ~InitializerNode(); 92 virtual InitializerNode * clone() const { assert( false ); return nullptr; } 93 94 ExpressionNode * get_expression() const { return expr; } 95 96 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; } 97 ExpressionNode * get_designators() const { return designator; } 98 99 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; } 100 bool get_maybeConstructed() const { return maybeConstructed; } 101 102 bool get_isDelete() const { return isDelete; } 103 104 InitializerNode * next_init() const { return kids; } 105 106 void print( std::ostream & os, int indent = 0 ) const; 107 void printOneLine( std::ostream & ) const; 108 109 virtual Initializer * build() const; 110 private: 111 ExpressionNode * expr; 112 bool aggregate; 113 ExpressionNode * designator; // may be list 114 InitializerNode * kids; 115 bool maybeConstructed; 116 bool isDelete; 117 }; // InitializerNode 118 119 //############################################################################## 120 121 class ExpressionNode final : public ParseNode { 122 public: 123 ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {} 124 virtual ~ExpressionNode() {} 125 virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; } 126 127 bool get_extension() const { return extension; } 128 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; } 129 130 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override { 131 os << expr.get(); 132 } 133 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {} 134 135 template<typename T> 136 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); } 137 138 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); } 139 140 std::unique_ptr<Expression> expr; // public because of lifetime implications 141 private: 142 bool extension = false; 143 }; // ExpressionNode 144 145 template< typename T > 146 struct maybeBuild_t< Expression, T > { 147 static inline Expression * doit( const T * orig ) { 148 if ( orig ) { 149 Expression * p = orig->build(); 150 p->set_extension( orig->get_extension() ); 151 p->location = orig->location; 152 return p; 153 } else { 154 return nullptr; 155 } // if 156 } 157 }; 82 158 83 159 // Must harmonize with OperName. … … 96 172 97 173 struct LabelNode { 98 std:: vector<ast::Label> labels;174 std::list< Label > labels; 99 175 }; 100 176 177 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string 178 Expression * build_constantFloat( std::string & str ); 179 Expression * build_constantChar( std::string & str ); 180 Expression * build_constantStr( std::string & str ); 181 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str ); 182 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str ); 183 Expression * build_field_name_FLOATINGconstant( const std::string & str ); 184 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ); 185 186 NameExpr * build_varref( const std::string * name ); 187 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ); 188 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name ); 189 DimensionExpr * build_dimensionref( const std::string * name ); 190 191 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node, CastExpr::CastKind kind = CastExpr::Default ); 192 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ); 193 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ); 194 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ); 195 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ); 196 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ); 197 Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 198 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ); 199 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ); 200 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ); 201 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 202 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 203 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ); 204 Expression * build_tuple( ExpressionNode * expr_node = nullptr ); 205 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ); 206 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ); 207 208 //############################################################################## 209 210 struct TypeData; 211 212 struct DeclarationNode : public ParseNode { 213 // These enumerations must harmonize with their names in DeclarationNode.cc. 214 enum BasicType { Void, Bool, Char, Int, Int128, 215 Float, Double, LongDouble, uuFloat80, uuFloat128, 216 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType }; 217 static const char * basicTypeNames[]; 218 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message 219 static const char * complexTypeNames[]; 220 enum Signedness { Signed, Unsigned, NoSignedness }; 221 static const char * signednessNames[]; 222 enum Length { Short, Long, LongLong, NoLength }; 223 static const char * lengthNames[]; 224 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType }; 225 static const char * builtinTypeNames[]; 226 227 static DeclarationNode * newStorageClass( Type::StorageClasses ); 228 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers ); 229 static DeclarationNode * newTypeQualifier( Type::Qualifiers ); 230 static DeclarationNode * newBasicType( BasicType ); 231 static DeclarationNode * newComplexType( ComplexType ); 232 static DeclarationNode * newSignedNess( Signedness ); 233 static DeclarationNode * newLength( Length ); 234 static DeclarationNode * newBuiltinType( BuiltinType ); 235 static DeclarationNode * newForall( DeclarationNode * ); 236 static DeclarationNode * newFromTypedef( const std::string * ); 237 static DeclarationNode * newFromGlobalScope(); 238 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * ); 239 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 240 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); 241 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible ); 242 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); 243 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init ); 244 static DeclarationNode * newEnumInLine( const std::string name ); 245 static DeclarationNode * newName( const std::string * ); 246 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params ); 247 static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * ); 248 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts ); 249 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params ); 250 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams ); 251 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind ); 252 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic ); 253 static DeclarationNode * newVarArray( DeclarationNode * qualifiers ); 254 static DeclarationNode * newBitfield( ExpressionNode * size ); 255 static DeclarationNode * newTuple( DeclarationNode * members ); 256 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false ); 257 static DeclarationNode * newVtableType( DeclarationNode * expr ); 258 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes 259 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement 260 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement 261 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message ); 262 263 DeclarationNode(); 264 ~DeclarationNode(); 265 DeclarationNode * clone() const override; 266 267 DeclarationNode * addQualifiers( DeclarationNode * ); 268 void checkQualifiers( const TypeData *, const TypeData * ); 269 void checkSpecifiers( DeclarationNode * ); 270 DeclarationNode * copySpecifiers( DeclarationNode * ); 271 DeclarationNode * addType( DeclarationNode * ); 272 DeclarationNode * addTypedef(); 273 DeclarationNode * addEnumBase( DeclarationNode * ); 274 DeclarationNode * addAssertions( DeclarationNode * ); 275 DeclarationNode * addName( std::string * ); 276 DeclarationNode * addAsmName( DeclarationNode * ); 277 DeclarationNode * addBitfield( ExpressionNode * size ); 278 DeclarationNode * addVarArgs(); 279 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr ); 280 DeclarationNode * addOldDeclList( DeclarationNode * list ); 281 DeclarationNode * setBase( TypeData * newType ); 282 DeclarationNode * copyAttribute( DeclarationNode * attr ); 283 DeclarationNode * addPointer( DeclarationNode * qualifiers ); 284 DeclarationNode * addArray( DeclarationNode * array ); 285 DeclarationNode * addNewPointer( DeclarationNode * pointer ); 286 DeclarationNode * addNewArray( DeclarationNode * array ); 287 DeclarationNode * addParamList( DeclarationNode * list ); 288 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions 289 DeclarationNode * addInitializer( InitializerNode * init ); 290 DeclarationNode * addTypeInitializer( DeclarationNode * init ); 291 292 DeclarationNode * cloneType( std::string * newName ); 293 DeclarationNode * cloneBaseType( DeclarationNode * newdecl ); 294 295 DeclarationNode * appendList( DeclarationNode * node ) { 296 return (DeclarationNode *)set_last( node ); 297 } 298 299 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 300 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 301 302 Declaration * build() const; 303 Type * buildType() const; 304 305 LinkageSpec::Spec get_linkage() const { return linkage; } 306 DeclarationNode * extractAggregate() const; 307 bool has_enumeratorValue() const { return (bool)enumeratorValue; } 308 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); } 309 310 bool get_extension() const { return extension; } 311 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; } 312 313 bool get_inLine() const { return inLine; } 314 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; } 315 316 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); } 317 318 struct Variable_t { 319 // const std::string * name; 320 TypeDecl::Kind tyClass; 321 DeclarationNode * assertions; 322 DeclarationNode * initializer; 323 }; 324 Variable_t variable; 325 326 struct Attr_t { 327 // const std::string * name; 328 ExpressionNode * expr; 329 DeclarationNode * type; 330 }; 331 Attr_t attr; 332 333 struct StaticAssert_t { 334 ExpressionNode * condition; 335 Expression * message; 336 }; 337 StaticAssert_t assert; 338 339 BuiltinType builtin = NoBuiltinType; 340 341 TypeData * type = nullptr; 342 343 bool inLine = false; 344 bool enumInLine = false; 345 Type::FuncSpecifiers funcSpecs; 346 Type::StorageClasses storageClasses; 347 348 ExpressionNode * bitfieldWidth = nullptr; 349 std::unique_ptr<ExpressionNode> enumeratorValue; 350 bool hasEllipsis = false; 351 LinkageSpec::Spec linkage; 352 Expression * asmName = nullptr; 353 std::list< Attribute * > attributes; 354 InitializerNode * initializer = nullptr; 355 bool extension = false; 356 std::string error; 357 StatementNode * asmStmt = nullptr; 358 StatementNode * directiveStmt = nullptr; 359 360 static UniqueName anonymous; 361 }; // DeclarationNode 362 363 Type * buildType( TypeData * type ); 364 365 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) { 366 Type * ret = orig ? orig->buildType() : nullptr; 367 delete orig; 368 return ret; 369 } 370 371 //############################################################################## 372 373 struct StatementNode final : public ParseNode { 374 StatementNode() { stmt = nullptr; } 375 StatementNode( Statement * stmt ) : stmt( stmt ) {} 376 StatementNode( DeclarationNode * decl ); 377 virtual ~StatementNode() {} 378 379 virtual StatementNode * clone() const final { assert( false ); return nullptr; } 380 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); } 381 382 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) { 383 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} ); 384 delete attr; 385 delete name; 386 return this; 387 } 388 389 virtual StatementNode * append_last_case( StatementNode * ); 390 391 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override { 392 os << stmt.get() << std::endl; 393 } 394 395 std::unique_ptr<Statement> stmt; 396 }; // StatementNode 397 398 Statement * build_expr( ExpressionNode * ctl ); 399 400 struct CondCtl { 401 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) : 402 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {} 403 404 StatementNode * init; 405 ExpressionNode * condition; 406 }; 407 408 struct ForCtrl { 409 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) : 410 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {} 411 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) : 412 init( new StatementNode( decl ) ), condition( condition ), change( change ) {} 413 414 StatementNode * init; 415 ExpressionNode * condition; 416 ExpressionNode * change; 417 }; 418 419 Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init ); 420 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ); 421 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ); 422 Statement * build_case( ExpressionNode * ctl ); 423 Statement * build_default(); 424 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 425 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 426 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 427 Statement * build_branch( BranchStmt::Type kind ); 428 Statement * build_branch( std::string * identifier, BranchStmt::Type kind ); 429 Statement * build_computedgoto( ExpressionNode * ctl ); 430 Statement * build_return( ExpressionNode * ctl ); 431 Statement * build_throw( ExpressionNode * ctl ); 432 Statement * build_resume( ExpressionNode * ctl ); 433 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target ); 434 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ); 435 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ); 436 Statement * build_finally( StatementNode * stmt ); 437 Statement * build_compound( StatementNode * first ); 438 StatementNode * maybe_build_compound( StatementNode * first ); 439 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr ); 440 Statement * build_directive( std::string * directive ); 441 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None); 442 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when ); 443 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing ); 444 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 445 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 446 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ); 447 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ); 448 449 //############################################################################## 450 451 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args > 452 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) { 453 SemanticErrorException errors; 454 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList ); 455 const NodeType * cur = firstNode; 456 457 while ( cur ) { 458 try { 459 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) ); 460 if ( result ) { 461 result->location = cur->location; 462 * out++ = result; 463 } else { 464 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." ); 465 } // if 466 } catch( SemanticErrorException & e ) { 467 errors.append( e ); 468 } // try 469 const ParseNode * temp = (cur->get_next()); 470 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr 471 if ( ! cur && temp ) { // non-homogeneous nodes ? 472 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 473 } // if 474 } // while 475 if ( ! errors.isEmpty() ) { 476 throw errors; 477 } // if 478 } 479 480 // in DeclarationNode.cc 481 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ); 482 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ); 483 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ); 484 485 template< typename SynTreeType, typename NodeType > 486 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) { 487 buildList( firstNode, outputList ); 488 delete firstNode; 489 } 490 491 // in ParseNode.cc 101 492 std::ostream & operator<<( std::ostream & out, const ParseNode * node ); 102 493 -
src/Parser/ParserTypes.h
r24d6572 r34b4268 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // parser.hh -- 8 // 6 // 7 // parser.hh -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 22 08:58:10 2001 -
src/Parser/StatementNode.cc
r24d6572 r34b4268 10 10 // Author : Rodolfo G. Esteves 11 11 // Created On : Sat May 16 14:59:41 2015 12 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 11 10:16:00 2023 14 // Update Count : 428 15 // 16 17 #include "StatementNode.h" 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Wed Feb 2 20:29:30 2022 14 // Update Count : 425 15 // 18 16 19 17 #include <cassert> // for assert, strict_dynamic_cast, assertf 18 #include <list> // for list 20 19 #include <memory> // for unique_ptr 21 20 #include <string> // for string 22 21 23 #include "AST/Label.hpp" // for Label24 #include "AST/Stmt.hpp" // for Stmt, AsmStmt, BranchStmt, CaseCla...25 22 #include "Common/SemanticError.h" // for SemanticError 26 23 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 27 #include "DeclarationNode.h" // for DeclarationNode 28 #include "ExpressionNode.h" // for ExpressionNode 24 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 25 #include "SynTree/Expression.h" // for Expression, ConstantExpr 26 #include "SynTree/Label.h" // for Label, noLabels 27 #include "SynTree/Declaration.h" 28 #include "SynTree/Statement.h" // for Statement, BranchStmt, CaseStmt 29 29 #include "parserutility.h" // for notZeroExpr 30 30 … … 33 33 using namespace std; 34 34 35 // Some helpers for cases that really want a single node but check for lists.36 static const ast::Stmt * buildMoveSingle( StatementNode * node ) {37 std::vector<ast::ptr<ast::Stmt>> list;38 buildMoveList( node, list );39 assertf( list.size() == 1, "CFA Internal Error: Extra/Missing Nodes" );40 return list.front().release();41 }42 43 static const ast::Stmt * buildMoveOptional( StatementNode * node ) {44 std::vector<ast::ptr<ast::Stmt>> list;45 buildMoveList( node, list );46 assertf( list.size() <= 1, "CFA Internal Error: Extra Nodes" );47 return list.empty() ? nullptr : list.front().release();48 }49 35 50 36 StatementNode::StatementNode( DeclarationNode * decl ) { … … 52 38 DeclarationNode * agg = decl->extractAggregate(); 53 39 if ( agg ) { 54 StatementNode * nextStmt = new StatementNode( 55 new ast::DeclStmt( decl->location, maybeBuild( decl ) ) ); 40 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild< Declaration >( decl ) ) ); 56 41 set_next( nextStmt ); 57 42 if ( decl->get_next() ) { … … 66 51 agg = decl; 67 52 } // if 68 // Local copy to avoid accessing the pointer after it is moved from. 69 CodeLocation declLocation = agg->location; 70 stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) ); 53 stmt.reset( new DeclStmt( maybeMoveBuild< Declaration >(agg) ) ); 71 54 } // StatementNode::StatementNode 72 55 73 StatementNode * StatementNode::add_label( 74 const CodeLocation & location, 75 const std::string * name, 76 DeclarationNode * attr ) { 77 stmt->labels.emplace_back( location, 78 *name, 79 attr ? std::move( attr->attributes ) 80 : std::vector<ast::ptr<ast::Attribute>>{} ); 81 delete attr; 82 delete name; 83 return this; 84 } 85 86 ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) { 87 ClauseNode * prev = this; 56 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) { 57 StatementNode * prev = this; 88 58 // find end of list and maintain previous pointer 89 for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next() ) {90 ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr);91 assert( dynamic_cast< ast::CaseClause *>( node->clause.get()) );59 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 60 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr); 61 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) ); 92 62 prev = curr; 93 63 } // for 94 ClauseNode * node = dynamic_cast< ClauseNode * >(prev);95 64 // convert from StatementNode list to Statement list 96 std::vector<ast::ptr<ast::Stmt>> stmts; 65 StatementNode * node = dynamic_cast< StatementNode * >(prev); 66 list< Statement * > stmts; 97 67 buildMoveList( stmt, stmts ); 98 68 // splice any new Statements to end of current Statements 99 auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() ); 100 for ( auto const & newStmt : stmts ) { 101 caseStmt->stmts.emplace_back( newStmt ); 102 } 103 stmts.clear(); 69 CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get()); 70 caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts ); 104 71 return this; 105 } // ClauseNode::append_last_case 106 107 ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) { 108 if ( ast::Expr * e = maybeMoveBuild( ctl ) ) { 109 return new ast::ExprStmt( location, e ); 110 } else { 111 return new ast::NullStmt( location ); 112 } 72 } // StatementNode::append_last_case 73 74 Statement * build_expr( ExpressionNode * ctl ) { 75 Expression * e = maybeMoveBuild< Expression >( ctl ); 76 77 if ( e ) return new ExprStmt( e ); 78 else return new NullStmt(); 113 79 } // build_expr 114 80 115 static ast::Expr * build_if_control( CondCtl * ctl, 116 std::vector<ast::ptr<ast::Stmt>> & inits ) { 117 assert( inits.empty() ); 118 if ( nullptr != ctl->init ) { 119 buildMoveList( ctl->init, inits ); 120 } // if 121 122 ast::Expr * cond = nullptr; 81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) { 82 if ( ctl->init != 0 ) { 83 buildMoveList( ctl->init, init ); 84 } // if 85 86 Expression * cond = nullptr; 123 87 if ( ctl->condition ) { 124 88 // compare the provided condition against 0 125 cond = notZeroExpr( maybeMoveBuild ( ctl->condition) );89 cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) ); 126 90 } else { 127 for ( ast::ptr<ast::Stmt> & stmt : inits) {91 for ( Statement * stmt : init ) { 128 92 // build the && of all of the declared variables compared against 0 129 auto declStmt = stmt.strict_as<ast::DeclStmt>();130 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();131 ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location,dwt ) );132 cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr) : nze;93 DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt ); 94 DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl ); 95 Expression * nze = notZeroExpr( new VariableExpr( dwt ) ); 96 cond = cond ? new LogicalExpr( cond, nze, true ) : nze; 133 97 } 134 98 } … … 137 101 } // build_if_control 138 102 139 ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 140 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 141 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 142 143 ast::Stmt const * astthen = buildMoveSingle( then ); 144 ast::Stmt const * astelse = buildMoveOptional( else_ ); 145 146 return new ast::IfStmt( location, astcond, astthen, astelse, 147 std::move( astinit ) 148 ); 103 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 104 list< Statement * > astinit; // maybe empty 105 Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 106 107 Statement * astthen, * astelse = nullptr; 108 list< Statement * > aststmt; 109 buildMoveList< Statement, StatementNode >( then, aststmt ); 110 assert( aststmt.size() == 1 ); 111 astthen = aststmt.front(); 112 113 if ( else_ ) { 114 list< Statement * > aststmt; 115 buildMoveList< Statement, StatementNode >( else_, aststmt ); 116 assert( aststmt.size() == 1 ); 117 astelse = aststmt.front(); 118 } // if 119 120 return new IfStmt( astcond, astthen, astelse, astinit ); 149 121 } // build_if 150 122 151 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) { 152 std::vector<ast::ptr<ast::CaseClause>> aststmt; 153 buildMoveList( stmt, aststmt ); 154 // If it is not a switch it is a choose statement. 155 if ( ! isSwitch ) { 156 for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) { 157 // Code after "case" is the end of case list. 158 if ( !stmt->stmts.empty() ) { 159 auto mutStmt = ast::mutate( stmt.get() ); 160 // I believe the stmts are actually always one block. 161 auto stmts = mutStmt->stmts.front().get_and_mutate(); 162 auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts ); 163 block->kids.push_back( new ast::BranchStmt( block->location, 164 ast::BranchStmt::Break, 165 ast::Label( block->location ) ) ); 166 stmt = mutStmt; 123 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { 124 list< Statement * > aststmt; 125 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 126 if ( ! isSwitch ) { // choose statement 127 for ( Statement * stmt : aststmt ) { 128 CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt ); 129 if ( ! caseStmt->stmts.empty() ) { // code after "case" => end of case list 130 CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() ); 131 block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) ); 167 132 } // if 168 133 } // for 169 134 } // if 170 135 // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements 171 return new ast::SwitchStmt( location, 172 maybeMoveBuild( ctl ), std::move( aststmt ) ); 136 return new SwitchStmt( maybeMoveBuild< Expression >(ctl), aststmt ); 173 137 } // build_switch 174 138 175 ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) { 176 // stmt starts empty and then added to 177 auto expr = maybeMoveBuild( ctl ); 178 return new ast::CaseClause( location, expr, {} ); 139 Statement * build_case( ExpressionNode * ctl ) { 140 return new CaseStmt( maybeMoveBuild< Expression >(ctl), {} ); // stmt starts empty and then added to 179 141 } // build_case 180 142 181 ast::CaseClause * build_default( const CodeLocation & location ) { 182 // stmt starts empty and then added to 183 return new ast::CaseClause( location, nullptr, {} ); 143 Statement * build_default() { 144 return new CaseStmt( nullptr, {}, true ); // stmt starts empty and then added to 184 145 } // build_default 185 146 186 ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) { 187 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 188 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 189 190 return new ast::WhileDoStmt( location, 191 astcond, 192 buildMoveSingle( stmt ), 193 buildMoveOptional( else_ ), 194 std::move( astinit ), 195 ast::While 196 ); 147 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) { 148 list< Statement * > astinit; // maybe empty 149 Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 150 151 list< Statement * > aststmt; // loop body, compound created if empty 152 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 153 assert( aststmt.size() == 1 ); 154 155 list< Statement * > astelse; // else clause, maybe empty 156 buildMoveList< Statement, StatementNode >( else_, astelse ); 157 158 return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false ); 197 159 } // build_while 198 160 199 ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 161 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 162 list< Statement * > aststmt; // loop body, compound created if empty 163 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 164 assert( aststmt.size() == 1 ); // compound created if empty 165 166 list< Statement * > astelse; // else clause, maybe empty 167 buildMoveList< Statement, StatementNode >( else_, astelse ); 168 200 169 // do-while cannot have declarations in the contitional, so init is always empty 201 return new ast::WhileDoStmt( location, 202 notZeroExpr( maybeMoveBuild( ctl ) ), 203 buildMoveSingle( stmt ), 204 buildMoveOptional( else_ ), 205 {}, 206 ast::DoWhile 207 ); 170 return new WhileDoStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), aststmt.front(), astelse.front(), {}, true ); 208 171 } // build_do_while 209 172 210 ast::Stmt * build_for( const CodeLocation & location,ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {211 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty173 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) { 174 list< Statement * > astinit; // maybe empty 212 175 buildMoveList( forctl->init, astinit ); 213 176 214 ast::Expr* astcond = nullptr; // maybe empty215 astcond = notZeroExpr( maybeMoveBuild ( forctl->condition) );216 217 ast::Expr* astincr = nullptr; // maybe empty218 astincr = maybeMoveBuild ( forctl->change);177 Expression * astcond = nullptr; // maybe empty 178 astcond = notZeroExpr( maybeMoveBuild< Expression >(forctl->condition) ); 179 180 Expression * astincr = nullptr; // maybe empty 181 astincr = maybeMoveBuild< Expression >(forctl->change); 219 182 delete forctl; 220 183 221 return new ast::ForStmt( location, 222 std::move( astinit ), 223 astcond, 224 astincr, 225 buildMoveSingle( stmt ), 226 buildMoveOptional( else_ ) 227 ); 184 list< Statement * > aststmt; // loop body, compound created if empty 185 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 186 assert( aststmt.size() == 1 ); 187 188 list< Statement * > astelse; // else clause, maybe empty 189 buildMoveList< Statement, StatementNode >( else_, astelse ); 190 191 return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() ); 228 192 } // build_for 229 193 230 ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) { 231 return new ast::BranchStmt( location, 232 kind, 233 ast::Label( location ) 234 ); 194 Statement * build_branch( BranchStmt::Type kind ) { 195 Statement * ret = new BranchStmt( "", kind ); 196 return ret; 235 197 } // build_branch 236 198 237 ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) { 238 ast::Stmt * ret = new ast::BranchStmt( location, 239 kind, 240 ast::Label( location, *identifier ) 241 ); 199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) { 200 Statement * ret = new BranchStmt( * identifier, kind ); 242 201 delete identifier; // allocated by lexer 243 202 return ret; 244 203 } // build_branch 245 204 246 ast::Stmt * build_computedgoto( ExpressionNode * ctl ) { 247 ast::Expr * expr = maybeMoveBuild( ctl ); 248 return new ast::BranchStmt( expr->location, expr ); 205 Statement * build_computedgoto( ExpressionNode * ctl ) { 206 return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto ); 249 207 } // build_computedgoto 250 208 251 ast::Stmt * build_return( const CodeLocation & location,ExpressionNode * ctl ) {252 std::vector<ast::ptr<ast::Expr>> exps;209 Statement * build_return( ExpressionNode * ctl ) { 210 list< Expression * > exps; 253 211 buildMoveList( ctl, exps ); 254 return new ast::ReturnStmt( location, 255 exps.size() > 0 ? exps.back().release() : nullptr 256 ); 212 return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr ); 257 213 } // build_return 258 214 259 static ast::Stmt * build_throw_stmt( 260 const CodeLocation & location, 261 ExpressionNode * ctl, 262 ast::ExceptionKind kind ) { 263 std::vector<ast::ptr<ast::Expr>> exps; 215 Statement * build_throw( ExpressionNode * ctl ) { 216 list< Expression * > exps; 264 217 buildMoveList( ctl, exps ); 265 218 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 266 return new ast::ThrowStmt( location, 267 kind, 268 !exps.empty() ? exps.back().release() : nullptr, 269 (ast::Expr *)nullptr 270 ); 271 } 272 273 ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) { 274 return build_throw_stmt( loc, ctl, ast::Terminate ); 219 return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 275 220 } // build_throw 276 221 277 ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) { 278 return build_throw_stmt( loc, ctl, ast::Resume ); 222 Statement * build_resume( ExpressionNode * ctl ) { 223 list< Expression * > exps; 224 buildMoveList( ctl, exps ); 225 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 226 return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 279 227 } // build_resume 280 228 281 ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) { 282 230 (void)ctl; 283 231 (void)target; … … 285 233 } // build_resume_at 286 234 287 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) { 288 std::vector<ast::ptr<ast::CatchClause>> aststmt; 289 buildMoveList( catch_, aststmt ); 290 ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) ); 291 ast::FinallyClause * finallyBlock = nullptr; 292 if ( finally_ ) { 293 finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() ); 235 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) { 236 list< CatchStmt * > aststmt; 237 buildMoveList< CatchStmt, StatementNode >( catch_, aststmt ); 238 CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_)); 239 FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_) ); 240 return new TryStmt( tryBlock, aststmt, finallyBlock ); 241 } // build_try 242 243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 244 list< Statement * > aststmt; 245 buildMoveList< Statement, StatementNode >( body, aststmt ); 246 assert( aststmt.size() == 1 ); 247 return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), aststmt.front() ); 248 } // build_catch 249 250 Statement * build_finally( StatementNode * stmt ) { 251 list< Statement * > aststmt; 252 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 253 assert( aststmt.size() == 1 ); 254 return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) ); 255 } // build_finally 256 257 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) { 258 auto node = new SuspendStmt(); 259 260 node->type = type; 261 262 list< Statement * > stmts; 263 buildMoveList< Statement, StatementNode >( then, stmts ); 264 if(!stmts.empty()) { 265 assert( stmts.size() == 1 ); 266 node->then = dynamic_cast< CompoundStmt * >( stmts.front() ); 294 267 } 295 return new ast::TryStmt( location, 296 tryBlock, 297 std::move( aststmt ), 298 finallyBlock 299 ); 300 } // build_try 301 302 ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 303 return new ast::CatchClause( location, 304 kind, 305 maybeMoveBuild( decl ), 306 maybeMoveBuild( cond ), 307 buildMoveSingle( body ) 308 ); 309 } // build_catch 310 311 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 312 return new ast::FinallyClause( location, 313 strict_dynamic_cast<const ast::CompoundStmt *>( 314 buildMoveSingle( stmt ) 315 ) 316 ); 317 } // build_finally 318 319 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) { 320 return new ast::SuspendStmt( location, 321 strict_dynamic_cast<const ast::CompoundStmt *, nullptr>( 322 buildMoveOptional( then ) 323 ), 324 kind 325 ); 326 } // build_suspend 327 328 ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 329 auto clause = new ast::WaitForClause( location ); 330 clause->target = maybeBuild( targetExpr ); 331 clause->stmt = maybeMoveBuild( stmt ); 332 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 268 269 return node; 270 } 271 272 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) { 273 auto node = new WaitForStmt(); 274 275 WaitForStmt::Target target; 276 target.function = maybeBuild<Expression>( targetExpr ); 333 277 334 278 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 335 279 targetExpr->set_next( nullptr ); 336 buildMoveList ( next, clause->target_args );280 buildMoveList< Expression >( next, target.arguments ); 337 281 338 282 delete targetExpr; 339 283 340 existing->clauses.insert( existing->clauses.begin(), clause ); 341 342 return existing; 284 node->clauses.push_back( WaitForStmt::Clause{ 285 target, 286 maybeMoveBuild<Statement >( stmt ), 287 notZeroExpr( maybeMoveBuild<Expression>( when ) ) 288 }); 289 290 return node; 343 291 } // build_waitfor 344 292 345 ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 346 existing->else_stmt = maybeMoveBuild( stmt ); 347 existing->else_cond = notZeroExpr( maybeMoveBuild( when ) ); 348 349 (void)location; 350 return existing; 351 } // build_waitfor_else 352 353 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 354 existing->timeout_time = maybeMoveBuild( timeout ); 355 existing->timeout_stmt = maybeMoveBuild( stmt ); 356 existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) ); 357 358 (void)location; 359 return existing; 293 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) { 294 WaitForStmt::Target target; 295 target.function = maybeBuild<Expression>( targetExpr ); 296 297 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 298 targetExpr->set_next( nullptr ); 299 buildMoveList< Expression >( next, target.arguments ); 300 301 delete targetExpr; 302 303 node->clauses.insert( node->clauses.begin(), WaitForStmt::Clause{ 304 std::move( target ), 305 maybeMoveBuild<Statement >( stmt ), 306 notZeroExpr( maybeMoveBuild<Expression>( when ) ) 307 }); 308 309 return node; 310 } // build_waitfor 311 312 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) { 313 auto node = new WaitForStmt(); 314 315 if( timeout ) { 316 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 317 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 318 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 319 } else { 320 node->orelse.statement = maybeMoveBuild<Statement >( stmt ); 321 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 322 } // if 323 324 return node; 360 325 } // build_waitfor_timeout 361 326 362 ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 363 ast::WhenClause * clause = new ast::WhenClause( loc ); 364 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 365 clause->stmt = maybeMoveBuild( stmt ); 366 clause->target = maybeMoveBuild( targetExpr ); 367 return new ast::WaitUntilStmt::ClauseNode( clause ); 368 } 369 ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) { 370 ast::WhenClause * clause = new ast::WhenClause( loc ); 371 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 372 clause->stmt = maybeMoveBuild( stmt ); 373 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause ); 374 } 375 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 376 ast::WhenClause * clause = new ast::WhenClause( loc ); 377 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 378 clause->stmt = maybeMoveBuild( stmt ); 379 clause->target = maybeMoveBuild( timeout ); 380 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause ); 381 } 382 383 ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) { 384 ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc ); 385 retStmt->predicateTree = root; 386 387 // iterative tree traversal 388 std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal 389 ast::WaitUntilStmt::ClauseNode * currNode = nullptr; 390 ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr; 391 ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout 392 nodeStack.push_back(root); 393 394 do { 395 currNode = nodeStack.back(); 396 nodeStack.pop_back(); // remove node since it will be processed 397 398 switch (currNode->op) { 399 case ast::WaitUntilStmt::ClauseNode::LEAF: 400 retStmt->clauses.push_back(currNode->leaf); 401 break; 402 case ast::WaitUntilStmt::ClauseNode::ELSE: 403 retStmt->else_stmt = currNode->leaf->stmt 404 ? ast::deepCopy( currNode->leaf->stmt ) 405 : nullptr; 406 407 retStmt->else_cond = currNode->leaf->when_cond 408 ? ast::deepCopy( currNode->leaf->when_cond ) 409 : nullptr; 410 411 delete currNode->leaf; 412 break; 413 case ast::WaitUntilStmt::ClauseNode::TIMEOUT: 414 retStmt->timeout_time = currNode->leaf->target 415 ? ast::deepCopy( currNode->leaf->target ) 416 : nullptr; 417 retStmt->timeout_stmt = currNode->leaf->stmt 418 ? ast::deepCopy( currNode->leaf->stmt ) 419 : nullptr; 420 retStmt->timeout_cond = currNode->leaf->when_cond 421 ? ast::deepCopy( currNode->leaf->when_cond ) 422 : nullptr; 423 424 delete currNode->leaf; 425 break; 426 default: 427 nodeStack.push_back( currNode->right ); // process right after left 428 nodeStack.push_back( currNode->left ); 429 430 // Cut else/timeout out of the tree 431 if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) { 432 if ( lastInternalNode ) 433 lastInternalNode->right = currNode->left; 434 else // if not set then root is LEFT_OR 435 retStmt->predicateTree = currNode->left; 436 437 currNode->left = nullptr; 438 cleanup = currNode; 439 } 440 441 lastInternalNode = currNode; 442 break; 443 } 444 } while ( !nodeStack.empty() ); 445 446 if ( cleanup ) delete cleanup; 447 448 return retStmt; 449 } 450 451 ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 452 std::vector<ast::ptr<ast::Expr>> e; 327 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_, ExpressionNode * else_when ) { 328 auto node = new WaitForStmt(); 329 330 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 331 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 332 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 333 334 node->orelse.statement = maybeMoveBuild<Statement >( else_ ); 335 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( else_when ) ); 336 337 return node; 338 } // build_waitfor_timeout 339 340 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 341 list< Expression * > e; 453 342 buildMoveList( exprs, e ); 454 ast::Stmt * s = maybeMoveBuild( stmt );455 return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) );343 Statement * s = maybeMoveBuild<Statement>( stmt ); 344 return new DeclStmt( new WithStmt( e, s ) ); 456 345 } // build_with 457 346 458 ast::Stmt * build_compound( const CodeLocation & location,StatementNode * first ) {459 auto cs = new ast::CompoundStmt( location);460 buildMoveList( first, cs-> kids);347 Statement * build_compound( StatementNode * first ) { 348 CompoundStmt * cs = new CompoundStmt(); 349 buildMoveList( first, cs->get_kids() ); 461 350 return cs; 462 351 } // build_compound … … 466 355 // statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a 467 356 // conical form for code generation. 468 StatementNode * maybe_build_compound( const CodeLocation & location,StatementNode * first ) {357 StatementNode * maybe_build_compound( StatementNode * first ) { 469 358 // Optimization: if the control-structure statement is a compound statement, do not wrap it. 470 359 // e.g., if (...) {...} do not wrap the existing compound statement. 471 if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 472 return new StatementNode( build_compound( location, first ) ); 360 if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 361 CompoundStmt * cs = new CompoundStmt(); 362 buildMoveList( first, cs->get_kids() ); 363 return new StatementNode( cs ); 473 364 } // if 474 365 return first; … … 476 367 477 368 // Question 478 ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode* instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {479 std::vector<ast::ptr<ast::Expr>> out, in;480 std::vector<ast::ptr<ast::ConstantExpr>> clob;369 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { 370 list< Expression * > out, in; 371 list< ConstantExpr * > clob; 481 372 482 373 buildMoveList( output, out ); 483 374 buildMoveList( input, in ); 484 375 buildMoveList( clobber, clob ); 485 return new ast::AsmStmt( location, 486 is_volatile, 487 maybeMoveBuild( instruction ), 488 std::move( out ), 489 std::move( in ), 490 std::move( clob ), 491 gotolabels ? gotolabels->labels : std::vector<ast::Label>() 492 ); 376 return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 493 377 } // build_asm 494 378 495 ast::Stmt * build_directive( const CodeLocation & location, string * directive ) { 496 auto stmt = new ast::DirectiveStmt( location, *directive ); 497 delete directive; 498 return stmt; 379 Statement * build_directive( string * directive ) { 380 return new DirectiveStmt( *directive ); 499 381 } // build_directive 500 382 501 ast::Stmt * build_mutex( const CodeLocation & location,ExpressionNode * exprs, StatementNode * stmt ) {502 std::vector<ast::ptr<ast::Expr>> expList;383 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ) { 384 list< Expression * > expList; 503 385 buildMoveList( exprs, expList ); 504 ast::Stmt * body = maybeMoveBuild( stmt );505 return new ast::MutexStmt( location, body, std::move( expList ));386 Statement * body = maybeMoveBuild<Statement>( stmt ); 387 return new MutexStmt( body, expList ); 506 388 } // build_mutex 507 389 -
src/Parser/TypeData.cc
r24d6572 r34b4268 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:12:51 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Apr 4 13:39:00 202313 // Update Count : 6 8011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 10 22:36:52 2022 13 // Update Count : 677 14 14 // 15 16 #include "TypeData.h"17 15 18 16 #include <cassert> // for assert 19 17 #include <ostream> // for operator<<, ostream, basic_ostream 20 18 21 #include "AST/Decl.hpp" // for AggregateDecl, ObjectDecl, TypeDe...22 #include "AST/Init.hpp" // for SingleInit, ListInit23 #include "AST/Print.hpp" // for print24 19 #include "Common/SemanticError.h" // for SemanticError 25 #include "Common/utility.h" // for splice, spliceBegin 26 #include "Parser/ExpressionNode.h" // for ExpressionNode 27 #include "Parser/StatementNode.h" // for StatementNode 20 #include "Common/utility.h" // for maybeClone, maybeBuild, maybeMoveB... 21 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 22 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, FunctionDecl 23 #include "SynTree/Expression.h" // for Expression, ConstantExpr (ptr only) 24 #include "SynTree/Initializer.h" // for SingleInit, Initializer (ptr only) 25 #include "SynTree/Statement.h" // for CompoundStmt, Statement 26 #include "SynTree/Type.h" // for BasicType, Type, Type::ForallList 27 #include "TypeData.h" 28 28 29 29 class Attribute; … … 33 33 TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ { 34 34 switch ( kind ) { 35 case Unknown: 36 case Pointer: 37 case Reference: 38 case EnumConstant: 39 case GlobalScope: 40 case Basic: 41 // No unique data to initialize. 42 break; 43 case Array: 35 case Unknown: 36 case Pointer: 37 case Reference: 38 case EnumConstant: 39 case GlobalScope: 40 // nothing else to initialize 41 break; 42 case Basic: 43 // basic = new Basic_t; 44 break; 45 case Array: 46 // array = new Array_t; 44 47 array.dimension = nullptr; 45 48 array.isVarLen = false; 46 49 array.isStatic = false; 47 50 break; 48 case Function: 51 case Function: 52 // function = new Function_t; 49 53 function.params = nullptr; 50 54 function.idList = nullptr; … … 53 57 function.withExprs = nullptr; 54 58 break; 55 case Enum: 59 // Enum is an Aggregate, so both structures are initialized together. 60 case Enum: 61 // enumeration = new Enumeration_t; 56 62 enumeration.name = nullptr; 57 63 enumeration.constants = nullptr; … … 59 65 enumeration.anon = false; 60 66 break; 61 case Aggregate: 62 aggregate.kind = ast::AggregateDecl::NoAggregate; 67 case Aggregate: 68 // aggregate = new Aggregate_t; 69 aggregate.kind = AggregateDecl::NoAggregate; 63 70 aggregate.name = nullptr; 64 71 aggregate.params = nullptr; … … 70 77 aggregate.anon = false; 71 78 break; 72 case AggregateInst: 79 case AggregateInst: 80 // aggInst = new AggInst_t; 73 81 aggInst.aggregate = nullptr; 74 82 aggInst.params = nullptr; 75 83 aggInst.hoistType = false; 76 84 break; 77 case Symbolic: 78 case SymbolicInst: 85 case Symbolic: 86 case SymbolicInst: 87 // symbolic = new Symbolic_t; 79 88 symbolic.name = nullptr; 80 89 symbolic.params = nullptr; … … 82 91 symbolic.assertions = nullptr; 83 92 break; 84 case Tuple: 93 case Tuple: 94 // tuple = new Tuple_t; 85 95 tuple = nullptr; 86 96 break; 87 case Typeof: 88 case Basetypeof: 97 case Typeof: 98 case Basetypeof: 99 // typeexpr = new Typeof_t; 89 100 typeexpr = nullptr; 90 101 break; 91 case Vtable:92 case Builtin:93 // No unique data to initialize.94 break;95 case Qualified:102 case Vtable: 103 break; 104 case Builtin: 105 // builtin = new Builtin_t; 106 case Qualified: 96 107 qualified.parent = nullptr; 97 108 qualified.child = nullptr; … … 106 117 107 118 switch ( kind ) { 108 case Unknown: 109 case Pointer: 110 case Reference: 111 case EnumConstant: 112 case GlobalScope: 113 case Basic: 114 // No unique data to deconstruct. 115 break; 116 case Array: 119 case Unknown: 120 case Pointer: 121 case Reference: 122 case EnumConstant: 123 case GlobalScope: 124 // nothing to destroy 125 break; 126 case Basic: 127 // delete basic; 128 break; 129 case Array: 117 130 delete array.dimension; 118 break; 119 case Function: 131 // delete array; 132 break; 133 case Function: 120 134 delete function.params; 121 135 delete function.idList; … … 123 137 delete function.body; 124 138 delete function.withExprs; 125 break; 126 case Aggregate: 139 // delete function; 140 break; 141 case Aggregate: 127 142 delete aggregate.name; 128 143 delete aggregate.params; 129 144 delete aggregate.actuals; 130 145 delete aggregate.fields; 131 break; 132 case AggregateInst: 146 // delete aggregate; 147 break; 148 case AggregateInst: 133 149 delete aggInst.aggregate; 134 150 delete aggInst.params; 135 break; 136 case Enum: 151 // delete aggInst; 152 break; 153 case Enum: 137 154 delete enumeration.name; 138 155 delete enumeration.constants; 139 break; 140 case Symbolic: 141 case SymbolicInst: 156 // delete enumeration; 157 break; 158 case Symbolic: 159 case SymbolicInst: 142 160 delete symbolic.name; 143 161 delete symbolic.params; 144 162 delete symbolic.actuals; 145 163 delete symbolic.assertions; 146 break; 147 case Tuple: 164 // delete symbolic; 165 break; 166 case Tuple: 167 // delete tuple->members; 148 168 delete tuple; 149 169 break; 150 case Typeof: 151 case Basetypeof: 170 case Typeof: 171 case Basetypeof: 172 // delete typeexpr->expr; 152 173 delete typeexpr; 153 174 break; 154 case Vtable: 155 case Builtin: 156 // No unique data to deconstruct. 157 break; 158 case Qualified: 175 case Vtable: 176 break; 177 case Builtin: 178 // delete builtin; 179 break; 180 case Qualified: 159 181 delete qualified.parent; 160 182 delete qualified.child; 161 break;162 183 } // switch 163 184 } // TypeData::~TypeData … … 171 192 172 193 switch ( kind ) { 173 case Unknown:174 case EnumConstant:175 case Pointer:176 case Reference:177 case GlobalScope:194 case Unknown: 195 case EnumConstant: 196 case Pointer: 197 case Reference: 198 case GlobalScope: 178 199 // nothing else to copy 179 200 break; 180 case Basic:201 case Basic: 181 202 newtype->basictype = basictype; 182 203 newtype->complextype = complextype; … … 184 205 newtype->length = length; 185 206 break; 186 case Array:207 case Array: 187 208 newtype->array.dimension = maybeClone( array.dimension ); 188 209 newtype->array.isVarLen = array.isVarLen; 189 210 newtype->array.isStatic = array.isStatic; 190 211 break; 191 case Function:212 case Function: 192 213 newtype->function.params = maybeClone( function.params ); 193 214 newtype->function.idList = maybeClone( function.idList ); … … 196 217 newtype->function.withExprs = maybeClone( function.withExprs ); 197 218 break; 198 case Aggregate:219 case Aggregate: 199 220 newtype->aggregate.kind = aggregate.kind; 200 221 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr; … … 207 228 newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr; 208 229 break; 209 case AggregateInst:230 case AggregateInst: 210 231 newtype->aggInst.aggregate = maybeClone( aggInst.aggregate ); 211 232 newtype->aggInst.params = maybeClone( aggInst.params ); 212 233 newtype->aggInst.hoistType = aggInst.hoistType; 213 234 break; 214 case Enum:235 case Enum: 215 236 newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr; 216 237 newtype->enumeration.constants = maybeClone( enumeration.constants ); … … 218 239 newtype->enumeration.anon = enumeration.anon; 219 240 break; 220 case Symbolic:221 case SymbolicInst:241 case Symbolic: 242 case SymbolicInst: 222 243 newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr; 223 244 newtype->symbolic.params = maybeClone( symbolic.params ); … … 226 247 newtype->symbolic.isTypedef = symbolic.isTypedef; 227 248 break; 228 case Tuple:249 case Tuple: 229 250 newtype->tuple = maybeClone( tuple ); 230 251 break; 231 case Typeof:232 case Basetypeof:252 case Typeof: 253 case Basetypeof: 233 254 newtype->typeexpr = maybeClone( typeexpr ); 234 255 break; 235 case Vtable:236 break; 237 case Builtin:256 case Vtable: 257 break; 258 case Builtin: 238 259 assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One ); 239 260 newtype->builtintype = builtintype; 240 261 break; 241 case Qualified:262 case Qualified: 242 263 newtype->qualified.parent = maybeClone( qualified.parent ); 243 264 newtype->qualified.child = maybeClone( qualified.child ); … … 249 270 250 271 void TypeData::print( ostream &os, int indent ) const { 251 ast::print( os, qualifiers ); 272 for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) { 273 if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' '; 274 } // for 252 275 253 276 if ( forall ) { … … 257 280 258 281 switch ( kind ) { 259 case Basic:282 case Basic: 260 283 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " "; 261 284 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " "; … … 263 286 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 264 287 break; 265 case Pointer:288 case Pointer: 266 289 os << "pointer "; 267 290 if ( base ) { … … 270 293 } // if 271 294 break; 272 case Reference:295 case Reference: 273 296 os << "reference "; 274 297 if ( base ) { … … 277 300 } // if 278 301 break; 279 case Array:302 case Array: 280 303 if ( array.isStatic ) { 281 304 os << "static "; … … 293 316 } // if 294 317 break; 295 case Function:318 case Function: 296 319 os << "function" << endl; 297 320 if ( function.params ) { … … 321 344 } // if 322 345 break; 323 case Aggregate:324 os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;346 case Aggregate: 347 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl; 325 348 if ( aggregate.params ) { 326 349 os << string( indent + 2, ' ' ) << "with type parameters" << endl; … … 339 362 } // if 340 363 break; 341 case AggregateInst:364 case AggregateInst: 342 365 if ( aggInst.aggregate ) { 343 366 os << "instance of " ; … … 351 374 } // if 352 375 break; 353 case Enum:354 os << "enumeration " << *enumeration.name << endl;;376 case Enum: 377 os << "enumeration "; 355 378 if ( enumeration.constants ) { 356 379 os << "with constants" << endl; … … 365 388 } // if 366 389 break; 367 case EnumConstant:390 case EnumConstant: 368 391 os << "enumeration constant "; 369 392 break; 370 case Symbolic:393 case Symbolic: 371 394 if ( symbolic.isTypedef ) { 372 395 os << "typedef definition "; … … 388 411 } // if 389 412 break; 390 case SymbolicInst:413 case SymbolicInst: 391 414 os << *symbolic.name; 392 415 if ( symbolic.actuals ) { … … 396 419 } // if 397 420 break; 398 case Tuple:421 case Tuple: 399 422 os << "tuple "; 400 423 if ( tuple ) { … … 403 426 } // if 404 427 break; 405 case Basetypeof:428 case Basetypeof: 406 429 os << "base-"; 407 430 #if defined(__GNUC__) && __GNUC__ >= 7 … … 409 432 #endif 410 433 // FALL THROUGH 411 case Typeof:434 case Typeof: 412 435 os << "type-of expression "; 413 436 if ( typeexpr ) { … … 415 438 } // if 416 439 break; 417 case Vtable:440 case Vtable: 418 441 os << "vtable"; 419 442 break; 420 case Builtin:443 case Builtin: 421 444 os << DeclarationNode::builtinTypeNames[builtintype]; 422 445 break; 423 case GlobalScope:424 break; 425 case Qualified:446 case GlobalScope: 447 break; 448 case Qualified: 426 449 qualified.parent->print( os ); 427 450 os << "."; 428 451 qualified.child->print( os ); 429 452 break; 430 case Unknown:453 case Unknown: 431 454 os << "entity of unknown type "; 432 455 break; 433 default:456 default: 434 457 os << "internal error: TypeData::print " << kind << endl; 435 458 assert( false ); … … 439 462 const std::string * TypeData::leafName() const { 440 463 switch ( kind ) { 441 case Unknown:442 case Pointer:443 case Reference:444 case EnumConstant:445 case GlobalScope:446 case Array:447 case Basic:448 case Function:449 case AggregateInst:450 case Tuple:451 case Typeof:452 case Basetypeof:453 case Builtin:454 case Vtable:464 case Unknown: 465 case Pointer: 466 case Reference: 467 case EnumConstant: 468 case GlobalScope: 469 case Array: 470 case Basic: 471 case Function: 472 case AggregateInst: 473 case Tuple: 474 case Typeof: 475 case Basetypeof: 476 case Builtin: 477 case Vtable: 455 478 assertf(false, "Tried to get leaf name from kind without a name: %d", kind); 456 479 break; 457 case Aggregate:480 case Aggregate: 458 481 return aggregate.name; 459 case Enum:482 case Enum: 460 483 return enumeration.name; 461 case Symbolic:462 case SymbolicInst:484 case Symbolic: 485 case SymbolicInst: 463 486 return symbolic.name; 464 case Qualified:487 case Qualified: 465 488 return qualified.child->leafName(); 466 489 } // switch … … 469 492 470 493 471 void buildForall( 472 const DeclarationNode * firstNode, 473 std::vector<ast::ptr<ast::TypeInstType>> &outputList ) { 474 { 475 std::vector<ast::ptr<ast::Type>> tmpList; 476 buildTypeList( firstNode, tmpList ); 477 for ( auto tmp : tmpList ) { 478 outputList.emplace_back( 479 strict_dynamic_cast<const ast::TypeInstType *>( 480 tmp.release() ) ); 481 } 482 } 494 template< typename ForallList > 495 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { 496 buildList( firstNode, outputList ); 483 497 auto n = firstNode; 484 for ( auto i = outputList.begin() ; 485 i != outputList.end() ; 486 ++i, n = (DeclarationNode*)n->get_next() ) { 487 // Only the object type class adds additional assertions. 488 if ( n->variable.tyClass != ast::TypeDecl::Otype ) { 489 continue; 490 } 491 492 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>(); 493 std::vector<ast::ptr<ast::DeclWithType>> newAssertions; 494 auto mutTypeDecl = ast::mutate( td ); 495 const CodeLocation & location = mutTypeDecl->location; 496 *i = mutTypeDecl; 497 498 // add assertion parameters to `type' tyvars in reverse order 499 // add assignment operator: T * ?=?(T *, T) 500 newAssertions.push_back( new ast::FunctionDecl( 501 location, 502 "?=?", 503 {}, // forall 504 {}, // assertions 505 { 506 new ast::ObjectDecl( 507 location, 508 "", 509 new ast::ReferenceType( i->get() ), 510 (ast::Init *)nullptr, 511 ast::Storage::Classes(), 512 ast::Linkage::Cforall, 513 (ast::Expr *)nullptr 514 ), 515 new ast::ObjectDecl( 516 location, 517 "", 518 i->get(), 519 (ast::Init *)nullptr, 520 ast::Storage::Classes(), 521 ast::Linkage::Cforall, 522 (ast::Expr *)nullptr 523 ), 524 }, // params 525 { 526 new ast::ObjectDecl( 527 location, 528 "", 529 i->get(), 530 (ast::Init *)nullptr, 531 ast::Storage::Classes(), 532 ast::Linkage::Cforall, 533 (ast::Expr *)nullptr 534 ), 535 }, // returns 536 (ast::CompoundStmt *)nullptr, 537 ast::Storage::Classes(), 538 ast::Linkage::Cforall 539 ) ); 540 541 // add default ctor: void ?{}(T *) 542 newAssertions.push_back( new ast::FunctionDecl( 543 location, 544 "?{}", 545 {}, // forall 546 {}, // assertions 547 { 548 new ast::ObjectDecl( 549 location, 550 "", 551 new ast::ReferenceType( i->get() ), 552 (ast::Init *)nullptr, 553 ast::Storage::Classes(), 554 ast::Linkage::Cforall, 555 (ast::Expr *)nullptr 556 ), 557 }, // params 558 {}, // returns 559 (ast::CompoundStmt *)nullptr, 560 ast::Storage::Classes(), 561 ast::Linkage::Cforall 562 ) ); 563 564 // add copy ctor: void ?{}(T *, T) 565 newAssertions.push_back( new ast::FunctionDecl( 566 location, 567 "?{}", 568 {}, // forall 569 {}, // assertions 570 { 571 new ast::ObjectDecl( 572 location, 573 "", 574 new ast::ReferenceType( i->get() ), 575 (ast::Init *)nullptr, 576 ast::Storage::Classes(), 577 ast::Linkage::Cforall, 578 (ast::Expr *)nullptr 579 ), 580 new ast::ObjectDecl( 581 location, 582 "", 583 i->get(), 584 (ast::Init *)nullptr, 585 ast::Storage::Classes(), 586 ast::Linkage::Cforall, 587 (ast::Expr *)nullptr 588 ), 589 }, // params 590 {}, // returns 591 (ast::CompoundStmt *)nullptr, 592 ast::Storage::Classes(), 593 ast::Linkage::Cforall 594 ) ); 595 596 // add dtor: void ^?{}(T *) 597 newAssertions.push_back( new ast::FunctionDecl( 598 location, 599 "^?{}", 600 {}, // forall 601 {}, // assertions 602 { 603 new ast::ObjectDecl( 604 location, 605 "", 606 new ast::ReferenceType( i->get() ), 607 (ast::Init *)nullptr, 608 ast::Storage::Classes(), 609 ast::Linkage::Cforall, 610 (ast::Expr *)nullptr 611 ), 612 }, // params 613 {}, // returns 614 (ast::CompoundStmt *)nullptr, 615 ast::Storage::Classes(), 616 ast::Linkage::Cforall 617 ) ); 618 619 spliceBegin( mutTypeDecl->assertions, newAssertions ); 620 } // for 621 } 622 623 624 void buildForall( 625 const DeclarationNode * firstNode, 626 std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) { 627 buildList( firstNode, outputForall ); 628 auto n = firstNode; 629 for ( auto i = outputForall.begin() ; 630 i != outputForall.end() ; 631 ++i, n = (DeclarationNode*)n->get_next() ) { 632 // Only the object type class adds additional assertions. 633 if ( n->variable.tyClass != ast::TypeDecl::Otype ) { 634 continue; 635 } 636 637 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>(); 638 std::vector<ast::ptr<ast::DeclWithType>> newAssertions; 639 auto mutTypeDecl = ast::mutate( td ); 640 const CodeLocation & location = mutTypeDecl->location; 641 *i = mutTypeDecl; 642 643 // add assertion parameters to `type' tyvars in reverse order 644 // add assignment operator: T * ?=?(T *, T) 645 newAssertions.push_back( new ast::FunctionDecl( 646 location, 647 "?=?", 648 {}, // forall 649 {}, // assertions 650 { 651 new ast::ObjectDecl( 652 location, 653 "", 654 new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ), 655 (ast::Init *)nullptr, 656 ast::Storage::Classes(), 657 ast::Linkage::Cforall, 658 (ast::Expr *)nullptr 659 ), 660 new ast::ObjectDecl( 661 location, 662 "", 663 new ast::TypeInstType( td->name, *i ), 664 (ast::Init *)nullptr, 665 ast::Storage::Classes(), 666 ast::Linkage::Cforall, 667 (ast::Expr *)nullptr 668 ), 669 }, // params 670 { 671 new ast::ObjectDecl( 672 location, 673 "", 674 new ast::TypeInstType( td->name, *i ), 675 (ast::Init *)nullptr, 676 ast::Storage::Classes(), 677 ast::Linkage::Cforall, 678 (ast::Expr *)nullptr 679 ), 680 }, // returns 681 (ast::CompoundStmt *)nullptr, 682 ast::Storage::Classes(), 683 ast::Linkage::Cforall 684 ) ); 685 686 // add default ctor: void ?{}(T *) 687 newAssertions.push_back( new ast::FunctionDecl( 688 location, 689 "?{}", 690 {}, // forall 691 {}, // assertions 692 { 693 new ast::ObjectDecl( 694 location, 695 "", 696 new ast::ReferenceType( 697 new ast::TypeInstType( td->name, i->get() ) ), 698 (ast::Init *)nullptr, 699 ast::Storage::Classes(), 700 ast::Linkage::Cforall, 701 (ast::Expr *)nullptr 702 ), 703 }, // params 704 {}, // returns 705 (ast::CompoundStmt *)nullptr, 706 ast::Storage::Classes(), 707 ast::Linkage::Cforall 708 ) ); 709 710 // add copy ctor: void ?{}(T *, T) 711 newAssertions.push_back( new ast::FunctionDecl( 712 location, 713 "?{}", 714 {}, // forall 715 {}, // assertions 716 { 717 new ast::ObjectDecl( 718 location, 719 "", 720 new ast::ReferenceType( 721 new ast::TypeInstType( td->name, *i ) ), 722 (ast::Init *)nullptr, 723 ast::Storage::Classes(), 724 ast::Linkage::Cforall, 725 (ast::Expr *)nullptr 726 ), 727 new ast::ObjectDecl( 728 location, 729 "", 730 new ast::TypeInstType( td->name, *i ), 731 (ast::Init *)nullptr, 732 ast::Storage::Classes(), 733 ast::Linkage::Cforall, 734 (ast::Expr *)nullptr 735 ), 736 }, // params 737 {}, // returns 738 (ast::CompoundStmt *)nullptr, 739 ast::Storage::Classes(), 740 ast::Linkage::Cforall 741 ) ); 742 743 // add dtor: void ^?{}(T *) 744 newAssertions.push_back( new ast::FunctionDecl( 745 location, 746 "^?{}", 747 {}, // forall 748 {}, // assertions 749 { 750 new ast::ObjectDecl( 751 location, 752 "", 753 new ast::ReferenceType( 754 new ast::TypeInstType( i->get() ) 755 ), 756 (ast::Init *)nullptr, 757 ast::Storage::Classes(), 758 ast::Linkage::Cforall, 759 (ast::Expr *)nullptr 760 ), 761 }, // params 762 {}, // returns 763 (ast::CompoundStmt *)nullptr, 764 ast::Storage::Classes(), 765 ast::Linkage::Cforall 766 ) ); 767 768 spliceBegin( mutTypeDecl->assertions, newAssertions ); 498 for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) { 499 TypeDecl * td = static_cast<TypeDecl *>(*i); 500 if ( n->variable.tyClass == TypeDecl::Otype ) { 501 // add assertion parameters to `type' tyvars in reverse order 502 // add dtor: void ^?{}(T *) 503 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false ); 504 dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 505 td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) ); 506 507 // add copy ctor: void ?{}(T *, T) 508 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false ); 509 copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 510 copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 511 td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) ); 512 513 // add default ctor: void ?{}(T *) 514 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false ); 515 ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 516 td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) ); 517 518 // add assignment operator: T * ?=?(T *, T) 519 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false ); 520 assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 521 assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 522 assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 523 td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) ); 524 } // if 769 525 } // for 770 526 } // buildForall 771 527 772 528 773 ast::Type * typebuild( const TypeData * td ) {529 Type * typebuild( const TypeData * td ) { 774 530 assert( td ); 775 531 switch ( td->kind ) { 776 case TypeData::Unknown:532 case TypeData::Unknown: 777 533 // fill in implicit int 778 return new ast::BasicType( 779 ast::BasicType::SignedInt, 780 buildQualifiers( td ) 781 ); 782 case TypeData::Basic: 534 return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); 535 case TypeData::Basic: 783 536 return buildBasicType( td ); 784 case TypeData::Pointer:537 case TypeData::Pointer: 785 538 return buildPointer( td ); 786 case TypeData::Array:539 case TypeData::Array: 787 540 return buildArray( td ); 788 case TypeData::Reference:541 case TypeData::Reference: 789 542 return buildReference( td ); 790 case TypeData::Function:791 return buildFunction Type( td );792 case TypeData::AggregateInst:543 case TypeData::Function: 544 return buildFunction( td ); 545 case TypeData::AggregateInst: 793 546 return buildAggInst( td ); 794 case TypeData::EnumConstant:795 return new ast::EnumInstType( "", buildQualifiers( td ));796 case TypeData::SymbolicInst:547 case TypeData::EnumConstant: 548 return new EnumInstType( buildQualifiers( td ), "" ); 549 case TypeData::SymbolicInst: 797 550 return buildSymbolicInst( td ); 798 case TypeData::Tuple:551 case TypeData::Tuple: 799 552 return buildTuple( td ); 800 case TypeData::Typeof:801 case TypeData::Basetypeof:553 case TypeData::Typeof: 554 case TypeData::Basetypeof: 802 555 return buildTypeof( td ); 803 case TypeData::Vtable:556 case TypeData::Vtable: 804 557 return buildVtable( td ); 805 case TypeData::Builtin:558 case TypeData::Builtin: 806 559 switch ( td->builtintype ) { 807 case DeclarationNode::Zero:808 return new ast::ZeroType();809 case DeclarationNode::One:810 return new ast::OneType();811 default:812 return new ast::VarArgsType( buildQualifiers( td ) );560 case DeclarationNode::Zero: 561 return new ZeroType( noQualifiers ); 562 case DeclarationNode::One: 563 return new OneType( noQualifiers ); 564 default: 565 return new VarArgsType( buildQualifiers( td ) ); 813 566 } // switch 814 case TypeData::GlobalScope: 815 return new ast::GlobalScopeType(); 816 case TypeData::Qualified: 817 return new ast::QualifiedType( 818 typebuild( td->qualified.parent ), 819 typebuild( td->qualified.child ), 820 buildQualifiers( td ) 821 ); 822 case TypeData::Symbolic: 823 case TypeData::Enum: 824 case TypeData::Aggregate: 567 case TypeData::GlobalScope: 568 return new GlobalScopeType(); 569 case TypeData::Qualified: 570 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) ); 571 case TypeData::Symbolic: 572 case TypeData::Enum: 573 case TypeData::Aggregate: 825 574 assert( false ); 826 575 } // switch … … 834 583 835 584 switch ( td->kind ) { 836 case TypeData::Aggregate:585 case TypeData::Aggregate: 837 586 if ( ! toplevel && td->aggregate.body ) { 838 587 ret = td->clone(); 839 588 } // if 840 589 break; 841 case TypeData::Enum:590 case TypeData::Enum: 842 591 if ( ! toplevel && td->enumeration.body ) { 843 592 ret = td->clone(); 844 593 } // if 845 594 break; 846 case TypeData::AggregateInst:595 case TypeData::AggregateInst: 847 596 if ( td->aggInst.aggregate ) { 848 597 ret = typeextractAggregate( td->aggInst.aggregate, false ); 849 598 } // if 850 599 break; 851 default:600 default: 852 601 if ( td->base ) { 853 602 ret = typeextractAggregate( td->base, false ); … … 858 607 859 608 860 ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {609 Type::Qualifiers buildQualifiers( const TypeData * td ) { 861 610 return td->qualifiers; 862 611 } // buildQualifiers … … 867 616 } // genTSError 868 617 869 ast::Type * buildBasicType( const TypeData * td ) {870 ast::BasicType::Kind ret;618 Type * buildBasicType( const TypeData * td ) { 619 BasicType::Kind ret; 871 620 872 621 switch ( td->basictype ) { 873 case DeclarationNode::Void:622 case DeclarationNode::Void: 874 623 if ( td->signedness != DeclarationNode::NoSignedness ) { 875 624 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); … … 878 627 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 879 628 } // if 880 return new ast::VoidType( buildQualifiers( td ) );881 break; 882 883 case DeclarationNode::Bool:629 return new VoidType( buildQualifiers( td ) ); 630 break; 631 632 case DeclarationNode::Bool: 884 633 if ( td->signedness != DeclarationNode::NoSignedness ) { 885 634 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); … … 889 638 } // if 890 639 891 ret = ast::BasicType::Bool;892 break; 893 894 case DeclarationNode::Char:640 ret = BasicType::Bool; 641 break; 642 643 case DeclarationNode::Char: 895 644 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the 896 645 // character types. The implementation shall define char to have the same range, representation, and behavior as 897 646 // either signed char or unsigned char. 898 static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };647 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; 899 648 900 649 if ( td->length != DeclarationNode::NoLength ) { … … 905 654 break; 906 655 907 case DeclarationNode::Int:908 static ast::BasicType::Kind inttype[2][4] = {909 { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },910 { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },656 case DeclarationNode::Int: 657 static BasicType::Kind inttype[2][4] = { 658 { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt }, 659 { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt }, 911 660 }; 912 661 913 Integral: ;662 Integral: ; 914 663 if ( td->signedness == DeclarationNode::NoSignedness ) { 915 664 const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed; … … 918 667 break; 919 668 920 case DeclarationNode::Int128:921 ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;669 case DeclarationNode::Int128: 670 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128; 922 671 if ( td->length != DeclarationNode::NoLength ) { 923 672 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); … … 925 674 break; 926 675 927 case DeclarationNode::Float:928 case DeclarationNode::Double:929 case DeclarationNode::LongDouble: // not set until below930 case DeclarationNode::uuFloat80:931 case DeclarationNode::uuFloat128:932 case DeclarationNode::uFloat16:933 case DeclarationNode::uFloat32:934 case DeclarationNode::uFloat32x:935 case DeclarationNode::uFloat64:936 case DeclarationNode::uFloat64x:937 case DeclarationNode::uFloat128:938 case DeclarationNode::uFloat128x:939 static ast::BasicType::Kind floattype[2][12] = {940 { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, (ast::BasicType::Kind)-1, (ast::BasicType::Kind)-1, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex, },941 { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x, },676 case DeclarationNode::Float: 677 case DeclarationNode::Double: 678 case DeclarationNode::LongDouble: // not set until below 679 case DeclarationNode::uuFloat80: 680 case DeclarationNode::uuFloat128: 681 case DeclarationNode::uFloat16: 682 case DeclarationNode::uFloat32: 683 case DeclarationNode::uFloat32x: 684 case DeclarationNode::uFloat64: 685 case DeclarationNode::uFloat64x: 686 case DeclarationNode::uFloat128: 687 case DeclarationNode::uFloat128x: 688 static BasicType::Kind floattype[2][12] = { 689 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex, }, 690 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x, }, 942 691 }; 943 692 944 FloatingPoint: ;693 FloatingPoint: ; 945 694 if ( td->signedness != DeclarationNode::NoSignedness ) { 946 695 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); … … 966 715 break; 967 716 968 case DeclarationNode::NoBasicType:717 case DeclarationNode::NoBasicType: 969 718 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types 970 719 if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) { … … 975 724 const_cast<TypeData *>(td)->basictype = DeclarationNode::Int; 976 725 goto Integral; 977 default:978 assertf( false, "unknown basic type" );726 default: 727 assertf( false, "unknown basic type" ); 979 728 return nullptr; 980 729 } // switch 981 730 982 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) ); 731 BasicType * bt = new BasicType( buildQualifiers( td ), ret ); 732 buildForall( td->forall, bt->get_forall() ); 983 733 return bt; 984 734 } // buildBasicType 985 735 986 736 987 ast::PointerType * buildPointer( const TypeData * td ) {988 ast::PointerType * pt;737 PointerType * buildPointer( const TypeData * td ) { 738 PointerType * pt; 989 739 if ( td->base ) { 990 pt = new ast::PointerType( 991 typebuild( td->base ), 992 buildQualifiers( td ) 993 ); 740 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) ); 994 741 } else { 995 pt = new ast::PointerType( 996 new ast::BasicType( ast::BasicType::SignedInt ), 997 buildQualifiers( td ) 998 ); 742 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 999 743 } // if 744 buildForall( td->forall, pt->get_forall() ); 1000 745 return pt; 1001 746 } // buildPointer 1002 747 1003 748 1004 ast::ArrayType * buildArray( const TypeData * td ) {1005 ast::ArrayType * at;749 ArrayType * buildArray( const TypeData * td ) { 750 ArrayType * at; 1006 751 if ( td->base ) { 1007 at = new ast::ArrayType( 1008 typebuild( td->base ), 1009 maybeBuild( td->array.dimension ), 1010 td->array.isVarLen ? ast::VariableLen : ast::FixedLen, 1011 td->array.isStatic ? ast::StaticDim : ast::DynamicDim, 1012 buildQualifiers( td ) 1013 ); 752 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ), 753 td->array.isVarLen, td->array.isStatic ); 1014 754 } else { 1015 at = new ast::ArrayType( 1016 new ast::BasicType( ast::BasicType::SignedInt ), 1017 maybeBuild( td->array.dimension ), 1018 td->array.isVarLen ? ast::VariableLen : ast::FixedLen, 1019 td->array.isStatic ? ast::StaticDim : ast::DynamicDim, 1020 buildQualifiers( td ) 1021 ); 755 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 756 maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic ); 1022 757 } // if 758 buildForall( td->forall, at->get_forall() ); 1023 759 return at; 1024 760 } // buildArray 1025 761 1026 762 1027 ast::ReferenceType * buildReference( const TypeData * td ) {1028 ast::ReferenceType * rt;763 ReferenceType * buildReference( const TypeData * td ) { 764 ReferenceType * rt; 1029 765 if ( td->base ) { 1030 rt = new ast::ReferenceType( 1031 typebuild( td->base ), 1032 buildQualifiers( td ) 1033 ); 766 rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) ); 1034 767 } else { 1035 rt = new ast::ReferenceType( 1036 new ast::BasicType( ast::BasicType::SignedInt ), 1037 buildQualifiers( td ) 1038 ); 768 rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 1039 769 } // if 770 buildForall( td->forall, rt->get_forall() ); 1040 771 return rt; 1041 772 } // buildReference 1042 773 1043 774 1044 ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {775 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1045 776 assert( td->kind == TypeData::Aggregate ); 1046 ast::AggregateDecl * at;777 AggregateDecl * at; 1047 778 switch ( td->aggregate.kind ) { 1048 case ast::AggregateDecl::Struct: 1049 case ast::AggregateDecl::Coroutine: 1050 case ast::AggregateDecl::Exception: 1051 case ast::AggregateDecl::Generator: 1052 case ast::AggregateDecl::Monitor: 1053 case ast::AggregateDecl::Thread: 1054 at = new ast::StructDecl( td->location, 1055 *td->aggregate.name, 1056 td->aggregate.kind, 1057 std::move( attributes ), 1058 linkage 1059 ); 1060 buildForall( td->aggregate.params, at->params ); 1061 break; 1062 case ast::AggregateDecl::Union: 1063 at = new ast::UnionDecl( td->location, 1064 *td->aggregate.name, 1065 std::move( attributes ), 1066 linkage 1067 ); 1068 buildForall( td->aggregate.params, at->params ); 1069 break; 1070 case ast::AggregateDecl::Trait: 1071 at = new ast::TraitDecl( td->location, 1072 *td->aggregate.name, 1073 std::move( attributes ), 1074 linkage 1075 ); 1076 buildList( td->aggregate.params, at->params ); 1077 break; 1078 default: 779 case AggregateDecl::Struct: 780 case AggregateDecl::Coroutine: 781 case AggregateDecl::Exception: 782 case AggregateDecl::Generator: 783 case AggregateDecl::Monitor: 784 case AggregateDecl::Thread: 785 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage ); 786 buildForall( td->aggregate.params, at->get_parameters() ); 787 break; 788 case AggregateDecl::Union: 789 at = new UnionDecl( *td->aggregate.name, attributes, linkage ); 790 buildForall( td->aggregate.params, at->get_parameters() ); 791 break; 792 case AggregateDecl::Trait: 793 at = new TraitDecl( *td->aggregate.name, attributes, linkage ); 794 buildList( td->aggregate.params, at->get_parameters() ); 795 break; 796 default: 1079 797 assert( false ); 1080 798 } // switch 1081 799 1082 buildList( td->aggregate.fields, at-> members);800 buildList( td->aggregate.fields, at->get_members() ); 1083 801 at->set_body( td->aggregate.body ); 1084 802 … … 1087 805 1088 806 1089 ast::BaseInstType * buildComAggInst( 1090 const TypeData * type, 1091 std::vector<ast::ptr<ast::Attribute>> && attributes, 1092 ast::Linkage::Spec linkage ) { 807 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1093 808 switch ( type->kind ) { 1094 case TypeData::Enum: 1095 if ( type->enumeration.body ) { 1096 ast::EnumDecl * typedecl = 1097 buildEnum( type, std::move( attributes ), linkage ); 1098 return new ast::EnumInstType( 1099 typedecl, 1100 buildQualifiers( type ) 1101 ); 1102 } else { 1103 return new ast::EnumInstType( 1104 *type->enumeration.name, 1105 buildQualifiers( type ) 1106 ); 1107 } // if 1108 break; 1109 case TypeData::Aggregate: 1110 if ( type->aggregate.body ) { 1111 ast::AggregateDecl * typedecl = 1112 buildAggregate( type, std::move( attributes ), linkage ); 1113 switch ( type->aggregate.kind ) { 1114 case ast::AggregateDecl::Struct: 1115 case ast::AggregateDecl::Coroutine: 1116 case ast::AggregateDecl::Monitor: 1117 case ast::AggregateDecl::Thread: 1118 return new ast::StructInstType( 1119 strict_dynamic_cast<ast::StructDecl *>( typedecl ), 1120 buildQualifiers( type ) 1121 ); 1122 case ast::AggregateDecl::Union: 1123 return new ast::UnionInstType( 1124 strict_dynamic_cast<ast::UnionDecl *>( typedecl ), 1125 buildQualifiers( type ) 1126 ); 1127 case ast::AggregateDecl::Trait: 1128 assert( false ); 1129 break; 1130 default: 1131 assert( false ); 1132 } // switch 1133 } else { 1134 switch ( type->aggregate.kind ) { 1135 case ast::AggregateDecl::Struct: 1136 case ast::AggregateDecl::Coroutine: 1137 case ast::AggregateDecl::Monitor: 1138 case ast::AggregateDecl::Thread: 1139 return new ast::StructInstType( 1140 *type->aggregate.name, 1141 buildQualifiers( type ) 1142 ); 1143 case ast::AggregateDecl::Union: 1144 return new ast::UnionInstType( 1145 *type->aggregate.name, 1146 buildQualifiers( type ) 1147 ); 1148 case ast::AggregateDecl::Trait: 1149 return new ast::TraitInstType( 1150 *type->aggregate.name, 1151 buildQualifiers( type ) 1152 ); 1153 default: 1154 assert( false ); 1155 } // switch 1156 break; 1157 } // if 1158 break; 1159 default: 809 case TypeData::Enum: { 810 if ( type->enumeration.body ) { 811 EnumDecl * typedecl = buildEnum( type, attributes, linkage ); 812 return new EnumInstType( buildQualifiers( type ), typedecl ); 813 } else { 814 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name ); 815 } // if 816 } 817 case TypeData::Aggregate: { 818 ReferenceToType * ret; 819 if ( type->aggregate.body ) { 820 AggregateDecl * typedecl = buildAggregate( type, attributes, linkage ); 821 switch ( type->aggregate.kind ) { 822 case AggregateDecl::Struct: 823 case AggregateDecl::Coroutine: 824 case AggregateDecl::Monitor: 825 case AggregateDecl::Thread: 826 ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl ); 827 break; 828 case AggregateDecl::Union: 829 ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl ); 830 break; 831 case AggregateDecl::Trait: 832 assert( false ); 833 //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl ); 834 break; 835 default: 836 assert( false ); 837 } // switch 838 } else { 839 switch ( type->aggregate.kind ) { 840 case AggregateDecl::Struct: 841 case AggregateDecl::Coroutine: 842 case AggregateDecl::Monitor: 843 case AggregateDecl::Thread: 844 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 845 break; 846 case AggregateDecl::Union: 847 ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name ); 848 break; 849 case AggregateDecl::Trait: 850 ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name ); 851 break; 852 default: 853 assert( false ); 854 } // switch 855 } // if 856 return ret; 857 } 858 default: 1160 859 assert( false ); 1161 860 } // switch 1162 assert( false );1163 861 } // buildAggInst 1164 862 1165 863 1166 ast::BaseInstType * buildAggInst( const TypeData * td ) {864 ReferenceToType * buildAggInst( const TypeData * td ) { 1167 865 assert( td->kind == TypeData::AggregateInst ); 1168 866 1169 ast::BaseInstType * ret = nullptr; 867 // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() ); 868 ReferenceToType * ret = nullptr; 1170 869 TypeData * type = td->aggInst.aggregate; 1171 870 switch ( type->kind ) { 1172 case TypeData::Enum: 1173 return new ast::EnumInstType( 1174 *type->enumeration.name, 1175 buildQualifiers( type ) 1176 ); 1177 case TypeData::Aggregate: 1178 switch ( type->aggregate.kind ) { 1179 case ast::AggregateDecl::Struct: 1180 case ast::AggregateDecl::Coroutine: 1181 case ast::AggregateDecl::Monitor: 1182 case ast::AggregateDecl::Thread: 1183 ret = new ast::StructInstType( 1184 *type->aggregate.name, 1185 buildQualifiers( type ) 1186 ); 1187 break; 1188 case ast::AggregateDecl::Union: 1189 ret = new ast::UnionInstType( 1190 *type->aggregate.name, 1191 buildQualifiers( type ) 1192 ); 1193 break; 1194 case ast::AggregateDecl::Trait: 1195 ret = new ast::TraitInstType( 1196 *type->aggregate.name, 1197 buildQualifiers( type ) 1198 ); 1199 break; 1200 default: 1201 assert( false ); 1202 } // switch 1203 break; 1204 default: 871 case TypeData::Enum: { 872 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name ); 873 } 874 case TypeData::Aggregate: { 875 switch ( type->aggregate.kind ) { 876 case AggregateDecl::Struct: 877 case AggregateDecl::Coroutine: 878 case AggregateDecl::Monitor: 879 case AggregateDecl::Thread: 880 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 881 break; 882 case AggregateDecl::Union: 883 ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name ); 884 break; 885 case AggregateDecl::Trait: 886 ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name ); 887 break; 888 default: 889 assert( false ); 890 } // switch 891 } 892 break; 893 default: 1205 894 assert( false ); 1206 895 } // switch 1207 896 1208 ret->hoistType = td->aggInst.hoistType; 1209 buildList( td->aggInst.params, ret->params ); 897 ret->set_hoistType( td->aggInst.hoistType ); 898 buildList( td->aggInst.params, ret->get_parameters() ); 899 buildForall( td->forall, ret->get_forall() ); 1210 900 return ret; 1211 901 } // buildAggInst 1212 902 1213 903 1214 ast::NamedTypeDecl * buildSymbolic( 1215 const TypeData * td, 1216 std::vector<ast::ptr<ast::Attribute>> attributes, 1217 const std::string & name, 1218 ast::Storage::Classes scs, 1219 ast::Linkage::Spec linkage ) { 904 NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) { 1220 905 assert( td->kind == TypeData::Symbolic ); 1221 ast::NamedTypeDecl * ret;906 NamedTypeDecl * ret; 1222 907 assert( td->base ); 1223 908 if ( td->symbolic.isTypedef ) { 1224 ret = new ast::TypedefDecl( 1225 td->location, 1226 name, 1227 scs, 1228 typebuild( td->base ), 1229 linkage 1230 ); 909 ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage ); 1231 910 } else { 1232 ret = new ast::TypeDecl( 1233 td->location, 1234 name, 1235 scs, 1236 typebuild( td->base ), 1237 ast::TypeDecl::Dtype, 1238 true 1239 ); 911 ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true ); 1240 912 } // if 1241 buildList( td->symbolic.assertions, ret-> assertions);1242 splice( ret->base.get_and_mutate()->attributes, attributes );913 buildList( td->symbolic.assertions, ret->get_assertions() ); 914 ret->base->attributes.splice( ret->base->attributes.end(), attributes ); 1243 915 return ret; 1244 916 } // buildSymbolic 1245 917 1246 918 1247 ast::EnumDecl * buildEnum( 1248 const TypeData * td, 1249 std::vector<ast::ptr<ast::Attribute>> && attributes, 1250 ast::Linkage::Spec linkage ) { 919 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1251 920 assert( td->kind == TypeData::Enum ); 1252 ast::Type * baseType = td->base ? typebuild(td->base) : nullptr; 1253 ast::EnumDecl * ret = new ast::EnumDecl( 1254 td->location, 1255 *td->enumeration.name, 1256 td->enumeration.typed, 1257 std::move( attributes ), 1258 linkage, 1259 baseType 1260 ); 1261 buildList( td->enumeration.constants, ret->members ); 1262 auto members = ret->members.begin(); 1263 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible; 921 Type * baseType = td->base ? typebuild(td->base) : nullptr; 922 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType ); 923 buildList( td->enumeration.constants, ret->get_members() ); 924 list< Declaration * >::iterator members = ret->get_members().begin(); 925 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible; 1264 926 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 1265 927 if ( cur->enumInLine ) { … … 1268 930 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); 1269 931 } else if ( cur->has_enumeratorValue() ) { 1270 ast::Decl * member = members->get_and_mutate(); 1271 ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member ); 1272 object->init = new ast::SingleInit( 1273 td->location, 1274 maybeMoveBuild( cur->consume_enumeratorValue() ), 1275 ast::NoConstruct 1276 ); 932 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members); 933 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) ); 1277 934 } else if ( !cur->initializer ) { 1278 if ( baseType && (!dynamic_cast< ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {935 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) { 1279 936 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 1280 937 } … … 1283 940 // if 1284 941 } // for 1285 ret-> body = td->enumeration.body;942 ret->set_body( td->enumeration.body ); 1286 943 return ret; 1287 944 } // buildEnum 1288 945 1289 946 1290 ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {947 TypeInstType * buildSymbolicInst( const TypeData * td ) { 1291 948 assert( td->kind == TypeData::SymbolicInst ); 1292 ast::TypeInstType * ret = new ast::TypeInstType( 1293 *td->symbolic.name, 1294 ast::TypeDecl::Dtype, 1295 buildQualifiers( td ) 1296 ); 1297 buildList( td->symbolic.actuals, ret->params ); 949 TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false ); 950 buildList( td->symbolic.actuals, ret->get_parameters() ); 951 buildForall( td->forall, ret->get_forall() ); 1298 952 return ret; 1299 953 } // buildSymbolicInst 1300 954 1301 955 1302 ast::TupleType * buildTuple( const TypeData * td ) {956 TupleType * buildTuple( const TypeData * td ) { 1303 957 assert( td->kind == TypeData::Tuple ); 1304 std:: vector<ast::ptr<ast::Type>> types;958 std::list< Type * > types; 1305 959 buildTypeList( td->tuple, types ); 1306 ast::TupleType * ret = new ast::TupleType( 1307 std::move( types ), 1308 buildQualifiers( td ) 1309 ); 960 TupleType * ret = new TupleType( buildQualifiers( td ), types ); 961 buildForall( td->forall, ret->get_forall() ); 1310 962 return ret; 1311 963 } // buildTuple 1312 964 1313 965 1314 ast::TypeofType * buildTypeof( const TypeData * td ) {966 TypeofType * buildTypeof( const TypeData * td ) { 1315 967 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 1316 968 assert( td->typeexpr ); 1317 return new ast::TypeofType( 1318 td->typeexpr->build(), 1319 td->kind == TypeData::Typeof 1320 ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof, 1321 buildQualifiers( td ) 1322 ); 969 // assert( td->typeexpr->expr ); 970 return new TypeofType{ buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof }; 1323 971 } // buildTypeof 1324 972 1325 973 1326 ast::VTableType * buildVtable( const TypeData * td ) {974 VTableType * buildVtable( const TypeData * td ) { 1327 975 assert( td->base ); 1328 return new ast::VTableType( 1329 typebuild( td->base ), 1330 buildQualifiers( td ) 1331 ); 976 return new VTableType{ buildQualifiers( td ), typebuild( td->base ) }; 1332 977 } // buildVtable 1333 978 1334 979 1335 ast::FunctionDecl * buildFunctionDecl( 1336 const TypeData * td, 1337 const string &name, 1338 ast::Storage::Classes scs, 1339 ast::Function::Specs funcSpec, 1340 ast::Linkage::Spec linkage, 1341 ast::Expr * asmName, 1342 std::vector<ast::ptr<ast::Attribute>> && attributes ) { 1343 assert( td->kind == TypeData::Function ); 1344 // For some reason FunctionDecl takes a bool instead of an ArgumentFlag. 1345 bool isVarArgs = !td->function.params || td->function.params->hasEllipsis; 1346 ast::CV::Qualifiers cvq = buildQualifiers( td ); 1347 std::vector<ast::ptr<ast::TypeDecl>> forall; 1348 std::vector<ast::ptr<ast::DeclWithType>> assertions; 1349 std::vector<ast::ptr<ast::DeclWithType>> params; 1350 std::vector<ast::ptr<ast::DeclWithType>> returns; 1351 buildList( td->function.params, params ); 1352 buildForall( td->forall, forall ); 1353 // Functions do not store their assertions there anymore. 1354 for ( ast::ptr<ast::TypeDecl> & type_param : forall ) { 1355 auto mut = type_param.get_and_mutate(); 1356 splice( assertions, mut->assertions ); 1357 } 1358 if ( td->base ) { 1359 switch ( td->base->kind ) { 1360 case TypeData::Tuple: 1361 buildList( td->base->tuple, returns ); 1362 break; 1363 default: 1364 returns.push_back( dynamic_cast<ast::DeclWithType *>( 1365 buildDecl( 1366 td->base, 1367 "", 1368 ast::Storage::Classes(), 1369 (ast::Expr *)nullptr, // bitfieldWidth 1370 ast::Function::Specs(), 1371 ast::Linkage::Cforall, 1372 (ast::Expr *)nullptr // asmName 1373 ) 1374 ) ); 1375 } // switch 1376 } else { 1377 returns.push_back( new ast::ObjectDecl( 1378 td->location, 1379 "", 1380 new ast::BasicType( ast::BasicType::SignedInt ), 1381 (ast::Init *)nullptr, 1382 ast::Storage::Classes(), 1383 ast::Linkage::Cforall 1384 ) ); 1385 } // if 1386 ast::Stmt * stmt = maybeBuild( td->function.body ); 1387 ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt ); 1388 ast::FunctionDecl * decl = new ast::FunctionDecl( td->location, 1389 name, 1390 std::move( forall ), 1391 std::move( assertions ), 1392 std::move( params ), 1393 std::move( returns ), 1394 body, 1395 scs, 1396 linkage, 1397 std::move( attributes ), 1398 funcSpec, 1399 (isVarArgs) ? ast::VariableArgs : ast::FixedArgs 1400 ); 1401 buildList( td->function.withExprs, decl->withExprs ); 1402 decl->asmName = asmName; 1403 // This may be redundant on a declaration. 1404 decl->type.get_and_mutate()->qualifiers = cvq; 1405 return decl; 1406 } // buildFunctionDecl 1407 1408 1409 ast::Decl * buildDecl( 1410 const TypeData * td, 1411 const string &name, 1412 ast::Storage::Classes scs, 1413 ast::Expr * bitfieldWidth, 1414 ast::Function::Specs funcSpec, 1415 ast::Linkage::Spec linkage, 1416 ast::Expr * asmName, 1417 ast::Init * init, 1418 std::vector<ast::ptr<ast::Attribute>> && attributes ) { 980 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) { 1419 981 if ( td->kind == TypeData::Function ) { 1420 982 if ( td->function.idList ) { // KR function ? … … 1422 984 } // if 1423 985 1424 return buildFunctionDecl( 1425 td, name, scs, funcSpec, linkage, 1426 asmName, std::move( attributes ) ); 986 FunctionDecl * decl; 987 Statement * stmt = maybeBuild<Statement>( td->function.body ); 988 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt ); 989 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec ); 990 buildList( td->function.withExprs, decl->withExprs ); 991 return decl->set_asmName( asmName ); 1427 992 } else if ( td->kind == TypeData::Aggregate ) { 1428 return buildAggregate( td, std::move( attributes ), linkage );993 return buildAggregate( td, attributes, linkage ); 1429 994 } else if ( td->kind == TypeData::Enum ) { 1430 return buildEnum( td, std::move( attributes ), linkage );995 return buildEnum( td, attributes, linkage ); 1431 996 } else if ( td->kind == TypeData::Symbolic ) { 1432 return buildSymbolic( td, std::move( attributes ), name, scs, linkage );997 return buildSymbolic( td, attributes, name, scs, linkage ); 1433 998 } else { 1434 auto ret = new ast::ObjectDecl( td->location, 1435 name, 1436 typebuild( td ), 1437 init, 1438 scs, 1439 linkage, 1440 bitfieldWidth, 1441 std::move( attributes ) 1442 ); 1443 ret->asmName = asmName; 1444 return ret; 999 return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName ); 1445 1000 } // if 1446 1001 return nullptr; … … 1448 1003 1449 1004 1450 ast::FunctionType * buildFunctionType( const TypeData * td ) {1005 FunctionType * buildFunction( const TypeData * td ) { 1451 1006 assert( td->kind == TypeData::Function ); 1452 ast::FunctionType * ft = new ast::FunctionType( 1453 ( !td->function.params || td->function.params->hasEllipsis ) 1454 ? ast::VariableArgs : ast::FixedArgs, 1455 buildQualifiers( td ) 1456 ); 1457 buildTypeList( td->function.params, ft->params ); 1007 FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis ); 1008 buildList( td->function.params, ft->parameters ); 1458 1009 buildForall( td->forall, ft->forall ); 1459 1010 if ( td->base ) { 1460 1011 switch ( td->base->kind ) { 1461 case TypeData::Tuple:1462 build TypeList( td->base->tuple, ft->returns );1012 case TypeData::Tuple: 1013 buildList( td->base->tuple, ft->returnVals ); 1463 1014 break; 1464 default: 1465 ft->returns.push_back( typebuild( td->base ) ); 1466 break; 1015 default: 1016 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) ); 1467 1017 } // switch 1468 1018 } else { 1469 ft->returns.push_back( 1470 new ast::BasicType( ast::BasicType::SignedInt ) ); 1019 ft->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) ); 1471 1020 } // if 1472 1021 return ft; 1473 } // buildFunction Type1022 } // buildFunction 1474 1023 1475 1024 … … 1502 1051 param->type = decl->type; // set copy declaration type to parameter type 1503 1052 decl->type = nullptr; // reset declaration type 1504 // Copy and reset attributes from declaration to parameter: 1505 splice( param->attributes, decl->attributes ); 1053 param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter 1506 1054 } // if 1507 1055 } // for -
src/Parser/TypeData.h
r24d6572 r34b4268 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 15:18:36 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Mar 1 10:44:00 202313 // Update Count : 20 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 10 22:18:49 2022 13 // Update Count : 203 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <iosfwd> // for ostream19 #include <list> // for list20 #include <string> // for string18 #include <iosfwd> // for ostream 19 #include <list> // for list 20 #include <string> // for string 21 21 22 #include "AST/Type.hpp" // for Type 23 #include "DeclarationNode.h" // for DeclarationNode 22 #include "ParseNode.h" // for DeclarationNode, DeclarationNode::Ag... 23 #include "SynTree/LinkageSpec.h" // for Spec 24 #include "SynTree/Type.h" // for Type, ReferenceToType (ptr only) 25 #include "SynTree/SynTree.h" // for Visitor Nodes 24 26 25 27 struct TypeData { … … 28 30 29 31 struct Aggregate_t { 30 ast::AggregateDecl::Aggregate kind;32 AggregateDecl::Aggregate kind; 31 33 const std::string * name = nullptr; 32 34 DeclarationNode * params = nullptr; … … 35 37 bool body; 36 38 bool anon; 39 37 40 bool tagged; 38 41 const std::string * parent = nullptr; … … 91 94 DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType; 92 95 93 ast::CV::Qualifiers qualifiers;96 Type::Qualifiers qualifiers; 94 97 DeclarationNode * forall = nullptr; 95 98 … … 112 115 }; 113 116 114 ast::Type * typebuild( const TypeData * );117 Type * typebuild( const TypeData * ); 115 118 TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true ); 116 ast::CV::Qualifiers buildQualifiers( const TypeData * td ); 117 ast::Type * buildBasicType( const TypeData * ); 118 ast::PointerType * buildPointer( const TypeData * ); 119 ast::ArrayType * buildArray( const TypeData * ); 120 ast::ReferenceType * buildReference( const TypeData * ); 121 ast::AggregateDecl * buildAggregate( const TypeData *, std::vector<ast::ptr<ast::Attribute>> ); 122 ast::BaseInstType * buildComAggInst( const TypeData *, std::vector<ast::ptr<ast::Attribute>> && attributes, ast::Linkage::Spec linkage ); 123 ast::BaseInstType * buildAggInst( const TypeData * ); 124 ast::TypeDecl * buildVariable( const TypeData * ); 125 ast::EnumDecl * buildEnum( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec ); 126 ast::TypeInstType * buildSymbolicInst( const TypeData * ); 127 ast::TupleType * buildTuple( const TypeData * ); 128 ast::TypeofType * buildTypeof( const TypeData * ); 129 ast::VTableType * buildVtable( const TypeData * ); 130 ast::Decl * buildDecl( 131 const TypeData *, const std::string &, ast::Storage::Classes, ast::Expr *, 132 ast::Function::Specs funcSpec, ast::Linkage::Spec, ast::Expr * asmName, 133 ast::Init * init = nullptr, std::vector<ast::ptr<ast::Attribute>> && attributes = std::vector<ast::ptr<ast::Attribute>>() ); 134 ast::FunctionType * buildFunctionType( const TypeData * ); 135 ast::Decl * addEnumBase( Declaration *, const TypeData * ); 119 Type::Qualifiers buildQualifiers( const TypeData * td ); 120 Type * buildBasicType( const TypeData * ); 121 PointerType * buildPointer( const TypeData * ); 122 ArrayType * buildArray( const TypeData * ); 123 ReferenceType * buildReference( const TypeData * ); 124 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > ); 125 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ); 126 ReferenceToType * buildAggInst( const TypeData * ); 127 TypeDecl * buildVariable( const TypeData * ); 128 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec ); 129 TypeInstType * buildSymbolicInst( const TypeData * ); 130 TupleType * buildTuple( const TypeData * ); 131 TypeofType * buildTypeof( const TypeData * ); 132 VTableType * buildVtable( const TypeData * ); 133 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, 134 Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() ); 135 FunctionType * buildFunction( const TypeData * ); 136 Declaration * addEnumBase( Declaration *, const TypeData * ); 136 137 void buildKRFunction( const TypeData::Function_t & function ); 137 138 -
src/Parser/TypedefTable.cc
r24d6572 r34b4268 16 16 17 17 #include "TypedefTable.h" 18 19 #include <cassert> // for assert 20 #include <string> // for string 21 #include <iostream> // for iostream 22 23 #include "ExpressionNode.h" // for LabelNode 24 #include "ParserTypes.h" // for Token 25 #include "StatementNode.h" // for CondCtl, ForCtrl 26 // This (generated) header must come late as it is missing includes. 27 #include "parser.hh" // for IDENTIFIER, TYPEDEFname, TYPEGENname 28 18 #include <cassert> // for assert 19 #include <iostream> 29 20 using namespace std; 30 21 31 22 #if 0 32 23 #define debugPrint( code ) code 33 34 static const char *kindName( int kind ) {35 switch ( kind ) {36 case IDENTIFIER: return "identifier";37 case TYPEDIMname: return "typedim";38 case TYPEDEFname: return "typedef";39 case TYPEGENname: return "typegen";40 default:41 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;42 abort();43 } // switch44 } // kindName45 24 #else 46 25 #define debugPrint( code ) 47 26 #endif 27 28 using namespace std; // string, iostream 29 30 debugPrint( 31 static const char *kindName( int kind ) { 32 switch ( kind ) { 33 case IDENTIFIER: return "identifier"; 34 case TYPEDIMname: return "typedim"; 35 case TYPEDEFname: return "typedef"; 36 case TYPEGENname: return "typegen"; 37 default: 38 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 39 abort(); 40 } // switch 41 } // kindName 42 ); 48 43 49 44 TypedefTable::~TypedefTable() { … … 83 78 typedefTable.addToEnclosingScope( name, kind, "MTD" ); 84 79 } // if 85 } // TypedefTable::makeTypedef86 87 void TypedefTable::makeTypedef( const string & name ) {88 return makeTypedef( name, TYPEDEFname );89 80 } // TypedefTable::makeTypedef 90 81 -
src/Parser/TypedefTable.h
r24d6572 r34b4268 19 19 20 20 #include "Common/ScopedMap.h" // for ScopedMap 21 #include "ParserTypes.h" 22 #include "parser.hh" // for IDENTIFIER, TYPEDEFname, TYPEGENname 21 23 22 24 class TypedefTable { 23 25 struct Note { size_t level; bool forall; }; 24 26 typedef ScopedMap< std::string, int, Note > KindTable; 25 KindTable kindTable; 27 KindTable kindTable; 26 28 unsigned int level = 0; 27 29 public: … … 31 33 bool existsCurr( const std::string & identifier ) const; 32 34 int isKind( const std::string & identifier ) const; 33 void makeTypedef( const std::string & name, int kind ); 34 void makeTypedef( const std::string & name ); 35 void makeTypedef( const std::string & name, int kind = TYPEDEFname ); 35 36 void addToScope( const std::string & identifier, int kind, const char * ); 36 37 void addToEnclosingScope( const std::string & identifier, int kind, const char * ); -
src/Parser/lex.ll
r24d6572 r34b4268 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : T ue May 2 08:45:21 202313 * Update Count : 76 912 * Last Modified On : Thu Oct 13 20:46:04 2022 13 * Update Count : 764 14 14 */ 15 15 … … 23 23 // line-number directives) and C/C++ style comments, which are ignored. 24 24 25 // *************************** Includes and Defines ****************************25 //**************************** Includes and Defines **************************** 26 26 27 27 #ifdef __clang__ … … 44 44 45 45 #include "config.h" // configure info 46 #include "DeclarationNode.h" // for DeclarationNode47 #include "ExpressionNode.h" // for LabelNode48 #include "InitializerNode.h" // for InitializerNode49 46 #include "ParseNode.h" 50 #include "ParserTypes.h" // for Token51 #include "StatementNode.h" // for CondCtl, ForCtrl52 47 #include "TypedefTable.h" 53 // This (generated) header must come late as it is missing includes.54 #include "parser.hh" // generated info55 48 56 49 string * build_postfix_name( string * name ); … … 221 214 __alignof { KEYWORD_RETURN(ALIGNOF); } // GCC 222 215 __alignof__ { KEYWORD_RETURN(ALIGNOF); } // GCC 223 and { QKEYWORD_RETURN(WAND); } // CFA224 216 asm { KEYWORD_RETURN(ASM); } 225 217 __asm { KEYWORD_RETURN(ASM); } // GCC … … 258 250 enable { KEYWORD_RETURN(ENABLE); } // CFA 259 251 enum { KEYWORD_RETURN(ENUM); } 252 __extension__ { KEYWORD_RETURN(EXTENSION); } // GCC 260 253 exception { KEYWORD_RETURN(EXCEPTION); } // CFA 261 __extension__ { KEYWORD_RETURN(EXTENSION); } // GCC262 254 extern { KEYWORD_RETURN(EXTERN); } 263 255 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA … … 348 340 vtable { KEYWORD_RETURN(VTABLE); } // CFA 349 341 waitfor { KEYWORD_RETURN(WAITFOR); } // CFA 350 waituntil { KEYWORD_RETURN(WAITUNTIL); } // CFA351 342 when { KEYWORD_RETURN(WHEN); } // CFA 352 343 while { KEYWORD_RETURN(WHILE); } … … 511 502 SemanticErrorThrow = true; 512 503 cerr << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1 513 << ": " << ErrorHelpers::error_str() << errmsg << " beforetoken \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;504 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl; 514 505 } 515 506 -
src/Parser/module.mk
r24d6572 r34b4268 21 21 SRC += \ 22 22 Parser/DeclarationNode.cc \ 23 Parser/DeclarationNode.h \24 23 Parser/ExpressionNode.cc \ 25 Parser/ExpressionNode.h \26 24 Parser/InitializerNode.cc \ 27 Parser/InitializerNode.h \28 25 Parser/lex.ll \ 29 26 Parser/ParseNode.cc \ … … 33 30 Parser/parserutility.cc \ 34 31 Parser/parserutility.h \ 35 Parser/RunParser.cpp \36 Parser/RunParser.hpp \37 32 Parser/StatementNode.cc \ 38 Parser/StatementNode.h \39 33 Parser/TypeData.cc \ 40 34 Parser/TypeData.h \ -
src/Parser/parser.yy
r24d6572 r34b4268 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 26 16:45:37 202313 // Update Count : 633012 // Last Modified On : Mon Nov 21 22:34:30 2022 13 // Update Count : 5848 14 14 // 15 15 … … 44 44 45 45 #include <cstdio> 46 #include <sstream>47 46 #include <stack> 48 47 using namespace std; 49 48 50 #include "SynTree/Type.h" // for Type 51 #include "DeclarationNode.h" // for DeclarationNode, ... 52 #include "ExpressionNode.h" // for ExpressionNode, ... 53 #include "InitializerNode.h" // for InitializerNode, ... 54 #include "ParserTypes.h" 55 #include "StatementNode.h" // for build_... 49 #include "SynTree/Declaration.h" 50 #include "ParseNode.h" 56 51 #include "TypedefTable.h" 57 52 #include "TypeData.h" 53 #include "SynTree/LinkageSpec.h" 58 54 #include "Common/SemanticError.h" // error_str 59 55 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 60 56 61 #include "SynTree/Attribute.h" // for Attribute57 #include "SynTree/Attribute.h" // for Attribute 62 58 63 59 // lex uses __null in a boolean context, it's fine. … … 67 63 68 64 extern DeclarationNode * parseTree; 69 extern ast::Linkage::Spec linkage;65 extern LinkageSpec::Spec linkage; 70 66 extern TypedefTable typedefTable; 71 67 72 stack< ast::Linkage::Spec> linkageStack;68 stack<LinkageSpec::Spec> linkageStack; 73 69 74 70 bool appendStr( string & to, string & from ) { … … 203 199 } // fieldDecl 204 200 205 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc,*new string( "0" ) ) )206 #define NEW_ONE new ExpressionNode( build_constantInteger( yylloc,*new string( "1" ) ) )201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) ) 202 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) 207 203 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 208 204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 210 206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized." 211 207 212 static ForCtrl * makeForCtrl( 213 const CodeLocation & location, 214 DeclarationNode * init, 215 enum OperKinds compop, 216 ExpressionNode * comp, 217 ExpressionNode * inc ) { 218 // Wrap both comp/inc if they are non-null. 219 if ( comp ) comp = new ExpressionNode( build_binary_val( location, 220 compop, 221 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 222 comp ) ); 223 if ( inc ) inc = new ExpressionNode( build_binary_val( location, 224 // choose += or -= for upto/downto 225 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn, 226 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 227 inc ) ); 228 // The StatementNode call frees init->name, it must happen later. 229 return new ForCtrl( new StatementNode( init ), comp, inc ); 230 } 231 232 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 233 209 if ( index->initializer ) { 234 210 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 237 213 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." ); 238 214 } // if 239 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 240 return makeForCtrl( location, initDecl, compop, comp, inc ); 215 return new ForCtrl( index->addInitializer( new InitializerNode( start ) ), 216 // NULL comp/inc => leave blank 217 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr, 218 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 219 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr ); 241 220 } // forCtrl 242 221 243 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {244 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());245 if ( constant && (constant-> rep == "0" || constant->rep== "1") ) {246 type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );222 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 223 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); 224 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 225 type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 247 226 } // if 248 DeclarationNode * initDecl = distAttr( 249 DeclarationNode::newTypeof( type, true ), 250 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 251 ); 252 return makeForCtrl( location, initDecl, compop, comp, inc ); 227 // type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) ); 228 return new ForCtrl( 229 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 230 // NULL comp/inc => leave blank 231 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr, 232 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 233 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr ); 253 234 } // forCtrl 254 235 255 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {256 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {257 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );258 } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get()) ) {259 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {260 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );236 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 237 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) { 238 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 239 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) { 240 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) { 241 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 261 242 } else { 262 243 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 300 281 %union { 301 282 Token tok; 302 ExpressionNode * expr; 283 ParseNode * pn; 284 ExpressionNode * en; 303 285 DeclarationNode * decl; 304 ast::AggregateDecl::Aggregate aggKey; 305 ast::TypeDecl::Kind tclass; 306 StatementNode * stmt; 307 ClauseNode * clause; 308 ast::WaitForStmt * wfs; 309 ast::WaitUntilStmt::ClauseNode * wucn; 286 AggregateDecl::Aggregate aggKey; 287 TypeDecl::Kind tclass; 288 StatementNode * sn; 289 WaitForStmt * wfs; 290 Expression * constant; 310 291 CondCtl * ifctl; 311 ForCtrl * forctl; 312 LabelNode * labels; 313 InitializerNode * init; 314 OperKinds oper; 292 ForCtrl * fctl; 293 OperKinds compop; 294 LabelNode * label; 295 InitializerNode * in; 296 OperKinds op; 315 297 std::string * str; 316 bool is_volatile;317 EnumHiding enum_hiding;318 ast::ExceptionKind except_kind;319 ast::GenericExpr * genexpr;298 bool flag; 299 EnumHiding hide; 300 CatchStmt::Kind catch_kind; 301 GenericExpr * genexpr; 320 302 } 321 303 322 // ************************ TERMINAL TOKENS ********************************304 //************************* TERMINAL TOKENS ******************************** 323 305 324 306 // keywords … … 349 331 %token ATTRIBUTE EXTENSION // GCC 350 332 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 351 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL// CFA333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR // CFA 352 334 %token DISABLE ENABLE TRY THROW THROWRESUME AT // CFA 353 335 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) … … 355 337 356 338 // names and constants: lexer differentiates between identifier and typedef names 357 %token<tok> IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname358 %token<tok> TIMEOUT W AND WORCATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA339 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname 340 %token<tok> TIMEOUT WOR CATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA 359 341 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 360 342 %token<tok> DIRECTIVE … … 382 364 %type<tok> identifier identifier_at identifier_or_type_name attr_name 383 365 %type<tok> quasi_keyword 384 %type< expr> string_literal366 %type<constant> string_literal 385 367 %type<str> string_literal_list 386 368 387 %type< enum_hiding> hide_opt visible_hide_opt369 %type<hide> hide_opt visible_hide_opt 388 370 389 371 // expressions 390 %type<e xpr> constant391 %type<e xpr> tuple tuple_expression_list392 %type<op er> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator393 %type<e xpr> primary_expression postfix_expression unary_expression394 %type<e xpr> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression395 %type<e xpr> shift_expression relational_expression equality_expression396 %type<e xpr> AND_expression exclusive_OR_expression inclusive_OR_expression397 %type<e xpr> logical_AND_expression logical_OR_expression398 %type<e xpr> conditional_expression constant_expression assignment_expression assignment_expression_opt399 %type<e xpr> comma_expression comma_expression_opt400 %type<e xpr> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt372 %type<en> constant 373 %type<en> tuple tuple_expression_list 374 %type<op> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator 375 %type<en> primary_expression postfix_expression unary_expression 376 %type<en> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression 377 %type<en> shift_expression relational_expression equality_expression 378 %type<en> AND_expression exclusive_OR_expression inclusive_OR_expression 379 %type<en> logical_AND_expression logical_OR_expression 380 %type<en> conditional_expression constant_expression assignment_expression assignment_expression_opt 381 %type<en> comma_expression comma_expression_opt 382 %type<en> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt 401 383 %type<ifctl> conditional_declaration 402 %type<f orctl> for_control_expression for_control_expression_list403 %type< oper> upupeq updown updowneq downupdowneq404 %type<e xpr> subrange384 %type<fctl> for_control_expression for_control_expression_list 385 %type<compop> upupeq updown updowneq downupdowneq 386 %type<en> subrange 405 387 %type<decl> asm_name_opt 406 %type<e xpr> asm_operands_opt asm_operands_list asm_operand407 %type<label s> label_list408 %type<e xpr> asm_clobbers_list_opt409 %type< is_volatile> asm_volatile_opt410 %type<e xpr> handler_predicate_opt388 %type<en> asm_operands_opt asm_operands_list asm_operand 389 %type<label> label_list 390 %type<en> asm_clobbers_list_opt 391 %type<flag> asm_volatile_opt 392 %type<en> handler_predicate_opt 411 393 %type<genexpr> generic_association generic_assoc_list 412 394 413 395 // statements 414 %type<stmt> statement labeled_statement compound_statement 415 %type<stmt> statement_decl statement_decl_list statement_list_nodecl 416 %type<stmt> selection_statement if_statement 417 %type<clause> switch_clause_list_opt switch_clause_list 418 %type<expr> case_value 419 %type<clause> case_clause case_value_list case_label case_label_list 420 %type<stmt> iteration_statement jump_statement 421 %type<stmt> expression_statement asm_statement 422 %type<stmt> with_statement 423 %type<expr> with_clause_opt 424 %type<stmt> exception_statement 425 %type<clause> handler_clause finally_clause 426 %type<except_kind> handler_key 427 %type<stmt> mutex_statement 428 %type<expr> when_clause when_clause_opt waitfor waituntil timeout 429 %type<stmt> waitfor_statement waituntil_statement 430 %type<wfs> wor_waitfor_clause 431 %type<wucn> waituntil_clause wand_waituntil_clause wor_waituntil_clause 396 %type<sn> statement labeled_statement compound_statement 397 %type<sn> statement_decl statement_decl_list statement_list_nodecl 398 %type<sn> selection_statement if_statement 399 %type<sn> switch_clause_list_opt switch_clause_list 400 %type<en> case_value 401 %type<sn> case_clause case_value_list case_label case_label_list 402 %type<sn> iteration_statement jump_statement 403 %type<sn> expression_statement asm_statement 404 %type<sn> with_statement 405 %type<en> with_clause_opt 406 %type<sn> exception_statement handler_clause finally_clause 407 %type<catch_kind> handler_key 408 %type<sn> mutex_statement 409 %type<en> when_clause when_clause_opt waitfor timeout 410 %type<sn> waitfor_statement 411 %type<wfs> waitfor_clause 432 412 433 413 // declarations … … 441 421 %type<decl> assertion assertion_list assertion_list_opt 442 422 443 %type<e xpr> bit_subrange_size_opt bit_subrange_size423 %type<en> bit_subrange_size_opt bit_subrange_size 444 424 445 425 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 454 434 455 435 %type<decl> enumerator_list enum_type enum_type_nobody 456 %type<in it> enumerator_value_opt436 %type<in> enumerator_value_opt 457 437 458 438 %type<decl> external_definition external_definition_list external_definition_list_opt … … 461 441 462 442 %type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract 463 %type<e xpr> field field_name_list field_name fraction_constants_opt443 %type<en> field field_name_list field_name fraction_constants_opt 464 444 465 445 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 502 482 %type<decl> typedef_name typedef_declaration typedef_expression 503 483 504 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function 505 %type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr 484 %type<decl> variable_type_redeclarator type_ptr type_array type_function 506 485 507 486 %type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function … … 510 489 %type<decl> type_parameter type_parameter_list type_initializer_opt 511 490 512 %type<e xpr> type_parameters_opt type_list array_type_list491 %type<en> type_parameters_opt type_list array_type_list 513 492 514 493 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 521 500 522 501 // initializers 523 %type<in it> initializer initializer_list_opt initializer_opt502 %type<in> initializer initializer_list_opt initializer_opt 524 503 525 504 // designators 526 %type<e xpr> designator designator_list designation505 %type<en> designator designator_list designation 527 506 528 507 … … 533 512 // Similar issues exit with the waitfor statement. 534 513 535 // Order of these lines matters (low-to-high precedence). THEN is left associative over W AND/WOR/TIMEOUT/ELSE, WAND/WOR536 // is leftassociative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.514 // Order of these lines matters (low-to-high precedence). THEN is left associative over WOR/TIMEOUT/ELSE, WOR is left 515 // associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE. 537 516 %precedence THEN // rule precedence for IF/WAITFOR statement 538 %precedence ANDAND // token precedence for start of WAND in WAITFOR statement539 %precedence WAND // token precedence for start of WAND in WAITFOR statement540 %precedence OROR // token precedence for start of WOR in WAITFOR statement541 517 %precedence WOR // token precedence for start of WOR in WAITFOR statement 542 518 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement … … 616 592 constant: 617 593 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant". 618 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( yylloc,*$1 ) ); }619 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }620 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }621 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }622 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( yylloc,*$1 ) ); }594 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); } 595 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 596 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 597 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 598 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( *$1 ) ); } 623 599 ; 624 600 625 601 quasi_keyword: // CFA 626 602 TIMEOUT 627 | WAND628 603 | WOR 629 604 | CATCH … … 646 621 647 622 string_literal: 648 string_literal_list { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 )); }623 string_literal_list { $$ = build_constantStr( *$1 ); } 649 624 ; 650 625 … … 663 638 primary_expression: 664 639 IDENTIFIER // typedef name cannot be used as a variable name 665 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }640 { $$ = new ExpressionNode( build_varref( $1 ) ); } 666 641 | quasi_keyword 667 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }642 { $$ = new ExpressionNode( build_varref( $1 ) ); } 668 643 | TYPEDIMname // CFA, generic length argument 669 644 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 670 645 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 671 { $$ = new ExpressionNode( build_dimensionref( yylloc,$1 ) ); }646 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); } 672 647 | tuple 673 648 | '(' comma_expression ')' 674 649 { $$ = $2; } 675 650 | '(' compound_statement ')' // GCC, lambda expression 676 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2) ) ) ); }651 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); } 677 652 | type_name '.' identifier // CFA, nested type 678 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc,$3 ) ) ); }653 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); } 679 654 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 680 655 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 682 657 { 683 658 // add the missing control expression to the GenericExpr and return it 684 $5->control = maybeMoveBuild ( $3 );659 $5->control = maybeMoveBuild<Expression>( $3 ); 685 660 $$ = new ExpressionNode( $5 ); 686 661 } … … 708 683 { 709 684 // steal the association node from the singleton and delete the wrapper 710 assert( 1 == $3->associations.size() ); 711 $1->associations.push_back( $3->associations.front() ); 685 $1->associations.splice($1->associations.end(), $3->associations); 712 686 delete $3; 713 687 $$ = $1; … … 719 693 { 720 694 // create a GenericExpr wrapper with one association pair 721 $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );695 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } ); 722 696 } 723 697 | DEFAULT ':' assignment_expression 724 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }698 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); } 725 699 ; 726 700 … … 731 705 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 732 706 // Current: Commas in subscripts make tuples. 733 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }707 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 734 708 | postfix_expression '[' assignment_expression ']' 735 709 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 737 711 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 738 712 // equivalent to the old x[i,j]. 739 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }713 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 740 714 | constant '[' assignment_expression ']' // 3[a], 'a'[a], 3.5[a] 741 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }715 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 742 716 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 743 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }717 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); } 744 718 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 745 719 { 746 720 Token fn; 747 721 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 748 $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc,fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );722 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 749 723 } 750 724 | postfix_expression '(' argument_expression_list_opt ')' 751 { $$ = new ExpressionNode( build_func( yylloc,$1, $3 ) ); }725 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 752 726 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 753 727 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 754 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,new string( "__builtin_va_arg") ) ),728 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ), 755 729 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 756 730 | postfix_expression '`' identifier // CFA, postfix call 757 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), $1 ) ); }731 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } 758 732 | constant '`' identifier // CFA, postfix call 759 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), $1 ) ); }733 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } 760 734 | string_literal '`' identifier // CFA, postfix call 761 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1) ); }735 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); } 762 736 | postfix_expression '.' identifier 763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }737 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 764 738 | postfix_expression '.' INTEGERconstant // CFA, tuple index 765 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }739 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); } 766 740 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 767 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 ) ) ); }741 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); } 768 742 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 769 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }743 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 770 744 | postfix_expression '.' aggregate_control 771 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$3, $1 ) ); }745 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); } 772 746 | postfix_expression ARROW identifier 773 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }747 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 774 748 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 775 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }749 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } 776 750 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 777 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }751 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 778 752 | postfix_expression ICR 779 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::IncrPost, $1 ) ); }753 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); } 780 754 | postfix_expression DECR 781 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::DecrPost, $1 ) ); }755 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); } 782 756 | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal 783 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, new InitializerNode( $5, true ) ) ); }757 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); } 784 758 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 785 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }759 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); } 786 760 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 787 761 { 788 762 Token fn; 789 763 fn.str = new string( "^?{}" ); // location undefined 790 $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );764 $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) ); 791 765 } 792 766 ; … … 807 781 '@' // CFA, default parameter 808 782 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 809 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }783 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } 810 784 | assignment_expression 811 785 ; … … 819 793 field_name 820 794 | FLOATING_DECIMALconstant field 821 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }795 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); } 822 796 | FLOATING_DECIMALconstant '[' field_name_list ']' 823 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc,$3 ) ) ); }797 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); } 824 798 | field_name '.' field 825 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }799 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 826 800 | field_name '.' '[' field_name_list ']' 827 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }801 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 828 802 | field_name ARROW field 829 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }803 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 830 804 | field_name ARROW '[' field_name_list ']' 831 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }805 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 832 806 ; 833 807 834 808 field_name: 835 809 INTEGERconstant fraction_constants_opt 836 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc,*$1 ), $2 ) ); }810 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); } 837 811 | FLOATINGconstant fraction_constants_opt 838 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc,*$1 ), $2 ) ); }812 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); } 839 813 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 840 814 { 841 $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc,$1 ), $2 ) );815 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); 842 816 } 843 817 ; … … 848 822 | fraction_constants_opt FLOATING_FRACTIONconstant 849 823 { 850 ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 );851 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1,constant ) ) : new ExpressionNode( constant );824 Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 ); 825 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant ); 852 826 } 853 827 ; … … 859 833 | constant 860 834 | string_literal 861 { $$ = $1; }835 { $$ = new ExpressionNode( $1 ); } 862 836 | EXTENSION cast_expression // GCC 863 837 { $$ = $2->set_extension( true ); } … … 868 842 { 869 843 switch ( $1 ) { 870 case OperKinds::AddressOf:871 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );844 case OperKinds::AddressOf: 845 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ); 872 846 break; 873 case OperKinds::PointTo:874 $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) );847 case OperKinds::PointTo: 848 $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); 875 849 break; 876 case OperKinds::And:877 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );850 case OperKinds::And: 851 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) ); 878 852 break; 879 default:853 default: 880 854 assert( false ); 881 855 } 882 856 } 883 857 | unary_operator cast_expression 884 { $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) ); }858 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); } 885 859 | ICR unary_expression 886 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Incr, $2 ) ); }860 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); } 887 861 | DECR unary_expression 888 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Decr, $2 ) ); }862 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); } 889 863 | SIZEOF unary_expression 890 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }864 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); } 891 865 | SIZEOF '(' type_no_function ')' 892 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }866 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); } 893 867 | ALIGNOF unary_expression // GCC, variable alignment 894 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }868 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); } 895 869 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 896 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }870 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); } 897 871 | OFFSETOF '(' type_no_function ',' identifier ')' 898 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc,$5 ) ) ); }872 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 899 873 | TYPEID '(' type_no_function ')' 900 874 { … … 921 895 unary_expression 922 896 | '(' type_no_function ')' cast_expression 923 { $$ = new ExpressionNode( build_cast( yylloc,$2, $4 ) ); }897 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 924 898 | '(' aggregate_control '&' ')' cast_expression // CFA 925 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }899 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 926 900 | '(' aggregate_control '*' ')' cast_expression // CFA 927 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }901 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 928 902 | '(' VIRTUAL ')' cast_expression // CFA 929 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }903 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); } 930 904 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 931 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }905 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); } 932 906 | '(' RETURN type_no_function ')' cast_expression // CFA 933 { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast::CastExpr::Return ) ); }907 { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); } 934 908 | '(' COERCE type_no_function ')' cast_expression // CFA 935 909 { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; } … … 937 911 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 938 912 // | '(' type_no_function ')' tuple 939 // { $$ = new ast::ExpressionNode( build_cast( yylloc,$2, $4 ) ); }913 // { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 940 914 ; 941 915 … … 955 929 cast_expression 956 930 | exponential_expression '\\' cast_expression 957 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Exp, $1, $3 ) ); }931 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); } 958 932 ; 959 933 … … 961 935 exponential_expression 962 936 | multiplicative_expression '*' exponential_expression 963 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mul, $1, $3 ) ); }937 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); } 964 938 | multiplicative_expression '/' exponential_expression 965 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Div, $1, $3 ) ); }939 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); } 966 940 | multiplicative_expression '%' exponential_expression 967 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mod, $1, $3 ) ); }941 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); } 968 942 ; 969 943 … … 971 945 multiplicative_expression 972 946 | additive_expression '+' multiplicative_expression 973 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Plus, $1, $3 ) ); }947 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); } 974 948 | additive_expression '-' multiplicative_expression 975 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Minus, $1, $3 ) ); }949 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); } 976 950 ; 977 951 … … 979 953 additive_expression 980 954 | shift_expression LS additive_expression 981 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LShift, $1, $3 ) ); }955 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); } 982 956 | shift_expression RS additive_expression 983 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::RShift, $1, $3 ) ); }957 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); } 984 958 ; 985 959 … … 987 961 shift_expression 988 962 | relational_expression '<' shift_expression 989 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LThan, $1, $3 ) ); }963 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); } 990 964 | relational_expression '>' shift_expression 991 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GThan, $1, $3 ) ); }965 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); } 992 966 | relational_expression LE shift_expression 993 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LEThan, $1, $3 ) ); }967 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); } 994 968 | relational_expression GE shift_expression 995 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GEThan, $1, $3 ) ); }969 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); } 996 970 ; 997 971 … … 999 973 relational_expression 1000 974 | equality_expression EQ relational_expression 1001 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Eq, $1, $3 ) ); }975 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); } 1002 976 | equality_expression NE relational_expression 1003 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Neq, $1, $3 ) ); }977 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); } 1004 978 ; 1005 979 … … 1007 981 equality_expression 1008 982 | AND_expression '&' equality_expression 1009 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitAnd, $1, $3 ) ); }983 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); } 1010 984 ; 1011 985 … … 1013 987 AND_expression 1014 988 | exclusive_OR_expression '^' AND_expression 1015 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Xor, $1, $3 ) ); }989 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); } 1016 990 ; 1017 991 … … 1019 993 exclusive_OR_expression 1020 994 | inclusive_OR_expression '|' exclusive_OR_expression 1021 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitOr, $1, $3 ) ); }995 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); } 1022 996 ; 1023 997 … … 1025 999 inclusive_OR_expression 1026 1000 | logical_AND_expression ANDAND inclusive_OR_expression 1027 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr) ); }1001 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); } 1028 1002 ; 1029 1003 … … 1031 1005 logical_AND_expression 1032 1006 | logical_OR_expression OROR logical_AND_expression 1033 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr) ); }1007 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); } 1034 1008 ; 1035 1009 … … 1037 1011 logical_OR_expression 1038 1012 | logical_OR_expression '?' comma_expression ':' conditional_expression 1039 { $$ = new ExpressionNode( build_cond( yylloc,$1, $3, $5 ) ); }1013 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); } 1040 1014 // FIX ME: computes $1 twice 1041 1015 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 1042 { $$ = new ExpressionNode( build_cond( yylloc,$1, $1, $4 ) ); }1016 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); } 1043 1017 ; 1044 1018 … … 1055 1029 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1056 1030 // } else { 1057 $$ = new ExpressionNode( build_binary_val( yylloc,$2, $1, $3 ) );1031 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); 1058 1032 // } // if 1059 1033 } … … 1100 1074 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1101 1075 '[' ',' tuple_expression_list ']' 1102 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }1076 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 1103 1077 | '[' push assignment_expression pop ',' tuple_expression_list ']' 1104 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $6 ) ) )); }1078 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); } 1105 1079 ; 1106 1080 … … 1118 1092 assignment_expression 1119 1093 | comma_expression ',' assignment_expression 1120 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1094 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 1121 1095 ; 1122 1096 … … 1139 1113 | mutex_statement 1140 1114 | waitfor_statement 1141 | waituntil_statement1142 1115 | exception_statement 1143 1116 | enable_disable_statement … … 1145 1118 | asm_statement 1146 1119 | DIRECTIVE 1147 { $$ = new StatementNode( build_directive( yylloc,$1 ) ); }1120 { $$ = new StatementNode( build_directive( $1 ) ); } 1148 1121 ; 1149 1122 … … 1151 1124 // labels cannot be identifiers 0 or 1 1152 1125 identifier_or_type_name ':' attribute_list_opt statement 1153 { $$ = $4->add_label( yylloc,$1, $3 ); }1126 { $$ = $4->add_label( $1, $3 ); } 1154 1127 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1155 1128 { … … 1163 1136 compound_statement: 1164 1137 '{' '}' 1165 { $$ = new StatementNode( build_compound( yylloc,(StatementNode *)0 ) ); }1138 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 1166 1139 | '{' push 1167 1140 local_label_declaration_opt // GCC, local labels appear at start of block 1168 1141 statement_decl_list // C99, intermix declarations and statements 1169 1142 pop '}' 1170 { $$ = new StatementNode( build_compound( yylloc,$4 ) ); }1143 { $$ = new StatementNode( build_compound( $4 ) ); } 1171 1144 ; 1172 1145 … … 1199 1172 expression_statement: 1200 1173 comma_expression_opt ';' 1201 { $$ = new StatementNode( build_expr( yylloc, $1 ) ); } 1174 { $$ = new StatementNode( build_expr( $1 ) ); } 1175 | MUTEX '(' ')' comma_expression ';' 1176 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); } 1202 1177 ; 1203 1178 … … 1208 1183 { $$ = $2; } 1209 1184 | SWITCH '(' comma_expression ')' case_clause 1210 { $$ = new StatementNode( build_switch( yylloc,true, $3, $5 ) ); }1185 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } 1211 1186 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1212 1187 { 1213 StatementNode *sw = new StatementNode( build_switch( yylloc,true, $3, $8 ) );1188 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) ); 1214 1189 // The semantics of the declaration list is changed to include associated initialization, which is performed 1215 1190 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1217 1192 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1218 1193 // statement. 1219 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1194 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1220 1195 } 1221 1196 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1222 1197 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1223 1198 | CHOOSE '(' comma_expression ')' case_clause // CFA 1224 { $$ = new StatementNode( build_switch( yylloc,false, $3, $5 ) ); }1199 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } 1225 1200 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1226 1201 { 1227 StatementNode *sw = new StatementNode( build_switch( yylloc,false, $3, $8 ) );1228 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1202 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) ); 1203 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1229 1204 } 1230 1205 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error … … 1235 1210 IF '(' conditional_declaration ')' statement %prec THEN 1236 1211 // explicitly deal with the shift/reduce conflict on if/else 1237 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc,$5 ), nullptr ) ); }1212 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); } 1238 1213 | IF '(' conditional_declaration ')' statement ELSE statement 1239 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc,$7 ) ) ); }1214 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); } 1240 1215 ; 1241 1216 … … 1249 1224 | declaration comma_expression // semi-colon separated 1250 1225 { $$ = new CondCtl( $1, $2 ); } 1251 ;1226 ; 1252 1227 1253 1228 // CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case … … 1257 1232 constant_expression { $$ = $1; } 1258 1233 | constant_expression ELLIPSIS constant_expression // GCC, subrange 1259 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1234 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 1260 1235 | subrange // CFA, subrange 1261 1236 ; 1262 1237 1263 1238 case_value_list: // CFA 1264 case_value { $$ = new ClauseNode( build_case( yylloc,$1 ) ); }1239 case_value { $$ = new StatementNode( build_case( $1 ) ); } 1265 1240 // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5" 1266 | case_value_list ',' case_value { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3) ) ); }1241 | case_value_list ',' case_value { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 ) ) ) ); } 1267 1242 ; 1268 1243 … … 1273 1248 | CASE case_value_list error // syntax error 1274 1249 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1275 | DEFAULT ':' { $$ = new ClauseNode( build_default( yylloc) ); }1250 | DEFAULT ':' { $$ = new StatementNode( build_default() ); } 1276 1251 // A semantic check is required to ensure only one default clause per switch/choose statement. 1277 1252 | DEFAULT error // syntax error … … 1281 1256 case_label_list: // CFA 1282 1257 case_label 1283 | case_label_list case_label { $$ = $1->set_last( $2); }1258 | case_label_list case_label { $$ = (StatementNode *)( $1->set_last( $2 )); } 1284 1259 ; 1285 1260 1286 1261 case_clause: // CFA 1287 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( yylloc,$2 ) ); }1262 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); } 1288 1263 ; 1289 1264 … … 1296 1271 switch_clause_list: // CFA 1297 1272 case_label_list statement_list_nodecl 1298 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc,$2 ) ) ); }1273 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); } 1299 1274 | switch_clause_list case_label_list statement_list_nodecl 1300 { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3) ) ) ); }1275 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); } 1301 1276 ; 1302 1277 1303 1278 iteration_statement: 1304 1279 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1305 { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) ); }1280 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); } 1306 1281 | WHILE '(' ')' statement ELSE statement // CFA 1307 1282 { 1308 $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) );1309 SemanticWarning( yylloc, Warning::SuperfluousElse );1283 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1284 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1310 1285 } 1311 1286 | WHILE '(' conditional_declaration ')' statement %prec THEN 1312 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1287 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } 1313 1288 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1314 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1289 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1315 1290 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1316 { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) ); }1291 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); } 1317 1292 | DO statement WHILE '(' ')' ELSE statement // CFA 1318 1293 { 1319 $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) );1320 SemanticWarning( yylloc, Warning::SuperfluousElse );1294 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1295 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1321 1296 } 1322 1297 | DO statement WHILE '(' comma_expression ')' ';' 1323 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ) ) ); }1298 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1324 1299 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1325 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ), $8 ) ); }1300 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); } 1326 1301 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1327 { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) ); }1302 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); } 1328 1303 | FOR '(' ')' statement ELSE statement // CFA 1329 1304 { 1330 $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) );1331 SemanticWarning( yylloc, Warning::SuperfluousElse );1305 $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); 1306 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1332 1307 } 1333 1308 | FOR '(' for_control_expression_list ')' statement %prec THEN 1334 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1309 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } 1335 1310 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1336 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1311 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); } 1337 1312 ; 1338 1313 … … 1348 1323 if ( $1->condition ) { 1349 1324 if ( $3->condition ) { 1350 $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr) );1325 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) ); 1351 1326 } // if 1352 1327 } else $1->condition = $3->condition; 1353 1328 if ( $1->change ) { 1354 1329 if ( $3->change ) { 1355 $1->change->expr.reset( new ast::CommaExpr( yylloc,$1->change->expr.release(), $3->change->expr.release() ) );1330 $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) ); 1356 1331 } // if 1357 1332 } else $1->change = $3->change; … … 1362 1337 for_control_expression: 1363 1338 ';' comma_expression_opt ';' comma_expression_opt 1364 { $$ = new ForCtrl( nullptr, $2, $4 ); }1339 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); } 1365 1340 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1366 { 1367 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr; 1368 $$ = new ForCtrl( init, $3, $5 ); 1369 } 1341 { $$ = new ForCtrl( $1, $3, $5 ); } 1370 1342 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1371 { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }1343 { $$ = new ForCtrl( $1, $2, $4 ); } 1372 1344 1373 1345 | '@' ';' comma_expression // CFA, empty loop-index 1374 { $$ = new ForCtrl( nullptr, $3, nullptr ); }1346 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); } 1375 1347 | '@' ';' comma_expression ';' comma_expression // CFA, empty loop-index 1376 { $$ = new ForCtrl( nullptr, $3, $5 ); }1348 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); } 1377 1349 1378 1350 | comma_expression // CFA, anonymous loop-index 1379 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }1351 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1380 1352 | downupdowneq comma_expression // CFA, anonymous loop-index 1381 { $$ = forCtrl( yylloc,$2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }1353 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1382 1354 1383 1355 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1384 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }1356 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1385 1357 | '@' updowneq comma_expression // CFA, anonymous loop-index 1386 1358 { 1387 1359 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1388 else $$ = forCtrl( yylloc,$3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );1360 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1389 1361 } 1390 1362 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1394 1366 } 1395 1367 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1396 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }1368 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1397 1369 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1398 1370 { 1399 1371 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1400 else $$ = forCtrl( yylloc,$3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );1372 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1401 1373 } 1402 1374 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1417 1389 1418 1390 | comma_expression ';' comma_expression // CFA 1419 { $$ = forCtrl( yylloc,$3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }1391 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1420 1392 | comma_expression ';' downupdowneq comma_expression // CFA 1421 { $$ = forCtrl( yylloc,$4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }1393 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1422 1394 1423 1395 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1424 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }1396 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1425 1397 | comma_expression ';' '@' updowneq comma_expression // CFA 1426 1398 { 1427 1399 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1428 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, NEW_ONE );1400 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1429 1401 } 1430 1402 | comma_expression ';' comma_expression updowneq '@' // CFA … … 1432 1404 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1433 1405 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1434 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, NEW_ONE );1406 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1435 1407 } 1436 1408 | comma_expression ';' '@' updowneq '@' // CFA, error … … 1438 1410 1439 1411 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1440 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }1412 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1441 1413 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1442 1414 { 1443 1415 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1444 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, $7 );1416 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 ); 1445 1417 } 1446 1418 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA … … 1448 1420 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1449 1421 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1450 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, $7 );1422 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 ); 1451 1423 } 1452 1424 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1453 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }1425 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1454 1426 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1455 1427 { 1456 1428 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1457 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, nullptr );1429 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr ); 1458 1430 } 1459 1431 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA … … 1461 1433 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1462 1434 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1463 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, nullptr );1435 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr ); 1464 1436 } 1465 1437 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA … … 1467 1439 1468 1440 | declaration comma_expression // CFA 1469 { $$ = forCtrl( yylloc,$1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }1441 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1470 1442 | declaration downupdowneq comma_expression // CFA 1471 { $$ = forCtrl( yylloc,$1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }1443 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1472 1444 1473 1445 | declaration comma_expression updowneq comma_expression // CFA 1474 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }1446 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1475 1447 | declaration '@' updowneq comma_expression // CFA 1476 1448 { 1477 1449 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1478 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, NEW_ONE );1450 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE ); 1479 1451 } 1480 1452 | declaration comma_expression updowneq '@' // CFA … … 1482 1454 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1483 1455 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1484 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, NEW_ONE );1456 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE ); 1485 1457 } 1486 1458 1487 1459 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1488 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }1460 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1489 1461 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1490 1462 { 1491 1463 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1492 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, $6 );1464 else $$ = forCtrl( $1, $4, $3, nullptr, $6 ); 1493 1465 } 1494 1466 | declaration comma_expression updowneq '@' '~' comma_expression // CFA … … 1496 1468 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1497 1469 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1498 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, $6 );1470 else $$ = forCtrl( $1, $2, $3, nullptr, $6 ); 1499 1471 } 1500 1472 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1501 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }1473 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1502 1474 | declaration '@' updowneq comma_expression '~' '@' // CFA 1503 1475 { 1504 1476 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1505 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, nullptr );1477 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr ); 1506 1478 } 1507 1479 | declaration comma_expression updowneq '@' '~' '@' // CFA … … 1509 1481 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1510 1482 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1511 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, nullptr );1483 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr ); 1512 1484 } 1513 1485 | declaration '@' updowneq '@' '~' '@' // CFA, error … … 1524 1496 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1525 1497 } 1526 ;1498 ; 1527 1499 1528 1500 downupdowneq: … … 1533 1505 | ErangeDownEq 1534 1506 { $$ = OperKinds::GEThan; } 1535 ;1507 ; 1536 1508 1537 1509 updown: … … 1540 1512 | ErangeDown 1541 1513 { $$ = OperKinds::GThan; } 1542 ;1514 ; 1543 1515 1544 1516 updowneq: … … 1548 1520 | ErangeDownEq 1549 1521 { $$ = OperKinds::GEThan; } 1550 ;1522 ; 1551 1523 1552 1524 jump_statement: 1553 1525 GOTO identifier_or_type_name ';' 1554 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }1526 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); } 1555 1527 | GOTO '*' comma_expression ';' // GCC, computed goto 1556 1528 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1559 1531 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1560 1532 | fall_through_name ';' // CFA 1561 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }1533 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); } 1562 1534 | fall_through_name identifier_or_type_name ';' // CFA 1563 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }1535 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); } 1564 1536 | fall_through_name DEFAULT ';' // CFA 1565 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }1537 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); } 1566 1538 | CONTINUE ';' 1567 1539 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1568 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }1540 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); } 1569 1541 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1570 1542 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1571 1543 // the target of the transfer appears only at the start of an iteration statement. 1572 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }1544 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); } 1573 1545 | BREAK ';' 1574 1546 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1575 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }1547 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); } 1576 1548 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1577 1549 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1578 1550 // the target of the transfer appears only at the start of an iteration statement. 1579 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }1551 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); } 1580 1552 | RETURN comma_expression_opt ';' 1581 { $$ = new StatementNode( build_return( yylloc,$2 ) ); }1553 { $$ = new StatementNode( build_return( $2 ) ); } 1582 1554 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1583 1555 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1584 1556 | SUSPEND ';' 1585 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None) ); }1557 { $$ = new StatementNode( build_suspend( nullptr ) ); } 1586 1558 | SUSPEND compound_statement 1587 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None) ); }1559 { $$ = new StatementNode( build_suspend( $2 ) ); } 1588 1560 | SUSPEND COROUTINE ';' 1589 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }1561 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); } 1590 1562 | SUSPEND COROUTINE compound_statement 1591 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }1563 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); } 1592 1564 | SUSPEND GENERATOR ';' 1593 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }1565 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); } 1594 1566 | SUSPEND GENERATOR compound_statement 1595 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }1567 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); } 1596 1568 | THROW assignment_expression_opt ';' // handles rethrow 1597 { $$ = new StatementNode( build_throw( yylloc,$2 ) ); }1569 { $$ = new StatementNode( build_throw( $2 ) ); } 1598 1570 | THROWRESUME assignment_expression_opt ';' // handles reresume 1599 { $$ = new StatementNode( build_resume( yylloc,$2 ) ); }1571 { $$ = new StatementNode( build_resume( $2 ) ); } 1600 1572 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1601 1573 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1609 1581 with_statement: 1610 1582 WITH '(' tuple_expression_list ')' statement 1611 { $$ = new StatementNode( build_with( yylloc,$3, $5 ) ); }1612 ; 1613 1614 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possiblychange syntax to "with mutex".1583 { $$ = new StatementNode( build_with( $3, $5 ) ); } 1584 ; 1585 1586 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex". 1615 1587 mutex_statement: 1616 MUTEX '(' argument_expression_list_opt ')' statement 1617 { 1618 if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; } 1619 $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) ); 1620 } 1588 MUTEX '(' argument_expression_list ')' statement 1589 { $$ = new StatementNode( build_mutex( $3, $5 ) ); } 1621 1590 ; 1622 1591 … … 1629 1598 { $$ = nullptr; } 1630 1599 | when_clause 1600 ; 1601 1602 waitfor: 1603 WAITFOR '(' cast_expression ')' 1604 { $$ = $3; } 1605 // | WAITFOR '(' cast_expression ',' argument_expression_list_opt ')' 1606 // { $$ = (ExpressionNode *)$3->set_last( $5 ); } 1607 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1608 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1631 1609 ; 1632 1610 … … 1639 1617 1640 1618 timeout: 1641 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1642 ; 1643 1644 wor: 1645 OROR 1646 | WOR 1647 1648 waitfor: 1649 WAITFOR '(' cast_expression ')' 1650 { $$ = $3; } 1651 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1652 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1653 ; 1654 1655 wor_waitfor_clause: 1619 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1620 ; 1621 1622 waitfor_clause: 1656 1623 when_clause_opt waitfor statement %prec THEN 1657 // Called first: create header for WaitForStmt. 1658 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1659 | wor_waitfor_clause wor when_clause_opt waitfor statement 1660 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1661 | wor_waitfor_clause wor when_clause_opt ELSE statement 1662 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); } 1663 | wor_waitfor_clause wor when_clause_opt timeout statement %prec THEN 1664 { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1624 { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1 ); } 1625 | when_clause_opt waitfor statement WOR waitfor_clause 1626 { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1, $5 ); } 1627 | when_clause_opt timeout statement %prec THEN 1628 { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1 ); } 1629 | when_clause_opt ELSE statement 1630 { $$ = build_waitfor_timeout( nullptr, maybe_build_compound( $3 ), $1 ); } 1665 1631 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1666 | w or_waitfor_clause wor when_clause_opt timeout statement worELSE statement // syntax error1632 | when_clause_opt timeout statement WOR ELSE statement // syntax error 1667 1633 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1668 | w or_waitfor_clause wor when_clause_opt timeout statement worwhen_clause ELSE statement1669 { $$ = build_waitfor_ else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 )); }1634 | when_clause_opt timeout statement WOR when_clause ELSE statement 1635 { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1, maybe_build_compound( $7 ), $5 ); } 1670 1636 ; 1671 1637 1672 1638 waitfor_statement: 1673 wor_waitfor_clause %prec THEN 1674 { $$ = new StatementNode( $1 ); } 1675 ; 1676 1677 wand: 1678 ANDAND 1679 | WAND 1680 ; 1681 1682 waituntil: 1683 WAITUNTIL '(' comma_expression ')' 1684 { $$ = $3; } 1685 ; 1686 1687 waituntil_clause: 1688 when_clause_opt waituntil statement 1689 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1690 | '(' wor_waituntil_clause ')' 1691 { $$ = $2; } 1692 ; 1693 1694 wand_waituntil_clause: 1695 waituntil_clause %prec THEN 1696 { $$ = $1; } 1697 | waituntil_clause wand wand_waituntil_clause 1698 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); } 1699 ; 1700 1701 wor_waituntil_clause: 1702 wand_waituntil_clause 1703 { $$ = $1; } 1704 | wor_waituntil_clause wor wand_waituntil_clause 1705 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); } 1706 | wor_waituntil_clause wor when_clause_opt ELSE statement 1707 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1708 | wor_waituntil_clause wor when_clause_opt timeout statement %prec THEN 1709 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); } 1710 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1711 | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1712 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1713 | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1714 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, 1715 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, 1716 build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ), 1717 build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); } 1718 ; 1719 1720 waituntil_statement: 1721 wor_waituntil_clause %prec THEN 1722 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1723 { 1724 $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) ); 1725 // $$ = new StatementNode( build_compound( yylloc, nullptr ) ); 1726 } 1639 when_clause_opt waitfor statement %prec THEN 1640 { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); } 1641 | when_clause_opt waitfor statement WOR waitfor_clause 1642 { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); } 1727 1643 ; 1728 1644 1729 1645 exception_statement: 1730 TRY compound_statement handler_clause %prec THEN1731 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr) ); }1646 TRY compound_statement handler_clause %prec THEN 1647 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); } 1732 1648 | TRY compound_statement finally_clause 1733 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }1649 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); } 1734 1650 | TRY compound_statement handler_clause finally_clause 1735 { $$ = new StatementNode( build_try( yylloc,$2, $3, $4 ) ); }1651 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); } 1736 1652 ; 1737 1653 1738 1654 handler_clause: 1739 1655 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1740 { $$ = new ClauseNode( build_catch( yylloc,$1, $4, $6, $8 ) ); }1656 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1741 1657 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1742 { $$ = $1->set_last( new ClauseNode( build_catch( yylloc,$2, $5, $7, $9 ) ) ); }1658 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1743 1659 ; 1744 1660 … … 1750 1666 1751 1667 handler_key: 1752 CATCH { $$ = ast::Terminate; }1753 | RECOVER { $$ = ast::Terminate; }1754 | CATCHRESUME { $$ = ast::Resume; }1755 | FIXUP { $$ = ast::Resume; }1668 CATCH { $$ = CatchStmt::Terminate; } 1669 | RECOVER { $$ = CatchStmt::Terminate; } 1670 | CATCHRESUME { $$ = CatchStmt::Resume; } 1671 | FIXUP { $$ = CatchStmt::Resume; } 1756 1672 ; 1757 1673 1758 1674 finally_clause: 1759 FINALLY compound_statement { $$ = new ClauseNode( build_finally( yylloc,$2 ) ); }1675 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); } 1760 1676 ; 1761 1677 … … 1783 1699 asm_statement: 1784 1700 ASM asm_volatile_opt '(' string_literal ')' ';' 1785 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr) ); }1701 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); } 1786 1702 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1787 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6 ) ); }1703 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); } 1788 1704 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1789 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8 ) ); }1705 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); } 1790 1706 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1791 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8, $10 ) ); }1707 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); } 1792 1708 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1793 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }1709 { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); } 1794 1710 ; 1795 1711 … … 1815 1731 asm_operand: // GCC 1816 1732 string_literal '(' constant_expression ')' 1817 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1733 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); } 1818 1734 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1819 { 1820 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) ); 1821 delete $2.str; 1822 } 1735 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); } 1823 1736 ; 1824 1737 … … 1827 1740 { $$ = nullptr; } // use default argument 1828 1741 | string_literal 1829 { $$ = $1; }1742 { $$ = new ExpressionNode( $1 ); } 1830 1743 | asm_clobbers_list_opt ',' string_literal 1831 { $$ = (ExpressionNode *)( $1->set_last( $3 )); }1744 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); } 1832 1745 ; 1833 1746 … … 1835 1748 identifier 1836 1749 { 1837 $$ = new LabelNode(); $$->labels. emplace_back( yylloc,*$1 );1750 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1838 1751 delete $1; // allocated by lexer 1839 1752 } 1840 1753 | label_list ',' identifier 1841 1754 { 1842 $$ = $1; $1->labels. emplace_back( yylloc,*$3 );1755 $$ = $1; $1->labels.push_back( *$3 ); 1843 1756 delete $3; // allocated by lexer 1844 1757 } … … 1891 1804 { 1892 1805 // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" ); 1893 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {1806 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 1894 1807 // printf( "\tattr %s\n", attr->name.c_str() ); 1895 1808 // } // for … … 1901 1814 static_assert: 1902 1815 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1903 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 )); }1816 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1904 1817 | STATICASSERT '(' constant_expression ')' ';' // CFA 1905 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc,*new string( "\"\"" ) ) ); }1818 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); } 1906 1819 1907 1820 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 1967 1880 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 1968 1881 // { 1969 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );1882 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true ); 1970 1883 // } 1971 1884 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 1972 1885 // { 1973 1886 // typedefTable.setNextIdentifier( *$5 ); 1974 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1887 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1975 1888 // } 1976 1889 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 1977 1890 // { 1978 1891 // typedefTable.setNextIdentifier( *$5 ); 1979 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1892 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1980 1893 // } 1981 1894 // | '[' ']' typegen_name … … 1989 1902 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1990 1903 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 1991 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1904 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1992 1905 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1993 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1906 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1994 1907 ; 1995 1908 … … 2027 1940 { 2028 1941 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 2029 if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) { 2030 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr; 2031 } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1942 $$ = $3->addType( $2 )->addTypedef(); 2032 1943 } 2033 1944 | typedef_declaration pop ',' push declarator … … 2037 1948 } 2038 1949 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 2039 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1950 { 1951 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" ); 1952 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef(); 1953 } 2040 1954 | type_specifier TYPEDEF declarator 2041 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1955 { 1956 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" ); 1957 $$ = $3->addType( $1 )->addTypedef(); 1958 } 2042 1959 | type_specifier TYPEDEF type_qualifier_list declarator 2043 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1960 { 1961 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" ); 1962 $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 ); 1963 } 2044 1964 ; 2045 1965 … … 2048 1968 TYPEDEF identifier '=' assignment_expression 2049 1969 { 2050 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1970 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2051 1971 } 2052 1972 | typedef_expression pop ',' push identifier '=' assignment_expression 2053 1973 { 2054 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1974 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2055 1975 } 2056 1976 ; … … 2062 1982 | typedef_expression // deprecated GCC, naming expression type 2063 1983 | sue_declaration_specifier 2064 {2065 assert( $1->type );2066 if ( $1->type->qualifiers.any() ) { // CV qualifiers ?2067 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;2068 }2069 // enums are never empty declarations because there must have at least one enumeration.2070 if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?2071 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;2072 }2073 }2074 1984 ; 2075 1985 … … 2077 1987 // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 2078 1988 // storage-class 2079 variable_declarator asm_name_opt initializer_opt1989 declarator asm_name_opt initializer_opt 2080 1990 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2081 | variable_type_redeclarator asm_name_opt initializer_opt2082 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }2083 2084 | general_function_declarator asm_name_opt2085 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }2086 | general_function_declarator asm_name_opt '=' VOID2087 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }2088 2089 1991 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 2090 1992 { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 2091 1993 ; 2092 1994 2093 general_function_declarator:2094 function_type_redeclarator2095 | function_declarator2096 ;2097 2098 1995 declaration_specifier: // type specifier + storage class 2099 1996 basic_declaration_specifier 1997 | sue_declaration_specifier 2100 1998 | type_declaration_specifier 2101 | sue_declaration_specifier2102 | sue_declaration_specifier invalid_types2103 {2104 SemanticError( yylloc, ::toString( "Missing ';' after end of ",2105 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),2106 " declaration" ) );2107 $$ = nullptr;2108 }2109 ;2110 2111 invalid_types:2112 aggregate_key2113 | basic_type_name2114 | indirect_type2115 1999 ; 2116 2000 … … 2129 2013 basic_type_specifier 2130 2014 | sue_type_specifier 2015 { 2016 // printf( "sue_type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2017 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2018 // printf( "\tattr %s\n", attr->name.c_str() ); 2019 // } // for 2020 } 2131 2021 | type_type_specifier 2132 2022 ; … … 2175 2065 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } 2176 2066 | forall 2177 { $$ = DeclarationNode::newForall( $1 ); }2178 2067 ; 2179 2068 2180 2069 forall: 2181 2070 FORALL '(' type_parameter_list ')' // CFA 2182 { $$ = $3; }2071 { $$ = DeclarationNode::newForall( $3 ); } 2183 2072 ; 2184 2073 … … 2337 2226 { $$ = DeclarationNode::newTypeof( $3 ); } 2338 2227 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2339 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ), true ); }2228 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 2340 2229 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2341 2230 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2350 2239 { 2351 2240 // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2352 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2241 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2353 2242 // printf( "\tattr %s\n", attr->name.c_str() ); 2354 2243 // } // for … … 2366 2255 { 2367 2256 // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2368 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2257 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2369 2258 // printf( "\tattr %s\n", attr->name.c_str() ); 2370 2259 // } // for … … 2444 2333 { 2445 2334 // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2446 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2335 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2447 2336 // printf( "\tattr %s\n", attr->name.c_str() ); 2448 2337 // } // for … … 2468 2357 '{' field_declaration_list_opt '}' type_parameters_opt 2469 2358 { 2359 // printf( "aggregate_type1 %s\n", $3.str->c_str() ); 2360 // if ( $2 ) 2361 // for ( Attribute * attr: reverseIterate( $2->attributes ) ) { 2362 // printf( "copySpecifiers12 %s\n", attr->name.c_str() ); 2363 // } // for 2470 2364 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); 2365 // printf( "aggregate_type2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2366 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2367 // printf( "aggregate_type3 %s\n", attr->name.c_str() ); 2368 // } // for 2471 2369 } 2472 2370 | aggregate_key attribute_list_opt TYPEDEFname // unqualified type name … … 2477 2375 '{' field_declaration_list_opt '}' type_parameters_opt 2478 2376 { 2377 // printf( "AGG3\n" ); 2479 2378 DeclarationNode::newFromTypedef( $3 ); 2480 2379 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2487 2386 '{' field_declaration_list_opt '}' type_parameters_opt 2488 2387 { 2388 // printf( "AGG4\n" ); 2489 2389 DeclarationNode::newFromTypeGen( $3, nullptr ); 2490 2390 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2513 2413 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 2514 2414 // delete newFromTypeGen. 2515 if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) { 2516 $$ = $3->addQualifiers( $2 ); 2517 } else { 2518 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2519 $3->type->symbolic.name = nullptr; // copied to $$ 2520 $3->type->symbolic.actuals = nullptr; 2521 delete $3; 2522 } 2415 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2416 $3->type->symbolic.name = nullptr; 2417 $3->type->symbolic.actuals = nullptr; 2418 delete $3; 2523 2419 } 2524 2420 ; … … 2531 2427 aggregate_data: 2532 2428 STRUCT vtable_opt 2533 { $$ = ast::AggregateDecl::Struct; }2429 { $$ = AggregateDecl::Struct; } 2534 2430 | UNION 2535 { $$ = ast::AggregateDecl::Union; }2431 { $$ = AggregateDecl::Union; } 2536 2432 | EXCEPTION // CFA 2537 { $$ = ast::AggregateDecl::Exception; }2538 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }2433 { $$ = AggregateDecl::Exception; } 2434 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2539 2435 ; 2540 2436 2541 2437 aggregate_control: // CFA 2542 2438 MONITOR 2543 { $$ = ast::AggregateDecl::Monitor; }2439 { $$ = AggregateDecl::Monitor; } 2544 2440 | MUTEX STRUCT 2545 { $$ = ast::AggregateDecl::Monitor; }2441 { $$ = AggregateDecl::Monitor; } 2546 2442 | GENERATOR 2547 { $$ = ast::AggregateDecl::Generator; }2443 { $$ = AggregateDecl::Generator; } 2548 2444 | MUTEX GENERATOR 2549 { 2550 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2551 $$ = ast::AggregateDecl::NoAggregate; 2552 } 2445 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2553 2446 | COROUTINE 2554 { $$ = ast::AggregateDecl::Coroutine; }2447 { $$ = AggregateDecl::Coroutine; } 2555 2448 | MUTEX COROUTINE 2556 { 2557 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2558 $$ = ast::AggregateDecl::NoAggregate; 2559 } 2449 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2560 2450 | THREAD 2561 { $$ = ast::AggregateDecl::Thread; }2451 { $$ = AggregateDecl::Thread; } 2562 2452 | MUTEX THREAD 2563 { 2564 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2565 $$ = ast::AggregateDecl::NoAggregate; 2566 } 2453 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2567 2454 ; 2568 2455 … … 2580 2467 $$ = fieldDecl( $1, $2 ); 2581 2468 // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2582 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2469 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2583 2470 // printf( "\tattr %s\n", attr->name.c_str() ); 2584 2471 // } // for … … 2586 2473 | EXTENSION type_specifier field_declaring_list_opt ';' // GCC 2587 2474 { $$ = fieldDecl( $2, $3 ); distExt( $$ ); } 2588 | STATIC type_specifier field_declaring_list_opt ';' // CFA2589 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }2590 2475 | INLINE type_specifier field_abstract_list_opt ';' // CFA 2591 2476 { … … 2598 2483 } 2599 2484 | INLINE aggregate_control ';' // CFA 2600 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }2485 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; } 2601 2486 | typedef_declaration ';' // CFA 2602 2487 | cfa_field_declaring_list ';' // CFA, new style field declaration … … 2624 2509 { $$ = $1->addBitfield( $2 ); } 2625 2510 | variable_type_redeclarator bit_subrange_size_opt 2626 // A semantic check is required to ensure bit_subrange only appears on integral types.2627 { $$ = $1->addBitfield( $2 ); }2628 | function_type_redeclarator bit_subrange_size_opt2629 2511 // A semantic check is required to ensure bit_subrange only appears on integral types. 2630 2512 { $$ = $1->addBitfield( $2 ); } … … 2681 2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2682 2564 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2683 {2684 if ( $3->storageClasses.val != 0 || $3->type->qualifiers. any())2565 { 2566 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) 2685 2567 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2686 2568 … … 2693 2575 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2694 2576 { 2695 if ( $3->storageClasses. any()|| $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }2577 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2696 2578 typedefTable.makeTypedef( *$6 ); 2697 2579 } … … 2727 2609 enum_type_nobody: // enum - {...} 2728 2610 ENUM attribute_list_opt identifier 2729 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }2611 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); } 2730 2612 | ENUM attribute_list_opt type_name 2731 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }2613 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); } 2732 2614 ; 2733 2615 … … 2869 2751 type_no_function: // sizeof, alignof, cast (constructor) 2870 2752 cfa_abstract_declarator_tuple // CFA 2871 | type_specifier // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing2753 | type_specifier 2872 2754 | type_specifier abstract_declarator 2873 2755 { $$ = $2->addType( $1 ); } … … 2914 2796 designator_list ':' // C99, CFA uses ":" instead of "=" 2915 2797 | identifier_at ':' // GCC, field name 2916 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }2798 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2917 2799 ; 2918 2800 … … 2926 2808 designator: 2927 2809 '.' identifier_at // C99, field name 2928 { $$ = new ExpressionNode( build_varref( yylloc,$2 ) ); }2810 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2929 2811 | '[' push assignment_expression pop ']' // C99, single array element 2930 2812 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2933 2815 { $$ = $3; } 2934 2816 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2935 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }2817 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); } 2936 2818 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2937 2819 { $$ = $4; } … … 2973 2855 { 2974 2856 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2975 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2976 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2977 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2857 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2858 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2859 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2978 2860 } 2979 2861 type_initializer_opt assertion_list_opt … … 2986 2868 { 2987 2869 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2988 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );2870 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 ); 2989 2871 } 2990 2872 // | type_specifier identifier_parameter_declarator 2991 2873 | assertion_list 2992 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2874 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2993 2875 ; 2994 2876 2995 2877 new_type_class: // CFA 2996 2878 // empty 2997 { $$ = ast::TypeDecl::Otype; }2879 { $$ = TypeDecl::Otype; } 2998 2880 | '&' 2999 { $$ = ast::TypeDecl::Dtype; }2881 { $$ = TypeDecl::Dtype; } 3000 2882 | '*' 3001 { $$ = ast::TypeDecl::DStype; } // dtype + sized2883 { $$ = TypeDecl::DStype; } // dtype + sized 3002 2884 // | '(' '*' ')' 3003 // { $$ = ast::TypeDecl::Ftype; }2885 // { $$ = TypeDecl::Ftype; } 3004 2886 | ELLIPSIS 3005 { $$ = ast::TypeDecl::Ttype; }2887 { $$ = TypeDecl::Ttype; } 3006 2888 ; 3007 2889 3008 2890 type_class: // CFA 3009 2891 OTYPE 3010 { $$ = ast::TypeDecl::Otype; }2892 { $$ = TypeDecl::Otype; } 3011 2893 | DTYPE 3012 { $$ = ast::TypeDecl::Dtype; }2894 { $$ = TypeDecl::Dtype; } 3013 2895 | FTYPE 3014 { $$ = ast::TypeDecl::Ftype; }2896 { $$ = TypeDecl::Ftype; } 3015 2897 | TTYPE 3016 { $$ = ast::TypeDecl::Ttype; }2898 { $$ = TypeDecl::Ttype; } 3017 2899 ; 3018 2900 … … 3040 2922 type_list: // CFA 3041 2923 type 3042 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }2924 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3043 2925 | assignment_expression 3044 2926 | type_list ',' type 3045 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }2927 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3046 2928 | type_list ',' assignment_expression 3047 2929 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3068 2950 { 3069 2951 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 3070 $$ = DeclarationNode::newTypeDecl( $1, nullptr);2952 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 3071 2953 } 3072 2954 | identifier_or_type_name '(' type_parameter_list ')' … … 3079 2961 trait_specifier: // CFA 3080 2962 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 3081 { 3082 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3083 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 3084 } 3085 | forall TRAIT identifier_or_type_name '{' '}' // alternate 3086 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); } 2963 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 3087 2964 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 3088 { 3089 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3090 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 3091 } 3092 | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 3093 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); } 2965 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 3094 2966 ; 3095 2967 … … 3150 3022 external_definition: 3151 3023 DIRECTIVE 3152 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc,$1 ) ) ); }3024 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 3153 3025 | declaration 3154 {3155 // Variable declarations of anonymous types requires creating a unique type-name across multiple translation3156 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is3157 // disallowed at the moment.3158 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {3159 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {3160 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;3161 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union3162 SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;3163 }3164 }3165 }3166 3026 | IDENTIFIER IDENTIFIER 3167 3027 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } … … 3183 3043 } 3184 3044 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3185 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr) ) ); }3045 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); } 3186 3046 | EXTERN STRINGliteral 3187 3047 { 3188 3048 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3189 linkage = ast::Linkage::update( yylloc, linkage, $2 );3049 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3190 3050 } 3191 3051 up external_definition down … … 3198 3058 { 3199 3059 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3200 linkage = ast::Linkage::update( yylloc, linkage, $2 );3060 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3201 3061 } 3202 3062 '{' up external_definition_list_opt down '}' … … 3209 3069 | type_qualifier_list 3210 3070 { 3211 if ( $1->type->qualifiers. any()) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3071 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3212 3072 if ( $1->type->forall ) forall = true; // remember generic type 3213 3073 } … … 3215 3075 { 3216 3076 distQual( $5, $1 ); 3217 forall = false;3077 forall = false; 3218 3078 $$ = $5; 3219 3079 } 3220 3080 | declaration_qualifier_list 3221 3081 { 3222 if ( $1->type && $1->type->qualifiers. any()) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3082 if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3223 3083 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 3224 3084 } … … 3226 3086 { 3227 3087 distQual( $5, $1 ); 3228 forall = false;3088 forall = false; 3229 3089 $$ = $5; 3230 3090 } 3231 3091 | declaration_qualifier_list type_qualifier_list 3232 3092 { 3233 if ( ($1->type && $1->type->qualifiers. any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3093 if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3234 3094 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3235 3095 } … … 3237 3097 { 3238 3098 distQual( $6, $1->addQualifiers( $2 ) ); 3239 forall = false;3099 forall = false; 3240 3100 $$ = $6; 3241 3101 } … … 3281 3141 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 3282 3142 } 3283 | declaration_specifier function_type_redeclarator with_clause_opt compound_statement3143 | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement 3284 3144 { 3285 3145 rebindForall( $1, $2 ); … … 3317 3177 | variable_type_redeclarator 3318 3178 | function_declarator 3319 | function_type_redeclarator3320 3179 ; 3321 3180 3322 3181 subrange: 3323 3182 constant_expression '~' constant_expression // CFA, integer subrange 3324 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }3183 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 3325 3184 ; 3326 3185 … … 3331 3190 { 3332 3191 DeclarationNode * name = new DeclarationNode(); 3333 name->asmName = maybeMoveBuild( $3 );3192 name->asmName = $3; 3334 3193 $$ = name->addQualifiers( $5 ); 3335 3194 } … … 3428 3287 variable_ptr: 3429 3288 ptrref_operator variable_declarator 3430 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3289 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3431 3290 | ptrref_operator type_qualifier_list variable_declarator 3432 3291 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3444 3303 | '(' attribute_list variable_ptr ')' array_dimension 3445 3304 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3446 | '(' variable_array ')' multi_array_dimension // redundant parenthesis3305 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 3447 3306 { $$ = $2->addArray( $4 ); } 3448 3307 | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis … … 3492 3351 function_ptr: 3493 3352 ptrref_operator function_declarator 3494 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3353 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3495 3354 | ptrref_operator type_qualifier_list function_declarator 3496 3355 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3544 3403 KR_function_ptr: 3545 3404 ptrref_operator KR_function_declarator 3546 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3405 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3547 3406 | ptrref_operator type_qualifier_list KR_function_declarator 3548 3407 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3568 3427 ; 3569 3428 3570 // This pattern parses a declaration for a variable that redefines a type name, e.g.:3429 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.: 3571 3430 // 3572 3431 // typedef int foo; … … 3574 3433 // int foo; // redefine typedef name in new scope 3575 3434 // } 3435 // 3436 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 3437 // and functions versus pointers to arrays and functions. 3576 3438 3577 3439 paren_type: … … 3588 3450 paren_type attribute_list_opt 3589 3451 { $$ = $1->addQualifiers( $2 ); } 3590 | variable_type_ptr3591 | variable_type_array attribute_list_opt3452 | type_ptr 3453 | type_array attribute_list_opt 3592 3454 { $$ = $1->addQualifiers( $2 ); } 3593 | variable_type_function attribute_list_opt3455 | type_function attribute_list_opt 3594 3456 { $$ = $1->addQualifiers( $2 ); } 3595 3457 ; 3596 3458 3597 variable_type_ptr:3459 type_ptr: 3598 3460 ptrref_operator variable_type_redeclarator 3599 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3461 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3600 3462 | ptrref_operator type_qualifier_list variable_type_redeclarator 3601 3463 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3602 | '(' variable_type_ptr ')' attribute_list_opt// redundant parenthesis3464 | '(' type_ptr ')' attribute_list_opt // redundant parenthesis 3603 3465 { $$ = $2->addQualifiers( $4 ); } 3604 | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis3466 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis 3605 3467 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3606 3468 ; 3607 3469 3608 variable_type_array:3470 type_array: 3609 3471 paren_type array_dimension 3610 3472 { $$ = $1->addArray( $2 ); } 3611 | '(' variable_type_ptr ')' array_dimension3473 | '(' type_ptr ')' array_dimension 3612 3474 { $$ = $2->addArray( $4 ); } 3613 | '(' attribute_list variable_type_ptr ')' array_dimension3475 | '(' attribute_list type_ptr ')' array_dimension 3614 3476 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3615 | '(' variable_type_array ')' multi_array_dimension// redundant parenthesis3477 | '(' type_array ')' multi_array_dimension // redundant parenthesis 3616 3478 { $$ = $2->addArray( $4 ); } 3617 | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis3479 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis 3618 3480 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3619 | '(' variable_type_array ')'// redundant parenthesis3481 | '(' type_array ')' // redundant parenthesis 3620 3482 { $$ = $2; } 3621 | '(' attribute_list variable_type_array ')'// redundant parenthesis3483 | '(' attribute_list type_array ')' // redundant parenthesis 3622 3484 { $$ = $3->addQualifiers( $2 ); } 3623 3485 ; 3624 3486 3625 variable_type_function: 3626 '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3627 { $$ = $2->addParamList( $6 ); } 3628 | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3629 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3630 | '(' variable_type_function ')' // redundant parenthesis 3631 { $$ = $2; } 3632 | '(' attribute_list variable_type_function ')' // redundant parenthesis 3633 { $$ = $3->addQualifiers( $2 ); } 3634 ; 3635 3636 // This pattern parses a declaration for a function prototype that redefines a type name. It precludes declaring an 3637 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to 3638 // arrays and functions. 3639 3640 function_type_redeclarator: 3641 function_type_no_ptr attribute_list_opt 3642 { $$ = $1->addQualifiers( $2 ); } 3643 | function_type_ptr 3644 | function_type_array attribute_list_opt 3645 { $$ = $1->addQualifiers( $2 ); } 3646 ; 3647 3648 function_type_no_ptr: 3487 type_function: 3649 3488 paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3650 3489 { $$ = $1->addParamList( $4 ); } 3651 | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3490 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3652 3491 { $$ = $2->addParamList( $6 ); } 3653 | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3492 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3654 3493 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3655 | '(' function_type_no_ptr ')'// redundant parenthesis3494 | '(' type_function ')' // redundant parenthesis 3656 3495 { $$ = $2; } 3657 | '(' attribute_list function_type_no_ptr ')' // redundant parenthesis 3658 { $$ = $3->addQualifiers( $2 ); } 3659 ; 3660 3661 function_type_ptr: 3662 ptrref_operator function_type_redeclarator 3663 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3664 | ptrref_operator type_qualifier_list function_type_redeclarator 3665 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3666 | '(' function_type_ptr ')' attribute_list_opt 3667 { $$ = $2->addQualifiers( $4 ); } 3668 | '(' attribute_list function_type_ptr ')' attribute_list_opt 3669 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3670 ; 3671 3672 function_type_array: 3673 '(' function_type_ptr ')' array_dimension 3674 { $$ = $2->addArray( $4 ); } 3675 | '(' attribute_list function_type_ptr ')' array_dimension 3676 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3677 | '(' function_type_array ')' multi_array_dimension // redundant parenthesis 3678 { $$ = $2->addArray( $4 ); } 3679 | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis 3680 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3681 | '(' function_type_array ')' // redundant parenthesis 3682 { $$ = $2; } 3683 | '(' attribute_list function_type_array ')' // redundant parenthesis 3496 | '(' attribute_list type_function ')' // redundant parenthesis 3684 3497 { $$ = $3->addQualifiers( $2 ); } 3685 3498 ; … … 3704 3517 identifier_parameter_ptr: 3705 3518 ptrref_operator identifier_parameter_declarator 3706 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3519 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3707 3520 | ptrref_operator type_qualifier_list identifier_parameter_declarator 3708 3521 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3761 3574 type_parameter_ptr: 3762 3575 ptrref_operator type_parameter_redeclarator 3763 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3576 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3764 3577 | ptrref_operator type_qualifier_list type_parameter_redeclarator 3765 3578 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3804 3617 abstract_ptr: 3805 3618 ptrref_operator 3806 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3619 { $$ = DeclarationNode::newPointer( 0, $1 ); } 3807 3620 | ptrref_operator type_qualifier_list 3808 3621 { $$ = DeclarationNode::newPointer( $2, $1 ); } 3809 3622 | ptrref_operator abstract_declarator 3810 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3623 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3811 3624 | ptrref_operator type_qualifier_list abstract_declarator 3812 3625 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3837 3650 // Only the first dimension can be empty. 3838 3651 '[' ']' 3839 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3652 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3840 3653 | '[' ']' multi_array_dimension 3841 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }3654 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); } 3842 3655 // Cannot use constant_expression because of tuples => semantic check 3843 3656 | '[' push assignment_expression pop ',' comma_expression ']' // CFA 3844 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }3657 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); } 3845 3658 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3846 3659 | '[' push array_type_list pop ']' // CFA … … 3851 3664 array_type_list: 3852 3665 basic_type_name 3853 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3666 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3854 3667 | type_name 3855 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3668 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3856 3669 | assignment_expression upupeq assignment_expression 3857 3670 | array_type_list ',' basic_type_name 3858 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3859 | array_type_list ',' type_name 3860 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3671 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3672 | array_type_list ',' type_name 3673 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3861 3674 | array_type_list ',' assignment_expression upupeq assignment_expression 3862 3675 ; … … 3867 3680 | ErangeUpEq 3868 3681 { $$ = OperKinds::LEThan; } 3869 ;3682 ; 3870 3683 3871 3684 multi_array_dimension: 3872 3685 '[' push assignment_expression pop ']' 3873 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }3686 { $$ = DeclarationNode::newArray( $3, 0, false ); } 3874 3687 | '[' push '*' pop ']' // C99 3875 3688 { $$ = DeclarationNode::newVarArray( 0 ); } 3876 3689 | multi_array_dimension '[' push assignment_expression pop ']' 3877 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }3690 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 3878 3691 | multi_array_dimension '[' push '*' pop ']' // C99 3879 3692 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } … … 3972 3785 array_parameter_1st_dimension: 3973 3786 '[' ']' 3974 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3787 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3975 3788 // multi_array_dimension handles the '[' '*' ']' case 3976 3789 | '[' push type_qualifier_list '*' pop ']' // remaining C99 3977 3790 { $$ = DeclarationNode::newVarArray( $3 ); } 3978 3791 | '[' push type_qualifier_list pop ']' 3979 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }3792 { $$ = DeclarationNode::newArray( 0, $3, false ); } 3980 3793 // multi_array_dimension handles the '[' assignment_expression ']' case 3981 3794 | '[' push type_qualifier_list assignment_expression pop ']' … … 4006 3819 variable_abstract_ptr: 4007 3820 ptrref_operator 4008 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3821 { $$ = DeclarationNode::newPointer( 0, $1 ); } 4009 3822 | ptrref_operator type_qualifier_list 4010 3823 { $$ = DeclarationNode::newPointer( $2, $1 ); } 4011 3824 | ptrref_operator variable_abstract_declarator 4012 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3825 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4013 3826 | ptrref_operator type_qualifier_list variable_abstract_declarator 4014 3827 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 4052 3865 // No SUE declaration in parameter list. 4053 3866 ptrref_operator type_specifier_nobody 4054 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3867 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4055 3868 | type_qualifier_list ptrref_operator type_specifier_nobody 4056 3869 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4057 3870 | ptrref_operator cfa_abstract_function 4058 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3871 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4059 3872 | type_qualifier_list ptrref_operator cfa_abstract_function 4060 3873 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4061 3874 | ptrref_operator cfa_identifier_parameter_declarator_tuple 4062 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3875 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4063 3876 | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple 4064 3877 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } … … 4069 3882 // shift/reduce conflict with new-style empty (void) function return type. 4070 3883 '[' ']' type_specifier_nobody 4071 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3884 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4072 3885 | cfa_array_parameter_1st_dimension type_specifier_nobody 4073 3886 { $$ = $2->addNewArray( $1 ); } 4074 3887 | '[' ']' multi_array_dimension type_specifier_nobody 4075 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3888 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4076 3889 | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody 4077 3890 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4080 3893 4081 3894 | '[' ']' cfa_identifier_parameter_ptr 4082 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3895 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4083 3896 | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr 4084 3897 { $$ = $2->addNewArray( $1 ); } 4085 3898 | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr 4086 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3899 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4087 3900 | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr 4088 3901 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4140 3953 cfa_abstract_ptr: // CFA 4141 3954 ptrref_operator type_specifier 4142 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3955 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4143 3956 | type_qualifier_list ptrref_operator type_specifier 4144 3957 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4145 3958 | ptrref_operator cfa_abstract_function 4146 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3959 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4147 3960 | type_qualifier_list ptrref_operator cfa_abstract_function 4148 3961 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4149 3962 | ptrref_operator cfa_abstract_declarator_tuple 4150 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3963 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4151 3964 | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple 4152 3965 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } -
src/Parser/parserutility.cc
r24d6572 r34b4268 10 10 // Created On : Sat May 16 15:30:39 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Mar 1 10:42:00 202313 // Update Count : 912 // Last Modified On : Tus Jul 18 10:12:00 2017 13 // Update Count : 8 14 14 // 15 15 … … 19 19 #include <string> // for string 20 20 21 #include "AST/Expr.hpp" // for UntypedExpr, CastExpr, ConstantExpr 22 #include "AST/Type.hpp" // for BasicType, ZeroType, BasicType::Kind... 21 #include "SynTree/Constant.h" // for Constant 22 #include "SynTree/Expression.h" // for UntypedExpr, CastExpr, ConstantExpr 23 #include "SynTree/Type.h" // for BasicType, ZeroType, BasicType::Kind... 23 24 24 25 // rewrite … … 27 28 // if ( (int)(x != 0) ) ... 28 29 29 ast::Expr * notZeroExpr( ast::Expr * orig ) { 30 return ( !orig ) ? nullptr : new ast::CastExpr( orig->location, 31 ast::UntypedExpr::createCall( orig->location, 32 "?!=?", 33 { 34 orig, 35 new ast::ConstantExpr( orig->location, 36 new ast::ZeroType(), 37 "0", 38 std::optional<unsigned long long>( 0 ) 39 ), 40 } 41 ), 42 new ast::BasicType( ast::BasicType::SignedInt ) 43 ); 30 Expression *notZeroExpr( Expression *orig ) { 31 if( !orig ) return nullptr; 32 UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) ); 33 comparison->get_args().push_back( orig ); 34 comparison->get_args().push_back( new ConstantExpr( Constant( new ZeroType( noQualifiers ), "0", (unsigned long long int)0 ) ) ); 35 return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 44 36 } 45 37 -
src/Parser/parserutility.h
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // parserutility.h -- Collected utilities for the parser.7 // parserutility.h -- 8 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:31:46 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Apr 4 14:03:00 202313 // Update Count : 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:32:58 2017 13 // Update Count : 4 14 14 // 15 15 16 16 #pragma once 17 17 18 #include "AST/Copy.hpp" // for shallowCopy 19 namespace ast { 20 class Expr; 21 } 18 class Expression; 22 19 23 ast::Expr * notZeroExpr( ast::Expr *orig ); 24 25 template< typename T > 26 static inline auto maybeBuild( T * orig ) -> decltype(orig->build()) { 27 return (orig) ? orig->build() : nullptr; 28 } 29 30 template< typename T > 31 static inline auto maybeMoveBuild( T * orig ) -> decltype(orig->build()) { 32 auto ret = maybeBuild<T>(orig); 33 delete orig; 34 return ret; 35 } 36 37 template<typename node_t> 38 node_t * maybeCopy( node_t const * node ) { 39 return node ? ast::shallowCopy( node ) : nullptr; 40 } 20 Expression *notZeroExpr( Expression *orig ); 41 21 42 22 // Local Variables: // -
src/ResolvExpr/AlternativeFinder.cc
r24d6572 r34b4268 14 14 // 15 15 16 #include "AlternativeFinder.h"17 18 16 #include <algorithm> // for copy 19 17 #include <cassert> // for strict_dynamic_cast, assert, assertf … … 28 26 29 27 #include "CompilationState.h" // for resolvep 30 #include "AdjustExprType.hpp" // for adjustExprType31 28 #include "Alternative.h" // for AltList, Alternative 29 #include "AlternativeFinder.h" 32 30 #include "AST/Expr.hpp" 33 31 #include "AST/SymbolTable.hpp" 34 32 #include "AST/Type.hpp" 35 #include "CastCost.hpp" // for castCost36 33 #include "Common/SemanticError.h" // for SemanticError 37 34 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 38 #include "ConversionCost.h" // for conversionCost39 35 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 40 36 #include "ExplodedActual.h" // for ExplodedActual 41 37 #include "InitTweak/InitTweak.h" // for getFunctionName 42 #include "PolyCost.hpp" // for polyCost43 38 #include "RenameVars.h" // for RenameVars, global_renamer 44 39 #include "ResolveAssertions.h" // for resolveAssertions 45 40 #include "ResolveTypeof.h" // for resolveTypeof 46 41 #include "Resolver.h" // for resolveStmtExpr 47 #include "SpecCost.hpp" // for specCost48 42 #include "SymTab/Indexer.h" // for Indexer 49 43 #include "SymTab/Mangler.h" // for Mangler … … 57 51 #include "Tuples/Explode.h" // for explode 58 52 #include "Tuples/Tuples.h" // for isTtype, handleTupleAssignment 59 #include "typeops.h" // for combos60 53 #include "Unify.h" // for unify 54 #include "typeops.h" // for adjustExprType, polyCost, castCost 61 55 62 56 #define PRINT( text ) if ( resolvep ) { text } -
src/ResolvExpr/AlternativeFinder.h
r24d6572 r34b4268 34 34 namespace ResolvExpr { 35 35 struct ArgPack; 36 37 Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,38 const SymTab::Indexer & indexer, const TypeEnvironment & env );39 40 void referenceToRvalueConversion( Expression *& expr, Cost & cost );41 36 42 37 /// First index is which argument, second index is which alternative for that argument, -
src/ResolvExpr/Candidate.cpp
r24d6572 r34b4268 17 17 18 18 #include <iostream> 19 #include <sstream>20 19 21 20 #include "AST/Print.hpp" … … 45 44 sorted.reserve(cands.size()); 46 45 for(const auto & c : cands) { 47 std:: ostringstream ss;46 std::stringstream ss; 48 47 print( ss, *c, indent ); 49 48 sorted.push_back(ss.str()); -
src/ResolvExpr/CandidateFinder.cpp
r24d6572 r34b4268 23 23 #include <vector> 24 24 25 #include "AdjustExprType.hpp"26 25 #include "Candidate.hpp" 27 26 #include "CompilationState.h" 28 27 #include "Cost.h" 29 #include "CastCost.hpp"30 #include "PolyCost.hpp"31 #include "SpecCost.hpp"32 #include "ConversionCost.h"33 28 #include "ExplodedArg.hpp" 34 29 #include "RenameVars.h" // for renameTyVars … … 408 403 unify( 409 404 ttype, argType, newResult.env, newResult.need, newResult.have, 410 newResult.open )405 newResult.open, symtab ) 411 406 ) { 412 407 finalResults.emplace_back( std::move( newResult ) ); … … 479 474 ) 480 475 481 if ( unify( paramType, argType, env, need, have, open ) ) {476 if ( unify( paramType, argType, env, need, have, open, symtab ) ) { 482 477 unsigned nextExpl = results[i].nextExpl + 1; 483 478 if ( nextExpl == expl.exprs.size() ) { nextExpl = 0; } … … 498 493 ast::OpenVarSet open = results[i].open; 499 494 500 if ( unify( paramType, cnst->result, env, need, have, open ) ) {495 if ( unify( paramType, cnst->result, env, need, have, open, symtab ) ) { 501 496 results.emplace_back( 502 497 i, new ast::DefaultArgExpr{ cnst->location, cnst }, std::move( env ), … … 541 536 542 537 // attempt to unify types 543 if ( unify( paramType, argType, env, need, have, open ) ) {538 if ( unify( paramType, argType, env, need, have, open, symtab ) ) { 544 539 // add new result 545 540 results.emplace_back( … … 708 703 if ( selfFinder.strictMode ) { 709 704 if ( ! unifyExact( 710 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, noWiden() ) // xxx - is no widening correct?705 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, noWiden(), symtab ) // xxx - is no widening correct? 711 706 ) { 712 707 // unification failed, do not pursue this candidate … … 716 711 else { 717 712 if ( ! unify( 718 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen )713 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) 719 714 ) { 720 715 // unification failed, do not pursue this candidate … … 1161 1156 1162 1157 // unification run for side-effects 1163 unify( toType, cand->expr->result, cand->env, need, have, open );1158 unify( toType, cand->expr->result, cand->env, need, have, open, symtab ); 1164 1159 Cost thisCost = 1165 1160 (castExpr->isGenerated == ast::GeneratedFlag::GeneratedCast) … … 1502 1497 if ( 1503 1498 unify( 1504 r2->expr->result, r3->expr->result, env, need, have, open, 1499 r2->expr->result, r3->expr->result, env, need, have, open, symtab, 1505 1500 common ) 1506 1501 ) { … … 1576 1571 if ( 1577 1572 unify( 1578 r1->expr->result, r2->expr->result, env, need, have, open, 1573 r1->expr->result, r2->expr->result, env, need, have, open, symtab, 1579 1574 common ) 1580 1575 ) { … … 1682 1677 1683 1678 // unification run for side-effects 1684 bool canUnify = unify( toType, cand->expr->result, env, need, have, open );1679 bool canUnify = unify( toType, cand->expr->result, env, need, have, open, symtab ); 1685 1680 (void) canUnify; 1686 1681 Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(), -
src/ResolvExpr/CandidateFinder.hpp
r24d6572 r34b4268 65 65 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 66 66 67 /// Create an expression that preforms reference to rvalue conversion on68 /// the given expression and update the cost of the expression.69 const ast::Expr * referenceToRvalueConversion(70 const ast::Expr * expr, Cost & cost );71 72 67 } // namespace ResolvExpr 73 68 -
src/ResolvExpr/CastCost.cc
r24d6572 r34b4268 13 13 // Update Count : 9 14 14 // 15 16 #include "CastCost.hpp"17 15 18 16 #include <cassert> // for assert … … 24 22 #include "ConversionCost.h" // for ConversionCost 25 23 #include "Cost.h" // for Cost, Cost::infinity 26 #include "ResolvExpr/ConversionCost.h" // for conversionCost27 #include "ResolvExpr/PtrsCastable.hpp" // for ptrsCastable28 24 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment, EqvClass 29 #include "ResolvExpr/typeops.h" // for ptrsCastable30 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers31 25 #include "SymTab/Indexer.h" // for Indexer 32 26 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl 33 27 #include "SynTree/Type.h" // for PointerType, Type, TypeInstType 28 #include "typeops.h" // for typesCompatibleIgnoreQualifiers 34 29 35 30 #if 0 … … 165 160 if ( 166 161 pointerType->qualifiers <= ptr->qualifiers 167 && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, env )162 && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env ) 168 163 ) { 169 164 cost = Cost::safe; … … 232 227 ) 233 228 234 if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {229 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) { 235 230 PRINT( std::cerr << "compatible!" << std::endl; ) 236 231 if (dynamic_cast<const ast::ZeroType *>(dst) || dynamic_cast<const ast::OneType *>(dst)) { -
src/ResolvExpr/CommonType.cc
r24d6572 r34b4268 14 14 // 15 15 16 #include "CommonType.hpp"17 18 16 #include <cassert> // for strict_dynamic_cast 19 17 #include <map> // for _Rb_tree_const_iterator … … 21 19 22 20 #include "AST/Decl.hpp" 23 #include "AST/Pass.hpp"24 21 #include "AST/Type.hpp" 25 22 #include "Common/PassVisitor.h" … … 676 673 const ast::Type * type2; 677 674 WidenMode widen; 675 const ast::SymbolTable & symtab; 678 676 ast::TypeEnvironment & tenv; 679 677 const ast::OpenVarSet & open; … … 685 683 686 684 CommonType_new( 687 const ast::Type * t2, WidenMode w, 685 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 688 686 ast::TypeEnvironment & env, const ast::OpenVarSet & o, 689 687 ast::AssertionSet & need, ast::AssertionSet & have ) 690 : type2( t2 ), widen( w ), tenv( env ), open( o ), need (need), have (have) ,result() {}688 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), need (need), have (have) ,result() {} 691 689 692 690 void previsit( const ast::Node * ) { visit_children = false; } … … 766 764 ast::AssertionSet need, have; 767 765 if ( ! tenv.bindVar( 768 var, voidPtr->base, entry->second, need, have, open, widen )766 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 769 767 ) return; 770 768 } … … 779 777 ast::OpenVarSet newOpen{ open }; 780 778 if (enumInst->base->base 781 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen )) {779 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen, symtab)) { 782 780 result = type1; 783 781 return true; … … 816 814 817 815 ast::OpenVarSet newOpen{ open }; 818 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {816 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { 819 817 result = pointer; 820 818 if ( q1.val != q2.val ) { … … 859 857 if (unifyExact( 860 858 arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, 861 noWiden() )) {859 noWiden(), symtab )) { 862 860 break; 863 861 … … 868 866 if (unifyExact( 869 867 tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open, 870 noWiden() )) {868 noWiden(), symtab )) { 871 869 break; 872 870 … … 892 890 893 891 if ( ! unifyExact( 894 base1, base2, tenv, need, have, open, noWiden() )892 base1, base2, tenv, need, have, open, noWiden(), symtab ) 895 893 ) return; 896 894 } … … 912 910 913 911 if ( ! unifyExact( 914 base1, base2, tenv, need, have, open, noWiden() )912 base1, base2, tenv, need, have, open, noWiden(), symtab ) 915 913 ) return; 916 914 } … … 920 918 } 921 919 else if (! unifyExact( 922 arg1, arg2, tenv, need, have, open, noWiden() )) return;920 arg1, arg2, tenv, need, have, open, noWiden(), symtab )) return; 923 921 924 922 ++crnt1; ++crnt2; … … 930 928 if (! unifyExact( 931 929 t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, 932 noWiden() )) return;930 noWiden(), symtab )) return; 933 931 } else if ( crnt2 != end2 ) { 934 932 // try unifying empty tuple with ttype … … 937 935 if (! unifyExact( 938 936 tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open, 939 noWiden() )) return;937 noWiden(), symtab )) return; 940 938 } 941 939 if ((f1->returns.size() == 0 && f2->returns.size() == 0) 942 || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden() ))) {940 || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden(), symtab))) { 943 941 result = pointer; 944 942 … … 997 995 998 996 ast::OpenVarSet newOpen{ open }; 999 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {997 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { 1000 998 result = ref; 1001 999 if ( q1.val != q2.val ) { … … 1012 1010 } else { 1013 1011 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 1014 result = commonType( type2, ref, tenv, need, have, open, widen );1012 result = commonType( type2, ref, tenv, need, have, open, widen, symtab ); 1015 1013 } 1016 1014 } … … 1030 1028 void postvisit( const ast::EnumInstType * enumInst ) { 1031 1029 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 1032 result = commonType( type2, enumInst, tenv, need, have, open, widen );1030 result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab); 1033 1031 } 1034 1032 1035 1033 void postvisit( const ast::TraitInstType * ) {} 1036 1034 1037 void postvisit( const ast::TypeInstType * inst ) {} 1035 void postvisit( const ast::TypeInstType * inst ) { 1036 if ( ! widen.first ) return; 1037 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 1038 if ( const ast::Type * base = 1039 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 1040 ) { 1041 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers; 1042 1043 // force t{1,2} to be cloned if their qualifiers must be mutated 1044 ast::ptr< ast::Type > t1{ base }, t2{ type2 }; 1045 reset_qualifiers( t1, q1 ); 1046 reset_qualifiers( t2 ); 1047 1048 ast::OpenVarSet newOpen{ open }; 1049 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { 1050 result = type2; 1051 reset_qualifiers( result, q1 | q2 ); 1052 } else { 1053 tryResolveWithTypedEnum( t1 ); 1054 } 1055 } 1056 } 1057 } 1038 1058 1039 1059 void postvisit( const ast::TupleType * tuple) { … … 1098 1118 ast::ptr< ast::Type > handleReference( 1099 1119 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 1100 ast::TypeEnvironment & env,1120 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 1101 1121 const ast::OpenVarSet & open 1102 1122 ) { … … 1106 1126 1107 1127 // need unify to bind type variables 1108 if ( unify( t1, t2, env, have, need, newOpen, common ) ) {1128 if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) { 1109 1129 ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers; 1110 1130 PRINT( … … 1130 1150 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 1131 1151 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1132 const ast::OpenVarSet & open, WidenMode widen 1152 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab 1133 1153 ) { 1134 1154 unsigned depth1 = type1->referenceDepth(); … … 1145 1165 if ( depth1 > depth2 ) { 1146 1166 assert( ref1 ); 1147 result = handleReference( ref1->base, type2, widen, env, open );1167 result = handleReference( ref1->base, type2, widen, symtab, env, open ); 1148 1168 } else { // implies depth1 < depth2 1149 1169 assert( ref2 ); 1150 result = handleReference( type1, ref2->base, widen, env, open );1170 result = handleReference( type1, ref2->base, widen, symtab, env, open ); 1151 1171 } 1152 1172 … … 1166 1186 } 1167 1187 // otherwise both are reference types of the same depth and this is handled by the visitor 1168 ast::Pass<CommonType_new> visitor{ type2, widen, env, open, need, have };1188 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open, need, have }; 1169 1189 type1->accept( visitor ); 1170 // ast::ptr< ast::Type > result = visitor.core.result; 1171 1172 return visitor.core.result; 1190 ast::ptr< ast::Type > result = visitor.core.result; 1191 1192 // handling for opaque type declarations (?) 1193 if ( ! result && widen.second ) { 1194 if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) { 1195 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 1196 auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt ); 1197 if ( type->base ) { 1198 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1199 ast::OpenVarSet newOpen{ open }; 1200 1201 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 1202 // type1 and type->base are left unchanged; calling convention forces 1203 // {type1,type->base}->strong_ref >= 1 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base }; 1205 reset_qualifiers( t1 ); 1206 reset_qualifiers( t2, q1 ); 1207 1208 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) { 1209 result = t1; 1210 reset_qualifiers( result, q1 | q2 ); 1211 } 1212 } 1213 } 1214 } 1215 } 1216 1217 return result; 1173 1218 } 1174 1219 -
src/ResolvExpr/ConversionCost.cc
r24d6572 r34b4268 22 22 #include "ResolvExpr/Cost.h" // for Cost 23 23 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 24 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers 25 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable 24 #include "ResolvExpr/Unify.h" 26 25 #include "SymTab/Indexer.h" // for Indexer 27 26 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl 28 27 #include "SynTree/Type.h" // for Type, BasicType, TypeInstType 28 #include "typeops.h" // for typesCompatibleIgnoreQualifiers 29 29 30 30 … … 532 532 } 533 533 } 534 if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {534 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) { 535 535 return Cost::zero; 536 536 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) { … … 566 566 ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers; 567 567 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( 568 srcAsRef->base, dstAsRef->base, env ) ) {568 srcAsRef->base, dstAsRef->base, symtab, env ) ) { 569 569 if ( tq1 == tq2 ) { 570 570 return Cost::zero; … … 587 587 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst ); 588 588 assert( dstAsRef ); 589 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {589 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) { 590 590 if ( srcIsLvalue ) { 591 591 if ( src->qualifiers == dstAsRef->base->qualifiers ) { … … 653 653 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers; 654 654 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( 655 pointerType->base, dstAsPtr->base, env ) ) {655 pointerType->base, dstAsPtr->base, symtab, env ) ) { 656 656 if ( tq1 == tq2 ) { 657 657 cost = Cost::zero; -
src/ResolvExpr/ConversionCost.h
r24d6572 r34b4268 32 32 namespace ResolvExpr { 33 33 class TypeEnvironment; 34 35 Cost conversionCost(36 const Type * src, const Type * dest, bool srcIsLvalue,37 const SymTab::Indexer & indexer, const TypeEnvironment & env );38 34 39 35 typedef std::function<Cost(const Type *, const Type *, bool, … … 84 80 const ast::SymbolTable &, const ast::TypeEnvironment &)>; 85 81 86 Cost conversionCost(87 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,88 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );89 90 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,91 bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,92 PtrsCalculation func );93 94 82 #warning when the old ConversionCost is removed, get ride of the _new suffix. 95 83 class ConversionCost_new : public ast::WithShortCircuiting { … … 131 119 }; 132 120 121 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest, 122 bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env, 123 PtrsCalculation func ); 124 133 125 } // namespace ResolvExpr 134 126 -
src/ResolvExpr/CurrentObject.cc
r24d6572 r34b4268 9 9 // Author : Rob Schluntz 10 10 // Created On : Tue Jun 13 15:28:32 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Apr 10 9:40:00 202313 // Update Count : 1 811 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 1 09:16:01 2022 13 // Update Count : 15 14 14 // 15 15 … … 26 26 #include "AST/Init.hpp" // for Designation 27 27 #include "AST/Node.hpp" // for readonly 28 #include "AST/Print.hpp" // for readonly28 #include "AST/Print.hpp" // for readonly 29 29 #include "AST/Type.hpp" 30 #include "Common/Eval.h" // for eval31 30 #include "Common/Indenter.h" // for Indenter, operator<< 32 31 #include "Common/SemanticError.h" // for SemanticError … … 593 592 594 593 namespace ast { 595 /// Iterates members of a type by initializer.596 class MemberIterator {597 public:598 virtual ~MemberIterator() {}599 600 /// Internal set position based on iterator ranges.601 virtual void setPosition(602 std::deque< ptr< Expr > >::const_iterator it,603 std::deque< ptr< Expr > >::const_iterator end ) = 0;604 605 /// Walks the current object using the given designators as a guide.606 void setPosition( const std::deque< ptr< Expr > > & designators ) {607 setPosition( designators.begin(), designators.end() );608 }609 610 /// Retrieve the list of possible (Type,Designation) pairs for the611 /// current position in the current object.612 virtual std::deque< InitAlternative > operator* () const = 0;613 614 /// True if the iterator is not currently at the end.615 virtual operator bool() const = 0;616 617 /// Moves the iterator by one member in the current object.618 virtual MemberIterator & bigStep() = 0;619 620 /// Moves the iterator by one member in the current subobject.621 virtual MemberIterator & smallStep() = 0;622 623 /// The type of the current object.624 virtual const Type * getType() = 0;625 626 /// The type of the current subobject.627 virtual const Type * getNext() = 0;628 629 /// Helper for operator*; aggregates must add designator to each init630 /// alternative, but adding designators in operator* creates duplicates.631 virtual std::deque< InitAlternative > first() const = 0;632 };633 634 594 /// create a new MemberIterator that traverses a type correctly 635 595 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); … … 671 631 }; 672 632 673 /// Iterates over an indexed type: 674 class IndexIterator : public MemberIterator { 675 protected: 633 /// Iterates array types 634 class ArrayIterator final : public MemberIterator { 676 635 CodeLocation location; 636 const ArrayType * array = nullptr; 637 const Type * base = nullptr; 677 638 size_t index = 0; 678 639 size_t size = 0; 679 std::unique_ptr<MemberIterator> memberIter; 680 public: 681 IndexIterator( const CodeLocation & loc, size_t size ) : 682 location( loc ), size( size ) 683 {} 640 std::unique_ptr< MemberIterator > memberIter; 641 642 void setSize( const Expr * expr ) { 643 auto res = eval( expr ); 644 if ( ! res.second ) { 645 SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) ); 646 } 647 size = res.first; 648 } 649 650 public: 651 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) : location( loc ), array( at ), base( at->base ) { 652 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 653 memberIter.reset( createMemberIterator( loc, base ) ); 654 if ( at->isVarLen ) { 655 SemanticError( location, at, "VLA initialization does not support @=: " ); 656 } 657 setSize( at->dimension ); 658 } 684 659 685 660 void setPosition( const Expr * expr ) { … … 690 665 auto arg = eval( expr ); 691 666 index = arg.first; 667 return; 692 668 693 669 // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { … … 707 683 708 684 void setPosition( 709 std::deque< ast::ptr<ast::Expr>>::const_iterator begin,710 std::deque< ast::ptr<ast::Expr>>::const_iterator end685 std::deque< ptr< Expr > >::const_iterator begin, 686 std::deque< ptr< Expr > >::const_iterator end 711 687 ) override { 712 688 if ( begin == end ) return; … … 719 695 720 696 operator bool() const override { return index < size; } 721 };722 723 /// Iterates over the members of array types:724 class ArrayIterator final : public IndexIterator {725 const ArrayType * array = nullptr;726 const Type * base = nullptr;727 728 size_t getSize( const Expr * expr ) {729 auto res = eval( expr );730 if ( !res.second ) {731 SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) );732 }733 return res.first;734 }735 736 public:737 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) :738 IndexIterator( loc, getSize( at->dimension) ),739 array( at ), base( at->base ) {740 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )741 memberIter.reset( createMemberIterator( loc, base ) );742 if ( at->isVarLen ) {743 SemanticError( location, at, "VLA initialization does not support @=: " );744 }745 }746 697 747 698 ArrayIterator & bigStep() override { … … 882 833 883 834 const Type * getNext() final { 884 bool hasMember = memberIter && *memberIter; 885 return hasMember ? memberIter->getType() : nullptr; 835 return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr; 886 836 } 887 837 … … 947 897 }; 948 898 949 /// Iterates across the positions in a tuple: 950 class TupleIterator final : public IndexIterator { 951 ast::TupleType const * const tuple; 952 953 const ast::Type * typeAtIndex() const { 954 assert( index < size ); 955 return tuple->types[ index ].get(); 956 } 957 958 public: 959 TupleIterator( const CodeLocation & loc, const TupleType * type ) 960 : IndexIterator( loc, type->size() ), tuple( type ) { 961 PRINT( std::cerr << "Creating tuple iterator: " << type << std::endl; ) 962 memberIter.reset( createMemberIterator( loc, typeAtIndex() ) ); 899 class TupleIterator final : public AggregateIterator { 900 public: 901 TupleIterator( const CodeLocation & loc, const TupleType * inst ) 902 : AggregateIterator( 903 loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members 904 ) {} 905 906 operator bool() const override { 907 return curMember != members.end() || (memberIter && *memberIter); 963 908 } 964 909 965 910 TupleIterator & bigStep() override { 966 ++index; 967 memberIter.reset( index < size ? 968 createMemberIterator( location, typeAtIndex() ) : nullptr ); 911 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 912 atbegin = false; 913 memberIter = nullptr; 914 curType = nullptr; 915 while ( curMember != members.end() ) { 916 ++curMember; 917 if ( init() ) return *this; 918 } 969 919 return *this; 970 }971 972 TupleIterator & smallStep() override {973 if ( memberIter ) {974 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; )975 memberIter->smallStep();976 if ( !memberIter ) {977 PRINT( std::cerr << "has valid member iter" << std::endl; )978 return *this;979 }980 }981 return bigStep();982 }983 984 const ast::Type * getType() override {985 return tuple;986 }987 988 const ast::Type * getNext() override {989 bool hasMember = memberIter && *memberIter;990 return hasMember ? memberIter->getType() : nullptr;991 }992 993 std::deque< InitAlternative > first() const override {994 PRINT( std::cerr << "first in TupleIterator (" << index << "/" << size << ")" << std::endl; )995 if ( memberIter && *memberIter ) {996 std::deque< InitAlternative > ret = memberIter->first();997 for ( InitAlternative & alt : ret ) {998 alt.designation.get_and_mutate()->designators.emplace_front(999 ConstantExpr::from_ulong( location, index ) );1000 }1001 return ret;1002 }1003 return {};1004 920 } 1005 921 }; -
src/ResolvExpr/CurrentObject.h
r24d6572 r34b4268 9 9 // Author : Rob Schluntz 10 10 // Created On : Thu Jun 8 11:07:25 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thu Apr 6 16:14:00 202313 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:36:48 2017 13 // Update Count : 3 14 14 // 15 15 … … 65 65 66 66 /// Iterates members of a type by initializer 67 class MemberIterator; 67 class MemberIterator { 68 public: 69 virtual ~MemberIterator() {} 70 71 /// Internal set position based on iterator ranges 72 virtual void setPosition( 73 std::deque< ptr< Expr > >::const_iterator it, 74 std::deque< ptr< Expr > >::const_iterator end ) = 0; 75 76 /// walks the current object using the given designators as a guide 77 void setPosition( const std::deque< ptr< Expr > > & designators ) { 78 setPosition( designators.begin(), designators.end() ); 79 } 80 81 /// retrieve the list of possible (Type,Designation) pairs for the current position in the 82 /// current object 83 virtual std::deque< InitAlternative > operator* () const = 0; 84 85 /// true if the iterator is not currently at the end 86 virtual operator bool() const = 0; 87 88 /// moves the iterator by one member in the current object 89 virtual MemberIterator & bigStep() = 0; 90 91 /// moves the iterator by one member in the current subobject 92 virtual MemberIterator & smallStep() = 0; 93 94 /// the type of the current object 95 virtual const Type * getType() = 0; 96 97 /// the type of the current subobject 98 virtual const Type * getNext() = 0; 99 100 /// helper for operator*; aggregates must add designator to each init alternative, but 101 /// adding designators in operator* creates duplicates 102 virtual std::deque< InitAlternative > first() const = 0; 103 }; 68 104 69 105 /// Builds initializer lists in resolution -
src/ResolvExpr/ExplodedArg.hpp
r24d6572 r34b4268 35 35 ExplodedArg() : env(), cost( Cost::zero ), exprs() {} 36 36 ExplodedArg( const Candidate & arg, const ast::SymbolTable & symtab ); 37 37 38 38 ExplodedArg( ExplodedArg && ) = default; 39 39 ExplodedArg & operator= ( ExplodedArg && ) = default; -
src/ResolvExpr/PolyCost.cc
r24d6572 r34b4268 15 15 16 16 #include "AST/SymbolTable.hpp" 17 #include "AST/Pass.hpp"18 17 #include "AST/Type.hpp" 19 18 #include "AST/TypeEnvironment.hpp" -
src/ResolvExpr/PtrsAssignable.cc
r24d6572 r34b4268 14 14 // 15 15 16 #include " PtrsAssignable.hpp"16 #include "typeops.h" 17 17 18 18 #include "AST/Pass.hpp" -
src/ResolvExpr/PtrsCastable.cc
r24d6572 r34b4268 14 14 // 15 15 16 #include "PtrsCastable.hpp"17 18 16 #include "AST/Decl.hpp" 19 17 #include "AST/Pass.hpp" … … 21 19 #include "AST/TypeEnvironment.hpp" 22 20 #include "Common/PassVisitor.h" 23 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable24 21 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 25 22 #include "SymTab/Indexer.h" // for Indexer … … 27 24 #include "SynTree/Type.h" // for TypeInstType, Type, BasicType 28 25 #include "SynTree/Visitor.h" // for Visitor 26 #include "typeops.h" // for ptrsAssignable 29 27 30 28 namespace ResolvExpr { … … 293 291 return objectCast( src, env, symtab ); 294 292 } else { 295 return ast::Pass<PtrsCastable_new>::read( src, dst, env, symtab ); 293 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab }; 294 src->accept( ptrs ); 295 return ptrs.core.result; 296 296 } 297 297 } -
src/ResolvExpr/RenameVars.cc
r24d6572 r34b4268 83 83 84 84 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 85 // rename 85 86 auto it = idMap.find( type->name ); 86 if ( it == idMap.end() ) return type; 87 88 // Unconditionally mutate because map will *always* have different name. 89 ast::TypeInstType * mut = ast::shallowCopy( type ); 90 // Reconcile base node since some copies might have been made. 91 mut->base = it->second.base; 92 mut->formal_usage = it->second.formal_usage; 93 mut->expr_id = it->second.expr_id; 94 return mut; 87 if ( it != idMap.end() ) { 88 // unconditionally mutate because map will *always* have different name 89 ast::TypeInstType * mut = ast::shallowCopy( type ); 90 // reconcile base node since some copies might have been made 91 mut->base = it->second.base; 92 mut->formal_usage = it->second.formal_usage; 93 mut->expr_id = it->second.expr_id; 94 type = mut; 95 } 96 97 return type; 95 98 } 96 99 … … 184 187 185 188 const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) { 189 // ast::Type *tc = ast::deepCopy(t); 186 190 ast::Pass<RenameVars_new> renamer; 187 191 renamer.core.mode = mode; -
src/ResolvExpr/ResolveAssertions.cc
r24d6572 r34b4268 26 26 #include <vector> // for vector 27 27 28 #include "AdjustExprType.hpp" // for adjustExprType29 28 #include "Alternative.h" // for Alternative, AssertionItem, AssertionList 30 29 #include "Common/FilterCombos.h" // for filterCombos 31 30 #include "Common/Indenter.h" // for Indenter 31 #include "Common/utility.h" // for sort_mins 32 32 #include "GenPoly/GenPoly.h" // for getFunctionType 33 #include "ResolvExpr/AlternativeFinder.h" // for computeConversionCost34 33 #include "ResolvExpr/RenameVars.h" // for renameTyVars 35 #include "SpecCost.hpp" // for specCost36 34 #include "SymTab/Indexer.h" // for Indexer 37 35 #include "SymTab/Mangler.h" // for Mangler 38 36 #include "SynTree/Expression.h" // for InferredParams 39 37 #include "TypeEnvironment.h" // for TypeEnvironment, etc. 38 #include "typeops.h" // for adjustExprType, specCost 40 39 #include "Unify.h" // for unify 41 40 -
src/ResolvExpr/Resolver.cc
r24d6572 r34b4268 38 38 #include "AST/SymbolTable.hpp" 39 39 #include "AST/Type.hpp" 40 #include "Common/Eval.h" // for eval41 #include "Common/Iterate.hpp" // for group_iterate42 40 #include "Common/PassVisitor.h" // for PassVisitor 43 41 #include "Common/SemanticError.h" // for SemanticError 44 42 #include "Common/Stats/ResolveTime.h" // for ResolveTime::start(), ResolveTime::stop() 45 #include "Common/ ToString.hpp" // for toCString43 #include "Common/utility.h" // for ValueGuard, group_iterate 46 44 #include "InitTweak/GenInit.h" 47 45 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt … … 1109 1107 void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) { 1110 1108 if ( const ast::CastExpr * castExpr = expr.as< ast::CastExpr >() ) { 1111 if ( typesCompatible( castExpr->arg->result, castExpr->result ) ) {1109 if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) { 1112 1110 // cast is to the same type as its argument, remove it 1113 1111 swap_and_save_env( expr, castExpr->arg ); … … 1731 1729 1732 1730 // Find all candidates for a function in canonical form 1733 funcFinder.find( clause.target , ResolvMode::withAdjustment() );1731 funcFinder.find( clause.target_func, ResolvMode::withAdjustment() ); 1734 1732 1735 1733 if ( funcFinder.candidates.empty() ) { 1736 1734 stringstream ss; 1737 1735 ss << "Use of undeclared indentifier '"; 1738 ss << clause.target .strict_as< ast::NameExpr >()->name;1736 ss << clause.target_func.strict_as< ast::NameExpr >()->name; 1739 1737 ss << "' in call to waitfor"; 1740 1738 SemanticError( stmt->location, ss.str() ); … … 1835 1833 if ( 1836 1834 ! unify( 1837 arg->expr->result, *param, resultEnv, need, have, open ) 1835 arg->expr->result, *param, resultEnv, need, have, open, 1836 symtab ) 1838 1837 ) { 1839 1838 // Type doesn't match … … 1922 1921 auto clause2 = new ast::WaitForClause( clause.location ); 1923 1922 1924 clause2->target = funcCandidates.front()->expr;1923 clause2->target_func = funcCandidates.front()->expr; 1925 1924 1926 1925 clause2->target_args.reserve( clause.target_args.size() ); … … 1945 1944 1946 1945 // Resolve the conditions as if it were an IfStmt, statements normally 1947 clause2-> when_cond = findSingleExpression( clause.when_cond, context );1946 clause2->cond = findSingleExpression( clause.cond, context ); 1948 1947 clause2->stmt = clause.stmt->accept( *visitor ); 1949 1948 -
src/ResolvExpr/Resolver.h
r24d6572 r34b4268 34 34 class Decl; 35 35 class DeletedExpr; 36 class Expr;37 36 class Init; 38 37 class StmtExpr; -
src/ResolvExpr/SatisfyAssertions.cpp
r24d6572 r34b4268 24 24 #include <vector> 25 25 26 #include "AdjustExprType.hpp"27 26 #include "Candidate.hpp" 28 27 #include "CandidateFinder.hpp" 29 #include "CommonType.hpp"30 28 #include "Cost.h" 31 29 #include "RenameVars.h" 32 #include "SpecCost.hpp"33 30 #include "typeops.h" 34 31 #include "Unify.h" … … 184 181 .strict_as<ast::FunctionType>()->params[0] 185 182 .strict_as<ast::ReferenceType>()->base; 186 // sat.cand->env.apply(thisArgType); 187 188 if (auto inst = thisArgType.as<ast::TypeInstType>()) { 189 auto cls = sat.cand->env.lookup(*inst); 190 if (cls && cls->bound) thisArgType = cls->bound; 191 } 183 sat.cand->env.apply(thisArgType); 192 184 193 185 std::string otypeKey = ""; … … 226 218 ast::TypeEnvironment tempNewEnv {newEnv}; 227 219 228 if ( unifyExact( toType, adjType, tempNewEnv, newNeed, have, newOpen, WidenMode {true, true} ) ) {220 if ( unifyExact( toType, adjType, tempNewEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) { 229 221 // set up binding slot for recursive assertions 230 222 ast::UniqueId crntResnSlot = 0; … … 242 234 // newEnv = sat.cand->env; 243 235 // newNeed.clear(); 244 if ( auto c = commonType( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true} ) ) {236 if ( auto c = commonType( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) { 245 237 // set up binding slot for recursive assertions 246 238 ast::UniqueId crntResnSlot = 0; … … 406 398 mergeOpenVars( open, i.match.open ); 407 399 408 if ( ! env.combine( i.match.env, open ) ) return false;400 if ( ! env.combine( i.match.env, open, symtab ) ) return false; 409 401 410 402 crnt.emplace_back( i ); -
src/ResolvExpr/Unify.cc
r24d6572 r34b4268 33 33 #include "AST/TypeEnvironment.hpp" 34 34 #include "Common/PassVisitor.h" // for PassVisitor 35 #include "CommonType.hpp" // for commonType36 35 #include "FindOpenVars.h" // for findOpenVars 37 #include "SpecCost.hpp" // for SpecCost38 36 #include "SynTree/LinkageSpec.h" // for C 39 37 #include "SynTree/Constant.h" // for Constant … … 45 43 #include "Tuples/Tuples.h" // for isTtype 46 44 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet 47 #include "typeops.h" // for flatten, occurs 45 #include "typeops.h" // for flatten, occurs, commonType 48 46 49 47 namespace ast { … … 52 50 53 51 namespace SymTab { 54 class Indexer;52 class Indexer; 55 53 } // namespace SymTab 56 54 … … 58 56 59 57 namespace ResolvExpr { 60 61 // Template Helpers:62 template< typename Iterator1, typename Iterator2 >63 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {64 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {65 Type *commonType = 0;66 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {67 return false;68 } // if69 commonTypes.push_back( commonType );70 } // for71 return ( list1Begin == list1End && list2Begin == list2End );72 }73 74 template< typename Iterator1, typename Iterator2 >75 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {76 std::list< Type* > commonTypes;77 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {78 deleteAll( commonTypes );79 return true;80 } else {81 return false;82 } // if83 }84 58 85 59 struct Unify_old : public WithShortCircuiting { … … 128 102 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 129 103 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 130 WidenMode widen );104 WidenMode widen, const ast::SymbolTable & symtab ); 131 105 132 106 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { … … 150 124 151 125 bool typesCompatible( 152 const ast::Type * first, const ast::Type * second, 126 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 153 127 const ast::TypeEnvironment & env ) { 154 128 ast::TypeEnvironment newEnv; … … 163 137 findOpenVars( newSecond, open, closed, need, have, newEnv, FirstOpen ); 164 138 165 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden() );139 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 166 140 } 167 141 … … 183 157 184 158 bool typesCompatibleIgnoreQualifiers( 185 const ast::Type * first, const ast::Type * second, 159 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 186 160 const ast::TypeEnvironment & env ) { 187 161 ast::TypeEnvironment newEnv; … … 216 190 subFirst, 217 191 subSecond, 218 newEnv, need, have, open, noWiden() );192 newEnv, need, have, open, noWiden(), symtab ); 219 193 } 220 194 … … 786 760 const ast::OpenVarSet & open; 787 761 WidenMode widen; 762 const ast::SymbolTable & symtab; 788 763 public: 789 764 static size_t traceId; … … 792 767 Unify_new( 793 768 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 794 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen ) 769 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 770 const ast::SymbolTable & symtab ) 795 771 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 796 result(false) {}772 symtab(symtab), result(false) {} 797 773 798 774 void previsit( const ast::Node * ) { visit_children = false; } … … 812 788 result = unifyExact( 813 789 pointer->base, pointer2->base, tenv, need, have, open, 814 noWiden() );790 noWiden(), symtab ); 815 791 } 816 792 } … … 835 811 836 812 result = unifyExact( 837 array->base, array2->base, tenv, need, have, open, noWiden()); 813 array->base, array2->base, tenv, need, have, open, noWiden(), 814 symtab ); 838 815 } 839 816 … … 841 818 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 842 819 result = unifyExact( 843 ref->base, ref2->base, tenv, need, have, open, noWiden()); 820 ref->base, ref2->base, tenv, need, have, open, noWiden(), 821 symtab ); 844 822 } 845 823 } … … 850 828 static bool unifyTypeList( 851 829 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 852 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open 830 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 831 const ast::SymbolTable & symtab 853 832 ) { 854 833 while ( crnt1 != end1 && crnt2 != end2 ) { … … 863 842 return unifyExact( 864 843 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 865 noWiden() );844 noWiden(), symtab ); 866 845 } else if ( ! isTuple1 && isTuple2 ) { 867 846 // combine remainder of list1, then unify 868 847 return unifyExact( 869 848 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 870 noWiden() );849 noWiden(), symtab ); 871 850 } 872 851 873 852 if ( ! unifyExact( 874 t1, t2, env, need, have, open, noWiden() )853 t1, t2, env, need, have, open, noWiden(), symtab ) 875 854 ) return false; 876 855 … … 886 865 return unifyExact( 887 866 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 888 noWiden() );867 noWiden(), symtab ); 889 868 } else if ( crnt2 != end2 ) { 890 869 // try unifying empty tuple with ttype … … 893 872 return unifyExact( 894 873 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 895 noWiden() );874 noWiden(), symtab ); 896 875 } 897 876 … … 903 882 const std::vector< ast::ptr< ast::Type > > & list2, 904 883 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 905 const ast::OpenVarSet & open 884 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 906 885 ) { 907 886 return unifyTypeList( 908 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open); 887 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 888 symtab ); 909 889 } 910 890 … … 947 927 ) return; 948 928 949 if ( ! unifyTypeList( params, params2, tenv, need, have, open ) ) return;929 if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return; 950 930 if ( ! unifyTypeList( 951 func->returns, func2->returns, tenv, need, have, open ) ) return;931 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 952 932 953 933 markAssertions( have, need, func ); … … 964 944 // check that the other type is compatible and named the same 965 945 auto otherInst = dynamic_cast< const XInstType * >( other ); 966 if (otherInst && inst->name == otherInst->name) 967 this->result = otherInst; 946 if (otherInst && inst->name == otherInst->name) this->result = otherInst; 968 947 return otherInst; 969 948 } … … 1021 1000 1022 1001 if ( ! unifyExact( 1023 pty, pty2, tenv, need, have, open, noWiden() ) ) {1002 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1024 1003 result = false; 1025 1004 return; … … 1051 1030 void postvisit( const ast::TypeInstType * typeInst ) { 1052 1031 // assert( open.find( *typeInst ) == open.end() ); 1053 auto otherInst = dynamic_cast< const ast::TypeInstType * >( type2 ); 1054 if (otherInst && typeInst->name == otherInst->name) 1055 this->result = otherInst; 1056 // return otherInst; 1032 handleRefType( typeInst, type2 ); 1057 1033 } 1058 1034 … … 1063 1039 const std::vector< ast::ptr< ast::Type > > & list1, 1064 1040 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1065 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open 1041 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1042 const ast::SymbolTable & symtab 1066 1043 ) { 1067 1044 auto crnt1 = list1.begin(); … … 1078 1055 return unifyExact( 1079 1056 t1, tupleFromTypes( list2 ), env, need, have, open, 1080 noWiden() );1057 noWiden(), symtab ); 1081 1058 } else if ( ! isTuple1 && isTuple2 ) { 1082 1059 // combine entirety of list1, then unify 1083 1060 return unifyExact( 1084 1061 tupleFromTypes( list1 ), t2, env, need, have, open, 1085 noWiden() );1062 noWiden(), symtab ); 1086 1063 } 1087 1064 1088 1065 if ( ! unifyExact( 1089 t1, t2, env, need, have, open, noWiden() )1066 t1, t2, env, need, have, open, noWiden(), symtab ) 1090 1067 ) return false; 1091 1068 … … 1101 1078 return unifyExact( 1102 1079 t1, tupleFromTypes( list2 ), env, need, have, open, 1103 noWiden() );1080 noWiden(), symtab ); 1104 1081 } else if ( crnt2 != list2.end() ) { 1105 1082 // try unifying empty tuple with ttype … … 1110 1087 return unifyExact( 1111 1088 tupleFromTypes( list1 ), t2, env, need, have, open, 1112 noWiden() );1089 noWiden(), symtab ); 1113 1090 } 1114 1091 … … 1129 1106 auto types2 = flatten( flat2 ); 1130 1107 1131 result = unifyList( types, types2, tenv, need, have, open );1108 result = unifyList( types, types2, tenv, need, have, open, symtab ); 1132 1109 } 1133 1110 … … 1153 1130 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1154 1131 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1155 ast::OpenVarSet & open 1132 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1156 1133 ) { 1157 1134 ast::ptr<ast::Type> common; 1158 return unify( type1, type2, env, need, have, open, common );1135 return unify( type1, type2, env, need, have, open, symtab, common ); 1159 1136 } 1160 1137 … … 1162 1139 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1163 1140 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1164 ast::OpenVarSet & open, ast::ptr<ast::Type> & common1141 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1165 1142 ) { 1166 1143 ast::OpenVarSet closed; … … 1168 1145 findOpenVars( type2, open, closed, need, have, env, FirstOpen ); 1169 1146 return unifyInexact( 1170 type1, type2, env, need, have, open, WidenMode{ true, true }, common );1147 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1171 1148 } 1172 1149 … … 1174 1151 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1175 1152 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1176 WidenMode widen 1153 WidenMode widen, const ast::SymbolTable & symtab 1177 1154 ) { 1178 1155 if ( type1->qualifiers != type2->qualifiers ) return false; … … 1193 1170 return env.bindVarToVar( 1194 1171 var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have, 1195 open, widen );1172 open, widen, symtab ); 1196 1173 } else if ( isopen1 ) { 1197 return env.bindVar( var1, type2, entry1->second, need, have, open, widen );1174 return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab ); 1198 1175 } else if ( isopen2 ) { 1199 1176 return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab ); … … 1203 1180 return env.bindVarToVar( 1204 1181 var1, var2, ast::TypeData{ var1->base->kind, var1->base->sized||var2->base->sized }, need, have, 1205 open, widen );1182 open, widen, symtab ); 1206 1183 } else if ( isopen1 ) { 1207 return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen );1184 return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen, symtab ); 1208 1185 } else if ( isopen2 ) { 1209 return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen );1186 return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen, symtab ); 1210 1187 }else { 1211 1188 return ast::Pass<Unify_new>::read( 1212 type1, type2, env, need, have, open, widen );1189 type1, type2, env, need, have, open, widen, symtab ); 1213 1190 } 1214 1191 … … 1218 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1219 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1220 const ast::OpenVarSet & open, WidenMode widen, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1221 1198 ast::ptr<ast::Type> & common 1222 1199 ) { … … 1232 1209 ast::ptr< ast::Type > t2_(t2); 1233 1210 1234 if ( unifyExact( t1, t2, env, need, have, open, widen ) ) {1211 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1235 1212 // if exact unification on unqualified types, try to merge qualifiers 1236 1213 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { … … 1242 1219 } 1243 1220 1244 } else if (( common = commonType( t1, t2, env, need, have, open, widen ))) {1221 } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) { 1245 1222 // no exact unification, but common type 1246 1223 auto c = shallowCopy(common.get()); -
src/ResolvExpr/Unify.h
r24d6572 r34b4268 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 13:09:04 2015 11 // Last Modified By : A ndrew Beach12 // Last Modified On : Tue Jan 17 11:12:00 202313 // Update Count : 511 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Mon Jun 18 11:58:00 2018 13 // Update Count : 4 14 14 // 15 15 … … 37 37 38 38 namespace ResolvExpr { 39 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 40 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType ); 41 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 42 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common ); 39 43 40 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 41 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType ); 42 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 43 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common ); 44 template< typename Iterator1, typename Iterator2 > 45 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) { 46 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 47 Type *commonType = 0; 48 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 49 return false; 50 } // if 51 commonTypes.push_back( commonType ); 52 } // for 53 if ( list1Begin != list1End || list2Begin != list2End ) { 54 return false; 55 } else { 56 return true; 57 } // if 58 } 44 59 45 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 46 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 60 template< typename Iterator1, typename Iterator2 > 61 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 62 std::list< Type* > commonTypes; 63 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) { 64 deleteAll( commonTypes ); 65 return true; 66 } else { 67 return false; 68 } // if 69 } 47 70 48 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 49 TypeEnvironment env;50 return typesCompatible( t1, t2, indexer, env );51 } 71 bool unify( 72 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 73 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 74 ast::OpenVarSet & open, const ast::SymbolTable & symtab ); 52 75 53 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 54 TypeEnvironment env;55 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );56 } 76 bool unify( 77 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 78 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 79 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common ); 57 80 58 bool unify( 59 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,60 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,61 ast::OpenVarSet & open);81 bool unifyExact( 82 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 83 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 84 WidenMode widen, const ast::SymbolTable & symtab ); 62 85 63 bool unify( 64 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 65 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 66 ast::OpenVarSet & open, ast::ptr<ast::Type> & common ); 67 68 bool unifyExact( 69 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 70 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 71 WidenMode widen ); 72 73 bool unifyInexact( 74 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 75 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 76 const ast::OpenVarSet & open, WidenMode widen, 77 ast::ptr<ast::Type> & common ); 78 79 bool typesCompatible( 80 const ast::Type *, const ast::Type *, 81 const ast::TypeEnvironment & env = {} ); 82 83 bool typesCompatibleIgnoreQualifiers( 84 const ast::Type *, const ast::Type *, 85 const ast::TypeEnvironment & env = {} ); 86 87 /// Creates the type represented by the list of returnVals in a FunctionType. 88 /// The caller owns the return value. 89 Type * extractResultType( FunctionType * functionType ); 90 /// Creates or extracts the type represented by returns in a `FunctionType`. 91 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ); 92 93 std::vector<ast::ptr<ast::Type>> flattenList( 94 const std::vector<ast::ptr<ast::Type>> & src, ast::TypeEnvironment & env 95 ); 86 bool unifyInexact( 87 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 88 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 89 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 90 ast::ptr<ast::Type> & common ); 96 91 97 92 } // namespace ResolvExpr -
src/ResolvExpr/WidenMode.h
r24d6572 r34b4268 19 19 struct WidenMode { 20 20 WidenMode( bool first, bool second ): first( first ), second( second ) {} 21 21 22 22 WidenMode &operator|=( const WidenMode &other ) { 23 23 first |= other.first; second |= other.second; return *this; … … 35 35 WidenMode newWM( *this ); newWM &= other; return newWM; 36 36 } 37 37 38 38 operator bool() { return first && second; } 39 39 -
src/ResolvExpr/module.mk
r24d6572 r34b4268 17 17 SRC_RESOLVEXPR = \ 18 18 ResolvExpr/AdjustExprType.cc \ 19 ResolvExpr/AdjustExprType.hpp \20 19 ResolvExpr/Alternative.cc \ 21 20 ResolvExpr/AlternativeFinder.cc \ … … 27 26 ResolvExpr/Candidate.hpp \ 28 27 ResolvExpr/CastCost.cc \ 29 ResolvExpr/CastCost.hpp \30 28 ResolvExpr/CommonType.cc \ 31 ResolvExpr/CommonType.hpp \32 29 ResolvExpr/ConversionCost.cc \ 33 30 ResolvExpr/ConversionCost.h \ … … 43 40 ResolvExpr/Occurs.cc \ 44 41 ResolvExpr/PolyCost.cc \ 45 ResolvExpr/PolyCost.hpp \46 42 ResolvExpr/PtrsAssignable.cc \ 47 ResolvExpr/PtrsAssignable.hpp \48 43 ResolvExpr/PtrsCastable.cc \ 49 ResolvExpr/PtrsCastable.hpp \50 44 ResolvExpr/RenameVars.cc \ 51 45 ResolvExpr/RenameVars.h \ … … 60 54 ResolvExpr/SatisfyAssertions.hpp \ 61 55 ResolvExpr/SpecCost.cc \ 62 ResolvExpr/SpecCost.hpp \63 56 ResolvExpr/TypeEnvironment.cc \ 64 57 ResolvExpr/TypeEnvironment.h \ -
src/ResolvExpr/typeops.h
r24d6572 r34b4268 10 10 // Created On : Sun May 17 07:28:22 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jan 18 11:54:00 202313 // Update Count : 712 // Last Modified On : Tue Oct 1 09:45:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 18 18 #include <vector> 19 19 20 #include "Cost.h" 21 #include "TypeEnvironment.h" 22 #include "WidenMode.h" 23 #include "AST/Fwd.hpp" 24 #include "AST/Node.hpp" 25 #include "AST/SymbolTable.hpp" 20 26 #include "AST/Type.hpp" 27 #include "AST/TypeEnvironment.hpp" 28 #include "SynTree/SynTree.h" 21 29 #include "SynTree/Type.h" 22 30 … … 26 34 27 35 namespace ResolvExpr { 28 class TypeEnvironment;29 30 36 // combos: takes a list of sets and returns a set of lists representing every possible way of forming a list by 31 37 // picking one element out of each set … … 55 61 } 56 62 63 // in AdjustExprType.cc 64 /// 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 ); 66 67 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer 68 void adjustExprType( Type *& type ); 69 70 template< typename ForwardIterator > 71 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) { 72 while ( begin != end ) { 73 adjustExprType( *begin++, env, indexer ); 74 } // while 75 } 76 77 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 78 const ast::Type * adjustExprType( 79 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 80 81 // in CastCost.cc 82 Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue, 83 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 84 Cost castCost( 85 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, 86 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 87 88 // in ConversionCost.cc 89 Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue, 90 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 91 Cost conversionCost( 92 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, 93 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 94 95 // in AlternativeFinder.cc 96 Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue, 97 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 98 99 // in PtrsAssignable.cc 100 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env ); 101 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 102 const ast::TypeEnvironment & env ); 103 104 // in PtrsCastable.cc 105 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 106 int ptrsCastable( 107 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 108 const ast::TypeEnvironment & env ); 109 110 // in Unify.cc 111 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 112 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 113 114 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 115 TypeEnvironment env; 116 return typesCompatible( t1, t2, indexer, env ); 117 } 118 119 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 120 TypeEnvironment env; 121 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 122 } 123 124 bool typesCompatible( 125 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 126 const ast::TypeEnvironment & env = {} ); 127 128 bool typesCompatibleIgnoreQualifiers( 129 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 130 const ast::TypeEnvironment & env = {} ); 131 132 /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value. 133 Type * extractResultType( FunctionType * functionType ); 134 /// Creates or extracts the type represented by the list of returns in a `FunctionType`. 135 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ); 136 137 // in CommonType.cc 138 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars ); 139 ast::ptr< ast::Type > commonType( 140 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 141 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 142 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab 143 ); 144 // in Unify.cc 145 std::vector< ast::ptr< ast::Type > > flattenList( 146 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env 147 ); 148 149 // in PolyCost.cc 150 int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 151 int polyCost( 152 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 153 154 // in SpecCost.cc 155 int specCost( Type * type ); 156 int specCost( const ast::Type * type ); 157 57 158 // in Occurs.cc 58 159 bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env ); … … 67 168 return false; 68 169 } 170 171 // in AlternativeFinder.cc 172 void referenceToRvalueConversion( Expression *& expr, Cost & cost ); 173 // in CandidateFinder.cpp 174 const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost ); 69 175 70 176 /// flatten tuple type into list of types … … 112 218 } 113 219 220 114 221 return new ast::TupleType{ std::move(types) }; 115 222 } … … 120 227 return tupleFromTypes( tys.begin(), tys.end() ); 121 228 } 229 230 122 231 123 232 // in TypeEnvironment.cc -
src/SymTab/Autogen.cc
r24d6572 r34b4268 10 10 // Created On : Thu Mar 03 15:45:56 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 14 15:03:00 202313 // Update Count : 6 412 // Last Modified On : Fri Apr 27 14:39:06 2018 13 // Update Count : 63 14 14 // 15 15 … … 211 211 } 212 212 213 bool isUnnamedBitfield( const ast::ObjectDecl * obj ) { 214 return obj && obj->name.empty() && obj->bitfieldWidth; 215 } 216 213 217 /// inserts a forward declaration for functionDecl into declsToAdd 214 218 void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) { … … 230 234 } 231 235 236 // shallow copy the pointer list for return 237 std::vector<ast::ptr<ast::TypeDecl>> getGenericParams (const ast::Type * t) { 238 if (auto structInst = dynamic_cast<const ast::StructInstType*>(t)) { 239 return structInst->base->params; 240 } 241 if (auto unionInst = dynamic_cast<const ast::UnionInstType*>(t)) { 242 return unionInst->base->params; 243 } 244 return {}; 245 } 246 232 247 /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *) 233 248 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic ) { … … 241 256 ftype->parameters.push_back( dstParam ); 242 257 return ftype; 258 } 259 260 /// Given type T, generate type of default ctor/dtor, i.e. function type void (*) (T &). 261 ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic) { 262 std::vector<ast::ptr<ast::TypeDecl>> typeParams; 263 if (maybePolymorphic) typeParams = getGenericParams(paramType); 264 auto dstParam = new ast::ObjectDecl(loc, "_dst", new ast::ReferenceType(paramType), nullptr, {}, ast::Linkage::Cforall); 265 return new ast::FunctionDecl(loc, fname, std::move(typeParams), {dstParam}, {}, new ast::CompoundStmt(loc), {}, ast::Linkage::Cforall); 243 266 } 244 267 -
src/SymTab/Autogen.h
r24d6572 r34b4268 9 9 // Author : Rob Schluntz 10 10 // Created On : Sun May 17 21:53:34 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Apr 14 15:06:00 202313 // Update Count : 1 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 16:38:06 2019 13 // Update Count : 16 14 14 // 15 15 … … 20 20 #include <string> // for string 21 21 22 #include "AST/Decl.hpp" 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 25 #include "AST/Node.hpp" 26 #include "AST/Stmt.hpp" 27 #include "AST/Type.hpp" 22 28 #include "CodeGen/OperatorTable.h" 23 29 #include "Common/UniqueName.h" // for UniqueName … … 39 45 /// returns true if obj's name is the empty string and it has a bitfield width 40 46 bool isUnnamedBitfield( ObjectDecl * obj ); 47 bool isUnnamedBitfield( const ast::ObjectDecl * obj ); 41 48 42 49 /// generate the type of an assignment function for paramType. … … 48 55 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true ); 49 56 57 ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic = true); 58 50 59 /// generate the type of a copy constructor for paramType. 51 60 /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic 52 61 FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true ); 53 62 63 /// Enum for loop direction 64 enum LoopDirection { LoopBackward, LoopForward }; 65 54 66 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 55 67 template< typename OutputIterator > 56 68 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 69 70 template< typename OutIter > 71 ast::ptr< ast::Stmt > genCall( 72 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 73 const CodeLocation & loc, const std::string & fname, OutIter && out, 74 const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward ); 57 75 58 76 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. … … 103 121 104 122 *out++ = new ExprStmt( fExpr ); 123 124 srcParam.clearArrayIndices(); 125 126 return listInit; 127 } 128 129 /// inserts into out a generated call expression to function fname with arguments dstParam and 130 /// srcParam. Should only be called with non-array types. 131 /// optionally returns a statement which must be inserted prior to the containing loop, if 132 /// there is one 133 template< typename OutIter > 134 ast::ptr< ast::Stmt > genScalarCall( 135 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 136 const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type, 137 const ast::Type * addCast = nullptr 138 ) { 139 bool isReferenceCtorDtor = false; 140 if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { 141 // reference constructors are essentially application of the rebind operator. 142 // apply & to both arguments, do not need a cast 143 fname = "?=?"; 144 dstParam = new ast::AddressExpr{ dstParam }; 145 addCast = nullptr; 146 isReferenceCtorDtor = true; 147 } 148 149 // want to be able to generate assignment, ctor, and dtor generically, so fname is one of 150 // "?=?", "?{}", or "^?{}" 151 ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } }; 152 153 if ( addCast ) { 154 // cast to T& with qualifiers removed, so that qualified objects can be constructed and 155 // destructed with the same functions as non-qualified objects. Unfortunately, lvalue 156 // is considered a qualifier - for AddressExpr to resolve, its argument must have an 157 // lvalue-qualified type, so remove all qualifiers except lvalue. 158 // xxx -- old code actually removed lvalue too... 159 ast::ptr< ast::Type > guard = addCast; // prevent castType from mutating addCast 160 ast::ptr< ast::Type > castType = addCast; 161 ast::remove_qualifiers( 162 castType, 163 ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic ); 164 dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } }; 165 } 166 fExpr->args.emplace_back( dstParam ); 167 168 ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr ); 169 170 // fetch next set of arguments 171 ++srcParam; 172 173 // return if adding reference fails -- will happen on default ctor and dtor 174 if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit; 175 176 std::vector< ast::ptr< ast::Expr > > args = *srcParam; 177 splice( fExpr->args, args ); 178 179 *out++ = new ast::ExprStmt{ loc, fExpr }; 105 180 106 181 srcParam.clearArrayIndices(); … … 173 248 } 174 249 250 /// Store in out a loop which calls fname on each element of the array with srcParam and 251 /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0 252 template< typename OutIter > 253 void genArrayCall( 254 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 255 const CodeLocation & loc, const std::string & fname, OutIter && out, 256 const ast::ArrayType * array, const ast::Type * addCast = nullptr, 257 LoopDirection forward = LoopForward 258 ) { 259 static UniqueName indexName( "_index" ); 260 261 // for a flexible array member nothing is done -- user must define own assignment 262 if ( ! array->dimension ) return; 263 264 if ( addCast ) { 265 // peel off array layer from cast 266 addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base; 267 } 268 269 ast::ptr< ast::Expr > begin, end; 270 std::string cmp, update; 271 272 if ( forward ) { 273 // generate: for ( int i = 0; i < N; ++i ) 274 begin = ast::ConstantExpr::from_int( loc, 0 ); 275 end = array->dimension; 276 cmp = "?<?"; 277 update = "++?"; 278 } else { 279 // generate: for ( int i = N-1; i >= 0; --i ) 280 begin = ast::UntypedExpr::createCall( loc, "?-?", 281 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } ); 282 end = ast::ConstantExpr::from_int( loc, 0 ); 283 cmp = "?>=?"; 284 update = "--?"; 285 } 286 287 ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{ 288 loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt }, 289 new ast::SingleInit{ loc, begin } }; 290 ast::ptr< ast::Expr > indexVar = new ast::VariableExpr{ loc, index }; 291 292 ast::ptr< ast::Expr > cond = ast::UntypedExpr::createCall( 293 loc, cmp, { indexVar, end } ); 294 295 ast::ptr< ast::Expr > inc = ast::UntypedExpr::createCall( 296 loc, update, { indexVar } ); 297 298 ast::ptr< ast::Expr > dstIndex = ast::UntypedExpr::createCall( 299 loc, "?[?]", { dstParam, indexVar } ); 300 301 // srcParam must keep track of the array indices to build the source parameter and/or 302 // array list initializer 303 srcParam.addArrayIndex( indexVar, array->dimension ); 304 305 // for stmt's body, eventually containing call 306 ast::CompoundStmt * body = new ast::CompoundStmt{ loc }; 307 ast::ptr< ast::Stmt > listInit = genCall( 308 srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast, 309 forward ); 310 311 // block containing the stmt and index variable 312 ast::CompoundStmt * block = new ast::CompoundStmt{ loc }; 313 block->push_back( new ast::DeclStmt{ loc, index } ); 314 if ( listInit ) { block->push_back( listInit ); } 315 block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } ); 316 317 *out++ = block; 318 } 319 175 320 template< typename OutputIterator > 176 321 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) { … … 180 325 } else { 181 326 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 327 } 328 } 329 330 template< typename OutIter > 331 ast::ptr< ast::Stmt > genCall( 332 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 333 const CodeLocation & loc, const std::string & fname, OutIter && out, 334 const ast::Type * type, const ast::Type * addCast, LoopDirection forward 335 ) { 336 if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) { 337 genArrayCall( 338 srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast, 339 forward ); 340 return {}; 341 } else { 342 return genScalarCall( 343 srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast ); 182 344 } 183 345 } … … 217 379 } 218 380 381 static inline ast::ptr< ast::Stmt > genImplicitCall( 382 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 383 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 384 LoopDirection forward = LoopForward 385 ) { 386 // unnamed bit fields are not copied as they cannot be accessed 387 if ( isUnnamedBitfield( obj ) ) return {}; 388 389 ast::ptr< ast::Type > addCast; 390 if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) { 391 assert( dstParam->result ); 392 addCast = dstParam->result; 393 } 394 395 std::vector< ast::ptr< ast::Stmt > > stmts; 396 genCall( 397 srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward ); 398 399 if ( stmts.empty() ) { 400 return {}; 401 } else if ( stmts.size() == 1 ) { 402 const ast::Stmt * callStmt = stmts.front(); 403 if ( addCast ) { 404 // implicitly generated ctor/dtor calls should be wrapped so that later passes are 405 // aware they were generated. 406 callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt }; 407 } 408 return callStmt; 409 } else { 410 assert( false ); 411 return {}; 412 } 413 } 219 414 } // namespace SymTab 220 415 -
src/SymTab/FixFunction.cc
r24d6572 r34b4268 21 21 #include "AST/Pass.hpp" 22 22 #include "AST/Type.hpp" 23 #include "Common/utility.h" // for copy23 #include "Common/utility.h" // for maybeClone, copy 24 24 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarati... 25 25 #include "SynTree/Expression.h" // for Expression -
src/SymTab/Indexer.cc
r24d6572 r34b4268 31 31 #include "InitTweak/InitTweak.h" // for isConstructor, isCopyFunction, isC... 32 32 #include "Mangler.h" // for Mangler 33 #include "ResolvExpr/AlternativeFinder.h" // for referenceToRvalueConversion 34 #include "ResolvExpr/Unify.h" // for typesCompatible 33 #include "ResolvExpr/typeops.h" // for typesCompatible 35 34 #include "SynTree/LinkageSpec.h" // for isMangled, isOverridable, Spec 36 35 #include "SynTree/Constant.h" // for Constant -
src/SymTab/Mangler.cc
r24d6572 r34b4268 24 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 25 25 #include "Common/PassVisitor.h" 26 #include "Common/ToString.hpp" // for toCString27 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 28 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 29 29 #include "SynTree/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... … … 439 439 private: 440 440 void mangleDecl( const ast::DeclWithType *declaration ); 441 void mangleRef( const ast::BaseInstType *refType, const std::string &prefix );441 void mangleRef( const ast::BaseInstType *refType, std::string prefix ); 442 442 443 443 void printQualifiers( const ast::Type *type ); … … 535 535 } 536 536 537 __attribute__((unused)) 538 inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) { 539 std::vector< ast::ptr< ast::Type > > ret; 540 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ), 541 std::mem_fun( &ast::DeclWithType::get_type ) ); 542 return ret; 543 } 544 537 545 void Mangler_new::postvisit( const ast::FunctionType * functionType ) { 538 546 printQualifiers( functionType ); … … 550 558 } 551 559 552 void Mangler_new::mangleRef( 553 const ast::BaseInstType * refType, const std::string & prefix ) { 560 void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) { 554 561 printQualifiers( refType ); 555 562 556 563 mangleName += prefix + std::to_string( refType->name.length() ) + refType->name; 557 564 558 if ( mangleGenericParams && ! refType->params.empty() ) { 559 mangleName += "_"; 560 for ( const ast::Expr * param : refType->params ) { 561 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 562 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 563 maybeAccept( paramType->type.get(), *visitor ); 565 if ( mangleGenericParams ) { 566 if ( ! refType->params.empty() ) { 567 mangleName += "_"; 568 for ( const ast::Expr * param : refType->params ) { 569 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 570 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 571 maybeAccept( paramType->type.get(), *visitor ); 572 } 573 mangleName += "_"; 564 574 } 565 mangleName += "_";566 575 } 567 576 } … … 647 656 } 648 657 649 // For debugging:650 658 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) { 651 659 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) { … … 657 665 // skip if not including qualifiers 658 666 if ( typeMode ) return; 659 auto funcType = dynamic_cast<const ast::FunctionType *>( type ); 660 if ( funcType && !funcType->forall.empty() ) { 661 std::list< std::string > assertionNames; 662 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 663 mangleName += Encoding::forall; 664 for ( auto & decl : funcType->forall ) { 665 switch ( decl->kind ) { 666 case ast::TypeDecl::Dtype: 667 dcount++; 668 break; 669 case ast::TypeDecl::Ftype: 670 fcount++; 671 break; 672 case ast::TypeDecl::Ttype: 673 vcount++; 674 break; 675 default: 676 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() ); 677 } // switch 678 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 679 } // for 680 for ( auto & assert : funcType->assertions ) { 681 assertionNames.push_back( ast::Pass<Mangler_new>::read( 682 assert->var.get(), 683 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); 684 acount++; 685 } // for 686 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_"; 687 for ( const auto & a : assertionNames ) mangleName += a; 688 mangleName += "_"; 667 if ( auto ptype = dynamic_cast< const ast::FunctionType * >(type) ) { 668 if ( ! ptype->forall.empty() ) { 669 std::list< std::string > assertionNames; 670 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 671 mangleName += Encoding::forall; 672 for ( auto & decl : ptype->forall ) { 673 switch ( decl->kind ) { 674 case ast::TypeDecl::Kind::Dtype: 675 dcount++; 676 break; 677 case ast::TypeDecl::Kind::Ftype: 678 fcount++; 679 break; 680 case ast::TypeDecl::Kind::Ttype: 681 vcount++; 682 break; 683 default: 684 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() ); 685 } // switch 686 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 687 } // for 688 for ( auto & assert : ptype->assertions ) { 689 assertionNames.push_back( ast::Pass<Mangler_new>::read( 690 assert->var.get(), 691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); 692 acount++; 693 } // for 694 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_"; 695 for(const auto & a : assertionNames) mangleName += a; 696 // std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 697 mangleName += "_"; 698 } // if 689 699 } // if 690 700 if ( ! inFunctionType ) { -
src/SymTab/Validate.cc
r24d6572 r34b4268 55 55 #include "Common/ScopedMap.h" // for ScopedMap 56 56 #include "Common/SemanticError.h" // for SemanticError 57 #include "Common/ToString.hpp" // for toCString58 57 #include "Common/UniqueName.h" // for UniqueName 59 #include "Common/utility.h" // for cloneAll, deleteAll58 #include "Common/utility.h" // for operator+, cloneAll, deleteAll 60 59 #include "CompilationState.h" // skip some passes in new-ast build 61 60 #include "Concurrency/Keywords.h" // for applyKeywords … … 64 63 #include "InitTweak/GenInit.h" // for fixReturnStatements 65 64 #include "InitTweak/InitTweak.h" // for isCtorDtorAssign 66 #include "ResolvExpr/typeops.h" // for extractResultType 67 #include "ResolvExpr/Unify.h" // for typesCompatible 65 #include "ResolvExpr/typeops.h" // for typesCompatible 68 66 #include "ResolvExpr/Resolver.h" // for findSingleExpression 69 67 #include "ResolvExpr/ResolveTypeof.h" // for resolveTypeof … … 864 862 865 863 void ReplaceTypedef::premutate( TypeDecl * typeDecl ) { 866 typedefNames.erase( typeDecl->name ); 864 TypedefMap::iterator i = typedefNames.find( typeDecl->name ); 865 if ( i != typedefNames.end() ) { 866 typedefNames.erase( i ) ; 867 } // if 868 867 869 typedeclNames.insert( typeDecl->name, typeDecl ); 868 870 } -
src/SymTab/ValidateType.cc
r24d6572 r34b4268 18 18 #include "CodeGen/OperatorTable.h" 19 19 #include "Common/PassVisitor.h" 20 #include "Common/ToString.hpp"21 20 #include "SymTab/FixFunction.h" 22 21 #include "SynTree/Declaration.h" -
src/SymTab/module.mk
r24d6572 r34b4268 20 20 SymTab/FixFunction.cc \ 21 21 SymTab/FixFunction.h \ 22 SymTab/GenImplicitCall.cpp \23 SymTab/GenImplicitCall.hpp \24 22 SymTab/Indexer.cc \ 25 23 SymTab/Indexer.h \ -
src/SynTree/AggregateDecl.cc
r24d6572 r34b4268 19 19 20 20 #include "Attribute.h" // for Attribute 21 #include "Common/Eval.h" // for eval22 21 #include "Common/utility.h" // for printAll, cloneAll, deleteAll 23 22 #include "Declaration.h" // for AggregateDecl, TypeDecl, Declaration -
src/SynTree/ApplicationExpr.cc
r24d6572 r34b4268 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ApplicationExpr.cc --7 // ApplicationExpr.cc.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 26 26 #include "Expression.h" // for ParamEntry, ApplicationExpr, Expression 27 27 #include "InitTweak/InitTweak.h" // for getFunction 28 #include "ResolvExpr/ Unify.h"// for extractResultType28 #include "ResolvExpr/typeops.h" // for extractResultType 29 29 #include "Type.h" // for Type, PointerType, FunctionType 30 30 -
src/SynTree/BasicType.cc
r24d6572 r34b4268 29 29 } 30 30 31 bool BasicType::isWholeNumber() const { 32 return kind == Bool || 33 kind ==Char || 34 kind == SignedChar || 35 kind == UnsignedChar || 36 kind == ShortSignedInt || 37 kind == ShortUnsignedInt || 38 kind == SignedInt || 39 kind == UnsignedInt || 40 kind == LongSignedInt || 41 kind == LongUnsignedInt || 42 kind == LongLongSignedInt || 43 kind ==LongLongUnsignedInt || 44 kind == SignedInt128 || 45 kind == UnsignedInt128; 46 } 47 31 48 bool BasicType::isInteger() const { 32 49 return kind <= UnsignedInt128; -
src/SynTree/FunctionDecl.cc
r24d6572 r34b4268 87 87 } // if 88 88 89 if ( !withExprs.empty() ) {90 os << indent << "... with clause" << std::endl;91 os << indent + 1;92 printAll( withExprs, os, indent + 1 );93 }94 95 89 if ( statements ) { 96 90 os << indent << "... with body" << endl << indent+1; -
src/SynTree/Type.cc
r24d6572 r34b4268 16 16 17 17 #include "Attribute.h" // for Attribute 18 #include "Common/ToString.hpp" // for toCString19 18 #include "Common/utility.h" // for cloneAll, deleteAll, printAll 20 19 #include "InitTweak/InitTweak.h" // for getPointerBase … … 106 105 int Type::referenceDepth() const { return 0; } 107 106 108 AggregateDecl * Type::getAggr() const {109 assertf( false, "Non-aggregate type: %s", toCString( this ) );110 }111 112 107 TypeSubstitution Type::genericSubstitution() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); } 113 108 -
src/SynTree/Type.h
r24d6572 r34b4268 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 : Sun Feb 19 22:37:10 202313 // Update Count : 17 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jul 14 15:40:00 2021 13 // Update Count : 171 14 14 // 15 15 … … 23 23 24 24 #include "BaseSyntaxNode.h" // for BaseSyntaxNode 25 #include "Common/ Iterate.hpp"// for operator+25 #include "Common/utility.h" // for operator+ 26 26 #include "Mutator.h" // for Mutator 27 27 #include "SynTree.h" // for AST nodes … … 124 124 bool operator!=( Qualifiers other ) const { return (val & Mask) != (other.val & Mask); } 125 125 bool operator<=( Qualifiers other ) const { 126 return is_const <= other.is_const // Any non-const converts to const without cost127 && is_volatile <= other.is_volatile //Any non-volatile converts to volatile without cost128 && is_mutex >= other.is_mutex //Any mutex converts to non-mutex without cost129 && is_atomic == other.is_atomic; //No conversion from atomic to non atomic is free126 return is_const <= other.is_const //Any non-const converts to const without cost 127 && is_volatile <= other.is_volatile //Any non-volatile converts to volatile without cost 128 && is_mutex >= other.is_mutex //Any mutex converts to non-mutex without cost 129 && is_atomic == other.is_atomic; //No conversion from atomic to non atomic is free 130 130 } 131 131 bool operator<( Qualifiers other ) const { return *this != other && *this <= other; } … … 185 185 virtual bool isComplete() const { return true; } 186 186 187 virtual AggregateDecl * getAggr() const ;187 virtual AggregateDecl * getAggr() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); } 188 188 189 189 virtual TypeSubstitution genericSubstitution() const; 190 190 191 virtual Type * clone() const = 0;191 virtual Type *clone() const = 0; 192 192 virtual void accept( Visitor & v ) = 0; 193 193 virtual void accept( Visitor & v ) const = 0; 194 virtual Type * acceptMutator( Mutator & m ) = 0;194 virtual Type *acceptMutator( Mutator & m ) = 0; 195 195 virtual void print( std::ostream & os, Indenter indent = {} ) const; 196 196 }; … … 207 207 virtual bool isComplete() const override { return false; } 208 208 209 virtual VoidType * clone() const override { return new VoidType( *this ); }210 virtual void accept( Visitor & v ) override { v.visit( this ); } 211 virtual void accept( Visitor & v ) const override { v.visit( this ); } 212 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }209 virtual VoidType *clone() const override { return new VoidType( *this ); } 210 virtual void accept( Visitor & v ) override { v.visit( this ); } 211 virtual void accept( Visitor & v ) const override { v.visit( this ); } 212 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 213 213 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 214 214 }; … … 259 259 // GENERATED END 260 260 261 static const char * typeNames[];// string names for basic types, MUST MATCH with Kind261 static const char *typeNames[]; // string names for basic types, MUST MATCH with Kind 262 262 263 263 BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); … … 266 266 void set_kind( Kind newValue ) { kind = newValue; } 267 267 268 virtual BasicType * clone() const override { return new BasicType( *this ); } 269 virtual void accept( Visitor & v ) override { v.visit( this ); } 270 virtual void accept( Visitor & v ) const override { v.visit( this ); } 271 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 272 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 268 virtual BasicType *clone() const override { return new BasicType( *this ); } 269 virtual void accept( Visitor & v ) override { v.visit( this ); } 270 virtual void accept( Visitor & v ) const override { v.visit( this ); } 271 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 272 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 273 bool isWholeNumber() const; 273 274 bool isInteger() const; 274 275 }; … … 279 280 280 281 // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] ) 281 Expression * dimension;282 Expression *dimension; 282 283 bool isVarLen; 283 284 bool isStatic; 284 285 285 PointerType( const Type::Qualifiers & tq, Type * base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );286 PointerType( const Type::Qualifiers & tq, Type * base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );286 PointerType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 287 PointerType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 287 288 PointerType( const PointerType& ); 288 289 virtual ~PointerType(); 289 290 290 Type * get_base() { return base; }291 void set_base( Type * newValue ) { base = newValue; }292 Expression * get_dimension() { return dimension; }293 void set_dimension( Expression * newValue ) { dimension = newValue; }291 Type *get_base() { return base; } 292 void set_base( Type *newValue ) { base = newValue; } 293 Expression *get_dimension() { return dimension; } 294 void set_dimension( Expression *newValue ) { dimension = newValue; } 294 295 bool get_isVarLen() { return isVarLen; } 295 296 void set_isVarLen( bool newValue ) { isVarLen = newValue; } … … 301 302 virtual bool isComplete() const override { return ! isVarLen; } 302 303 303 virtual PointerType * clone() const override { return new PointerType( *this ); }304 virtual void accept( Visitor & v ) override { v.visit( this ); } 305 virtual void accept( Visitor & v ) const override { v.visit( this ); } 306 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }304 virtual PointerType *clone() const override { return new PointerType( *this ); } 305 virtual void accept( Visitor & v ) override { v.visit( this ); } 306 virtual void accept( Visitor & v ) const override { v.visit( this ); } 307 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 307 308 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 308 309 }; … … 310 311 class ArrayType : public Type { 311 312 public: 312 Type * base;313 Expression * dimension;313 Type *base; 314 Expression *dimension; 314 315 bool isVarLen; 315 316 bool isStatic; 316 317 317 ArrayType( const Type::Qualifiers & tq, Type * base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );318 ArrayType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 318 319 ArrayType( const ArrayType& ); 319 320 virtual ~ArrayType(); 320 321 321 Type * get_base() { return base; }322 void set_base( Type * newValue ) { base = newValue; }323 Expression * get_dimension() { return dimension; }324 void set_dimension( Expression * newValue ) { dimension = newValue; }322 Type *get_base() { return base; } 323 void set_base( Type *newValue ) { base = newValue; } 324 Expression *get_dimension() { return dimension; } 325 void set_dimension( Expression *newValue ) { dimension = newValue; } 325 326 bool get_isVarLen() { return isVarLen; } 326 327 void set_isVarLen( bool newValue ) { isVarLen = newValue; } … … 333 334 virtual bool isComplete() const override { return dimension || isVarLen; } 334 335 335 virtual ArrayType * clone() const override { return new ArrayType( *this ); }336 virtual void accept( Visitor & v ) override { v.visit( this ); } 337 virtual void accept( Visitor & v ) const override { v.visit( this ); } 338 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }336 virtual ArrayType *clone() const override { return new ArrayType( *this ); } 337 virtual void accept( Visitor & v ) override { v.visit( this ); } 338 virtual void accept( Visitor & v ) const override { v.visit( this ); } 339 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 339 340 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 340 341 }; … … 348 349 virtual ~QualifiedType(); 349 350 350 virtual QualifiedType * clone() const override { return new QualifiedType( *this ); }351 virtual void accept( Visitor & v ) override { v.visit( this ); } 352 virtual void accept( Visitor & v ) const override { v.visit( this ); } 353 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }351 virtual QualifiedType *clone() const override { return new QualifiedType( *this ); } 352 virtual void accept( Visitor & v ) override { v.visit( this ); } 353 virtual void accept( Visitor & v ) const override { v.visit( this ); } 354 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 354 355 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 355 356 }; … … 357 358 class ReferenceType : public Type { 358 359 public: 359 Type * base;360 361 ReferenceType( const Type::Qualifiers & tq, Type * base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );360 Type *base; 361 362 ReferenceType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 362 363 ReferenceType( const ReferenceType & ); 363 364 virtual ~ReferenceType(); 364 365 365 Type * get_base() { return base; }366 void set_base( Type * newValue ) { base = newValue; }366 Type *get_base() { return base; } 367 void set_base( Type *newValue ) { base = newValue; } 367 368 368 369 virtual int referenceDepth() const override; … … 375 376 virtual TypeSubstitution genericSubstitution() const override; 376 377 377 virtual ReferenceType * clone() const override { return new ReferenceType( *this ); }378 virtual void accept( Visitor & v ) override { v.visit( this ); } 379 virtual void accept( Visitor & v ) const override { v.visit( this ); } 380 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }378 virtual ReferenceType *clone() const override { return new ReferenceType( *this ); } 379 virtual void accept( Visitor & v ) override { v.visit( this ); } 380 virtual void accept( Visitor & v ) const override { v.visit( this ); } 381 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 381 382 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 382 383 }; … … 405 406 bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; } 406 407 407 virtual FunctionType * clone() const override { return new FunctionType( *this ); }408 virtual void accept( Visitor & v ) override { v.visit( this ); } 409 virtual void accept( Visitor & v ) const override { v.visit( this ); } 410 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }408 virtual FunctionType *clone() const override { return new FunctionType( *this ); } 409 virtual void accept( Visitor & v ) override { v.visit( this ); } 410 virtual void accept( Visitor & v ) const override { v.visit( this ); } 411 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 411 412 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 412 413 }; … … 414 415 class ReferenceToType : public Type { 415 416 public: 416 std::list< Expression * > parameters;417 std::list< Expression* > parameters; 417 418 std::string name; 418 419 bool hoistType; … … 428 429 void set_hoistType( bool newValue ) { hoistType = newValue; } 429 430 430 virtual ReferenceToType * clone() const override = 0;431 virtual ReferenceToType *clone() const override = 0; 431 432 virtual void accept( Visitor & v ) override = 0; 432 virtual Type * acceptMutator( Mutator & m ) override = 0;433 virtual Type *acceptMutator( Mutator & m ) override = 0; 433 434 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 434 435 … … 443 444 // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree, 444 445 // where the structure used in this type is actually defined 445 StructDecl * baseStruct;446 StructDecl *baseStruct; 446 447 447 448 StructInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ), baseStruct( 0 ) {} … … 449 450 StructInstType( const StructInstType & other ) : Parent( other ), baseStruct( other.baseStruct ) {} 450 451 451 StructDecl * get_baseStruct() const { return baseStruct; }452 void set_baseStruct( StructDecl * newValue ) { baseStruct = newValue; }452 StructDecl *get_baseStruct() const { return baseStruct; } 453 void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; } 453 454 454 455 /// Accesses generic parameters of base struct (NULL if none such) … … 466 467 void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override; 467 468 468 virtual StructInstType * clone() const override { return new StructInstType( *this ); }469 virtual void accept( Visitor & v ) override { v.visit( this ); } 470 virtual void accept( Visitor & v ) const override { v.visit( this ); } 471 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }469 virtual StructInstType *clone() const override { return new StructInstType( *this ); } 470 virtual void accept( Visitor & v ) override { v.visit( this ); } 471 virtual void accept( Visitor & v ) const override { v.visit( this ); } 472 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 472 473 473 474 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 481 482 // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree, 482 483 // where the union used in this type is actually defined 483 UnionDecl * baseUnion;484 UnionDecl *baseUnion; 484 485 485 486 UnionInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ), baseUnion( 0 ) {} … … 487 488 UnionInstType( const UnionInstType & other ) : Parent( other ), baseUnion( other.baseUnion ) {} 488 489 489 UnionDecl * get_baseUnion() const { return baseUnion; }490 UnionDecl *get_baseUnion() const { return baseUnion; } 490 491 void set_baseUnion( UnionDecl * newValue ) { baseUnion = newValue; } 491 492 … … 504 505 void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override; 505 506 506 virtual UnionInstType * clone() const override { return new UnionInstType( *this ); }507 virtual void accept( Visitor & v ) override { v.visit( this ); } 508 virtual void accept( Visitor & v ) const override { v.visit( this ); } 509 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }507 virtual UnionInstType *clone() const override { return new UnionInstType( *this ); } 508 virtual void accept( Visitor & v ) override { v.visit( this ); } 509 virtual void accept( Visitor & v ) const override { v.visit( this ); } 510 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 510 511 511 512 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 519 520 // this decl is not "owned" by the enum inst; it is merely a pointer to elsewhere in the tree, 520 521 // where the enum used in this type is actually defined 521 EnumDecl * baseEnum = nullptr;522 EnumDecl *baseEnum = nullptr; 522 523 523 524 EnumInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {} … … 525 526 EnumInstType( const EnumInstType & other ) : Parent( other ), baseEnum( other.baseEnum ) {} 526 527 527 EnumDecl * get_baseEnum() const { return baseEnum; }528 void set_baseEnum( EnumDecl * newValue ) { baseEnum = newValue; }528 EnumDecl *get_baseEnum() const { return baseEnum; } 529 void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; } 529 530 530 531 virtual bool isComplete() const override; … … 532 533 virtual AggregateDecl * getAggr() const override; 533 534 534 virtual EnumInstType * clone() const override { return new EnumInstType( *this ); }535 virtual void accept( Visitor & v ) override { v.visit( this ); } 536 virtual void accept( Visitor & v ) const override { v.visit( this ); } 537 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }535 virtual EnumInstType *clone() const override { return new EnumInstType( *this ); } 536 virtual void accept( Visitor & v ) override { v.visit( this ); } 537 virtual void accept( Visitor & v ) const override { v.visit( this ); } 538 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 538 539 539 540 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 556 557 virtual bool isComplete() const override; 557 558 558 virtual TraitInstType * clone() const override { return new TraitInstType( *this ); }559 virtual void accept( Visitor & v ) override { v.visit( this ); } 560 virtual void accept( Visitor & v ) const override { v.visit( this ); } 561 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }559 virtual TraitInstType *clone() const override { return new TraitInstType( *this ); } 560 virtual void accept( Visitor & v ) override { v.visit( this ); } 561 virtual void accept( Visitor & v ) const override { v.visit( this ); } 562 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 562 563 private: 563 564 virtual std::string typeString() const override; … … 569 570 // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree, 570 571 // where the type used here is actually defined 571 TypeDecl * baseType;572 TypeDecl *baseType; 572 573 bool isFtype; 573 574 574 TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl * baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >() );575 TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl *baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 575 576 TypeInstType( const Type::Qualifiers & tq, const std::string & name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 576 577 TypeInstType( const TypeInstType & other ); 577 578 ~TypeInstType(); 578 579 579 TypeDecl * get_baseType() const { return baseType; }580 void set_baseType( TypeDecl * newValue );580 TypeDecl *get_baseType() const { return baseType; } 581 void set_baseType( TypeDecl *newValue ); 581 582 bool get_isFtype() const { return isFtype; } 582 583 void set_isFtype( bool newValue ) { isFtype = newValue; } … … 584 585 virtual bool isComplete() const override; 585 586 586 virtual TypeInstType * clone() const override { return new TypeInstType( *this ); }587 virtual void accept( Visitor & v ) override { v.visit( this ); } 588 virtual void accept( Visitor & v ) const override { v.visit( this ); } 589 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }587 virtual TypeInstType *clone() const override { return new TypeInstType( *this ); } 588 virtual void accept( Visitor & v ) override { v.visit( this ); } 589 virtual void accept( Visitor & v ) const override { v.visit( this ); } 590 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 590 591 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 591 592 private: … … 622 623 // virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness 623 624 624 virtual TupleType * clone() const override { return new TupleType( *this ); }625 virtual void accept( Visitor & v ) override { v.visit( this ); } 626 virtual void accept( Visitor & v ) const override { v.visit( this ); } 627 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }625 virtual TupleType *clone() const override { return new TupleType( *this ); } 626 virtual void accept( Visitor & v ) override { v.visit( this ); } 627 virtual void accept( Visitor & v ) const override { v.visit( this ); } 628 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 628 629 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 629 630 }; … … 631 632 class TypeofType : public Type { 632 633 public: 633 Expression * expr;///< expression to take the type of634 bool is_basetypeof; ///< true iff is basetypeof type635 636 TypeofType( const Type::Qualifiers & tq, Expression * expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );637 TypeofType( const Type::Qualifiers & tq, Expression * expr, bool is_basetypeof,634 Expression *expr; ///< expression to take the type of 635 bool is_basetypeof; ///< true iff is basetypeof type 636 637 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 638 TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 638 639 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 639 640 TypeofType( const TypeofType& ); 640 641 virtual ~TypeofType(); 641 642 642 Expression * get_expr() const { return expr; }643 void set_expr( Expression * newValue ) { expr = newValue; }643 Expression *get_expr() const { return expr; } 644 void set_expr( Expression *newValue ) { expr = newValue; } 644 645 645 646 virtual bool isComplete() const override { assert( false ); return false; } 646 647 647 virtual TypeofType * clone() const override { return new TypeofType( *this ); }648 virtual void accept( Visitor & v ) override { v.visit( this ); } 649 virtual void accept( Visitor & v ) const override { v.visit( this ); } 650 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }648 virtual TypeofType *clone() const override { return new TypeofType( *this ); } 649 virtual void accept( Visitor & v ) override { v.visit( this ); } 650 virtual void accept( Visitor & v ) const override { v.visit( this ); } 651 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 651 652 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 652 653 }; … … 654 655 class VTableType : public Type { 655 656 public: 656 Type * base;657 658 VTableType( const Type::Qualifiers & tq, Type * base,657 Type *base; 658 659 VTableType( const Type::Qualifiers & tq, Type *base, 659 660 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 660 661 VTableType( const VTableType & ); 661 662 virtual ~VTableType(); 662 663 663 Type * get_base() { return base; }664 void set_base( Type * newValue ) { base = newValue; }665 666 virtual VTableType * clone() const override { return new VTableType( *this ); }667 virtual void accept( Visitor & v ) override { v.visit( this ); } 668 virtual void accept( Visitor & v ) const override { v.visit( this ); } 669 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }664 Type *get_base() { return base; } 665 void set_base( Type *newValue ) { base = newValue; } 666 667 virtual VTableType *clone() const override { return new VTableType( *this ); } 668 virtual void accept( Visitor & v ) override { v.visit( this ); } 669 virtual void accept( Visitor & v ) const override { v.visit( this ); } 670 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 670 671 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 671 672 }; … … 674 675 public: 675 676 std::string name; 676 Expression * expr;677 Type * type;677 Expression *expr; 678 Type *type; 678 679 bool isType; 679 680 680 AttrType( const Type::Qualifiers & tq, const std::string & name, Expression * expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );681 AttrType( const Type::Qualifiers & tq, const std::string & name, Type * type, const std::list< Attribute * > & attributes = std::list< Attribute * >() );681 AttrType( const Type::Qualifiers & tq, const std::string & name, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 682 AttrType( const Type::Qualifiers & tq, const std::string & name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 682 683 AttrType( const AttrType& ); 683 684 virtual ~AttrType(); … … 685 686 const std::string & get_name() const { return name; } 686 687 void set_name( const std::string & newValue ) { name = newValue; } 687 Expression * get_expr() const { return expr; }688 void set_expr( Expression * newValue ) { expr = newValue; }689 Type * get_type() const { return type; }690 void set_type( Type * newValue ) { type = newValue; }688 Expression *get_expr() const { return expr; } 689 void set_expr( Expression *newValue ) { expr = newValue; } 690 Type *get_type() const { return type; } 691 void set_type( Type *newValue ) { type = newValue; } 691 692 bool get_isType() const { return isType; } 692 693 void set_isType( bool newValue ) { isType = newValue; } … … 694 695 virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here 695 696 696 virtual AttrType * clone() const override { return new AttrType( *this ); }697 virtual void accept( Visitor & v ) override { v.visit( this ); } 698 virtual void accept( Visitor & v ) const override { v.visit( this ); } 699 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }697 virtual AttrType *clone() const override { return new AttrType( *this ); } 698 virtual void accept( Visitor & v ) override { v.visit( this ); } 699 virtual void accept( Visitor & v ) const override { v.visit( this ); } 700 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 700 701 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 701 702 }; … … 709 710 virtual bool isComplete() const override{ return true; } // xxx - is this right? 710 711 711 virtual VarArgsType * clone() const override { return new VarArgsType( *this ); }712 virtual void accept( Visitor & v ) override { v.visit( this ); } 713 virtual void accept( Visitor & v ) const override { v.visit( this ); } 714 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }712 virtual VarArgsType *clone() const override { return new VarArgsType( *this ); } 713 virtual void accept( Visitor & v ) override { v.visit( this ); } 714 virtual void accept( Visitor & v ) const override { v.visit( this ); } 715 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 715 716 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 716 717 }; … … 722 723 ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 723 724 724 virtual ZeroType * clone() const override { return new ZeroType( *this ); }725 virtual void accept( Visitor & v ) override { v.visit( this ); } 726 virtual void accept( Visitor & v ) const override { v.visit( this ); } 727 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }725 virtual ZeroType *clone() const override { return new ZeroType( *this ); } 726 virtual void accept( Visitor & v ) override { v.visit( this ); } 727 virtual void accept( Visitor & v ) const override { v.visit( this ); } 728 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 728 729 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 729 730 }; … … 735 736 OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 736 737 737 virtual OneType * clone() const override { return new OneType( *this ); }738 virtual void accept( Visitor & v ) override { v.visit( this ); } 739 virtual void accept( Visitor & v ) const override { v.visit( this ); } 740 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }738 virtual OneType *clone() const override { return new OneType( *this ); } 739 virtual void accept( Visitor & v ) override { v.visit( this ); } 740 virtual void accept( Visitor & v ) const override { v.visit( this ); } 741 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 741 742 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 742 743 }; … … 746 747 GlobalScopeType(); 747 748 748 virtual GlobalScopeType * clone() const override { return new GlobalScopeType( *this ); }749 virtual void accept( Visitor & v ) override { v.visit( this ); } 750 virtual void accept( Visitor & v ) const override { v.visit( this ); } 751 virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }749 virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); } 750 virtual void accept( Visitor & v ) override { v.visit( this ); } 751 virtual void accept( Visitor & v ) const override { v.visit( this ); } 752 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 752 753 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 753 754 }; -
src/Tuples/Explode.cc
r24d6572 r34b4268 17 17 #include <list> // for list 18 18 19 #include "AST/Pass.hpp" // for Pass20 19 #include "SynTree/Mutator.h" // for Mutator 21 20 #include "Common/PassVisitor.h" // for PassVisitor -
src/Validate/Autogen.cpp
r24d6572 r34b4268 25 25 26 26 #include "AST/Attribute.hpp" 27 #include "AST/Copy.hpp"28 27 #include "AST/Create.hpp" 29 28 #include "AST/Decl.hpp" … … 40 39 #include "InitTweak/GenInit.h" // for fixReturnStatements 41 40 #include "InitTweak/InitTweak.h" // for isAssignment, isCopyConstructor 42 #include "SymTab/GenImplicitCall.hpp" // for genImplicitCall43 41 #include "SymTab/Mangler.h" // for Mangler 44 42 #include "CompilationState.h" 43 44 // TODO: The other new ast function should be moved over to this file. 45 #include "SymTab/Autogen.h" 45 46 46 47 namespace Validate { … … 93 94 94 95 const CodeLocation& getLocation() const { return getDecl()->location; } 95 ast::FunctionDecl * genProto( std::string&& name,96 ast::FunctionDecl * genProto( const std::string& name, 96 97 std::vector<ast::ptr<ast::DeclWithType>>&& params, 97 98 std::vector<ast::ptr<ast::DeclWithType>>&& returns ) const; … … 321 322 void FuncGenerator::produceDecl( const ast::FunctionDecl * decl ) { 322 323 assert( nullptr != decl->stmts ); 323 const auto & oldParams = getGenericParams(type);324 assert( decl->type_params.size() == oldParams.size());325 326 /*327 ast::DeclReplacer::TypeMap typeMap;328 for (auto it = oldParams.begin(), jt = decl->type_params.begin(); it != oldParams.end(); ++it, ++jt) {329 typeMap.emplace(*it, *jt);330 }331 332 const ast::FunctionDecl * mut = strict_dynamic_cast<const ast::FunctionDecl *>(ast::DeclReplacer::replace(decl, typeMap));333 assert (mut == decl);334 */335 324 336 325 definitions.push_back( decl ); … … 346 335 } 347 336 348 void replaceAll( std::vector<ast::ptr<ast::DeclWithType>> & dwts,349 const ast::DeclReplacer::TypeMap & map ) {350 for ( auto & dwt : dwts ) {351 dwt = strict_dynamic_cast<const ast::DeclWithType *>(352 ast::DeclReplacer::replace( dwt, map ) );353 }354 }355 356 337 /// Generates a basic prototype function declaration. 357 ast::FunctionDecl * FuncGenerator::genProto( std::string&& name,338 ast::FunctionDecl * FuncGenerator::genProto( const std::string& name, 358 339 std::vector<ast::ptr<ast::DeclWithType>>&& params, 359 340 std::vector<ast::ptr<ast::DeclWithType>>&& returns ) const { … … 361 342 // Handle generic prameters and assertions, if any. 362 343 auto const & old_type_params = getGenericParams( type ); 363 ast::DeclReplacer::TypeMap oldToNew;364 344 std::vector<ast::ptr<ast::TypeDecl>> type_params; 365 345 std::vector<ast::ptr<ast::DeclWithType>> assertions; 366 367 ast::DeclReplacer::TypeMap typeMap;368 346 for ( auto & old_param : old_type_params ) { 369 347 ast::TypeDecl * decl = ast::deepCopy( old_param ); 370 decl->init = nullptr; 371 splice( assertions, decl->assertions ); 372 oldToNew.emplace( std::make_pair( old_param, decl ) ); 348 for ( auto assertion : decl->assertions ) { 349 assertions.push_back( assertion ); 350 } 351 decl->assertions.clear(); 373 352 type_params.push_back( decl ); 374 typeMap.emplace(old_param, decl); 375 } 376 377 for (auto & param : params) { 378 param = ast::DeclReplacer::replace(param, typeMap); 379 } 380 for (auto & param : returns) { 381 param = ast::DeclReplacer::replace(param, typeMap); 382 } 383 replaceAll( params, oldToNew ); 384 replaceAll( returns, oldToNew ); 385 replaceAll( assertions, oldToNew ); 353 } 354 // TODO: The values in params and returns still may point at the old 355 // generic params, that does not appear to be an issue but perhaps it 356 // should be addressed. 386 357 387 358 ast::FunctionDecl * decl = new ast::FunctionDecl( 388 359 // Auto-generated routines use the type declaration's location. 389 360 getLocation(), 390 std::move( name ),361 name, 391 362 std::move( type_params ), 392 363 std::move( assertions ), … … 452 423 for ( unsigned int index = 0 ; index < fields ; ++index ) { 453 424 auto member = aggr->members[index].strict_as<ast::DeclWithType>(); 454 if ( ast::isUnnamedBitfield(425 if ( SymTab::isUnnamedBitfield( 455 426 dynamic_cast<const ast::ObjectDecl *>( member ) ) ) { 456 427 if ( index == fields - 1 ) { … … 544 515 InitTweak::InitExpander_new srcParam( src ); 545 516 // Assign to destination. 546 ast:: MemberExpr * dstSelect = new ast::MemberExpr(517 ast::Expr * dstSelect = new ast::MemberExpr( 547 518 location, 548 519 field, … … 596 567 } 597 568 598 ast:: MemberExpr * srcSelect = (srcParam) ? new ast::MemberExpr(569 ast::Expr * srcSelect = (srcParam) ? new ast::MemberExpr( 599 570 location, field, new ast::VariableExpr( location, srcParam ) 600 571 ) : nullptr; … … 628 599 // Not sure why it could be null. 629 600 // Don't make a function for a parameter that is an unnamed bitfield. 630 if ( nullptr == field || ast::isUnnamedBitfield( field ) ) {601 if ( nullptr == field || SymTab::isUnnamedBitfield( field ) ) { 631 602 continue; 632 603 // Matching Parameter: Initialize the field by copy. -
src/Validate/FixQualifiedTypes.cpp
r24d6572 r34b4268 16 16 #include "Validate/FixQualifiedTypes.hpp" 17 17 18 #include "AST/Copy.hpp"19 #include "AST/LinkageSpec.hpp" // for Linkage20 18 #include "AST/Pass.hpp" 21 19 #include "AST/TranslationUnit.hpp" 22 #include "Common/ToString.hpp" // for toString23 #include "SymTab/Mangler.h" // for Mangler24 20 #include "Validate/NoIdSymbolTable.hpp" 21 #include "SymTab/Mangler.h" // for Mangler 22 #include "AST/LinkageSpec.hpp" // for Linkage 25 23 26 24 namespace Validate { -
src/Validate/FixReturnTypes.cpp
r24d6572 r34b4268 20 20 #include "AST/Type.hpp" 21 21 #include "CodeGen/CodeGenerator.h" 22 #include "ResolvExpr/ Unify.h"22 #include "ResolvExpr/typeops.h" 23 23 24 24 namespace ast { -
src/Validate/ForallPointerDecay.cpp
r24d6572 r34b4268 22 22 #include "CodeGen/OperatorTable.h" 23 23 #include "Common/CodeLocation.h" 24 #include "Common/ToString.hpp"25 24 #include "SymTab/FixFunction.h" 26 25 -
src/Validate/GenericParameter.cpp
r24d6572 r34b4268 16 16 #include "GenericParameter.hpp" 17 17 18 #include "AST/Copy.hpp"19 18 #include "AST/Decl.hpp" 20 19 #include "AST/Expr.hpp" -
src/Validate/HandleAttributes.cc
r24d6572 r34b4268 17 17 18 18 #include "CompilationState.h" 19 #include "Common/Eval.h"20 19 #include "Common/PassVisitor.h" 21 #include "Common/ToString.hpp"22 20 #include "Common/SemanticError.h" 23 21 #include "ResolvExpr/Resolver.h" -
src/Validate/HoistStruct.cpp
r24d6572 r34b4268 16 16 #include "Validate/HoistStruct.hpp" 17 17 18 #include <sstream>19 20 18 #include "AST/Pass.hpp" 21 19 #include "AST/TranslationUnit.hpp" 20 #include "Common/utility.h" 22 21 23 22 namespace Validate { -
src/Validate/ReplaceTypedef.cpp
r24d6572 r34b4268 16 16 #include "ReplaceTypedef.hpp" 17 17 18 #include "AST/Copy.hpp"19 18 #include "AST/Pass.hpp" 20 19 #include "Common/ScopedMap.h" 21 20 #include "Common/UniqueName.h" 22 21 #include "Common/utility.h" 23 #include "ResolvExpr/ Unify.h"22 #include "ResolvExpr/typeops.h" 24 23 25 24 namespace Validate { … … 150 149 // constant/enumerator. The effort required to fix this corner case 151 150 // likely outweighs the utility of allowing it. 152 if ( !ResolvExpr::typesCompatible( t0, t1 )151 if ( !ResolvExpr::typesCompatible( t0, t1, ast::SymbolTable() ) 153 152 || ast::Pass<VarLenChecker>::read( t0 ) 154 153 || ast::Pass<VarLenChecker>::read( t1 ) ) { … … 187 186 188 187 void ReplaceTypedefCore::previsit( ast::TypeDecl const * decl ) { 189 typedefNames.erase( decl->name ); 188 TypedefMap::iterator iter = typedefNames.find( decl->name ); 189 if ( iter != typedefNames.end() ) { 190 typedefNames.erase( iter ); 191 } 190 192 typedeclNames.insert( decl->name, decl ); 191 193 } -
src/Virtual/ExpandCasts.cc
r24d6572 r34b4268 20 20 #include <string> // for string, allocator, operator==, ope... 21 21 22 #include "AST/Copy.hpp"23 22 #include "AST/Decl.hpp" 24 23 #include "AST/Expr.hpp" -
src/Virtual/module.mk
r24d6572 r34b4268 19 19 Virtual/ExpandCasts.h \ 20 20 Virtual/Tables.cc \ 21 Virtual/Tables.h \ 22 Virtual/VirtualDtor.cpp \ 23 Virtual/VirtualDtor.hpp 21 Virtual/Tables.h -
src/include/cassert
r24d6572 r34b4268 20 20 #include_next <cassert> 21 21 22 #include "Common/ToString.hpp" 22 #include <string> 23 24 template < typename ... Params > 25 std::string toString( const Params & ... params ); 23 26 24 27 #ifdef NDEBUG -
src/main.cc
r24d6572 r34b4268 9 9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Apr 10 21:12:17 202313 // Update Count : 6 8211 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Oct 5 12:06:00 2022 13 // Update Count : 679 14 14 // 15 15 … … 32 32 33 33 #include "AST/Convert.hpp" 34 #include "AST/Pass.hpp" // for pass_visitor_stats35 #include "AST/TranslationUnit.hpp" // for TranslationUnit36 #include "AST/Util.hpp" // for checkInvariants37 34 #include "CompilationState.h" 38 35 #include "../config.h" // for CFA_LIBDIR … … 43 40 #include "CodeTools/TrackLoc.h" // for fillLocations 44 41 #include "Common/CodeLocationTools.hpp" // for forceFillCodeLocations 42 #include "Common/CompilerError.h" // for CompilerError 45 43 #include "Common/DeclStats.hpp" // for printDeclStats 46 44 #include "Common/ResolvProtoDump.hpp" // for dumpAsResolverProto 47 45 #include "Common/Stats.h" // for Stats 46 #include "Common/UnimplementedError.h" // for UnimplementedError 48 47 #include "Common/utility.h" // for deleteAll, filter, printAll 49 #include "Concurrency/Actors.hpp" // for implementActors50 48 #include "Concurrency/Keywords.h" // for implementMutex, implement... 51 49 #include "Concurrency/Waitfor.h" // for generateWaitfor 52 #include "Concurrency/Waituntil.hpp" // for generateWaitUntil53 50 #include "ControlStruct/ExceptDecl.h" // for translateExcept 54 51 #include "ControlStruct/ExceptTranslate.h" // for translateThrows, translat... … … 62 59 #include "InitTweak/GenInit.h" // for genInit 63 60 #include "MakeLibCfa.h" // for makeLibCfa 64 #include "Parser/RunParser.hpp" // for buildList, dumpParseTree,... 61 #include "Parser/ParseNode.h" // for DeclarationNode, buildList 62 #include "Parser/TypedefTable.h" // for TypedefTable 65 63 #include "ResolvExpr/CandidatePrinter.hpp" // for printCandidates 66 64 #include "ResolvExpr/Resolver.h" // for resolve … … 86 84 #include "Validate/VerifyCtorDtorAssign.hpp" // for verifyCtorDtorAssign 87 85 #include "Virtual/ExpandCasts.h" // for expandCasts 88 #include "Virtual/VirtualDtor.hpp" // for implementVirtDtors89 86 90 87 static void NewPass( const char * const name ) { … … 105 102 } 106 103 107 // Helpers for checkInvariant: 108 void checkInvariants( std::list< Declaration * > & ) {} 109 using ast::checkInvariants; 110 111 #define PASS( name, pass, unit, ... ) \ 104 #define PASS( name, pass ) \ 112 105 if ( errorp ) { cerr << name << endl; } \ 113 106 NewPass(name); \ 114 107 Stats::Time::StartBlock(name); \ 115 pass(unit,##__VA_ARGS__); \ 116 Stats::Time::StopBlock(); \ 117 if ( invariant ) { \ 118 checkInvariants(unit); \ 119 } 120 121 #define DUMP( cond, unit ) \ 122 if ( cond ) { \ 123 dump(unit); \ 124 return EXIT_SUCCESS; \ 125 } 108 pass; \ 109 Stats::Time::StopBlock(); 110 111 LinkageSpec::Spec linkage = LinkageSpec::Cforall; 112 TypedefTable typedefTable; 113 DeclarationNode * parseTree = nullptr; // program parse tree 126 114 127 115 static bool waiting_for_gdb = false; // flag to set cfa-cpp to wait for gdb on start … … 130 118 131 119 static void parse_cmdline( int argc, char * argv[] ); 120 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 132 121 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); 133 122 static void dump( ast::TranslationUnit && transUnit, ostream & out = cout ); … … 245 234 ostream * output = & cout; 246 235 list< Declaration * > translationUnit; 247 ast::TranslationUnit transUnit;248 236 249 237 Signal( SIGSEGV, sigSegvBusHandler, SA_SIGINFO ); … … 290 278 FILE * gcc_builtins = fopen( (PreludeDirector + "/gcc-builtins.cf").c_str(), "r" ); 291 279 assertf( gcc_builtins, "cannot open gcc-builtins.cf\n" ); 292 parse( gcc_builtins, ast::Linkage::Compiler );280 parse( gcc_builtins, LinkageSpec::Compiler ); 293 281 294 282 // read the extra prelude in, if not generating the cfa library 295 283 FILE * extras = fopen( (PreludeDirector + "/extras.cf").c_str(), "r" ); 296 284 assertf( extras, "cannot open extras.cf\n" ); 297 parse( extras, ast::Linkage::BuiltinC );285 parse( extras, LinkageSpec::BuiltinC ); 298 286 299 287 if ( ! libcfap ) { … … 301 289 FILE * prelude = fopen( (PreludeDirector + "/prelude.cfa").c_str(), "r" ); 302 290 assertf( prelude, "cannot open prelude.cfa\n" ); 303 parse( prelude, ast::Linkage::Intrinsic );291 parse( prelude, LinkageSpec::Intrinsic ); 304 292 305 293 // Read to cfa builtins, if not generating the cfa library 306 294 FILE * builtins = fopen( (PreludeDirector + "/builtins.cf").c_str(), "r" ); 307 295 assertf( builtins, "cannot open builtins.cf\n" ); 308 parse( builtins, ast::Linkage::BuiltinCFA ); 309 } // if 310 } // if 311 312 parse( input, libcfap ? ast::Linkage::Intrinsic : ast::Linkage::Cforall, yydebug ); 313 314 transUnit = buildUnit(); 315 316 DUMP( astp, std::move( transUnit ) ); 317 296 parse( builtins, LinkageSpec::BuiltinCFA ); 297 } // if 298 } // if 299 300 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, yydebug ); 301 302 if ( parsep ) { 303 parseTree->printList( cout ); 304 delete parseTree; 305 return EXIT_SUCCESS; 306 } // if 307 308 buildList( parseTree, translationUnit ); 309 delete parseTree; 310 parseTree = nullptr; 311 312 if ( astp ) { 313 dump( translationUnit ); 314 return EXIT_SUCCESS; 315 } // if 316 317 // Temporary: fill locations after parsing so that every node has a location, for early error messages. 318 // Eventually we should pass the locations from the parser to every node, but this quick and dirty solution 319 // works okay for now. 320 CodeTools::fillLocations( translationUnit ); 318 321 Stats::Time::StopBlock(); 319 322 … … 322 325 ast::pass_visitor_stats.max = Stats::Counters::build<Stats::Counters::MaxCounter<double>>("Max depth - New"); 323 326 } 324 325 PASS( "Hoist Type Decls", Validate::hoistTypeDecls, transUnit ); 326 327 PASS( "Translate Exception Declarations", ControlStruct::translateExcept, transUnit ); 328 DUMP( exdeclp, std::move( transUnit ) ); 329 PASS( "Verify Ctor, Dtor & Assign", Validate::verifyCtorDtorAssign, transUnit ); 330 PASS( "Replace Typedefs", Validate::replaceTypedef, transUnit ); 331 PASS( "Fix Return Types", Validate::fixReturnTypes, transUnit ); 332 PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers, transUnit ); 333 334 PASS( "Link Reference To Types", Validate::linkReferenceToTypes, transUnit ); 335 336 PASS( "Fix Qualified Types", Validate::fixQualifiedTypes, transUnit ); 337 PASS( "Hoist Struct", Validate::hoistStruct, transUnit ); 338 PASS( "Eliminate Typedef", Validate::eliminateTypedef, transUnit ); 339 PASS( "Validate Generic Parameters", Validate::fillGenericParameters, transUnit ); 340 PASS( "Translate Dimensions", Validate::translateDimensionParameters, transUnit ); 341 PASS( "Check Function Returns", Validate::checkReturnStatements, transUnit ); 342 PASS( "Fix Return Statements", InitTweak::fixReturnStatements, transUnit ); 343 PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords, transUnit ); 344 PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit ); 345 PASS( "Implement Waituntil", Concurrency::generateWaitUntil, transUnit ); 346 PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls, transUnit ); 347 348 PASS( "Generate Autogen Routines", Validate::autogenerateRoutines, transUnit ); 349 350 PASS( "Implement Actors", Concurrency::implementActors, transUnit ); 351 PASS( "Implement Virtual Destructors", Virtual::implementVirtDtors, transUnit ); 352 PASS( "Implement Mutex", Concurrency::implementMutex, transUnit ); 353 PASS( "Implement Thread Start", Concurrency::implementThreadStarter, transUnit ); 354 PASS( "Compound Literal", Validate::handleCompoundLiterals, transUnit ); 355 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer, transUnit ); 356 PASS( "Find Global Decls", Validate::findGlobalDecls, transUnit ); 357 PASS( "Fix Label Address", Validate::fixLabelAddresses, transUnit ); 327 auto transUnit = convert( std::move( translationUnit ) ); 328 329 forceFillCodeLocations( transUnit ); 330 331 PASS( "Translate Exception Declarations", ControlStruct::translateExcept( transUnit ) ); 332 if ( exdeclp ) { 333 dump( std::move( transUnit ) ); 334 return EXIT_SUCCESS; 335 } 336 337 PASS( "Verify Ctor, Dtor & Assign", Validate::verifyCtorDtorAssign( transUnit ) ); 338 PASS( "Hoist Type Decls", Validate::hoistTypeDecls( transUnit ) ); 339 // Hoist Type Decls pulls some declarations out of contexts where 340 // locations are not tracked. Perhaps they should be, but for now 341 // the full fill solves it. 342 forceFillCodeLocations( transUnit ); 343 344 PASS( "Replace Typedefs", Validate::replaceTypedef( transUnit ) ); 345 PASS( "Fix Return Types", Validate::fixReturnTypes( transUnit ) ); 346 PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers( transUnit ) ); 347 348 PASS( "Link Reference To Types", Validate::linkReferenceToTypes( transUnit ) ); 349 350 PASS( "Fix Qualified Types", Validate::fixQualifiedTypes( transUnit ) ); 351 PASS( "Hoist Struct", Validate::hoistStruct( transUnit ) ); 352 PASS( "Eliminate Typedef", Validate::eliminateTypedef( transUnit ) ); 353 PASS( "Validate Generic Parameters", Validate::fillGenericParameters( transUnit ) ); 354 PASS( "Translate Dimensions", Validate::translateDimensionParameters( transUnit ) ); 355 PASS( "Check Function Returns", Validate::checkReturnStatements( transUnit ) ); 356 PASS( "Fix Return Statements", InitTweak::fixReturnStatements( transUnit ) ); 357 PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) ); 358 PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) ); 359 PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls( transUnit ) ); 360 361 PASS( "Generate Autogen Routines", Validate::autogenerateRoutines( transUnit ) ); 362 363 PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) ); 364 PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) ); 365 PASS( "Compound Literal", Validate::handleCompoundLiterals( transUnit ) ); 366 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer( transUnit ) ); 367 PASS( "Find Global Decls", Validate::findGlobalDecls( transUnit ) ); 368 PASS( "Fix Label Address", Validate::fixLabelAddresses( transUnit ) ); 358 369 359 370 if ( symtabp ) { … … 366 377 } // if 367 378 368 DUMP( validp, std::move( transUnit ) ); 369 370 PASS( "Translate Throws", ControlStruct::translateThrows, transUnit ); 371 PASS( "Fix Labels", ControlStruct::fixLabels, transUnit ); 372 PASS( "Fix Names", CodeGen::fixNames, transUnit ); 373 PASS( "Gen Init", InitTweak::genInit, transUnit ); 374 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples, transUnit ); 379 if ( validp ) { 380 dump( std::move( transUnit ) ); 381 return EXIT_SUCCESS; 382 } // if 383 384 PASS( "Translate Throws", ControlStruct::translateThrows( transUnit ) ); 385 PASS( "Fix Labels", ControlStruct::fixLabels( transUnit ) ); 386 PASS( "Fix Names", CodeGen::fixNames( transUnit ) ); 387 PASS( "Gen Init", InitTweak::genInit( transUnit ) ); 388 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( transUnit ) ); 375 389 376 390 if ( libcfap ) { … … 384 398 } // if 385 399 386 DUMP( bresolvep, std::move( transUnit ) ); 400 if ( bresolvep ) { 401 dump( std::move( transUnit ) ); 402 return EXIT_SUCCESS; 403 } // if 387 404 388 405 if ( resolvprotop ) { … … 391 408 } // if 392 409 393 PASS( "Resolve", ResolvExpr::resolve, transUnit ); 394 DUMP( exprp, std::move( transUnit ) ); 395 396 PASS( "Fix Init", InitTweak::fix, transUnit, buildingLibrary() ); 410 PASS( "Resolve", ResolvExpr::resolve( transUnit ) ); 411 if ( exprp ) { 412 dump( std::move( transUnit ) ); 413 return EXIT_SUCCESS; 414 } // if 415 416 forceFillCodeLocations( transUnit ); 417 418 PASS( "Fix Init", InitTweak::fix(transUnit, buildingLibrary())); 397 419 398 420 // fix ObjectDecl - replaces ConstructorInit nodes 399 DUMP( ctorinitp, std::move( transUnit ) ); 421 if ( ctorinitp ) { 422 dump( std::move( transUnit ) ); 423 return EXIT_SUCCESS; 424 } // if 400 425 401 426 // Currently not working due to unresolved issues with UniqueExpr 402 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr , transUnit); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused403 404 PASS( "Translate Tries", ControlStruct::translateTries , transUnit);405 PASS( "Gen Waitfor", Concurrency::generateWaitFor , transUnit);427 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( transUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused 428 429 PASS( "Translate Tries", ControlStruct::translateTries( transUnit ) ); 430 PASS( "Gen Waitfor", Concurrency::generateWaitFor( transUnit ) ); 406 431 407 432 // Needs to happen before tuple types are expanded. 408 PASS( "Convert Specializations", GenPoly::convertSpecializations, transUnit ); 409 410 PASS( "Expand Tuples", Tuples::expandTuples, transUnit ); 411 DUMP( tuplep, std::move( transUnit ) ); 433 PASS( "Convert Specializations", GenPoly::convertSpecializations( transUnit ) ); 434 435 PASS( "Expand Tuples", Tuples::expandTuples( transUnit ) ); 436 437 if ( tuplep ) { 438 dump( std::move( transUnit ) ); 439 return EXIT_SUCCESS; 440 } // if 412 441 413 442 // Must come after Translate Tries. 414 PASS( "Virtual Expand Casts", Virtual::expandCasts, transUnit ); 415 416 PASS( "Instantiate Generics", GenPoly::instantiateGeneric, transUnit ); 417 DUMP( genericsp, std::move( transUnit ) ); 418 419 PASS( "Convert L-Value", GenPoly::convertLvalue, transUnit ); 443 PASS( "Virtual Expand Casts", Virtual::expandCasts( transUnit ) ); 444 445 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( transUnit ) ); 446 if ( genericsp ) { 447 dump( std::move( transUnit ) ); 448 return EXIT_SUCCESS; 449 } // if 450 451 PASS( "Convert L-Value", GenPoly::convertLvalue( transUnit ) ); 420 452 421 453 translationUnit = convert( std::move( transUnit ) ); 422 454 423 DUMP( bboxp, translationUnit ); 424 PASS( "Box", GenPoly::box, translationUnit ); 425 426 PASS( "Link-Once", CodeGen::translateLinkOnce, translationUnit ); 455 if ( bboxp ) { 456 dump( translationUnit ); 457 return EXIT_SUCCESS; 458 } // if 459 PASS( "Box", GenPoly::box( translationUnit ) ); 460 461 PASS( "Link-Once", CodeGen::translateLinkOnce( translationUnit ) ); 427 462 428 463 // Code has been lowered to C, now we can start generation. 429 464 430 DUMP( bcodegenp, translationUnit ); 465 if ( bcodegenp ) { 466 dump( translationUnit ); 467 return EXIT_SUCCESS; 468 } // if 431 469 432 470 if ( optind < argc ) { // any commands after the flags and input file ? => output file name … … 435 473 436 474 CodeTools::fillLocations( translationUnit ); 437 PASS( "Code Gen", CodeGen::generate , translationUnit, *output, ! genproto, prettycodegenp, true, linemarks);475 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) ); 438 476 439 477 CodeGen::FixMain::fix( translationUnit, *output, … … 445 483 if ( errorp ) { 446 484 cerr << "---AST at error:---" << endl; 447 // We check which section the errors came from without looking at 448 // transUnit because std::move means it could look like anything. 449 if ( !translationUnit.empty() ) { 450 dump( translationUnit, cerr ); 451 } else { 452 dump( std::move( transUnit ), cerr ); 453 } 485 dump( translationUnit, cerr ); 454 486 cerr << endl << "---End of AST, begin error message:---\n" << endl; 455 487 } // if 456 488 e.print(); 489 if ( output != &cout ) { 490 delete output; 491 } // if 492 return EXIT_FAILURE; 493 } catch ( UnimplementedError & e ) { 494 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl; 495 if ( output != &cout ) { 496 delete output; 497 } // if 498 return EXIT_FAILURE; 499 } catch ( CompilerError & e ) { 500 cerr << "Compiler Error: " << e.get_what() << endl; 501 cerr << "(please report bugs to [REDACTED])" << endl; 457 502 if ( output != &cout ) { 458 503 delete output; … … 483 528 484 529 485 static const char optstring[] = ":c:gh ilLmNnpdP:S:twW:D:";530 static const char optstring[] = ":c:ghlLmNnpdP:S:twW:D:"; 486 531 487 532 enum { PreludeDir = 128 }; … … 490 535 { "gdb", no_argument, nullptr, 'g' }, 491 536 { "help", no_argument, nullptr, 'h' }, 492 { "invariant", no_argument, nullptr, 'i' },493 537 { "libcfa", no_argument, nullptr, 'l' }, 494 538 { "linemarks", no_argument, nullptr, 'L' }, 495 { "no-main", no_argument, nullptr, 'm' },539 { "no-main", no_argument, 0, 'm' }, 496 540 { "no-linemarks", no_argument, nullptr, 'N' }, 497 541 { "no-prelude", no_argument, nullptr, 'n' }, … … 512 556 "wait for gdb to attach", // -g 513 557 "print translator help message", // -h 514 "invariant checking during AST passes", // -i515 558 "generate libcfa.c", // -l 516 559 "generate line marks", // -L … … 544 587 { "rproto", resolvprotop, true, "resolver-proto instance" }, 545 588 { "rsteps", resolvep, true, "print resolver steps" }, 589 { "tree", parsep, true, "print parse tree" }, 546 590 // code dumps 547 591 { "ast", astp, true, "print AST after parsing" }, … … 606 650 usage( argv ); // no return 607 651 break; 608 case 'i': // invariant checking609 invariant = true;610 break;611 652 case 'l': // generate libcfa.c 612 653 libcfap = true; … … 707 748 } // parse_cmdline 708 749 750 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit ) { 751 extern int yyparse( void ); 752 extern FILE * yyin; 753 extern int yylineno; 754 755 ::linkage = linkage; // set globals 756 yyin = input; 757 yylineno = 1; 758 int parseStatus = yyparse(); 759 760 fclose( input ); 761 if ( shouldExit || parseStatus != 0 ) { 762 exit( parseStatus ); 763 } // if 764 } // parse 765 709 766 static bool notPrelude( Declaration * decl ) { 710 767 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); -
tests/.expect/PRNG.x64.txt
r24d6572 r34b4268 1 1 2 CFA xoshiro256pp 3 4 PRNG() PRNG(5) PRNG(0,5) 5 13944458589275087071 3 2 6 129977468648444256 0 4 7 2357727400298891021 2 2 8 8855179187835660146 3 3 9 9957620185645882382 4 1 10 13396406983727409795 0 5 11 3342782395220265920 0 5 12 1707651271867677937 1 0 13 16402561450140881681 0 1 14 17838519215740313729 4 2 15 7425936020594490136 4 0 16 4174865704721714670 3 5 17 16055269689200152092 0 2 18 15091270195803594018 1 5 19 11807315541476180798 1 1 20 10697186588988060306 4 1 21 14665526411527044929 3 2 22 11289342279096164771 2 5 23 16126980828050300615 1 4 24 7821578301767524260 4 1 2 PRNG() PRNG(5) PRNG(0,5) 3 861 3 0 4 10137507171299805328 1 2 5 12205946788447993741 4 0 6 16222929371023265189 2 5 7 11921944259646500358 1 1 8 9511863719043198063 2 0 9 18170109536749574203 0 1 10 15896208456307578543 0 3 11 4171113079117645375 1 4 12 5535309872453329531 1 1 13 13293369315461644140 2 2 14 855811942427900360 1 1 15 9125507373316195824 1 5 16 6942856496042419510 1 5 17 16774706561877323900 2 4 18 17765436951300330249 4 0 19 3766082030894719812 1 2 20 15818141700523398820 3 5 21 1244962761353699441 0 5 22 4506898200126256218 1 2 25 23 seed 1009 26 24 27 25 Sequential 28 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%26 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 29 27 30 28 Concurrent 31 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%32 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%33 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%34 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%29 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 30 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 31 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 32 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 35 33 36 prng() prng(5)prng(0,5)37 13944458589275087071 3 238 129977468648444256 0 4 39 2357727400298891021 2 2 40 8855179187835660146 3 3 41 9957620185645882382 4142 13396406983727409795 0 5 43 3342782395220265920 0 5 44 1707651271867677937 1 0 45 16402561450140881681 0 1 46 17838519215740313729 4 2 47 7425936020594490136 4 0 48 4174865704721714670 3 5 49 16055269689200152092 0 2 50 15091270195803594018 1551 11807315541476180798 1 1 52 10697186588988060306 4 1 53 14665526411527044929 3254 11289342279096164771 2555 16126980828050300615 1 4 56 7821578301767524260 4 1 34 prng() prng(5) prng(0,5) 35 861 3 0 36 10137507171299805328 1 2 37 12205946788447993741 4 0 38 16222929371023265189 2 5 39 11921944259646500358 1 1 40 9511863719043198063 2 0 41 18170109536749574203 0 1 42 15896208456307578543 0 3 43 4171113079117645375 1 4 44 5535309872453329531 1 1 45 13293369315461644140 2 2 46 855811942427900360 1 1 47 9125507373316195824 1 5 48 6942856496042419510 1 5 49 16774706561877323900 2 4 50 17765436951300330249 4 0 51 3766082030894719812 1 2 52 15818141700523398820 3 5 53 1244962761353699441 0 5 54 4506898200126256218 1 2 57 55 seed 1009 58 56 59 57 Sequential 60 trials 20000000 buckets 100000 min 139 max 265 avg 200.0 std 14.1 rstd 7.0%58 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 61 59 62 60 Concurrent 63 trials 20000000 buckets 100000 min 139 max 265 avg 200.0 std 14.1 rstd 7.0%64 trials 20000000 buckets 100000 min 139 max 265 avg 200.0 std 14.1 rstd 7.0%65 trials 20000000 buckets 100000 min 139 max 265 avg 200.0 std 14.1 rstd 7.0%66 trials 20000000 buckets 100000 min 139 max 265 avg 200.0 std 14.1 rstd 7.0%61 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 62 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 63 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 64 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 67 65 68 prng(t) prng(t,5)prng(t,0,5)69 13944458589275087071 3 270 129977468648444256 0 4 71 2357727400298891021 2 2 72 8855179187835660146 3 3 73 9957620185645882382 4174 13396406983727409795 0 5 75 3342782395220265920 0 5 76 1707651271867677937 1 0 77 16402561450140881681 0 1 78 17838519215740313729 4 2 79 7425936020594490136 4 0 80 4174865704721714670 3 5 81 16055269689200152092 0 2 82 15091270195803594018 1583 11807315541476180798 1 1 84 10697186588988060306 4 1 85 14665526411527044929 3286 11289342279096164771 2587 16126980828050300615 1 4 88 7821578301767524260 4 1 66 prng(t) prng(t,5) prng(t,0,5) 67 861 3 0 68 10137507171299805328 1 2 69 12205946788447993741 4 0 70 16222929371023265189 2 5 71 11921944259646500358 1 1 72 9511863719043198063 2 0 73 18170109536749574203 0 1 74 15896208456307578543 0 3 75 4171113079117645375 1 4 76 5535309872453329531 1 1 77 13293369315461644140 2 2 78 855811942427900360 1 1 79 9125507373316195824 1 5 80 6942856496042419510 1 5 81 16774706561877323900 2 4 82 17765436951300330249 4 0 83 3766082030894719812 1 2 84 15818141700523398820 3 5 85 1244962761353699441 0 5 86 4506898200126256218 1 2 89 87 seed 1009 90 88 91 89 Sequential 92 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%90 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 93 91 94 92 Concurrent 95 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%96 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%97 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%98 trials 100000000 buckets 100000 min 875 max 11 46 avg 1000.0 std 31.6rstd 3.2%93 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 94 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 95 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% 96 trials 100000000 buckets 100000 min 875 max 1138 avg 1000.0 std 31.8 rstd 3.2% -
tests/.expect/PRNG.x86.txt
r24d6572 r34b4268 1 1 2 CFA xoshiro128pp 3 4 PRNG() PRNG(5) PRNG(0,5) 5 2884683541 0 0 6 3465286746 2 4 7 3268922916 0 1 8 2396374907 3 0 9 2135076892 4 1 10 944377718 3 1 11 2204845346 3 3 12 3736609533 0 4 13 4063231336 0 2 14 1075394776 0 2 15 712844808 4 0 16 4246343110 3 1 17 3793873837 2 1 18 3690340337 1 4 19 319207944 1 4 20 1815791072 3 5 21 2581617261 1 5 22 3873329448 1 3 23 832631329 4 0 24 651551615 3 5 2 PRNG() PRNG(5) PRNG(0,5) 3 8333105 1 2 4 1989339636 4 5 5 266970699 3 2 6 1928130121 3 4 7 1351003938 4 5 8 1624164922 4 3 9 363429604 1 2 10 3355083174 1 1 11 214422584 1 1 12 2266729947 1 2 13 3649702519 2 4 14 2250875012 2 4 15 4184653025 1 3 16 2640851227 2 5 17 206468178 2 3 18 2600873108 1 3 19 3007574582 3 3 20 394476790 0 2 21 1312145388 1 5 22 2989081290 2 4 25 23 seed 1009 26 24 27 25 Sequential 28 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%26 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 29 27 30 28 Concurrent 31 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%32 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%33 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%34 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%29 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 30 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 31 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 32 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 35 33 36 prng() prng(5)prng(0,5)37 2884683541 0 038 3465286746 2 439 3268922916 0 140 2396374907 3 041 2135076892 4 142 944377718 3 143 2204845346 3 344 3736609533 0 445 4063231336 0 246 1075394776 0247 712844808 4 048 4246343110 3 149 3793873837 2 150 3690340337 1 451 319207944 1 452 1815791072 3 553 2581617261 1 554 3873329448 1 355 832631329 4 056 651551615 3 534 prng() prng(5) prng(0,5) 35 8333105 1 2 36 1989339636 4 5 37 266970699 3 2 38 1928130121 3 4 39 1351003938 4 5 40 1624164922 4 3 41 363429604 1 2 42 3355083174 1 1 43 214422584 1 1 44 2266729947 1 2 45 3649702519 2 4 46 2250875012 2 4 47 4184653025 1 3 48 2640851227 2 5 49 206468178 2 3 50 2600873108 1 3 51 3007574582 3 3 52 394476790 0 2 53 1312145388 1 5 54 2989081290 2 4 57 55 seed 1009 58 56 59 57 Sequential 60 trials 20000000 buckets 100000 min 144 max 270 avg 200.0 std 14.1 rstd 7.1%58 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 61 59 62 60 Concurrent 63 trials 20000000 buckets 100000 min 144 max 270 avg 200.0 std 14.1 rstd 7.1%64 trials 20000000 buckets 100000 min 144 max 270 avg 200.0 std 14.1 rstd 7.1%65 trials 20000000 buckets 100000 min 144 max 270 avg 200.0 std 14.1 rstd 7.1%66 trials 20000000 buckets 100000 min 144 max 270 avg 200.0 std 14.1 rstd 7.1%61 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 62 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 63 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 64 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 67 65 68 prng(t) prng(t,5)prng(t,0,5)69 2884683541 0 070 3465286746 2 471 3268922916 0 172 2396374907 3 073 2135076892 4 174 944377718 3 175 2204845346 3 376 3736609533 0 477 4063231336 0 278 1075394776 0279 712844808 4 080 4246343110 3 181 3793873837 2 182 3690340337 1 483 319207944 1 484 1815791072 3 585 2581617261 1 586 3873329448 1 387 832631329 4 088 651551615 3 566 prng(t) prng(t,5) prng(t,0,5) 67 8333105 1 2 68 1989339636 4 5 69 266970699 3 2 70 1928130121 3 4 71 1351003938 4 5 72 1624164922 4 3 73 363429604 1 2 74 3355083174 1 1 75 214422584 1 1 76 2266729947 1 2 77 3649702519 2 4 78 2250875012 2 4 79 4184653025 1 3 80 2640851227 2 5 81 206468178 2 3 82 2600873108 1 3 83 3007574582 3 3 84 394476790 0 2 85 1312145388 1 5 86 2989081290 2 4 89 87 seed 1009 90 88 91 89 Sequential 92 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%90 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 93 91 94 92 Concurrent 95 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%96 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%97 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%98 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5 rstd 3.2%93 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 94 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 95 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% 96 trials 100000000 buckets 100000 min 873 max 1140 avg 1000.0 std 31.3 rstd 3.1% -
tests/.expect/array.txt
r24d6572 r34b4268 1 array.cfa: 119:25: warning: Preprocessor started1 array.cfa:52:25: warning: Compiled -
tests/.expect/attributes.arm64.txt
r24d6572 r34b4268 26 26 return _X4_retS12__anonymous0_1; 27 27 } 28 __attribute__ ((unused)) st atic struct __anonymous0 _X5DummyS12__anonymous0_1;28 __attribute__ ((unused)) struct __anonymous0 _X5DummyS12__anonymous0_1; 29 29 struct __attribute__ ((unused)) Agn1; 30 30 struct __attribute__ ((unused)) Agn2 { … … 1351 1351 signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0)); 1352 1352 signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)()); 1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)( __attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused))signed int __param_0));1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
tests/.expect/attributes.x64.txt
r24d6572 r34b4268 26 26 return _X4_retS12__anonymous0_1; 27 27 } 28 __attribute__ ((unused)) st atic struct __anonymous0 _X5DummyS12__anonymous0_1;28 __attribute__ ((unused)) struct __anonymous0 _X5DummyS12__anonymous0_1; 29 29 struct __attribute__ ((unused)) Agn1; 30 30 struct __attribute__ ((unused)) Agn2 { … … 1351 1351 signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0)); 1352 1352 signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)()); 1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)( __attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused))signed int __param_0));1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
tests/.expect/attributes.x86.txt
r24d6572 r34b4268 26 26 return _X4_retS12__anonymous0_1; 27 27 } 28 __attribute__ ((unused)) st atic struct __anonymous0 _X5DummyS12__anonymous0_1;28 __attribute__ ((unused)) struct __anonymous0 _X5DummyS12__anonymous0_1; 29 29 struct __attribute__ ((unused)) Agn1; 30 30 struct __attribute__ ((unused)) Agn2 { … … 1351 1351 signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0)); 1352 1352 signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)()); 1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)( __attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused))signed int __param_0));1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
tests/.expect/declarationSpecifier.arm64.txt
r24d6572 r34b4268 51 51 52 52 } 53 staticvolatile const struct __anonymous0 _X3x10KVS12__anonymous0_1;53 volatile const struct __anonymous0 _X3x10KVS12__anonymous0_1; 54 54 struct __anonymous1 { 55 55 signed int _X1ii_1; … … 96 96 97 97 } 98 staticvolatile const struct __anonymous1 _X3x11KVS12__anonymous1_1;98 volatile const struct __anonymous1 _X3x11KVS12__anonymous1_1; 99 99 struct __anonymous2 { 100 100 signed int _X1ii_1; … … 141 141 142 142 } 143 staticvolatile const struct __anonymous2 _X3x12KVS12__anonymous2_1;143 volatile const struct __anonymous2 _X3x12KVS12__anonymous2_1; 144 144 struct __anonymous3 { 145 145 signed int _X1ii_1; … … 322 322 } 323 323 static volatile const struct __anonymous6 _X3x16KVS12__anonymous6_1; 324 struct __anonymous7 { 325 signed int _X1ii_1; 326 }; 327 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1); 328 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1); 329 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1); 330 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1); 331 static inline void _X12_constructorFv_S12__anonymous7i_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed int _X1ii_1); 332 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){ 333 { 334 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1) /* ?{} */); 335 } 336 337 } 338 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){ 339 { 340 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X4_srcS12__anonymous7_1._X1ii_1) /* ?{} */); 341 } 342 343 } 344 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){ 345 { 346 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1) /* ^?{} */); 347 } 348 349 } 350 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){ 351 struct __anonymous7 _X4_retS12__anonymous7_1; 352 { 353 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X4_srcS12__anonymous7_1._X1ii_1)); 354 } 355 356 { 357 ((void)_X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1((&_X4_retS12__anonymous7_1), (*_X4_dstS12__anonymous7_1))); 358 } 359 360 return _X4_retS12__anonymous7_1; 361 } 362 static inline void _X12_constructorFv_S12__anonymous7i_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed int _X1ii_1){ 363 { 364 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X1ii_1) /* ?{} */); 365 } 366 367 } 368 static volatile const struct __anonymous7 _X3x17KVS12__anonymous7_1; 324 369 volatile const signed short int _X3x20KVs_1; 325 370 static volatile const signed short int _X3x21KVs_1; … … 330 375 static volatile const signed short int _X3x26KVs_1; 331 376 static volatile const signed short int _X3x27KVs_1; 332 struct __anonymous7 {333 signed short int _X1is_1;334 };335 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1);336 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1);337 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1);338 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1);339 static inline void _X12_constructorFv_S12__anonymous7s_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed short int _X1is_1);340 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){341 {342 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1) /* ?{} */);343 }344 345 }346 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){347 {348 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X4_srcS12__anonymous7_1._X1is_1) /* ?{} */);349 }350 351 }352 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){353 {354 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1) /* ^?{} */);355 }356 357 }358 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){359 struct __anonymous7 _X4_retS12__anonymous7_1;360 {361 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X4_srcS12__anonymous7_1._X1is_1));362 }363 364 {365 ((void)_X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1((&_X4_retS12__anonymous7_1), (*_X4_dstS12__anonymous7_1)));366 }367 368 return _X4_retS12__anonymous7_1;369 }370 static inline void _X12_constructorFv_S12__anonymous7s_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed short int _X1is_1){371 {372 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X1is_1) /* ?{} */);373 }374 375 }376 static volatile const struct __anonymous7 _X3x29KVS12__anonymous7_1;377 377 struct __anonymous8 { 378 378 signed short int _X1is_1; … … 419 419 420 420 } 421 static volatile const struct __anonymous8 _X3x30KVS12__anonymous8_1;421 volatile const struct __anonymous8 _X3x29KVS12__anonymous8_1; 422 422 struct __anonymous9 { 423 423 signed short int _X1is_1; … … 464 464 465 465 } 466 static volatile const struct __anonymous9 _X3x31KVS12__anonymous9_1;466 volatile const struct __anonymous9 _X3x30KVS12__anonymous9_1; 467 467 struct __anonymous10 { 468 468 signed short int _X1is_1; … … 509 509 510 510 } 511 static volatile const struct __anonymous10 _X3x32KVS13__anonymous10_1;511 volatile const struct __anonymous10 _X3x31KVS13__anonymous10_1; 512 512 struct __anonymous11 { 513 513 signed short int _X1is_1; … … 554 554 555 555 } 556 static volatile const struct __anonymous11 _X3x3 3KVS13__anonymous11_1;556 static volatile const struct __anonymous11 _X3x32KVS13__anonymous11_1; 557 557 struct __anonymous12 { 558 558 signed short int _X1is_1; … … 599 599 600 600 } 601 static volatile const struct __anonymous12 _X3x3 4KVS13__anonymous12_1;601 static volatile const struct __anonymous12 _X3x33KVS13__anonymous12_1; 602 602 struct __anonymous13 { 603 603 signed short int _X1is_1; … … 644 644 645 645 } 646 static volatile const struct __anonymous13 _X3x35KVS13__anonymous13_1; 646 static volatile const struct __anonymous13 _X3x34KVS13__anonymous13_1; 647 struct __anonymous14 { 648 signed short int _X1is_1; 649 }; 650 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1); 651 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1); 652 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1); 653 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1); 654 static inline void _X12_constructorFv_S13__anonymous14s_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed short int _X1is_1); 655 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){ 656 { 657 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1) /* ?{} */); 658 } 659 660 } 661 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){ 662 { 663 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X4_srcS13__anonymous14_1._X1is_1) /* ?{} */); 664 } 665 666 } 667 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){ 668 { 669 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1) /* ^?{} */); 670 } 671 672 } 673 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){ 674 struct __anonymous14 _X4_retS13__anonymous14_1; 675 { 676 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X4_srcS13__anonymous14_1._X1is_1)); 677 } 678 679 { 680 ((void)_X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1((&_X4_retS13__anonymous14_1), (*_X4_dstS13__anonymous14_1))); 681 } 682 683 return _X4_retS13__anonymous14_1; 684 } 685 static inline void _X12_constructorFv_S13__anonymous14s_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed short int _X1is_1){ 686 { 687 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X1is_1) /* ?{} */); 688 } 689 690 } 691 static volatile const struct __anonymous14 _X3x35KVS13__anonymous14_1; 692 struct __anonymous15 { 693 signed short int _X1is_1; 694 }; 695 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1); 696 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1); 697 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1); 698 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1); 699 static inline void _X12_constructorFv_S13__anonymous15s_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed short int _X1is_1); 700 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){ 701 { 702 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1) /* ?{} */); 703 } 704 705 } 706 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){ 707 { 708 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X4_srcS13__anonymous15_1._X1is_1) /* ?{} */); 709 } 710 711 } 712 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){ 713 { 714 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1) /* ^?{} */); 715 } 716 717 } 718 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){ 719 struct __anonymous15 _X4_retS13__anonymous15_1; 720 { 721 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X4_srcS13__anonymous15_1._X1is_1)); 722 } 723 724 { 725 ((void)_X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1((&_X4_retS13__anonymous15_1), (*_X4_dstS13__anonymous15_1))); 726 } 727 728 return _X4_retS13__anonymous15_1; 729 } 730 static inline void _X12_constructorFv_S13__anonymous15s_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed short int _X1is_1){ 731 { 732 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X1is_1) /* ?{} */); 733 } 734 735 } 736 static volatile const struct __anonymous15 _X3x36KVS13__anonymous15_1; 647 737 _Thread_local signed int _X3x37i_1; 648 738 __thread signed int _X3x38i_1; … … 663 753 static inline volatile const signed short int _X3f27Fs___1(); 664 754 static inline volatile const signed short int _X3f28Fs___1(); 665 struct __anonymous14 {666 signed int _X1ii_1;667 };668 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1);669 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1);670 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1);671 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1);672 static inline void _X12_constructorFv_S13__anonymous14i_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed int _X1ii_1);673 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){674 {675 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1) /* ?{} */);676 }677 678 }679 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){680 {681 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X4_srcS13__anonymous14_1._X1ii_1) /* ?{} */);682 }683 684 }685 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){686 {687 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1) /* ^?{} */);688 }689 690 }691 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){692 struct __anonymous14 _X4_retS13__anonymous14_1;693 {694 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X4_srcS13__anonymous14_1._X1ii_1));695 }696 697 {698 ((void)_X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1((&_X4_retS13__anonymous14_1), (*_X4_dstS13__anonymous14_1)));699 }700 701 return _X4_retS13__anonymous14_1;702 }703 static inline void _X12_constructorFv_S13__anonymous14i_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed int _X1ii_1){704 {705 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X1ii_1) /* ?{} */);706 }707 708 }709 static inline volatile const struct __anonymous14 _X3f31FS13__anonymous14___1();710 struct __anonymous15 {711 signed int _X1ii_1;712 };713 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1);714 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1);715 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1);716 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1);717 static inline void _X12_constructorFv_S13__anonymous15i_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed int _X1ii_1);718 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){719 {720 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1) /* ?{} */);721 }722 723 }724 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){725 {726 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X4_srcS13__anonymous15_1._X1ii_1) /* ?{} */);727 }728 729 }730 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){731 {732 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1) /* ^?{} */);733 }734 735 }736 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){737 struct __anonymous15 _X4_retS13__anonymous15_1;738 {739 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X4_srcS13__anonymous15_1._X1ii_1));740 }741 742 {743 ((void)_X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1((&_X4_retS13__anonymous15_1), (*_X4_dstS13__anonymous15_1)));744 }745 746 return _X4_retS13__anonymous15_1;747 }748 static inline void _X12_constructorFv_S13__anonymous15i_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed int _X1ii_1){749 {750 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X1ii_1) /* ?{} */);751 }752 753 }754 static inline volatile const struct __anonymous15 _X3f32FS13__anonymous15___1();755 755 struct __anonymous16 { 756 756 signed int _X1ii_1; … … 797 797 798 798 } 799 static inline volatile const struct __anonymous16 _X3f3 3FS13__anonymous16___1();799 static inline volatile const struct __anonymous16 _X3f31FS13__anonymous16___1(); 800 800 struct __anonymous17 { 801 801 signed int _X1ii_1; … … 842 842 843 843 } 844 static inline volatile const struct __anonymous17 _X3f3 4FS13__anonymous17___1();844 static inline volatile const struct __anonymous17 _X3f32FS13__anonymous17___1(); 845 845 struct __anonymous18 { 846 846 signed int _X1ii_1; … … 887 887 888 888 } 889 static inline volatile const struct __anonymous18 _X3f3 5FS13__anonymous18___1();889 static inline volatile const struct __anonymous18 _X3f33FS13__anonymous18___1(); 890 890 struct __anonymous19 { 891 891 signed int _X1ii_1; … … 932 932 933 933 } 934 static inline volatile const struct __anonymous19 _X3f3 6FS13__anonymous19___1();934 static inline volatile const struct __anonymous19 _X3f34FS13__anonymous19___1(); 935 935 struct __anonymous20 { 936 936 signed int _X1ii_1; … … 977 977 978 978 } 979 static inline volatile const struct __anonymous20 _X3f3 7FS13__anonymous20___1();979 static inline volatile const struct __anonymous20 _X3f35FS13__anonymous20___1(); 980 980 struct __anonymous21 { 981 981 signed int _X1ii_1; … … 1022 1022 1023 1023 } 1024 static inline volatile const struct __anonymous21 _X3f38FS13__anonymous21___1(); 1024 static inline volatile const struct __anonymous21 _X3f36FS13__anonymous21___1(); 1025 struct __anonymous22 { 1026 signed int _X1ii_1; 1027 }; 1028 static inline void _X12_constructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1); 1029 static inline void _X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1); 1030 static inline void _X11_destructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1); 1031 static inline struct __anonymous22 _X16_operator_assignFS13__anonymous22_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1); 1032 static inline void _X12_constructorFv_S13__anonymous22i_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, signed int _X1ii_1); 1033 static inline void _X12_constructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1){ 1034 { 1035 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1) /* ?{} */); 1036 } 1037 1038 } 1039 static inline void _X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1){ 1040 { 1041 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X4_srcS13__anonymous22_1._X1ii_1) /* ?{} */); 1042 } 1043 1044 } 1045 static inline void _X11_destructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1){ 1046 { 1047 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1) /* ^?{} */); 1048 } 1049 1050 } 1051 static inline struct __anonymous22 _X16_operator_assignFS13__anonymous22_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1){ 1052 struct __anonymous22 _X4_retS13__anonymous22_1; 1053 { 1054 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X4_srcS13__anonymous22_1._X1ii_1)); 1055 } 1056 1057 { 1058 ((void)_X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1((&_X4_retS13__anonymous22_1), (*_X4_dstS13__anonymous22_1))); 1059 } 1060 1061 return _X4_retS13__anonymous22_1; 1062 } 1063 static inline void _X12_constructorFv_S13__anonymous22i_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, signed int _X1ii_1){ 1064 { 1065 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X1ii_1) /* ?{} */); 1066 } 1067 1068 } 1069 static inline volatile const struct __anonymous22 _X3f37FS13__anonymous22___1(); 1070 struct __anonymous23 { 1071 signed int _X1ii_1; 1072 }; 1073 static inline void _X12_constructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1); 1074 static inline void _X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1); 1075 static inline void _X11_destructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1); 1076 static inline struct __anonymous23 _X16_operator_assignFS13__anonymous23_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1); 1077 static inline void _X12_constructorFv_S13__anonymous23i_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, signed int _X1ii_1); 1078 static inline void _X12_constructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1){ 1079 { 1080 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1) /* ?{} */); 1081 } 1082 1083 } 1084 static inline void _X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1){ 1085 { 1086 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X4_srcS13__anonymous23_1._X1ii_1) /* ?{} */); 1087 } 1088 1089 } 1090 static inline void _X11_destructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1){ 1091 { 1092 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1) /* ^?{} */); 1093 } 1094 1095 } 1096 static inline struct __anonymous23 _X16_operator_assignFS13__anonymous23_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1){ 1097 struct __anonymous23 _X4_retS13__anonymous23_1; 1098 { 1099 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X4_srcS13__anonymous23_1._X1ii_1)); 1100 } 1101 1102 { 1103 ((void)_X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1((&_X4_retS13__anonymous23_1), (*_X4_dstS13__anonymous23_1))); 1104 } 1105 1106 return _X4_retS13__anonymous23_1; 1107 } 1108 static inline void _X12_constructorFv_S13__anonymous23i_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, signed int _X1ii_1){ 1109 { 1110 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X1ii_1) /* ?{} */); 1111 } 1112 1113 } 1114 static inline volatile const struct __anonymous23 _X3f38FS13__anonymous23___1(); 1025 1115 static inline volatile const signed short int _X3f41Fs___1(); 1026 1116 static inline volatile const signed short int _X3f42Fs___1(); -
tests/.expect/declarationSpecifier.x64.txt
r24d6572 r34b4268 51 51 52 52 } 53 staticvolatile const struct __anonymous0 _X3x10KVS12__anonymous0_1;53 volatile const struct __anonymous0 _X3x10KVS12__anonymous0_1; 54 54 struct __anonymous1 { 55 55 signed int _X1ii_1; … … 96 96 97 97 } 98 staticvolatile const struct __anonymous1 _X3x11KVS12__anonymous1_1;98 volatile const struct __anonymous1 _X3x11KVS12__anonymous1_1; 99 99 struct __anonymous2 { 100 100 signed int _X1ii_1; … … 141 141 142 142 } 143 staticvolatile const struct __anonymous2 _X3x12KVS12__anonymous2_1;143 volatile const struct __anonymous2 _X3x12KVS12__anonymous2_1; 144 144 struct __anonymous3 { 145 145 signed int _X1ii_1; … … 322 322 } 323 323 static volatile const struct __anonymous6 _X3x16KVS12__anonymous6_1; 324 struct __anonymous7 { 325 signed int _X1ii_1; 326 }; 327 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1); 328 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1); 329 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1); 330 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1); 331 static inline void _X12_constructorFv_S12__anonymous7i_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed int _X1ii_1); 332 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){ 333 { 334 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1) /* ?{} */); 335 } 336 337 } 338 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){ 339 { 340 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X4_srcS12__anonymous7_1._X1ii_1) /* ?{} */); 341 } 342 343 } 344 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){ 345 { 346 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1) /* ^?{} */); 347 } 348 349 } 350 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){ 351 struct __anonymous7 _X4_retS12__anonymous7_1; 352 { 353 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X4_srcS12__anonymous7_1._X1ii_1)); 354 } 355 356 { 357 ((void)_X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1((&_X4_retS12__anonymous7_1), (*_X4_dstS12__anonymous7_1))); 358 } 359 360 return _X4_retS12__anonymous7_1; 361 } 362 static inline void _X12_constructorFv_S12__anonymous7i_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed int _X1ii_1){ 363 { 364 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X1ii_1) /* ?{} */); 365 } 366 367 } 368 static volatile const struct __anonymous7 _X3x17KVS12__anonymous7_1; 324 369 volatile const signed short int _X3x20KVs_1; 325 370 static volatile const signed short int _X3x21KVs_1; … … 330 375 static volatile const signed short int _X3x26KVs_1; 331 376 static volatile const signed short int _X3x27KVs_1; 332 struct __anonymous7 {333 signed short int _X1is_1;334 };335 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1);336 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1);337 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1);338 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1);339 static inline void _X12_constructorFv_S12__anonymous7s_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed short int _X1is_1);340 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){341 {342 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1) /* ?{} */);343 }344 345 }346 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){347 {348 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X4_srcS12__anonymous7_1._X1is_1) /* ?{} */);349 }350 351 }352 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){353 {354 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1) /* ^?{} */);355 }356 357 }358 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){359 struct __anonymous7 _X4_retS12__anonymous7_1;360 {361 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X4_srcS12__anonymous7_1._X1is_1));362 }363 364 {365 ((void)_X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1((&_X4_retS12__anonymous7_1), (*_X4_dstS12__anonymous7_1)));366 }367 368 return _X4_retS12__anonymous7_1;369 }370 static inline void _X12_constructorFv_S12__anonymous7s_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed short int _X1is_1){371 {372 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X1is_1) /* ?{} */);373 }374 375 }376 static volatile const struct __anonymous7 _X3x29KVS12__anonymous7_1;377 377 struct __anonymous8 { 378 378 signed short int _X1is_1; … … 419 419 420 420 } 421 static volatile const struct __anonymous8 _X3x30KVS12__anonymous8_1;421 volatile const struct __anonymous8 _X3x29KVS12__anonymous8_1; 422 422 struct __anonymous9 { 423 423 signed short int _X1is_1; … … 464 464 465 465 } 466 static volatile const struct __anonymous9 _X3x31KVS12__anonymous9_1;466 volatile const struct __anonymous9 _X3x30KVS12__anonymous9_1; 467 467 struct __anonymous10 { 468 468 signed short int _X1is_1; … … 509 509 510 510 } 511 static volatile const struct __anonymous10 _X3x32KVS13__anonymous10_1;511 volatile const struct __anonymous10 _X3x31KVS13__anonymous10_1; 512 512 struct __anonymous11 { 513 513 signed short int _X1is_1; … … 554 554 555 555 } 556 static volatile const struct __anonymous11 _X3x3 3KVS13__anonymous11_1;556 static volatile const struct __anonymous11 _X3x32KVS13__anonymous11_1; 557 557 struct __anonymous12 { 558 558 signed short int _X1is_1; … … 599 599 600 600 } 601 static volatile const struct __anonymous12 _X3x3 4KVS13__anonymous12_1;601 static volatile const struct __anonymous12 _X3x33KVS13__anonymous12_1; 602 602 struct __anonymous13 { 603 603 signed short int _X1is_1; … … 644 644 645 645 } 646 static volatile const struct __anonymous13 _X3x35KVS13__anonymous13_1; 646 static volatile const struct __anonymous13 _X3x34KVS13__anonymous13_1; 647 struct __anonymous14 { 648 signed short int _X1is_1; 649 }; 650 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1); 651 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1); 652 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1); 653 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1); 654 static inline void _X12_constructorFv_S13__anonymous14s_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed short int _X1is_1); 655 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){ 656 { 657 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1) /* ?{} */); 658 } 659 660 } 661 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){ 662 { 663 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X4_srcS13__anonymous14_1._X1is_1) /* ?{} */); 664 } 665 666 } 667 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){ 668 { 669 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1) /* ^?{} */); 670 } 671 672 } 673 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){ 674 struct __anonymous14 _X4_retS13__anonymous14_1; 675 { 676 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X4_srcS13__anonymous14_1._X1is_1)); 677 } 678 679 { 680 ((void)_X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1((&_X4_retS13__anonymous14_1), (*_X4_dstS13__anonymous14_1))); 681 } 682 683 return _X4_retS13__anonymous14_1; 684 } 685 static inline void _X12_constructorFv_S13__anonymous14s_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed short int _X1is_1){ 686 { 687 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X1is_1) /* ?{} */); 688 } 689 690 } 691 static volatile const struct __anonymous14 _X3x35KVS13__anonymous14_1; 692 struct __anonymous15 { 693 signed short int _X1is_1; 694 }; 695 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1); 696 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1); 697 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1); 698 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1); 699 static inline void _X12_constructorFv_S13__anonymous15s_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed short int _X1is_1); 700 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){ 701 { 702 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1) /* ?{} */); 703 } 704 705 } 706 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){ 707 { 708 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X4_srcS13__anonymous15_1._X1is_1) /* ?{} */); 709 } 710 711 } 712 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){ 713 { 714 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1) /* ^?{} */); 715 } 716 717 } 718 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){ 719 struct __anonymous15 _X4_retS13__anonymous15_1; 720 { 721 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X4_srcS13__anonymous15_1._X1is_1)); 722 } 723 724 { 725 ((void)_X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1((&_X4_retS13__anonymous15_1), (*_X4_dstS13__anonymous15_1))); 726 } 727 728 return _X4_retS13__anonymous15_1; 729 } 730 static inline void _X12_constructorFv_S13__anonymous15s_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed short int _X1is_1){ 731 { 732 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X1is_1) /* ?{} */); 733 } 734 735 } 736 static volatile const struct __anonymous15 _X3x36KVS13__anonymous15_1; 647 737 _Thread_local signed int _X3x37i_1; 648 738 __thread signed int _X3x38i_1; … … 663 753 static inline volatile const signed short int _X3f27Fs___1(); 664 754 static inline volatile const signed short int _X3f28Fs___1(); 665 struct __anonymous14 {666 signed int _X1ii_1;667 };668 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1);669 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1);670 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1);671 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1);672 static inline void _X12_constructorFv_S13__anonymous14i_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed int _X1ii_1);673 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){674 {675 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1) /* ?{} */);676 }677 678 }679 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){680 {681 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X4_srcS13__anonymous14_1._X1ii_1) /* ?{} */);682 }683 684 }685 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){686 {687 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1) /* ^?{} */);688 }689 690 }691 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){692 struct __anonymous14 _X4_retS13__anonymous14_1;693 {694 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X4_srcS13__anonymous14_1._X1ii_1));695 }696 697 {698 ((void)_X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1((&_X4_retS13__anonymous14_1), (*_X4_dstS13__anonymous14_1)));699 }700 701 return _X4_retS13__anonymous14_1;702 }703 static inline void _X12_constructorFv_S13__anonymous14i_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed int _X1ii_1){704 {705 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X1ii_1) /* ?{} */);706 }707 708 }709 static inline volatile const struct __anonymous14 _X3f31FS13__anonymous14___1();710 struct __anonymous15 {711 signed int _X1ii_1;712 };713 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1);714 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1);715 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1);716 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1);717 static inline void _X12_constructorFv_S13__anonymous15i_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed int _X1ii_1);718 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){719 {720 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1) /* ?{} */);721 }722 723 }724 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){725 {726 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X4_srcS13__anonymous15_1._X1ii_1) /* ?{} */);727 }728 729 }730 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){731 {732 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1) /* ^?{} */);733 }734 735 }736 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){737 struct __anonymous15 _X4_retS13__anonymous15_1;738 {739 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X4_srcS13__anonymous15_1._X1ii_1));740 }741 742 {743 ((void)_X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1((&_X4_retS13__anonymous15_1), (*_X4_dstS13__anonymous15_1)));744 }745 746 return _X4_retS13__anonymous15_1;747 }748 static inline void _X12_constructorFv_S13__anonymous15i_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed int _X1ii_1){749 {750 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X1ii_1) /* ?{} */);751 }752 753 }754 static inline volatile const struct __anonymous15 _X3f32FS13__anonymous15___1();755 755 struct __anonymous16 { 756 756 signed int _X1ii_1; … … 797 797 798 798 } 799 static inline volatile const struct __anonymous16 _X3f3 3FS13__anonymous16___1();799 static inline volatile const struct __anonymous16 _X3f31FS13__anonymous16___1(); 800 800 struct __anonymous17 { 801 801 signed int _X1ii_1; … … 842 842 843 843 } 844 static inline volatile const struct __anonymous17 _X3f3 4FS13__anonymous17___1();844 static inline volatile const struct __anonymous17 _X3f32FS13__anonymous17___1(); 845 845 struct __anonymous18 { 846 846 signed int _X1ii_1; … … 887 887 888 888 } 889 static inline volatile const struct __anonymous18 _X3f3 5FS13__anonymous18___1();889 static inline volatile const struct __anonymous18 _X3f33FS13__anonymous18___1(); 890 890 struct __anonymous19 { 891 891 signed int _X1ii_1; … … 932 932 933 933 } 934 static inline volatile const struct __anonymous19 _X3f3 6FS13__anonymous19___1();934 static inline volatile const struct __anonymous19 _X3f34FS13__anonymous19___1(); 935 935 struct __anonymous20 { 936 936 signed int _X1ii_1; … … 977 977 978 978 } 979 static inline volatile const struct __anonymous20 _X3f3 7FS13__anonymous20___1();979 static inline volatile const struct __anonymous20 _X3f35FS13__anonymous20___1(); 980 980 struct __anonymous21 { 981 981 signed int _X1ii_1; … … 1022 1022 1023 1023 } 1024 static inline volatile const struct __anonymous21 _X3f38FS13__anonymous21___1(); 1024 static inline volatile const struct __anonymous21 _X3f36FS13__anonymous21___1(); 1025 struct __anonymous22 { 1026 signed int _X1ii_1; 1027 }; 1028 static inline void _X12_constructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1); 1029 static inline void _X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1); 1030 static inline void _X11_destructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1); 1031 static inline struct __anonymous22 _X16_operator_assignFS13__anonymous22_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1); 1032 static inline void _X12_constructorFv_S13__anonymous22i_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, signed int _X1ii_1); 1033 static inline void _X12_constructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1){ 1034 { 1035 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1) /* ?{} */); 1036 } 1037 1038 } 1039 static inline void _X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1){ 1040 { 1041 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X4_srcS13__anonymous22_1._X1ii_1) /* ?{} */); 1042 } 1043 1044 } 1045 static inline void _X11_destructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1){ 1046 { 1047 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1) /* ^?{} */); 1048 } 1049 1050 } 1051 static inline struct __anonymous22 _X16_operator_assignFS13__anonymous22_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1){ 1052 struct __anonymous22 _X4_retS13__anonymous22_1; 1053 { 1054 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X4_srcS13__anonymous22_1._X1ii_1)); 1055 } 1056 1057 { 1058 ((void)_X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1((&_X4_retS13__anonymous22_1), (*_X4_dstS13__anonymous22_1))); 1059 } 1060 1061 return _X4_retS13__anonymous22_1; 1062 } 1063 static inline void _X12_constructorFv_S13__anonymous22i_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, signed int _X1ii_1){ 1064 { 1065 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X1ii_1) /* ?{} */); 1066 } 1067 1068 } 1069 static inline volatile const struct __anonymous22 _X3f37FS13__anonymous22___1(); 1070 struct __anonymous23 { 1071 signed int _X1ii_1; 1072 }; 1073 static inline void _X12_constructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1); 1074 static inline void _X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1); 1075 static inline void _X11_destructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1); 1076 static inline struct __anonymous23 _X16_operator_assignFS13__anonymous23_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1); 1077 static inline void _X12_constructorFv_S13__anonymous23i_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, signed int _X1ii_1); 1078 static inline void _X12_constructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1){ 1079 { 1080 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1) /* ?{} */); 1081 } 1082 1083 } 1084 static inline void _X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1){ 1085 { 1086 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X4_srcS13__anonymous23_1._X1ii_1) /* ?{} */); 1087 } 1088 1089 } 1090 static inline void _X11_destructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1){ 1091 { 1092 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1) /* ^?{} */); 1093 } 1094 1095 } 1096 static inline struct __anonymous23 _X16_operator_assignFS13__anonymous23_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1){ 1097 struct __anonymous23 _X4_retS13__anonymous23_1; 1098 { 1099 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X4_srcS13__anonymous23_1._X1ii_1)); 1100 } 1101 1102 { 1103 ((void)_X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1((&_X4_retS13__anonymous23_1), (*_X4_dstS13__anonymous23_1))); 1104 } 1105 1106 return _X4_retS13__anonymous23_1; 1107 } 1108 static inline void _X12_constructorFv_S13__anonymous23i_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, signed int _X1ii_1){ 1109 { 1110 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X1ii_1) /* ?{} */); 1111 } 1112 1113 } 1114 static inline volatile const struct __anonymous23 _X3f38FS13__anonymous23___1(); 1025 1115 static inline volatile const signed short int _X3f41Fs___1(); 1026 1116 static inline volatile const signed short int _X3f42Fs___1(); -
tests/.expect/declarationSpecifier.x86.txt
r24d6572 r34b4268 51 51 52 52 } 53 staticvolatile const struct __anonymous0 _X3x10KVS12__anonymous0_1;53 volatile const struct __anonymous0 _X3x10KVS12__anonymous0_1; 54 54 struct __anonymous1 { 55 55 signed int _X1ii_1; … … 96 96 97 97 } 98 staticvolatile const struct __anonymous1 _X3x11KVS12__anonymous1_1;98 volatile const struct __anonymous1 _X3x11KVS12__anonymous1_1; 99 99 struct __anonymous2 { 100 100 signed int _X1ii_1; … … 141 141 142 142 } 143 staticvolatile const struct __anonymous2 _X3x12KVS12__anonymous2_1;143 volatile const struct __anonymous2 _X3x12KVS12__anonymous2_1; 144 144 struct __anonymous3 { 145 145 signed int _X1ii_1; … … 322 322 } 323 323 static volatile const struct __anonymous6 _X3x16KVS12__anonymous6_1; 324 struct __anonymous7 { 325 signed int _X1ii_1; 326 }; 327 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1); 328 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1); 329 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1); 330 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1); 331 static inline void _X12_constructorFv_S12__anonymous7i_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed int _X1ii_1); 332 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){ 333 { 334 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1) /* ?{} */); 335 } 336 337 } 338 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){ 339 { 340 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X4_srcS12__anonymous7_1._X1ii_1) /* ?{} */); 341 } 342 343 } 344 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){ 345 { 346 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1) /* ^?{} */); 347 } 348 349 } 350 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){ 351 struct __anonymous7 _X4_retS12__anonymous7_1; 352 { 353 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X4_srcS12__anonymous7_1._X1ii_1)); 354 } 355 356 { 357 ((void)_X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1((&_X4_retS12__anonymous7_1), (*_X4_dstS12__anonymous7_1))); 358 } 359 360 return _X4_retS12__anonymous7_1; 361 } 362 static inline void _X12_constructorFv_S12__anonymous7i_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed int _X1ii_1){ 363 { 364 ((void)((*_X4_dstS12__anonymous7_1)._X1ii_1=_X1ii_1) /* ?{} */); 365 } 366 367 } 368 static volatile const struct __anonymous7 _X3x17KVS12__anonymous7_1; 324 369 volatile const signed short int _X3x20KVs_1; 325 370 static volatile const signed short int _X3x21KVs_1; … … 330 375 static volatile const signed short int _X3x26KVs_1; 331 376 static volatile const signed short int _X3x27KVs_1; 332 struct __anonymous7 {333 signed short int _X1is_1;334 };335 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1);336 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1);337 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1);338 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1);339 static inline void _X12_constructorFv_S12__anonymous7s_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed short int _X1is_1);340 static inline void _X12_constructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){341 {342 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1) /* ?{} */);343 }344 345 }346 static inline void _X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){347 {348 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X4_srcS12__anonymous7_1._X1is_1) /* ?{} */);349 }350 351 }352 static inline void _X11_destructorFv_S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1){353 {354 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1) /* ^?{} */);355 }356 357 }358 static inline struct __anonymous7 _X16_operator_assignFS12__anonymous7_S12__anonymous7S12__anonymous7_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, struct __anonymous7 _X4_srcS12__anonymous7_1){359 struct __anonymous7 _X4_retS12__anonymous7_1;360 {361 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X4_srcS12__anonymous7_1._X1is_1));362 }363 364 {365 ((void)_X12_constructorFv_S12__anonymous7S12__anonymous7_autogen___1((&_X4_retS12__anonymous7_1), (*_X4_dstS12__anonymous7_1)));366 }367 368 return _X4_retS12__anonymous7_1;369 }370 static inline void _X12_constructorFv_S12__anonymous7s_autogen___1(struct __anonymous7 *_X4_dstS12__anonymous7_1, signed short int _X1is_1){371 {372 ((void)((*_X4_dstS12__anonymous7_1)._X1is_1=_X1is_1) /* ?{} */);373 }374 375 }376 static volatile const struct __anonymous7 _X3x29KVS12__anonymous7_1;377 377 struct __anonymous8 { 378 378 signed short int _X1is_1; … … 419 419 420 420 } 421 static volatile const struct __anonymous8 _X3x30KVS12__anonymous8_1;421 volatile const struct __anonymous8 _X3x29KVS12__anonymous8_1; 422 422 struct __anonymous9 { 423 423 signed short int _X1is_1; … … 464 464 465 465 } 466 static volatile const struct __anonymous9 _X3x31KVS12__anonymous9_1;466 volatile const struct __anonymous9 _X3x30KVS12__anonymous9_1; 467 467 struct __anonymous10 { 468 468 signed short int _X1is_1; … … 509 509 510 510 } 511 static volatile const struct __anonymous10 _X3x32KVS13__anonymous10_1;511 volatile const struct __anonymous10 _X3x31KVS13__anonymous10_1; 512 512 struct __anonymous11 { 513 513 signed short int _X1is_1; … … 554 554 555 555 } 556 static volatile const struct __anonymous11 _X3x3 3KVS13__anonymous11_1;556 static volatile const struct __anonymous11 _X3x32KVS13__anonymous11_1; 557 557 struct __anonymous12 { 558 558 signed short int _X1is_1; … … 599 599 600 600 } 601 static volatile const struct __anonymous12 _X3x3 4KVS13__anonymous12_1;601 static volatile const struct __anonymous12 _X3x33KVS13__anonymous12_1; 602 602 struct __anonymous13 { 603 603 signed short int _X1is_1; … … 644 644 645 645 } 646 static volatile const struct __anonymous13 _X3x35KVS13__anonymous13_1; 646 static volatile const struct __anonymous13 _X3x34KVS13__anonymous13_1; 647 struct __anonymous14 { 648 signed short int _X1is_1; 649 }; 650 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1); 651 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1); 652 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1); 653 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1); 654 static inline void _X12_constructorFv_S13__anonymous14s_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed short int _X1is_1); 655 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){ 656 { 657 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1) /* ?{} */); 658 } 659 660 } 661 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){ 662 { 663 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X4_srcS13__anonymous14_1._X1is_1) /* ?{} */); 664 } 665 666 } 667 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){ 668 { 669 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1) /* ^?{} */); 670 } 671 672 } 673 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){ 674 struct __anonymous14 _X4_retS13__anonymous14_1; 675 { 676 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X4_srcS13__anonymous14_1._X1is_1)); 677 } 678 679 { 680 ((void)_X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1((&_X4_retS13__anonymous14_1), (*_X4_dstS13__anonymous14_1))); 681 } 682 683 return _X4_retS13__anonymous14_1; 684 } 685 static inline void _X12_constructorFv_S13__anonymous14s_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed short int _X1is_1){ 686 { 687 ((void)((*_X4_dstS13__anonymous14_1)._X1is_1=_X1is_1) /* ?{} */); 688 } 689 690 } 691 static volatile const struct __anonymous14 _X3x35KVS13__anonymous14_1; 692 struct __anonymous15 { 693 signed short int _X1is_1; 694 }; 695 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1); 696 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1); 697 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1); 698 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1); 699 static inline void _X12_constructorFv_S13__anonymous15s_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed short int _X1is_1); 700 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){ 701 { 702 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1) /* ?{} */); 703 } 704 705 } 706 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){ 707 { 708 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X4_srcS13__anonymous15_1._X1is_1) /* ?{} */); 709 } 710 711 } 712 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){ 713 { 714 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1) /* ^?{} */); 715 } 716 717 } 718 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){ 719 struct __anonymous15 _X4_retS13__anonymous15_1; 720 { 721 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X4_srcS13__anonymous15_1._X1is_1)); 722 } 723 724 { 725 ((void)_X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1((&_X4_retS13__anonymous15_1), (*_X4_dstS13__anonymous15_1))); 726 } 727 728 return _X4_retS13__anonymous15_1; 729 } 730 static inline void _X12_constructorFv_S13__anonymous15s_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed short int _X1is_1){ 731 { 732 ((void)((*_X4_dstS13__anonymous15_1)._X1is_1=_X1is_1) /* ?{} */); 733 } 734 735 } 736 static volatile const struct __anonymous15 _X3x36KVS13__anonymous15_1; 647 737 _Thread_local signed int _X3x37i_1; 648 738 __thread signed int _X3x38i_1; … … 663 753 static inline volatile const signed short int _X3f27Fs___1(); 664 754 static inline volatile const signed short int _X3f28Fs___1(); 665 struct __anonymous14 {666 signed int _X1ii_1;667 };668 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1);669 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1);670 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1);671 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1);672 static inline void _X12_constructorFv_S13__anonymous14i_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed int _X1ii_1);673 static inline void _X12_constructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){674 {675 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1) /* ?{} */);676 }677 678 }679 static inline void _X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){680 {681 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X4_srcS13__anonymous14_1._X1ii_1) /* ?{} */);682 }683 684 }685 static inline void _X11_destructorFv_S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1){686 {687 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1) /* ^?{} */);688 }689 690 }691 static inline struct __anonymous14 _X16_operator_assignFS13__anonymous14_S13__anonymous14S13__anonymous14_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, struct __anonymous14 _X4_srcS13__anonymous14_1){692 struct __anonymous14 _X4_retS13__anonymous14_1;693 {694 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X4_srcS13__anonymous14_1._X1ii_1));695 }696 697 {698 ((void)_X12_constructorFv_S13__anonymous14S13__anonymous14_autogen___1((&_X4_retS13__anonymous14_1), (*_X4_dstS13__anonymous14_1)));699 }700 701 return _X4_retS13__anonymous14_1;702 }703 static inline void _X12_constructorFv_S13__anonymous14i_autogen___1(struct __anonymous14 *_X4_dstS13__anonymous14_1, signed int _X1ii_1){704 {705 ((void)((*_X4_dstS13__anonymous14_1)._X1ii_1=_X1ii_1) /* ?{} */);706 }707 708 }709 static inline volatile const struct __anonymous14 _X3f31FS13__anonymous14___1();710 struct __anonymous15 {711 signed int _X1ii_1;712 };713 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1);714 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1);715 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1);716 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1);717 static inline void _X12_constructorFv_S13__anonymous15i_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed int _X1ii_1);718 static inline void _X12_constructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){719 {720 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1) /* ?{} */);721 }722 723 }724 static inline void _X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){725 {726 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X4_srcS13__anonymous15_1._X1ii_1) /* ?{} */);727 }728 729 }730 static inline void _X11_destructorFv_S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1){731 {732 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1) /* ^?{} */);733 }734 735 }736 static inline struct __anonymous15 _X16_operator_assignFS13__anonymous15_S13__anonymous15S13__anonymous15_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, struct __anonymous15 _X4_srcS13__anonymous15_1){737 struct __anonymous15 _X4_retS13__anonymous15_1;738 {739 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X4_srcS13__anonymous15_1._X1ii_1));740 }741 742 {743 ((void)_X12_constructorFv_S13__anonymous15S13__anonymous15_autogen___1((&_X4_retS13__anonymous15_1), (*_X4_dstS13__anonymous15_1)));744 }745 746 return _X4_retS13__anonymous15_1;747 }748 static inline void _X12_constructorFv_S13__anonymous15i_autogen___1(struct __anonymous15 *_X4_dstS13__anonymous15_1, signed int _X1ii_1){749 {750 ((void)((*_X4_dstS13__anonymous15_1)._X1ii_1=_X1ii_1) /* ?{} */);751 }752 753 }754 static inline volatile const struct __anonymous15 _X3f32FS13__anonymous15___1();755 755 struct __anonymous16 { 756 756 signed int _X1ii_1; … … 797 797 798 798 } 799 static inline volatile const struct __anonymous16 _X3f3 3FS13__anonymous16___1();799 static inline volatile const struct __anonymous16 _X3f31FS13__anonymous16___1(); 800 800 struct __anonymous17 { 801 801 signed int _X1ii_1; … … 842 842 843 843 } 844 static inline volatile const struct __anonymous17 _X3f3 4FS13__anonymous17___1();844 static inline volatile const struct __anonymous17 _X3f32FS13__anonymous17___1(); 845 845 struct __anonymous18 { 846 846 signed int _X1ii_1; … … 887 887 888 888 } 889 static inline volatile const struct __anonymous18 _X3f3 5FS13__anonymous18___1();889 static inline volatile const struct __anonymous18 _X3f33FS13__anonymous18___1(); 890 890 struct __anonymous19 { 891 891 signed int _X1ii_1; … … 932 932 933 933 } 934 static inline volatile const struct __anonymous19 _X3f3 6FS13__anonymous19___1();934 static inline volatile const struct __anonymous19 _X3f34FS13__anonymous19___1(); 935 935 struct __anonymous20 { 936 936 signed int _X1ii_1; … … 977 977 978 978 } 979 static inline volatile const struct __anonymous20 _X3f3 7FS13__anonymous20___1();979 static inline volatile const struct __anonymous20 _X3f35FS13__anonymous20___1(); 980 980 struct __anonymous21 { 981 981 signed int _X1ii_1; … … 1022 1022 1023 1023 } 1024 static inline volatile const struct __anonymous21 _X3f38FS13__anonymous21___1(); 1024 static inline volatile const struct __anonymous21 _X3f36FS13__anonymous21___1(); 1025 struct __anonymous22 { 1026 signed int _X1ii_1; 1027 }; 1028 static inline void _X12_constructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1); 1029 static inline void _X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1); 1030 static inline void _X11_destructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1); 1031 static inline struct __anonymous22 _X16_operator_assignFS13__anonymous22_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1); 1032 static inline void _X12_constructorFv_S13__anonymous22i_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, signed int _X1ii_1); 1033 static inline void _X12_constructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1){ 1034 { 1035 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1) /* ?{} */); 1036 } 1037 1038 } 1039 static inline void _X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1){ 1040 { 1041 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X4_srcS13__anonymous22_1._X1ii_1) /* ?{} */); 1042 } 1043 1044 } 1045 static inline void _X11_destructorFv_S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1){ 1046 { 1047 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1) /* ^?{} */); 1048 } 1049 1050 } 1051 static inline struct __anonymous22 _X16_operator_assignFS13__anonymous22_S13__anonymous22S13__anonymous22_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, struct __anonymous22 _X4_srcS13__anonymous22_1){ 1052 struct __anonymous22 _X4_retS13__anonymous22_1; 1053 { 1054 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X4_srcS13__anonymous22_1._X1ii_1)); 1055 } 1056 1057 { 1058 ((void)_X12_constructorFv_S13__anonymous22S13__anonymous22_autogen___1((&_X4_retS13__anonymous22_1), (*_X4_dstS13__anonymous22_1))); 1059 } 1060 1061 return _X4_retS13__anonymous22_1; 1062 } 1063 static inline void _X12_constructorFv_S13__anonymous22i_autogen___1(struct __anonymous22 *_X4_dstS13__anonymous22_1, signed int _X1ii_1){ 1064 { 1065 ((void)((*_X4_dstS13__anonymous22_1)._X1ii_1=_X1ii_1) /* ?{} */); 1066 } 1067 1068 } 1069 static inline volatile const struct __anonymous22 _X3f37FS13__anonymous22___1(); 1070 struct __anonymous23 { 1071 signed int _X1ii_1; 1072 }; 1073 static inline void _X12_constructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1); 1074 static inline void _X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1); 1075 static inline void _X11_destructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1); 1076 static inline struct __anonymous23 _X16_operator_assignFS13__anonymous23_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1); 1077 static inline void _X12_constructorFv_S13__anonymous23i_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, signed int _X1ii_1); 1078 static inline void _X12_constructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1){ 1079 { 1080 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1) /* ?{} */); 1081 } 1082 1083 } 1084 static inline void _X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1){ 1085 { 1086 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X4_srcS13__anonymous23_1._X1ii_1) /* ?{} */); 1087 } 1088 1089 } 1090 static inline void _X11_destructorFv_S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1){ 1091 { 1092 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1) /* ^?{} */); 1093 } 1094 1095 } 1096 static inline struct __anonymous23 _X16_operator_assignFS13__anonymous23_S13__anonymous23S13__anonymous23_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, struct __anonymous23 _X4_srcS13__anonymous23_1){ 1097 struct __anonymous23 _X4_retS13__anonymous23_1; 1098 { 1099 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X4_srcS13__anonymous23_1._X1ii_1)); 1100 } 1101 1102 { 1103 ((void)_X12_constructorFv_S13__anonymous23S13__anonymous23_autogen___1((&_X4_retS13__anonymous23_1), (*_X4_dstS13__anonymous23_1))); 1104 } 1105 1106 return _X4_retS13__anonymous23_1; 1107 } 1108 static inline void _X12_constructorFv_S13__anonymous23i_autogen___1(struct __anonymous23 *_X4_dstS13__anonymous23_1, signed int _X1ii_1){ 1109 { 1110 ((void)((*_X4_dstS13__anonymous23_1)._X1ii_1=_X1ii_1) /* ?{} */); 1111 } 1112 1113 } 1114 static inline volatile const struct __anonymous23 _X3f38FS13__anonymous23___1(); 1025 1115 static inline volatile const signed short int _X3f41Fs___1(); 1026 1116 static inline volatile const signed short int _X3f42Fs___1(); -
tests/.expect/forall.txt
r24d6572 r34b4268 1 1 2 f 3 97 4 f 5 g 6 f 7 f 8 g 9 fT 10 fT 11 fT 12 fTU 13 fTU 14 fTU 15 1 2 16 2 1 17 1, 2 18 @ 0 2 0 4 6.4 6.4 6.4 6.4+3.i 4 19 3. 3. 20 45 21 12 3 1 forall.cfa:244:25: warning: Compiled -
tests/.expect/nested_function.x64.txt
r24d6572 r34b4268 1 total 1451 total 80 -
tests/.expect/nested_function.x86.txt
r24d6572 r34b4268 1 total 2451 total 55 -
tests/Makefile.am
r24d6572 r34b4268 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : S un May 28 08:15:43 202314 ## Update Count : 19613 ## Last Modified On : Sat Jun 5 14:49:25 2021 14 ## Update Count : 92 15 15 ############################################################################### 16 16 … … 22 22 DEFAULT_INCLUDES = -I${abs_srcdir} 23 23 24 debug ?= yes 25 installed ?= no 26 ARCH = ${if ${arch},"--arch=${arch}"} 27 arch_support = "x86/x64/arm" 28 TIMEOUT = ${if ${timeout},"--timeout=${timeout}"} 29 GLOBAL_TIMEOUT = ${if ${global-timeout},"--global-timeout=${global-timeout}"} 30 ARCHIVE_ERRORS = ${if ${archive-errors},"--archive-errors=${archive-errors}"} 31 32 DEBUG_FLAGS = -debug -g -O0 33 34 quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes meta/dumpable 24 debug=yes 25 installed=no 26 archiveerrors= 27 28 DEBUG_FLAGS=-debug -g -O0 29 30 quick_test=avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes meta/dumpable 31 32 concurrent= 33 timeouts= 35 34 36 35 TEST_PY = python3 ${builddir}/test.py … … 38 37 # applies to both programs 39 38 # since automake doesn't have support for CFA we have to 40 AM_CFLAGS = $ {if ${test}, 2> ${test}, }\41 -fdebug-prefix-map=$ {abspath ${abs_srcdir}}= \39 AM_CFLAGS = $(if $(test), 2> $(test), ) \ 40 -fdebug-prefix-map=$(abspath ${abs_srcdir})= \ 42 41 -fdebug-prefix-map=/tmp= \ 43 42 -fno-diagnostics-show-caret \ … … 52 51 53 52 # get the desired cfa to test 54 TARGET_CFA = $ {if ${filter ${installed},yes}, @CFACC_INSTALL@, @CFACC@}53 TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@) 55 54 56 55 # adjust CC to current flags 57 CC = LC_ALL=C $ {if ${DISTCC_CFA_PATH},distcc ${DISTCC_CFA_PATH} ${ARCH_FLAGS} ,${TARGET_CFA} ${DEBUG_FLAGS} ${ARCH_FLAGS}}58 CFACC = $ {CC}56 CC = LC_ALL=C $(if $(DISTCC_CFA_PATH),distcc $(DISTCC_CFA_PATH) ${ARCH_FLAGS} ,$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 57 CFACC = $(CC) 59 58 60 59 # get local binary for depedencies … … 62 61 63 62 # adjusted CC but without the actual distcc call 64 CFACCLOCAL = $ {if ${DISTCC_CFA_PATH},${DISTCC_CFA_PATH} ${ARCH_FLAGS} ,${TARGET_CFA} ${DEBUG_FLAGS} ${ARCH_FLAGS}}65 CFACCLINK = $ {CFACCLOCAL} -quiet ${if ${test}, 2> ${test}, } ${${shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g'}}66 67 PRETTY_PATH = mkdir -p ${dir ${abspath ${@}}}&& cd ${srcdir} &&68 69 .PHONY : concurrencylist .validate .test_makeflags70 .INTERMEDIATE : .validate .validate.cfa .test_makeflags63 CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH) ${ARCH_FLAGS} ,$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 64 CFACCLINK = $(CFACCLOCAL) -quiet $(if $(test), 2> $(test), ) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) 65 66 PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} && 67 68 .PHONY: list .validate .test_makeflags 69 .INTERMEDIATE: .validate .validate.cfa .test_makeflags 71 70 EXTRA_PROGRAMS = avl_test linkonce linking/mangling/anon .dummy_hack # build but do not install 72 71 EXTRA_DIST = test.py \ … … 79 78 avltree/avl-private.h \ 80 79 avltree/avl.h \ 80 concurrent/clib_tls.c \ 81 concurrent/clib.c \ 81 82 configs/.in/parseconfig-all.txt \ 82 83 configs/.in/parseconfig-errors.txt \ … … 87 88 io/.in/many_read.data \ 88 89 meta/fork+exec.hfa \ 89 concurrency/clib_tls.c \ 90 concurrency/clib.c \ 91 concurrency/unified_locking/mutex_test.hfa \ 92 concurrency/channels/parallel_harness.hfa 90 unified_locking/mutex_test.hfa 93 91 94 92 dist-hook: … … 96 94 for file in `${TEST_PY} --list-dist`; do \ 97 95 if test -f ${srcdir}/$${file}; then \ 98 $ {MKDIR_P}$$(dirname ${distdir}/$${file}); \96 $(MKDIR_P) $$(dirname ${distdir}/$${file}); \ 99 97 cp -df ${srcdir}/$${file} ${distdir}/$${file}; \ 100 98 fi; \ … … 108 106 109 107 #---------------------------------------------------------------------------------------------------------------- 110 111 # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 112 all-local : # This name is important to automake and implies the default build target. 113 @+${TEST_PY} --debug=${debug} --install=${installed} --invariant ${ARCHIVE_ERRORS} ${TIMEOUT} ${GLOBAL_TIMEOUT} ${ARCH} --all 114 115 tests : all-local # synonym 116 117 install : all-local # synonym, PAB only 118 119 quick : 120 @+${TEST_PY} --debug=${debug} --install=${installed} ${ARCHIVE_ERRORS} ${ARCH} ${quick_test} 121 122 concurrency : 123 @+${TEST_PY} --debug=${debug} --install=${installed} ${ARCHIVE_ERRORS} ${TIMEOUT} ${GLOBAL_TIMEOUT} ${ARCH} -Iconcurrency 124 125 list : 126 @+${TEST_PY} --list 127 128 help : 129 @echo "user targets:" 130 @echo " Run the complete test suite." 131 @echo " $$ make (null) / tests [debug=yes/no] [installed=yes/no] [archive-errors=dump-dir] [timeout=seconds] [global-timeout=seconds] [arch=${arch_support}]" 132 @echo "" 133 @echo " Run the short (quick) test suite." 134 @echo " $$ make quick [debug=yes/no] [installed=yes/no] [archive-errors=dump-dir] [arch=${arch_support}]" 135 @echo "" 136 @echo " Run the concurrency test suite." 137 @echo " $$ make concurrency [debug=yes/no] [installed=yes/no] [archive-errors=dump-dir] [timeout=seconds] [global-timeout=seconds] [arch=${arch_support}]" 138 @echo "" 139 @echo " List all tests in the test suite." 140 @echo " $$ make list" 108 all-local : 109 @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test} 110 111 all-tests : 112 @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 141 113 142 114 mostlyclean-local : … … 150 122 find ${builddir} -path '*.Po' -delete 151 123 124 list : 125 @+${TEST_PY} --list ${concurrent} 126 152 127 .test_makeflags: 153 128 @echo "${MAKEFLAGS}" 154 129 155 130 .validate: .validate.cfa 156 $ {CFACOMPILE}.validate.cfa -fsyntax-only -Wall -Wextra -Werror131 $(CFACOMPILE) .validate.cfa -fsyntax-only -Wall -Wextra -Werror 157 132 158 133 .validate.cfa: … … 166 141 @echo "int bar() { return 0; }" > ${@} 167 142 143 concurrency : 144 @+${TEST_PY} --debug=${debug} --install=${installed} -Iconcurrent 145 168 146 #---------------------------------------------------------------------------------------------------------------- 169 147 170 148 # Use for all tests, make sure the path are correct and all flags are added 171 CFACOMPILETEST=$ {PRETTY_PATH} ${CFACOMPILE} ${shell realpath --relative-to=${srcdir} ${<}} ${${shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g'}}149 CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g')) 172 150 173 151 #---------------------------------------------------------------------------------------------------------------- … … 176 154 # split into two steps to support compiling remotely using distcc 177 155 # don't use distcc to do the linking because distcc doesn't do linking 178 % : %.cfa $ {CFACCBIN}179 $ {CFACOMPILETEST} -c -o ${abspath ${@}}.o -DIN_DIR="${abspath ${dir ${<}}}/.in/"180 $ {CFACCLINK} ${@}.o -o ${abspath ${@}}181 rm $ {abspath ${@}}.o156 % : %.cfa $(CFACCBIN) 157 $(CFACOMPILETEST) -c -o $(abspath ${@}).o -DIN_DIR="$(abspath $(dir ${<}))/.in/" 158 $(CFACCLINK) ${@}.o -o $(abspath ${@}) 159 rm $(abspath ${@}).o 182 160 183 161 # implicit rule for c++ test 184 162 # convient for testing the testsuite itself but not actuall used 185 163 % : %.cpp 186 $ {PRETTY_PATH} ${CXXCOMPILE} ${shell realpath --relative-to=${srcdir} ${<}} -o ${abspath ${@}}164 $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 187 165 188 166 #------------------------------------------------------------------------------ … … 195 173 # Generated code 196 174 GENERATED_CODE = declarationSpecifier gccExtensions extension attributes functions KRfunctions 197 $ {GENERATED_CODE} : % : %.cfa ${CFACCBIN}198 $ {CFACOMPILETEST} -CFA -XCFA -p -c -fsyntax-only -o ${abspath ${@}}175 $(GENERATED_CODE): % : %.cfa $(CFACCBIN) 176 $(CFACOMPILETEST) -CFA -XCFA -p -c -fsyntax-only -o $(abspath ${@}) 199 177 200 178 #------------------------------------------------------------------------------ … … 202 180 #------------------------------------------------------------------------------ 203 181 # tests that just validate syntax and compiler output should be compared to stderr 204 CFACOMPILE_SYNTAX = $ {CFACOMPILETEST} -Wno-unused-variable -Wno-unused-label -c -fsyntax-only -o ${abspath ${@}}205 206 SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator \207 init1 limits nested-types cast labelledExit array quasiKeyword include/stdincludes include/includes builtins/sync warnings/self-assignment concurrency/waitfor/parse208 $ {SYNTAX_ONLY_CODE} : % : %.cfa ${CFACCBIN}209 $ {CFACOMPILE_SYNTAX}210 $ {if ${test}, cp ${test} ${abspath ${@}}, }182 CFACOMPILE_SYNTAX = $(CFACOMPILETEST) -Wno-unused-variable -Wno-unused-label -c -fsyntax-only -o $(abspath ${@}) 183 184 SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator forall \ 185 init1 limits nested-types cast labelledExit array quasiKeyword include/stdincludes include/includes builtins/sync warnings/self-assignment 186 $(SYNTAX_ONLY_CODE): % : %.cfa $(CFACCBIN) 187 $(CFACOMPILE_SYNTAX) 188 $(if $(test), cp $(test) $(abspath ${@}), ) 211 189 212 190 # expected failures 213 191 # use custom target since they require a custom define *and* have a name that doesn't match the file 214 215 array-ERR1 : array.cfa ${CFACCBIN} 216 ${CFACOMPILE_SYNTAX} -DERR1 217 -cp ${test} ${abspath ${@}} 218 219 array-ERR2 : array.cfa ${CFACCBIN} 220 ${CFACOMPILE_SYNTAX} -DERR2 221 -cp ${test} ${abspath ${@}} 222 223 array-ERR3 : array.cfa ${CFACCBIN} 224 ${CFACOMPILE_SYNTAX} -DERR3 225 -cp ${test} ${abspath ${@}} 226 227 alloc-ERROR : alloc.cfa ${CFACCBIN} 228 ${CFACOMPILE_SYNTAX} -DERR1 229 -cp ${test} ${abspath ${@}} 230 231 init1-ERROR : init1.cfa ${CFACCBIN} 232 ${CFACOMPILE_SYNTAX} -DERR1 233 -cp ${test} ${abspath ${@}} 234 235 typedefRedef-ERR1 : typedefRedef.cfa ${CFACCBIN} 236 ${CFACOMPILE_SYNTAX} -DERR1 237 -cp ${test} ${abspath ${@}} 238 239 nested-types-ERR1 : nested-types.cfa ${CFACCBIN} 240 ${CFACOMPILE_SYNTAX} -DERR1 241 -cp ${test} ${abspath ${@}} 242 243 nested-types-ERR2 : nested-types.cfa ${CFACCBIN} 244 ${CFACOMPILE_SYNTAX} -DERR2 245 -cp ${test} ${abspath ${@}} 246 247 raii/memberCtors-ERR1 : raii/memberCtors.cfa ${CFACCBIN} 248 ${CFACOMPILE_SYNTAX} -DERR1 249 -cp ${test} ${abspath ${@}} 250 251 raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa ${CFACCBIN} 252 ${CFACOMPILE_SYNTAX} -DERR1 253 -cp ${test} ${abspath ${@}} 254 255 raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa ${CFACCBIN} 256 ${CFACOMPILE_SYNTAX} -DERR1 257 -cp ${test} ${abspath ${@}} 258 259 raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa ${CFACCBIN} 260 ${CFACOMPILE_SYNTAX} -DERR2 261 -cp ${test} ${abspath ${@}} 192 alloc-ERROR : alloc.cfa $(CFACCBIN) 193 $(CFACOMPILE_SYNTAX) -DERR1 194 -cp $(test) $(abspath ${@}) 195 196 init1-ERROR : init1.cfa $(CFACCBIN) 197 $(CFACOMPILE_SYNTAX) -DERR1 198 -cp $(test) $(abspath ${@}) 199 200 typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN) 201 $(CFACOMPILE_SYNTAX) -DERR1 202 -cp $(test) $(abspath ${@}) 203 204 nested-types-ERR1 : nested-types.cfa $(CFACCBIN) 205 $(CFACOMPILE_SYNTAX) -DERR1 206 -cp $(test) $(abspath ${@}) 207 208 nested-types-ERR2 : nested-types.cfa $(CFACCBIN) 209 $(CFACOMPILE_SYNTAX) -DERR2 210 -cp $(test) $(abspath ${@}) 211 212 raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN) 213 $(CFACOMPILE_SYNTAX) -DERR1 214 -cp $(test) $(abspath ${@}) 215 216 raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN) 217 $(CFACOMPILE_SYNTAX) -DERR1 218 -cp $(test) $(abspath ${@}) 219 220 raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN) 221 $(CFACOMPILE_SYNTAX) -DERR1 222 -cp $(test) $(abspath ${@}) 223 224 raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN) 225 $(CFACOMPILE_SYNTAX) -DERR2 226 -cp $(test) $(abspath ${@}) 262 227 263 228 # Exception Tests 264 229 # Test with libcfathread; it changes how storage works. 265 230 266 exceptions/%-threads : exceptions/%.cfa $ {CFACCBIN}267 $ {CFACOMPILETEST} -include exceptions/with-threads.hfa -c -o ${abspath ${@}}.o268 $ {CFACCLOCAL} ${${shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g'}} ${abspath ${@}}.o -o ${abspath ${@}}231 exceptions/%-threads : exceptions/%.cfa $(CFACCBIN) 232 $(CFACOMPILETEST) -include exceptions/with-threads.hfa -c -o $(abspath ${@}).o 233 $(CFACCLOCAL) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) $(abspath ${@}).o -o $(abspath ${@}) 269 234 270 235 # Linking tests 271 236 # Meta tests to make sure we see linking errors (can't compile with -O2 since it may multiply number of calls) 272 linking/linkerror : linking/linkerror.cfa $ {CFACCBIN}273 $ {CFACOMPILETEST} -O0 -c -o ${abspath ${@}}.o274 $ {CFACCLINK} -O0 ${@}.o -o ${abspath ${@}}275 rm $ {abspath ${@}}.o237 linking/linkerror : linking/linkerror.cfa $(CFACCBIN) 238 $(CFACOMPILETEST) -O0 -c -o $(abspath ${@}).o 239 $(CFACCLINK) -O0 ${@}.o -o $(abspath ${@}) 240 rm $(abspath ${@}).o 276 241 277 242 #------------------------------------------------------------------------------ -
tests/PRNG.cfa
r24d6572 r34b4268 1 // 1 // -*- Mode: C -*- 2 // 2 3 // Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo 3 // 4 // PRNG.c -- high-perforamnce pseudo-random numbers 5 // 6 // The contents of this file are covered under the licence agreement in the 7 // file "LICENCE" distributed with Cforall. 8 // 4 // 5 // PRNG.c -- 6 // 9 7 // Author : Peter A. Buhr 10 8 // Created On : Wed Dec 29 09:38:12 2021 11 9 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu May 25 15:39:52 202313 // Update Count : 42210 // Last Modified On : Tue Nov 22 22:51:12 2022 11 // Update Count : 381 14 12 // 15 13 … … 17 15 #include <stdlib.hfa> // PRNG 18 16 #include <clock.hfa> 17 #include <thread.hfa> 19 18 #include <limits.hfa> // MAX 20 19 #include <math.hfa> // sqrt 21 20 #include <malloc.h> // malloc_stats 22 21 #include <locale.h> // setlocale 23 #include <thread.hfa>24 22 #include <mutex_stmt.hfa> 25 23 26 #define xstr(s) str(s) 27 #define str(s) #s 28 29 #if defined( __x86_64__ ) || defined( __aarch64__ ) // 64-bit architecture 24 #ifdef __x86_64__ // 64-bit architecture 30 25 #define PRNG PRNG64 31 26 #else // 32-bit architecture 32 27 #define PRNG PRNG32 33 28 #endif // __x86_64__ 34 35 //#define TIME36 29 37 30 #ifdef TIME // use -O2 -nodebug … … 45 38 #endif // TIME 46 39 47 static void avgstd( size_t trials, size_t buckets[] ) {48 size_t min = MAX, max = 0;40 void avgstd( unsigned int buckets[] ) { 41 unsigned int min = MAX, max = 0; 49 42 double sum = 0.0, diff; 50 43 for ( i; BUCKETS ) { … … 61 54 } // for 62 55 double std = sqrt( sum / BUCKETS ); 63 mutex( sout ) sout | "trials" | trials| "buckets" | BUCKETS56 mutex( sout ) sout | "trials" | TRIALS | "buckets" | BUCKETS 64 57 | "min" | min | "max" | max 65 58 | "avg" | wd(0,1, avg) | "std" | wd(0,1, std) | "rstd" | wd(0,1, (avg == 0 ? 0.0 : std / avg * 100)) | "%"; … … 67 60 68 61 69 size_t seed = 1009;62 unsigned int seed = 1009; 70 63 71 64 thread T1 {}; 72 65 void main( T1 & ) { 73 size_t * buckets = calloc( BUCKETS );// too big for task stack74 for ( TRIALS / 50 ) {66 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 67 for ( TRIALS / 100 ) { 75 68 buckets[rand() % BUCKETS] += 1; // concurrent 76 69 } // for 77 avgstd( TRIALS / 50,buckets );70 avgstd( buckets ); 78 71 free( buckets ); 79 72 } // main … … 83 76 PRNG prng; 84 77 if ( seed != 0 ) set_seed( prng, seed ); 85 size_t * buckets = calloc( BUCKETS );// too big for task stack78 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 86 79 for ( TRIALS ) { 87 80 buckets[prng( prng ) % BUCKETS] += 1; // concurrent 88 81 } // for 89 avgstd( TRIALS,buckets );82 avgstd( buckets ); 90 83 free( buckets ); 91 84 } // main … … 93 86 thread T3 {}; 94 87 void main( T3 & th ) { 95 size_t * buckets = calloc( BUCKETS );// too big for task stack96 for ( TRIALS / 5) {88 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 89 for ( TRIALS ) { 97 90 buckets[prng() % BUCKETS] += 1; // concurrent 98 91 } // for 99 avgstd( TRIALS / 5,buckets );92 avgstd( buckets ); 100 93 free( buckets ); 101 94 } // main … … 103 96 thread T4 {}; 104 97 void main( T4 & th ) { 105 size_t * buckets = calloc( BUCKETS );// too big for task stack98 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 106 99 for ( TRIALS ) { 107 buckets[prng( th ) % BUCKETS] += 1; // concurrent108 } // for 109 avgstd( TRIALS,buckets );100 buckets[prng( th ) % BUCKETS] += 1; // concurrent 101 } // for 102 avgstd( buckets ); 110 103 free( buckets ); 111 104 } // main … … 115 108 static void dummy( thread$ & th ) __attribute__(( noinline )); 116 109 static void dummy( thread$ & th ) { 117 size_t * buckets = (size_t *)calloc( BUCKETS, sizeof(size_t) ); // too big for task stack118 for ( size_t i = 0; i < TRIALS; i += 1 ) {110 unsigned int * buckets = (unsigned int *)calloc( BUCKETS, sizeof(unsigned int) ); // too big for task stack 111 for ( unsigned int i = 0; i < TRIALS; i += 1 ) { 119 112 buckets[prng( th ) % BUCKETS] += 1; // sequential 120 113 } // for 121 avgstd( TRIALS,buckets );114 avgstd( buckets ); 122 115 free( buckets ); 123 116 } // dummy 124 117 125 126 118 int main() { 127 // setlocale( LC_NUMERIC, getenv( "LANG" ) ); // causes leaked storage message 128 129 // only works on the current pthread thread 130 // locale_t loc = newlocale( LC_NUMERIC_MASK, getenv( "LANG" ), (locale_t)0p ); 131 // if ( loc == (locale_t)0p ) abort( "newlocale" ); 132 // uselocale( loc ); 119 // causes leaked storage message 120 // setlocale( LC_NUMERIC, getenv( "LANG" ) ); // print digit separator 133 121 134 122 enum { TASKS = 4 }; 135 123 Time start; 136 137 124 #ifdef TIME // too slow for test and generates non-repeatable results 138 125 #if 1 139 sout | "glib rand" | nl | nl; 140 141 size_t rseed; 126 unsigned int rseed; 142 127 if ( seed != 0 ) rseed = seed; 143 128 else rseed = rdtscl(); … … 145 130 146 131 sout | sepDisable; 147 sout | nl | wd(26, "rand()" ) | wd(12, "rand(5)") | wd(12, "rand(0,5)" );148 for ( 20 ) { 149 sout | wd( 26, rand()) | nonl;150 sout | wd(1 2, rand() % 5) | nonl;151 sout | wd(1 2, rand() % (5 - 0 + 1) + 0);132 sout | wd(13, "rand()" ) | wd(10, "rand(5)") | wd(13, "rand(0,5)" ); 133 for ( 20 ) { 134 sout | wd(13, rand()) | nonl; 135 sout | wd(10, rand() % 5) | nonl; 136 sout | wd(13, rand() % (5 - 0 + 1) + 0); 152 137 } // for 153 138 sout | sepEnable; … … 157 142 STARTTIME; 158 143 { 159 size_t * buckets = calloc( BUCKETS );// too big for task stack160 for ( i; TRIALS / 5) {144 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 145 for ( i; TRIALS / 10 ) { 161 146 buckets[rand() % BUCKETS] += 1; // sequential 162 147 } // for 163 avgstd( TRIALS / 5,buckets );148 avgstd( buckets ); 164 149 free( buckets ); 165 150 } 166 ENDTIME( " x 5" );151 ENDTIME( " x 10 " ); 167 152 168 153 sout | nl | "Concurrent"; … … 174 159 } // wait for threads to complete 175 160 } 176 ENDTIME( " x 50 " );161 ENDTIME( " x 100 " ); 177 162 #endif // 0 178 163 #endif // TIME 179 180 sout | nl | "CFA " xstr(PRNG_NAME);181 182 164 #if 1 183 165 PRNG prng; … … 186 168 187 169 sout | sepDisable; 188 sout | nl | wd( 26, "PRNG()" ) | wd(12, "PRNG(5)") | wd(12, "PRNG(0,5)" );189 for ( 20 ) { 190 sout | wd( 26, prng( prng )) | nonl; // cascading => side-effect functions called in arbitary order191 sout | wd(1 2, prng( prng, 5 )) | nonl;192 sout | wd(1 2, prng( prng, 0, 5 ));170 sout | nl | wd(13, "PRNG()" ) | wd(10, "PRNG(5)") | wd(13, "PRNG(0,5)" ); 171 for ( 20 ) { 172 sout | wd(13, prng( prng )) | nonl; // cascading => side-effect functions called in arbitary order 173 sout | wd(10, prng( prng, 5 )) | nonl; 174 sout | wd(13, prng( prng, 0, 5 )); 193 175 } // for 194 176 sout | sepEnable; … … 198 180 STARTTIME; 199 181 { 200 size_t * buckets = calloc( BUCKETS );// too big for task stack182 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 201 183 for ( TRIALS ) { 202 184 buckets[prng( prng ) % BUCKETS] += 1; // sequential 203 185 } // for 204 avgstd( TRIALS,buckets );186 avgstd( buckets ); 205 187 free( buckets ); 206 188 } … … 221 203 222 204 sout | sepDisable; 223 sout | nl | wd( 26, "prng()" ) | wd(12, "prng(5)") | wd(12, "prng(0,5)" );224 for ( 20 ) { 225 sout | wd( 26, prng()) | nonl; // cascading => side-effect functions called in arbitary order226 sout | wd(1 2, prng( 5 )) | nonl;227 sout | wd(1 2, prng( 0, 5 ));205 sout | nl | wd(13, "prng()" ) | wd(10, "prng(5)") | wd(13, "prng(0,5)" ); 206 for ( 20 ) { 207 sout | wd(13, prng()) | nonl; // cascading => side-effect functions called in arbitary order 208 sout | wd(10, prng( 5 )) | nonl; 209 sout | wd(13, prng( 0, 5 )); 228 210 } // for 229 211 sout | sepEnable; … … 233 215 STARTTIME; 234 216 { 235 size_t * buckets = calloc( BUCKETS );// too big for task stack236 for ( TRIALS / 5) {217 unsigned int * buckets = calloc( BUCKETS ); // too big for task stack 218 for ( TRIALS ) { 237 219 buckets[prng() % BUCKETS] += 1; 238 220 } // for 239 avgstd( TRIALS / 5,buckets );221 avgstd( buckets ); 240 222 free( buckets ); 241 223 } 242 ENDTIME( " x 5 ");224 ENDTIME(); 243 225 244 226 sout | nl | "Concurrent"; … … 250 232 } // wait for threads to complete 251 233 } 252 ENDTIME( " x 5 ");234 ENDTIME(); 253 235 #endif // 0 254 236 #if 1 … … 257 239 258 240 sout | sepDisable; 259 sout | nl | wd( 26, "prng(t)" ) | wd(12, "prng(t,5)") | wd(12, "prng(t,0,5)" );260 for ( 20 ) { 261 sout | wd( 26, prng( th )) | nonl; // cascading => side-effect functions called in arbitary order262 sout | wd(1 2, prng( th, 5 )) | nonl;263 sout | wd(1 2, prng( th, 0, 5 ));241 sout | nl | wd(13, "prng(t)" ) | wd(10, "prng(t,5)") | wd(13, "prng(t,0,5)" ); 242 for ( 20 ) { 243 sout | wd(13, prng( th )) | nonl; // cascading => side-effect functions called in arbitary order 244 sout | wd(10, prng( th, 5 )) | nonl; 245 sout | wd(13, prng( th, 0, 5 )); 264 246 } // for 265 247 sout | sepEnable; … … 284 266 #endif // 0 285 267 // malloc_stats(); 286 // freelocale( loc );287 268 } // main 288 269 -
tests/array.cfa
r24d6572 r34b4268 15 15 // 16 16 17 // Tests syntax. Comments explain semantics. Test does not show semantics. 18 // Mostly illustrates facts about C (with which CFA is being tested to agree).19 // Is a test oracle under `gcc -x c`.17 int a1[0]; 18 //int a2[*]; 19 //double a4[3.0]; 20 20 21 #ifdef ERR1 22 #define E1(...) __VA_ARGS__ 23 #else 24 #define E1(...) 25 #endif 21 int m1[0][3]; 22 //int m2[*][*]; 23 int m4[3][3]; 26 24 27 #ifdef ERR2 28 #define E2(...) __VA_ARGS__ 29 #else 30 #define E2(...) 31 #endif 25 typedef int T; 32 26 33 #ifdef ERR3 34 #define E3(...) __VA_ARGS__ 35 #else 36 #define E3(...) 37 #endif 27 int fred() { 28 // int a1[]; 29 // int a2[*]; 30 int a4[3]; 31 int T[3]; 32 } 38 33 39 int a1[0]; 40 E1( int a2[*]; ) 41 #ifndef __cforall 42 E1( double a4[3.0]; ) // BUG 275: CFA accepts but should reject 43 #endif 34 int mary( int T[3], 35 int p1[const 3], 36 int p2[static 3], 37 int p3[static const 3] 38 ) { 39 } 44 40 45 int m1[0][3]; 46 E1( int m2[*][*]; ) 47 int m4[3][3]; 41 int (*tom())[3] { 42 } 48 43 49 typedef int T; 50 51 int fred(int n) { 52 E1( int a1[]; ) 53 E1( int a2[*]; ) 54 int a4[3]; 55 int T[3]; 56 int a5[n]; 57 } 58 59 int mary( int T[3], // same as: int *T 60 int p1[const 3], // same as: int const *p1 61 int p2[static 3], // same as T, but length >=3 checked 62 int p3[static const 3] // both above: 3 is static, p3 is const 63 ) { 64 } 65 66 // function taking (), returning pointer to array of ints 67 int (*tom())[3] { 68 } 69 70 // function taking (), returning pointer to function of same type as mary 71 int (*(jane)())( int T[3], 72 int p1[const 3], 73 int p2[static 3], 74 int p3[static const 3] 75 ) { 76 } 77 78 // functions returning same exotic pointers, in CFA's non-onion syntax 79 #ifdef __cforall 80 [ * [3] int ] toms_twin(...) { 81 } 82 [ * [int]( [3] int T, 83 [const 3] int p1, 84 [static 3] int p2, 85 [static const 3] int p3 86 ) 87 ] janes_twin(...) { 88 } 89 #endif 90 91 // GCC 11+ gives a false warning (-Wvla-parameter) on the valid (C11 ARM p134-135) combination: 92 // declare with type int[*], define with type int[n]. 93 // https://gcc.gnu.org/bugzilla//show_bug.cgi?id=100420 suggests the internal representation of 94 // of a[*] is the same as a[0]. 95 // https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wno-vla-parameter explains 96 // the purpose of -Wvla-parameter is to report conflicts between int[] and int[n], which would 97 // understandably also include those between int[42] and int[n]. 98 // https://stackoverflow.com/questions/17371645/why-use-an-asterisk-instead-of-an-integer-for-a-vla-array-parameter-of-a-f 99 // explains the declare-*, define-n pattern. 100 101 // To work around the false warning, and keep to this test's purpose of exercising CFA's 102 // handling of exotic C array syntax, what would ideally be demonstrated as a declaration of 103 // fm1, followed by its definition, is instead split into fm1x and fm1y. And similarly for 104 // fm5. 105 106 int fm1x( int, int, int[][*] ); 107 int fm1y( int r, int c, int m[][c] ) {} 108 int fm2( int r, int c, int (*m)[c] ) {} // same as fm1 109 E2( int fm3( int r, int c, int m[][static c] ) {} ) // that's not static 110 E3( int fm4( int r, int c, int m[][] ); ) // m's immediate element type is incomplete 111 int fm5x( int, int, int[*][*] ); // same as fm1 decl 112 #ifndef __cforall 113 int fm5y( int r, int c, int m[r][c] ) {} // BUG 276: CFA chokes but should accept 114 // C: same as fm1 defn 115 #endif 116 44 int (*(jane)())( int T[3], 45 int p1[const 3], 46 int p2[static 3], 47 int p3[static const 3] 48 ) { 49 } 117 50 118 51 int main() { 119 #pragma GCC warning " Preprocessor started"// force non-empty .expect file, NO TABS!!!52 #pragma GCC warning "Compiled" // force non-empty .expect file, NO TABS!!! 120 53 } 121 54 -
tests/attributes.cfa
r24d6572 r34b4268 10 10 // Created On : Mon Feb 6 16:07:02 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 23 20:33:07 202313 // Update Count : 3 912 // Last Modified On : Mon Mar 15 13:53:31 2021 13 // Update Count : 38 14 14 // 15 15 … … 22 22 23 23 // aggregate_name 24 st atic struct __attribute__(( unused )) {} Dummy;24 struct __attribute__(( unused )) {} Dummy; 25 25 struct __attribute__(( unused )) Agn1; 26 26 struct __attribute__(( unused )) Agn2 {}; -
tests/avltree/avl.h
r24d6572 r34b4268 9 9 // #include <lib.h> 10 10 11 forall(T) 12 trait Comparable { 11 trait Comparable(T) { 13 12 int ?<?(T, T); 14 13 }; -
tests/collections/vector-demo.cfa
r24d6572 r34b4268 143 143 assert( v`capacity > 5 && v`length == 5 ); 144 144 145 v[2] = -0.1 f; // v is [0.0, 98.6, -0.1, 0.2, 0.3]; iter at -0.1, where only the new memory had that change145 v[2] = -0.1; // v is [0.0, 98.6, -0.1, 0.2, 0.3]; iter at -0.1, where only the new memory had that change 146 146 147 147 float val3 = iter`val; -
tests/declarationSpecifier.cfa
r24d6572 r34b4268 10 10 // Created On : Wed Aug 17 08:21:04 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 23 20:53:31 202313 // Update Count : 812 // Last Modified On : Tue Apr 30 18:20:36 2019 13 // Update Count : 4 14 14 // 15 15 … … 25 25 short int volatile static const x8; 26 26 27 static const volatile struct { int i; } x10; 28 static const struct { int i; } volatile x11; 29 static struct { int i; } const volatile x12; 30 const static struct { int i; } volatile x13; 31 struct { int i; } static const volatile x14; 32 struct { int i; } const static volatile x15; 33 struct { int i; } const volatile static x16; 27 const volatile struct { int i; } x10; 28 const struct { int i; } volatile x11; 29 struct { int i; } const volatile x12; 30 static const volatile struct { int i; } x13; 31 const static struct { int i; } volatile x14; 32 struct { int i; } static const volatile x15; 33 struct { int i; } const static volatile x16; 34 struct { int i; } const volatile static x17; 34 35 35 36 const Int volatile x20; … … 42 43 Int volatile static const x27; 43 44 44 static const volatile struct { Int i; } x29; 45 static const struct { Int i; } volatile x30; 46 static struct { Int i; } const volatile x31; 47 const static struct { Int i; } volatile x32; 48 struct { Int i; } static const volatile x33; 49 struct { Int i; } const static volatile x34; 50 struct { Int i; } const volatile static x35; 45 const volatile struct { Int i; } x29; 46 const struct { Int i; } volatile x30; 47 struct { Int i; } const volatile x31; 48 static const volatile struct { Int i; } x32; 49 const static struct { Int i; } volatile x33; 50 struct { Int i; } static const volatile x34; 51 struct { Int i; } const static volatile x35; 52 struct { Int i; } const volatile static x36; 51 53 52 54 _Thread_local int x37; -
tests/enum_tests/.expect/typedIntEnum.txt
r24d6572 r34b4268 1 0 =02 1 =13 1000 =10004 1001 =10015 2000 =20006 2001 =20017 2002 =20021 0 2 1 3 1000 4 1001 5 2000 6 2001 7 2002 -
tests/enum_tests/pointerEnum.cfa
r24d6572 r34b4268 11 11 int main() { 12 12 E * v = First; 13 //sout | "v: " | e.x;13 sout | "v: " | e.x; 14 14 } -
tests/enum_tests/typedIntEnum.cfa
r24d6572 r34b4268 12 12 13 13 int main() { 14 printf(" 0=%d\n", zero);15 printf(" 1=%d\n", one);16 printf(" 1000=%d\n", thousand);17 printf(" 1001=%d\n", thousand_one);18 printf(" 2000=%d\n", two_thousand);19 printf(" 2001=%d\n", two_thousand_one);20 printf(" 2002=%d\n", two_thousand_two);14 printf("%d\n", zero); 15 printf("%d\n", one); 16 printf("%d\n", thousand); 17 printf("%d\n", thousand_one); 18 printf("%d\n", two_thousand); 19 printf("%d\n", two_thousand_one); 20 printf("%d\n", two_thousand_two); 21 21 return 0; 22 22 } -
tests/errors/.expect/declaration.txt
r24d6572 r34b4268 1 errors/declaration.cfa:16:1 error: duplicate static storage class(es)in declaration of x1: static const volatile short int1 errors/declaration.cfa:16:1 error: duplicate static in declaration of x1: static const volatile short int 2 2 3 errors/declaration.cfa:17:1 error: conflicting extern & static storage classesin declaration of x2: extern const volatile short int3 errors/declaration.cfa:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int 4 4 5 errors/declaration.cfa:18:1 error: conflicting extern & auto storage classes, conflicting extern & static storage classes, conflicting extern & static storage classes, duplicate extern storage class(es)in declaration of x3: extern const volatile short int5 errors/declaration.cfa:18:1 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int 6 6 7 errors/declaration.cfa:19:1 error: duplicate static storage class(es)in declaration of x4: static const volatile instance of const volatile struct __anonymous07 errors/declaration.cfa:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0 8 8 with members 9 9 i: int … … 11 11 12 12 13 errors/declaration.cfa:20:1 error: duplicate const qualifier(s), duplicate static storage class(es), duplicate volatile qualifier(s)in declaration of x5: static const volatile instance of const volatile struct __anonymous113 errors/declaration.cfa:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1 14 14 with members 15 15 i: int … … 17 17 18 18 19 errors/declaration.cfa:22:1 error: duplicate static storage class(es)in declaration of x6: static const volatile Int19 errors/declaration.cfa:22:1 error: duplicate static in declaration of x6: static const volatile Int 20 20 21 errors/declaration.cfa:24:1 error: duplicate const qualifier(s)in declaration of f01: static inline function21 errors/declaration.cfa:24:1 error: duplicate const in declaration of f01: static inline function 22 22 with no parameters 23 23 returning const volatile int 24 24 25 25 26 errors/declaration.cfa:25:1 error: duplicate volatile qualifier(s)in declaration of f02: static inline function26 errors/declaration.cfa:25:1 error: duplicate volatile in declaration of f02: static inline function 27 27 with no parameters 28 28 returning const volatile int 29 29 30 30 31 errors/declaration.cfa:26:1 error: duplicate const qualifier(s)in declaration of f03: static inline function31 errors/declaration.cfa:26:1 error: duplicate const in declaration of f03: static inline function 32 32 with no parameters 33 33 returning const volatile int 34 34 35 35 36 errors/declaration.cfa:27:1 error: duplicate volatile qualifier(s)in declaration of f04: static inline function36 errors/declaration.cfa:27:1 error: duplicate volatile in declaration of f04: static inline function 37 37 with no parameters 38 38 returning const volatile int 39 39 40 40 41 errors/declaration.cfa:28:1 error: duplicate const qualifier(s)in declaration of f05: static inline function41 errors/declaration.cfa:28:1 error: duplicate const in declaration of f05: static inline function 42 42 with no parameters 43 43 returning const volatile int 44 44 45 45 46 errors/declaration.cfa:29:1 error: duplicate volatile qualifier(s)in declaration of f06: static inline function46 errors/declaration.cfa:29:1 error: duplicate volatile in declaration of f06: static inline function 47 47 with no parameters 48 48 returning const volatile int 49 49 50 50 51 errors/declaration.cfa:30:1 error: duplicate const qualifier(s)in declaration of f07: static inline function51 errors/declaration.cfa:30:1 error: duplicate const in declaration of f07: static inline function 52 52 with no parameters 53 53 returning const volatile int 54 54 55 55 56 errors/declaration.cfa:31:1 error: duplicate const volatile qualifier(s)in declaration of f08: static inline function56 errors/declaration.cfa:31:1 error: duplicate const, duplicate volatile in declaration of f08: static inline function 57 57 with no parameters 58 58 returning const volatile int 59 59 60 60 61 errors/declaration.cfa:33:1 error: duplicate const volatile qualifier(s)in declaration of f09: static inline function61 errors/declaration.cfa:33:1 error: duplicate const, duplicate volatile in declaration of f09: static inline function 62 62 with no parameters 63 63 returning const volatile int 64 64 65 65 66 errors/declaration.cfa:34:1 error: duplicate const qualifier(s), duplicate _Atomic qualifier(s), duplicate _Atomic qualifier(s), duplicate const restrict volatile qualifier(s)in declaration of f09: static inline function66 errors/declaration.cfa:34:1 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function 67 67 with no parameters 68 68 returning const restrict volatile _Atomic int -
tests/forall.cfa
r24d6572 r34b4268 10 10 // Created On : Wed May 9 08:48:15 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 23 20:29:59 2023 13 // Update Count : 91 14 // 15 16 #include <fstream.hfa> 12 // Last Modified On : Sat Jun 5 10:06:08 2021 13 // Update Count : 36 14 // 17 15 18 16 void g1() { 19 forall( T ) T f( T p ) { sout | 'f'; return p; }; 20 void f( int p ) { sout | p; }; 21 void g( void ) { sout | 'g'; }; 22 void h( void (*p)(void) ) { p(); }; 23 24 int x = 1; 25 void (*y)(void) = g; 26 char z = 'a'; 27 float w = 3.5; 17 forall( T ) T f( T ) {}; 18 void f( int ) {}; 19 void h( void (*p)(void) ) {}; 20 21 int x; 22 void (*y)(void); 23 char z; 24 float w; 28 25 29 26 f( x ); … … 31 28 f( z ); 32 29 f( w ); 33 h( y );34 f( y );35 30 h( f( y ) ); 36 31 } 37 32 38 33 void g2() { 39 forall( T ) void f( T, T ) { sout | "fT";}40 forall( T, U ) void f( T, U ) { sout | "fTU";}34 forall( T ) void f( T, T ) {} 35 forall( T, U ) void f( T, U ) {} 41 36 42 37 int x; 43 38 float y; 44 int * z; 45 float * w; 46 47 f( x, x ); 48 f( y, y ); 49 f( w, w ); 39 int *z; 40 float *w; 41 50 42 f( x, y ); 51 43 f( z, w ); … … 58 50 59 51 forall( T ) 60 void swap( T & left, T & right ) { // by reference 61 T temp = left; 62 left = right; 63 right = temp; 64 } 65 66 forall( T ) 67 [ T, T ] swap( T i, T j ) { // by value 68 return [ j, i ]; 69 } 70 71 forall( T ) trait sumable { 52 void swap( T left, T right ) { 53 T temp = left; 54 left = right; 55 right = temp; 56 } 57 58 trait sumable( T ) { 72 59 void ?{}( T &, zero_t ); // 0 literal constructor 73 60 T ?+?( T, T ); // assortment of additions … … 77 64 }; // sumable 78 65 79 forall( T | sumable( T ) ) // use trait66 forall( T | sumable( T ) ) // use trait 80 67 T sum( size_t size, T a[] ) { 81 68 T total = 0; // initialize by 0 constructor … … 85 72 } // sum 86 73 87 forall( T | { T ?+?( T, T ); T ?++( T & ); [T] ?+=?( T &, T ); } )74 forall( T | { T ?+?( T, T ); T ?++( T & ); [T] ?+=?( T &,T ); } ) 88 75 T twice( T t ) { 89 76 return t + t; … … 95 82 } 96 83 97 voidfred() {98 int x = 1, y = 2, a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };84 int fred() { 85 int x = 1, y = 2, a[10]; 99 86 float f; 100 87 101 sout | x | y;102 88 swap( x, y ); 103 sout | x | y | nl | swap( x, y ); 104 // [ x, y ] = swap( y, x ); 105 sout | twice( ' ' ) | ' ' | twice( 0hh ) | twice( 1h ) | twice( 0n ) | twice( 2 ) 106 | twice( 3.2f ) | twice( 3.2 ) | twice( 3.2d ) | twice( 3.2+1.5i ) | twice( x ); 89 twice( x ); 107 90 f = min( 4.0, 3.0 ); 108 sout | f | min( 4.0, 3.0 ); 109 sout | sum( 10, a ); 91 sum( 10, a ); 110 92 } 111 93 … … 195 177 196 178 forall( T ) struct S { T t; } (int) x, y, z; 197 staticforall( T ) struct { T t; } (int) a, b, c;179 forall( T ) struct { T t; } (int) a, b, c; 198 180 199 181 forall( T ) static forall( S ) { … … 204 186 205 187 forall( T ) { 206 //extern "C" {188 extern "C" { 207 189 struct SS { T t; }; 208 T foo( T p ) { return p;}209 //}190 T foo( T ) {} 191 } 210 192 } 211 193 … … 213 195 W(int,int) w; 214 196 215 voidjane() {197 int jane() { 216 198 // int j = bar( 3, 4 ); 217 199 int k = baz( 3, 4, 5 ); 218 200 int i = foo( 3 ); 219 sout | k | i;220 201 } 221 202 … … 230 211 T t; 231 212 T t2 = t; 232 sout | &tr | tp;233 213 } 234 214 … … 262 242 263 243 int main( void ) { 264 g1(); 265 g2(); 266 fred(); 267 jane(); 244 #pragma GCC warning "Compiled" // force non-empty .expect file, NO TABS!!! 268 245 } 269 246 -
tests/function-operator.cfa
r24d6572 r34b4268 10 10 // Created On : Fri Aug 25 15:21:11 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 25 07:26:10 202313 // Update Count : 1 212 // Last Modified On : Thu Apr 11 18:27:45 2019 13 // Update Count : 10 14 14 // 15 15 … … 22 22 23 23 // STL-like Algorithms 24 forall(T &, U &) 25 trait Assignable { T ?=?(T &, U); }; 26 forall(T &) 27 trait Copyable { void ?{}(T &, T); }; 28 forall(T &) 29 trait Destructable { void ^?{}(T &); }; 24 trait Assignable(T &, U &) { T ?=?(T &, U); }; 25 trait Copyable(T &) { void ?{}(T &, T); }; 26 trait Destructable(T &) { void ^?{}(T &); }; 30 27 31 28 trait Iterator(iter & | sized(iter) | Copyable(iter) | Destructable(iter), T) { -
tests/include/includes.cfa
r24d6572 r34b4268 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 22 10:16:58 202313 // Update Count : 81112 // Last Modified On : Sun May 22 08:27:20 2022 13 // Update Count : 779 14 14 // 15 15 … … 72 72 #include <gshadow.h> 73 73 #include <iconv.h> 74 //#include <ifaddrs.h> // causes warning messages that break the build 74 #include <ifaddrs.h> 75 75 #include <inttypes.h> 76 76 #include <langinfo.h> … … 97 97 #include <ncurses_dll.h> // may not be installed, comes with ncurses 98 98 #endif 99 //#include <netdb.h>99 #include <netdb.h> 100 100 #include <nl_types.h> 101 101 #include <nss.h> … … 111 111 #include <pwd.h> 112 112 #include <regex.h> 113 //#include <resolv.h>113 #include <resolv.h> 114 114 #include <re_comp.h> 115 115 #include <sched.h> … … 170 170 #endif // __CFA__ 171 171 172 int main( ) {172 int main( int argc, char const * argv[] ) { 173 173 #pragma GCC warning "Compiled" // force non-empty .expect file, NO TABS!!! 174 174 } -
tests/io/comp_basic.cfa
r24d6572 r34b4268 26 26 #include <unistd.h> 27 27 28 st atic struct {28 struct { 29 29 barrier & bar; 30 30 int pipe[2]; 31 31 32 } globals; 32 33 -
tests/io/comp_fair.cfa
r24d6572 r34b4268 26 26 #include <unistd.h> 27 27 28 st atic struct {28 struct { 29 29 barrier & bar; 30 30 int pipe[2]; 31 31 32 } globals; 32 33 -
tests/linking/mangling/header.hfa
r24d6572 r34b4268 8 8 extern name_but_a_typedefed_t a_typedefed_global; 9 9 10 // Must be extern C to prevent name mangling. 11 extern "C" { 12 extern struct /* anonymous */ { 13 int some_int; 14 int some_other_int; 15 } a_global_with_no_type; 16 } 10 extern struct /* anonymous */ { 11 int some_int; 12 int some_other_int; 13 } a_global_with_no_type; -
tests/linking/mangling/lib.cfa
r24d6572 r34b4268 3 3 name_but_a_typedefed_t a_typedefed_global; 4 4 5 // Must be extern C to prevent name mangling. 6 extern "C" { 7 // This declaration is necessary to create an instance of a_global_with_no_type. 8 // typeof is a trick to get a_global_with_no_type's type because its type is anonymous. 9 // Otherwise C generates conflicting types for a_global_with_no_type in .h and .c 10 // because C uses name equivalence and the two anonymous types cannot have the same name. 11 typeof(a_global_with_no_type) a_global_with_no_type; 12 } 5 struct { 6 int some_int; 7 int some_other_int; 8 } a_global_with_no_type; -
tests/linking/mangling/main.cfa
r24d6572 r34b4268 1 1 #include <fstream.hfa> 2 2 3 st atic struct { int a; } test; // purposefully before the include to force anonymous name numbering3 struct { int a; } test; //purposefully before the include 4 4 5 5 #include "header.hfa" … … 13 13 14 14 sout | "Done!"; 15 16 return 0; 15 17 } -
tests/pybin/settings.py
r24d6572 r34b4268 126 126 global archive 127 127 global install 128 global invariant129 128 130 129 global continue_ … … 141 140 all_install = [Install(o) for o in list(dict.fromkeys(options.install))] 142 141 archive = os.path.abspath(os.path.join(original_path, options.archive_errors)) if options.archive_errors else None 143 invariant = options.invariant144 142 continue_ = options.continue_ 145 143 dry_run = options.dry_run # must be called before tools.config_hash() -
tests/quotedKeyword.cfa
r24d6572 r34b4268 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 23 20:31:05 202313 // Update Count : 2 612 // Last Modified On : Fri Feb 7 19:07:07 2020 13 // Update Count : 25 14 14 // 15 15 16 16 #include <fstream.hfa> 17 17 18 st atic struct {18 struct { 19 19 int ``otype; 20 20 int ``struct; -
tests/sum.cfa
r24d6572 r34b4268 11 11 // Created On : Wed May 27 17:56:53 2015 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Fri Feb 24 22:52:12 202314 // Update Count : 34 713 // Last Modified On : Thu Aug 5 21:27:25 2021 14 // Update Count : 346 15 15 // 16 16 … … 18 18 #include <stdlib.hfa> 19 19 20 forall( T ) 21 trait sumable { 20 trait sumable( T ) { 22 21 void ?{}( T &, zero_t ); // 0 literal constructor 23 22 void ?{}( T &, one_t ); // 1 literal constructor -
tests/test.py
r24d6572 r34b4268 114 114 parser.add_argument('--install', help='Run all tests based on installed binaries or tree binaries', type=comma_separated(yes_no), default='no') 115 115 parser.add_argument('--continue', help='When multiple specifications are passed (debug/install/arch), sets whether or not to continue if the last specification failed', type=yes_no, default='yes', dest='continue_') 116 parser.add_argument('--invariant', help='Tell the compiler to check invariants while running.', action='store_true')117 116 parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=180) 118 117 parser.add_argument('--global-timeout', help='Maximum cumulative duration in seconds after the ALL tests are considered to have timed out', type=int, default=7200) … … 173 172 test.prepare() 174 173 175 # extra flags for cfa to pass through make.176 cfa_flags = 'CFAFLAGS=--invariant' if settings.invariant else None177 178 174 # ---------- 179 175 # MAKE … … 181 177 # build, skipping to next test on error 182 178 with Timed() as comp_dur: 183 make_ret, _, _ = make( test.target(), flags=cfa_flags, output_file=subprocess.DEVNULL, error=out_file, error_file=err_file)179 make_ret, _, _ = make( test.target(), output_file=subprocess.DEVNULL, error=out_file, error_file = err_file ) 184 180 185 181 # ----------
Note:
See TracChangeset
for help on using the changeset viewer.